diff --git a/DEPS b/DEPS index 540a4e19..1a536c6f 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '28f45b949acc746849100fbe112ee5280f0594c9', + 'skia_revision': '706d21ffd03a0a446f7b997c801356abb891eaeb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '3a64285df68a0f0791271cccf242e59e6b40b669', + 'v8_revision': '609ae417e503d25c01b7284e1d1eab3ddd853b75', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -59,7 +59,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5ad8474335798295a9c502999324635845d28ff7', + 'pdfium_revision': '258f19f26b3ccfc6b64429111a4a11bdc64be131', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -191,7 +191,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '60fc535386f97c6a0078738ba13ba3c4ef94ae01', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'a4cc90bc9bfb5cc932075aebccb734e38932b107', # commit position 11754 + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'f608241f0aa331004210377c2744a5e5e74c044f', # commit position 11893 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + 'c60ec8b35c3fe6027d7a3faae89d1c8d7dd3ce98', @@ -215,7 +215,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '73a89e6a418e17421667bdebbd9a8ad40512fecb', # commit position 11890 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '4b88ad3da9fe9ab8043593f577737ec531de1e86', # commit position 11897 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), @@ -270,7 +270,7 @@ 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + - '1ae15ca2ece76a60c1b1b20951c3cd38c2fa855a', + '271451854ad0fc877ee2ee2c380a0e30d00cb144', 'src/third_party/openh264/src': Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488', @@ -815,6 +815,21 @@ ], }, { + 'name': 'blimp_fonts', + 'pattern': '\\.sha1', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=linux*', + '--directory', + '--recursive', + '--quiet', + '--no_auth', + '--num_threads=16', + '--bucket', 'chromium-fonts', + 'src/third_party/blimp_fonts', + ], + }, + { # Pull sanitizer-instrumented third-party libraries if requested via # GYP_DEFINES. 'name': 'instrumented_libraries',
diff --git a/ash/mus/sysui_application.cc b/ash/mus/sysui_application.cc index 9154947..16585a31 100644 --- a/ash/mus/sysui_application.cc +++ b/ash/mus/sysui_application.cc
@@ -278,8 +278,7 @@ SysUIApplication::~SysUIApplication() {} void SysUIApplication::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { ash_init_.reset(new AshInit()); ash_init_->Initialize(connector);
diff --git a/ash/mus/sysui_application.h b/ash/mus/sysui_application.h index 78d15990..dba0f5e 100644 --- a/ash/mus/sysui_application.h +++ b/ash/mus/sysui_application.h
@@ -23,8 +23,7 @@ private: // mojo::ShellClient: void Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override;
diff --git a/base/win/object_watcher.cc b/base/win/object_watcher.cc index 93efd06..4df54a4 100644 --- a/base/win/object_watcher.cc +++ b/base/win/object_watcher.cc
@@ -51,7 +51,7 @@ object_ = NULL; wait_object_ = NULL; - MessageLoop::current()->RemoveDestructionObserver(this); + origin_loop_->RemoveDestructionObserver(this); return true; } @@ -82,6 +82,11 @@ NOTREACHED() << "Already watching an object"; return false; } + + origin_loop_ = MessageLoop::current(); + if (!origin_loop_) + return false; + run_once_ = execute_only_once; // Since our job is to just notice when an object is signaled and report the @@ -95,7 +100,6 @@ callback_ = base::Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(), delegate); object_ = object; - origin_loop_ = MessageLoop::current(); if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting, this, INFINITE, wait_flags)) { @@ -107,7 +111,7 @@ // We need to know if the current message loop is going away so we can // prevent the wait thread from trying to access a dead message loop. - MessageLoop::current()->AddDestructionObserver(this); + origin_loop_->AddDestructionObserver(this); return true; }
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h index 3701d0f..e1e86fe7 100644 --- a/base/win/object_watcher.h +++ b/base/win/object_watcher.h
@@ -46,6 +46,10 @@ // If the object is already signaled before being watched, OnObjectSignaled is // still called after (but not necessarily immediately after) watch is started. // +// NOTE: Use of this class requires that there be a current message loop; +// otherwise, when the object is signaled, there would be no loop to post the +// callback task to. This means that you cannot use ObjectWatcher in test code +// that doesn't create a message loop (unless you add such a loop). class BASE_EXPORT ObjectWatcher : public MessageLoop::DestructionObserver { public: class BASE_EXPORT Delegate { @@ -62,14 +66,14 @@ // When the object is signaled, the given delegate is notified on the thread // where StartWatchingOnce is called. The ObjectWatcher is not responsible for // deleting the delegate. - // Returns true if the watch was started. Otherwise, false is returned. + // Returns whether watching was successfully initiated. bool StartWatchingOnce(HANDLE object, Delegate* delegate); // Notifies the delegate, on the thread where this method is called, each time // the object is set. By definition, the handle must be an auto-reset object. // The caller must ensure that it (or any Windows system code) doesn't reset // the event or else the delegate won't be called. - // Returns true if the watch was started. Otherwise, false is returned. + // Returns whether watching was successfully initiated. bool StartWatchingMultipleTimes(HANDLE object, Delegate* delegate); // Stops watching. Does nothing if the watch has already completed. If the
diff --git a/base/win/registry.cc b/base/win/registry.cc index ee7b8cda..7837b8a68 100644 --- a/base/win/registry.cc +++ b/base/win/registry.cc
@@ -415,7 +415,7 @@ if (!key_watcher_) key_watcher_.reset(new Watcher(this)); - if (!key_watcher_.get()->StartWatching(key_, callback)) + if (!key_watcher_->StartWatching(key_, callback)) return false; return true;
diff --git a/blimp/README.md b/blimp/README.md index adff5d3..3ed48f9 100644 --- a/blimp/README.md +++ b/blimp/README.md
@@ -14,7 +14,10 @@ For running blimp, read more at [running](docs/running.md). +## Updating Fonts + +For updating the fonts that blimp supports, read more at [fonts](docs/fonts.md). + ## New to Markdown? For learning more about Markdown, read more at [markdown](docs/markdown.md). -
diff --git a/blimp/docs/container.md b/blimp/docs/container.md index 31adc80..7a1902a 100644 --- a/blimp/docs/container.md +++ b/blimp/docs/container.md
@@ -43,7 +43,7 @@ ```bash ./blimp/tools/generate-engine-manifest.py \ - --build-dir out-linux/Debug \ + --build-dir out-chromeos/Debug \ --target //blimp/engine:blimp_engine \ --output blimp/engine/engine-manifest.txt ``` @@ -56,7 +56,7 @@ Using the tarfile you can create a Docker image: ```bash -docker build -t blimp_engine - < ./out-linux/Debug/blimp_engine_bundle.tar +docker build -t blimp_engine - < ./out-chromeos/Debug/blimp_engine_bundle.tar.gz ``` ## Running the Engine in a Docker Container @@ -74,7 +74,8 @@ public certificate. Permissions should be set to 644. * `$CONFIG_DIR/client_token`: A file with a non-empty string used as the client token (the shared secret between the client and the engine). - Persmissions should also be set to 644. + Permissions should also be set to 644. See [running](running.md) for how + to get the default token from the source code. This setup step is only required once and can be reused for all the rest of the runs of the engine. @@ -94,4 +95,3 @@ ``` See the [blimp engine `Dockerfile`](../engine/Dockerfile) to find out what flags are passed by default. -
diff --git a/blimp/docs/fonts.md b/blimp/docs/fonts.md new file mode 100644 index 0000000..44b744f --- /dev/null +++ b/blimp/docs/fonts.md
@@ -0,0 +1,39 @@ +# Updating Blimp Fonts + +1. Clone the git-repositories listed in + `//third_party/blimp_fonts/README.chromium`, and roll forward to the commit + you want. +1. Copy the necessary files to `//third_party/blimp_fonts`. +1. Verify that the `LICENSE` file is still up to date and lists all relevant + licenses and which fonts use which license. +1. Update the `//third_party/blimp_fonts:fonts` target to include all the + current fonts and their license files. +1. Update the engine dependencies using + `//blimp/tools/generate-engine-manifest.py`. This step is documented in + `//blimp/docs/container.md`. +1. Run the `upload_to_google_storage.py` (from depot_tools) script to upload + the files. To do this, execute: + + ```bash + find ./third_party/blimp_fonts \ + -regex '^.*.\(ttf\|otf\)$' -type f -print0 | \ + upload_to_google_storage.py --use_null_terminator -b chromium-fonts - + ``` + + If the set of fonts includes more than `.ttf` or `.otf` files, you must + update the regular expression to include such fonts. +1. Verify that `//third_party/blimp_fonts/.gitignore` lists the correct files + to ignore. +1. Add all the `.sha1` files to the chromium src repository, by executing the + following command: + + ```bash + git add ./third_party/blimp_fonts/*.sha1 + ``` + +1. Commit and upload the change for review: + + ```bash + git commit + git cl upload + ```
diff --git a/blimp/docs/running.md b/blimp/docs/running.md index 8accd3e..bb92199f 100644 --- a/blimp/docs/running.md +++ b/blimp/docs/running.md
@@ -100,6 +100,8 @@ compositor. * `--disable-cached-picture-raster`: Ensures that rasterized content is not destroyed before serialization. +* `--android-fonts-path=$PATH`: Path to where the fonts are located. + Typically this would be `out-linux/Debug/gen/third_party/blimp_fonts`. #### Typical invocation When the client connects to a manually specified engine instead of using the @@ -122,6 +124,7 @@ --disable-cached-picture-raster \ --blimp-client-token-path=/tmp/blimpengine-token \ --user-data-dir=/tmp/blimpengine \ + --android-fonts-path=out-linux/Debug/gen/third_party/blimp_fonts \ --enable-logging=stderr \ --vmodule="blimp*=1" ```
diff --git a/blimp/engine/BUILD.gn b/blimp/engine/BUILD.gn index 5bd4c21..a19eb10 100644 --- a/blimp/engine/BUILD.gn +++ b/blimp/engine/BUILD.gn
@@ -223,6 +223,7 @@ ":blimp_engine_app", ":pak", "//sandbox/linux:chrome_sandbox", + "//third_party/blimp_fonts", ] # List dependencies as both deps and data_deps to ensure changes trigger a
diff --git a/blimp/engine/DEPS b/blimp/engine/DEPS index e4ebc4e..5c16370 100644 --- a/blimp/engine/DEPS +++ b/blimp/engine/DEPS
@@ -6,6 +6,7 @@ "+components/web_cache/renderer", "+content/public", "+net", + "+third_party/blimp_fonts", "+third_party/khronos/GLES2/gl2.h", "+third_party/WebKit/public/web/WebInputEvent.h", "+ui/aura",
diff --git a/blimp/engine/Dockerfile b/blimp/engine/Dockerfile index 0410cf8..7e3cbbaa 100644 --- a/blimp/engine/Dockerfile +++ b/blimp/engine/Dockerfile
@@ -13,7 +13,10 @@ RUN useradd -ms /bin/bash blimp_user +# The glob below expands to all files, but does not add directories +# recursively. ADD * /engine/ +ADD gen/third_party/blimp_fonts /engine/fonts RUN mv /engine/chrome_sandbox /engine/chrome-sandbox RUN chown -R blimp_user /engine @@ -21,4 +24,3 @@ WORKDIR "/engine" ENTRYPOINT ["/engine/start_engine.sh"] -
diff --git a/blimp/engine/engine-manifest.txt b/blimp/engine/engine-manifest.txt index d84b8f9..b24bcc8b 100644 --- a/blimp/engine/engine-manifest.txt +++ b/blimp/engine/engine-manifest.txt
@@ -1,7 +1,7 @@ # Runtime dependencies for the Blimp Engine # # This file was generated by running: -# generate-engine-manifest.py --build-dir out/Linux --target //blimp/engine:blimp_engine --output blimp/engine/engine-manifest.txt +# generate-engine-manifest.py --build-dir out-chromeos/Debug --target //blimp/engine:blimp_engine --output blimp/engine/engine-manifest.txt # # Note: Any unnecessary dependencies should be added to # manifest-blacklist.txt and this file should be regenerated. @@ -9,4 +9,209 @@ icudtl.dat natives_blob.bin blimp_engine.pak -./chrome_sandbox \ No newline at end of file +./chrome_sandbox +gen/third_party/blimp_fonts/AndroidClock.ttf +gen/third_party/blimp_fonts/AndroidClock_Highlight.ttf +gen/third_party/blimp_fonts/AndroidClock_Solid.ttf +gen/third_party/blimp_fonts/CarroisGothicSC-Regular.ttf +gen/third_party/blimp_fonts/Clockopia.ttf +gen/third_party/blimp_fonts/ComingSoon.ttf +gen/third_party/blimp_fonts/CutiveMono.ttf +gen/third_party/blimp_fonts/DancingScript-Bold.ttf +gen/third_party/blimp_fonts/DancingScript-Regular.ttf +gen/third_party/blimp_fonts/DroidSansFallback.ttf +gen/third_party/blimp_fonts/DroidSansFallbackFull.ttf +gen/third_party/blimp_fonts/DroidSansMono.ttf +gen/third_party/blimp_fonts/LICENSE +gen/third_party/blimp_fonts/LICENSE.Apache +gen/third_party/blimp_fonts/LICENSE.OFL +gen/third_party/blimp_fonts/MTLc3m.ttf +gen/third_party/blimp_fonts/MTLmr3m.ttf +gen/third_party/blimp_fonts/NanumGothic.ttf +gen/third_party/blimp_fonts/NanumGothicBold.ttf +gen/third_party/blimp_fonts/NotoColorEmoji.ttf +gen/third_party/blimp_fonts/NotoKufiArabic-Bold.ttf +gen/third_party/blimp_fonts/NotoKufiArabic-Regular.ttf +gen/third_party/blimp_fonts/NotoNaskhArabic-Bold.ttf +gen/third_party/blimp_fonts/NotoNaskhArabic-Regular.ttf +gen/third_party/blimp_fonts/NotoNaskhArabicUI-Bold.ttf +gen/third_party/blimp_fonts/NotoNaskhArabicUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSans-Bold.ttf +gen/third_party/blimp_fonts/NotoSans-BoldItalic.ttf +gen/third_party/blimp_fonts/NotoSans-Italic.ttf +gen/third_party/blimp_fonts/NotoSans-Regular.ttf +gen/third_party/blimp_fonts/NotoSansArmenian-Bold.ttf +gen/third_party/blimp_fonts/NotoSansArmenian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansAvestan-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBalinese-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBamum-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBatak-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBengali-Bold.ttf +gen/third_party/blimp_fonts/NotoSansBengali-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBengaliUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansBengaliUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBrahmi-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBuginese-Regular.ttf +gen/third_party/blimp_fonts/NotoSansBuhid-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCanadianAboriginal-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCarian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCham-Bold.ttf +gen/third_party/blimp_fonts/NotoSansCham-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCherokee-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCoptic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCuneiform-Regular.ttf +gen/third_party/blimp_fonts/NotoSansCypriot-Regular.ttf +gen/third_party/blimp_fonts/NotoSansDeseret-Regular.ttf +gen/third_party/blimp_fonts/NotoSansDevanagari-Bold.ttf +gen/third_party/blimp_fonts/NotoSansDevanagari-Regular.ttf +gen/third_party/blimp_fonts/NotoSansDevanagariUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansDevanagariUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansEgyptianHieroglyphs-Regular.ttf +gen/third_party/blimp_fonts/NotoSansEthiopic-Bold.ttf +gen/third_party/blimp_fonts/NotoSansEthiopic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGeorgian-Bold.ttf +gen/third_party/blimp_fonts/NotoSansGeorgian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGlagolitic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGothic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGujarati-Bold.ttf +gen/third_party/blimp_fonts/NotoSansGujarati-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGujaratiUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansGujaratiUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGurmukhi-Bold.ttf +gen/third_party/blimp_fonts/NotoSansGurmukhi-Regular.ttf +gen/third_party/blimp_fonts/NotoSansGurmukhiUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansGurmukhiUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansHanunoo-Regular.ttf +gen/third_party/blimp_fonts/NotoSansHebrew-Bold.ttf +gen/third_party/blimp_fonts/NotoSansHebrew-Regular.ttf +gen/third_party/blimp_fonts/NotoSansImperialAramaic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansInscriptionalPahlavi-Regular.ttf +gen/third_party/blimp_fonts/NotoSansInscriptionalParthian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansJP-Regular-Subsetted.otf +gen/third_party/blimp_fonts/NotoSansJP-Regular.otf +gen/third_party/blimp_fonts/NotoSansJavanese-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKR-Regular.otf +gen/third_party/blimp_fonts/NotoSansKaithi-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKannada-Bold.ttf +gen/third_party/blimp_fonts/NotoSansKannada-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKannadaUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansKannadaUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKayahLi-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKharoshthi-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKhmer-Bold.ttf +gen/third_party/blimp_fonts/NotoSansKhmer-Regular.ttf +gen/third_party/blimp_fonts/NotoSansKhmerUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansKhmerUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLao-Bold.ttf +gen/third_party/blimp_fonts/NotoSansLao-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLaoUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansLaoUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLepcha-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLimbu-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLinearB-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLisu-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLycian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansLydian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMalayalam-Bold.ttf +gen/third_party/blimp_fonts/NotoSansMalayalam-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMalayalamUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansMalayalamUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMandaic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMeeteiMayek-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMongolian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMyanmar-Bold.ttf +gen/third_party/blimp_fonts/NotoSansMyanmar-Regular.ttf +gen/third_party/blimp_fonts/NotoSansMyanmarUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansMyanmarUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansNKo-Regular.ttf +gen/third_party/blimp_fonts/NotoSansNewTaiLue-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOgham-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOlChiki-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOldItalic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOldPersian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOldSouthArabian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOldTurkic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOriya-Bold.ttf +gen/third_party/blimp_fonts/NotoSansOriya-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOriyaUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansOriyaUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansOsmanya-Regular.ttf +gen/third_party/blimp_fonts/NotoSansPhagsPa-Regular.ttf +gen/third_party/blimp_fonts/NotoSansPhoenician-Regular.ttf +gen/third_party/blimp_fonts/NotoSansRejang-Regular.ttf +gen/third_party/blimp_fonts/NotoSansRunic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSC-Regular.otf +gen/third_party/blimp_fonts/NotoSansSamaritan-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSaurashtra-Regular.ttf +gen/third_party/blimp_fonts/NotoSansShavian-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSinhala-Bold.ttf +gen/third_party/blimp_fonts/NotoSansSinhala-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSundanese-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSylotiNagri-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSymbols-Regular-Subsetted.ttf +gen/third_party/blimp_fonts/NotoSansSymbols-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSyriacEastern-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSyriacEstrangela-Regular.ttf +gen/third_party/blimp_fonts/NotoSansSyriacWestern-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTC-Regular.otf +gen/third_party/blimp_fonts/NotoSansTagalog-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTagbanwa-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTaiLe-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTaiTham-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTaiViet-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTamil-Bold.ttf +gen/third_party/blimp_fonts/NotoSansTamil-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTamilUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansTamilUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTelugu-Bold.ttf +gen/third_party/blimp_fonts/NotoSansTelugu-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTeluguUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansTeluguUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansThaana-Bold.ttf +gen/third_party/blimp_fonts/NotoSansThaana-Regular.ttf +gen/third_party/blimp_fonts/NotoSansThai-Bold.ttf +gen/third_party/blimp_fonts/NotoSansThai-Regular.ttf +gen/third_party/blimp_fonts/NotoSansThaiUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansThaiUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTibetan-Regular.ttf +gen/third_party/blimp_fonts/NotoSansTifinagh-Regular.ttf +gen/third_party/blimp_fonts/NotoSansUI-Bold.ttf +gen/third_party/blimp_fonts/NotoSansUI-BoldItalic.ttf +gen/third_party/blimp_fonts/NotoSansUI-Italic.ttf +gen/third_party/blimp_fonts/NotoSansUI-Regular.ttf +gen/third_party/blimp_fonts/NotoSansUgaritic-Regular.ttf +gen/third_party/blimp_fonts/NotoSansVai-Regular.ttf +gen/third_party/blimp_fonts/NotoSansYi-Regular.ttf +gen/third_party/blimp_fonts/NotoSerif-Bold.ttf +gen/third_party/blimp_fonts/NotoSerif-BoldItalic.ttf +gen/third_party/blimp_fonts/NotoSerif-Italic.ttf +gen/third_party/blimp_fonts/NotoSerif-Regular.ttf +gen/third_party/blimp_fonts/NotoSerifArmenian-Bold.ttf +gen/third_party/blimp_fonts/NotoSerifArmenian-Regular.ttf +gen/third_party/blimp_fonts/NotoSerifGeorgian-Bold.ttf +gen/third_party/blimp_fonts/NotoSerifGeorgian-Regular.ttf +gen/third_party/blimp_fonts/NotoSerifKhmer-Bold.ttf +gen/third_party/blimp_fonts/NotoSerifKhmer-Regular.ttf +gen/third_party/blimp_fonts/NotoSerifLao-Bold.ttf +gen/third_party/blimp_fonts/NotoSerifLao-Regular.ttf +gen/third_party/blimp_fonts/NotoSerifThai-Bold.ttf +gen/third_party/blimp_fonts/NotoSerifThai-Regular.ttf +gen/third_party/blimp_fonts/Roboto-Black.ttf +gen/third_party/blimp_fonts/Roboto-BlackItalic.ttf +gen/third_party/blimp_fonts/Roboto-Bold.ttf +gen/third_party/blimp_fonts/Roboto-BoldItalic.ttf +gen/third_party/blimp_fonts/Roboto-Italic.ttf +gen/third_party/blimp_fonts/Roboto-Light.ttf +gen/third_party/blimp_fonts/Roboto-LightItalic.ttf +gen/third_party/blimp_fonts/Roboto-Medium.ttf +gen/third_party/blimp_fonts/Roboto-MediumItalic.ttf +gen/third_party/blimp_fonts/Roboto-Regular.ttf +gen/third_party/blimp_fonts/Roboto-Thin.ttf +gen/third_party/blimp_fonts/Roboto-ThinItalic.ttf +gen/third_party/blimp_fonts/RobotoCondensed-Bold.ttf +gen/third_party/blimp_fonts/RobotoCondensed-BoldItalic.ttf +gen/third_party/blimp_fonts/RobotoCondensed-Italic.ttf +gen/third_party/blimp_fonts/RobotoCondensed-Light.ttf +gen/third_party/blimp_fonts/RobotoCondensed-LightItalic.ttf +gen/third_party/blimp_fonts/RobotoCondensed-Regular.ttf +gen/third_party/blimp_fonts/fonts.xml \ No newline at end of file
diff --git a/blimp/engine/start_engine.sh b/blimp/engine/start_engine.sh index f507c24..a9cf193 100755 --- a/blimp/engine/start_engine.sh +++ b/blimp/engine/start_engine.sh
@@ -8,11 +8,12 @@ -p /engine/data/stunnel.pem \ -P /engine/stunnel.pid \ -d 25466 -r 25467 -f & -/engine/blimp_engine_app \ +LD_LIBRARY_PATH=/engine/ /engine/blimp_engine_app \ --disable-gpu \ --use-remote-compositing \ --disable-cached-picture-raster \ --blimp-client-token-path=/engine/data/client_token \ + --android-fonts-path=/engine/fonts \ $@ & # Stop execution if either stunnel or blimp_engine_app die.
diff --git a/blimp/tools/manifest-blacklist.txt b/blimp/tools/manifest-blacklist.txt index ce4c1c9b..d21b052a 100644 --- a/blimp/tools/manifest-blacklist.txt +++ b/blimp/tools/manifest-blacklist.txt
@@ -2,13 +2,11 @@ # Wildcards (* or ?) are allowed. *.mojo +*mojom.js ./libfont_service_library.so ./libtracing_library.so ./libmus_library.so ./libosmesa.so ./libresource_provider_library.so ./mojo_runner -gen/* -mus/mus.mojo snapshot_blob.bin -
diff --git a/build/config/gcc/BUILD.gn b/build/config/gcc/BUILD.gn index 41473eb..2c1c61f 100644 --- a/build/config/gcc/BUILD.gn +++ b/build/config/gcc/BUILD.gn
@@ -60,7 +60,7 @@ } } -# Settings for executables and shared libraries. +# Settings for executables. config("executable_ldconfig") { if (is_android) { ldflags = [
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 5d31a221..9b5c57f6 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -83,8 +83,6 @@ clip_tree_index_(-1), scroll_tree_index_(-1), draw_depth_(0.f), - needs_push_properties_(false), - num_dependents_need_push_properties_(0), sorting_context_id_(0), current_draw_mode_(DRAW_MODE_NONE), element_id_(0), @@ -129,6 +127,7 @@ layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); layer_tree_impl_->UnregisterScrollLayer(this); layer_tree_impl_->UnregisterLayer(this); + layer_tree_impl_->RemoveLayerShouldPushProperties(this); layer_tree_impl_->RemoveFromElementMap(this); @@ -158,12 +157,6 @@ } void LayerImpl::SetParent(LayerImpl* parent) { - if (parent_should_know_need_push_properties()) { - if (parent_) - parent_->RemoveDependentNeedsPushProperties(); - if (parent) - parent->AddDependentNeedsPushProperties(); - } parent_ = parent; } @@ -631,8 +624,7 @@ // Reset any state that should be cleared for the next update. layer_property_changed_ = false; update_rect_ = gfx::Rect(); - needs_push_properties_ = false; - num_dependents_need_push_properties_ = 0; + layer_tree_impl()->RemoveLayerShouldPushProperties(this); } bool LayerImpl::IsAffectedByPageScale() const { @@ -763,7 +755,7 @@ return "cc::LayerImpl"; } -void LayerImpl::ResetAllChangeTrackingForSubtree() { +void LayerImpl::ResetAllChangeTrackingForSubtreeInternal() { layer_property_changed_ = false; if (TransformNode* transform_node = layer_tree_impl_->property_trees()->transform_tree.Node( @@ -778,18 +770,20 @@ render_surface_->ResetPropertyChangedFlag(); if (mask_layer_) - mask_layer_->ResetAllChangeTrackingForSubtree(); + mask_layer_->ResetAllChangeTrackingForSubtreeInternal(); if (replica_layer_) { // This also resets the replica mask, if it exists. - replica_layer_->ResetAllChangeTrackingForSubtree(); + replica_layer_->ResetAllChangeTrackingForSubtreeInternal(); } for (size_t i = 0; i < children_.size(); ++i) - children_[i]->ResetAllChangeTrackingForSubtree(); + children_[i]->ResetAllChangeTrackingForSubtreeInternal(); +} - needs_push_properties_ = false; - num_dependents_need_push_properties_ = 0; +void LayerImpl::ResetAllChangeTrackingForSubtree() { + layer_tree_impl()->LayersThatShouldPushProperties().clear(); + ResetAllChangeTrackingForSubtreeInternal(); } int LayerImpl::num_copy_requests_in_target_subtree() { @@ -1568,28 +1562,8 @@ } void LayerImpl::SetNeedsPushProperties() { - if (needs_push_properties_) - return; - if (!parent_should_know_need_push_properties() && parent_) - parent_->AddDependentNeedsPushProperties(); - needs_push_properties_ = true; -} - -void LayerImpl::AddDependentNeedsPushProperties() { - DCHECK_GE(num_dependents_need_push_properties_, 0); - - if (!parent_should_know_need_push_properties() && parent_) - parent_->AddDependentNeedsPushProperties(); - - num_dependents_need_push_properties_++; -} - -void LayerImpl::RemoveDependentNeedsPushProperties() { - num_dependents_need_push_properties_--; - DCHECK_GE(num_dependents_need_push_properties_, 0); - - if (!parent_should_know_need_push_properties() && parent_) - parent_->RemoveDependentNeedsPushProperties(); + if (layer_tree_impl_) + layer_tree_impl()->AddLayerShouldPushProperties(this); } void LayerImpl::GetAllPrioritizedTilesForTracing(
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 91d3e0d..211673b 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -591,16 +591,6 @@ virtual size_t GPUMemoryUsageInBytes() const; void SetNeedsPushProperties(); - void AddDependentNeedsPushProperties(); - void RemoveDependentNeedsPushProperties(); - bool parent_should_know_need_push_properties() const { - return needs_push_properties() || descendant_needs_push_properties(); - } - - bool needs_push_properties() const { return needs_push_properties_; } - bool descendant_needs_push_properties() const { - return num_dependents_need_push_properties_ > 0; - } virtual void RunMicroBenchmark(MicroBenchmarkImpl* benchmark); @@ -701,6 +691,7 @@ void NoteLayerPropertyChangedForDescendantsInternal(); void PushLayerPropertyChangedForSubtreeInternal(); + void ResetAllChangeTrackingForSubtreeInternal(); virtual const char* LayerTypeAsString() const; @@ -804,15 +795,6 @@ protected: friend class TreeSynchronizer; - // This flag is set when the layer needs to push properties to the active - // side. - bool needs_push_properties_; - - // The number of direct children or dependent layers that need to be recursed - // to in order for them or a descendent of them to push properties to the - // active side. - int num_dependents_need_push_properties_; - // Layers that share a sorting context id will be sorted together in 3d // space. 0 is a special value that means this layer will not be sorted and // will be drawn in paint order.
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index a8336d8..bd221ce 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc
@@ -26,48 +26,60 @@ namespace cc { namespace { -#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test) \ - root->ResetAllChangeTrackingForSubtree(); \ - root->layer_tree_impl()->property_trees()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ - code_to_test; \ - EXPECT_TRUE(root->needs_push_properties()); \ - EXPECT_FALSE(child->needs_push_properties()); \ - EXPECT_FALSE(grand_child->needs_push_properties()); \ - EXPECT_TRUE(root->LayerPropertyChanged()); \ - EXPECT_TRUE(child->LayerPropertyChanged()); \ +#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test) \ + root->ResetAllChangeTrackingForSubtree(); \ + root->layer_tree_impl()->property_trees()->ResetAllChangeTracking( \ + PropertyTrees::ResetFlags::ALL_TREES); \ + code_to_test; \ + EXPECT_TRUE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ + EXPECT_FALSE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(child)); \ + EXPECT_FALSE(root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting( \ + grand_child)); \ + EXPECT_TRUE(root->LayerPropertyChanged()); \ + EXPECT_TRUE(child->LayerPropertyChanged()); \ EXPECT_TRUE(grand_child->LayerPropertyChanged()); -#define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test) \ - root->ResetAllChangeTrackingForSubtree(); \ - code_to_test; \ - EXPECT_FALSE(root->needs_push_properties()); \ - EXPECT_FALSE(child->needs_push_properties()); \ - EXPECT_FALSE(grand_child->needs_push_properties()); \ - EXPECT_FALSE(root->LayerPropertyChanged()); \ - EXPECT_FALSE(child->LayerPropertyChanged()); \ +#define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test) \ + root->ResetAllChangeTrackingForSubtree(); \ + code_to_test; \ + EXPECT_FALSE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ + EXPECT_FALSE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(child)); \ + EXPECT_FALSE(root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting( \ + grand_child)); \ + EXPECT_FALSE(root->LayerPropertyChanged()); \ + EXPECT_FALSE(child->LayerPropertyChanged()); \ EXPECT_FALSE(grand_child->LayerPropertyChanged()); -#define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( \ - code_to_test) \ - root->ResetAllChangeTrackingForSubtree(); \ - code_to_test; \ - EXPECT_TRUE(root->needs_push_properties()); \ - EXPECT_FALSE(child->needs_push_properties()); \ - EXPECT_FALSE(grand_child->needs_push_properties()); \ - EXPECT_FALSE(root->LayerPropertyChanged()); \ - EXPECT_FALSE(child->LayerPropertyChanged()); \ +#define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( \ + code_to_test) \ + root->ResetAllChangeTrackingForSubtree(); \ + code_to_test; \ + EXPECT_TRUE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ + EXPECT_FALSE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(child)); \ + EXPECT_FALSE(root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting( \ + grand_child)); \ + EXPECT_FALSE(root->LayerPropertyChanged()); \ + EXPECT_FALSE(child->LayerPropertyChanged()); \ EXPECT_FALSE(grand_child->LayerPropertyChanged()); -#define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test) \ - root->ResetAllChangeTrackingForSubtree(); \ - root->layer_tree_impl()->property_trees()->full_tree_damaged = false; \ - code_to_test; \ - EXPECT_TRUE(root->needs_push_properties()); \ - EXPECT_FALSE(child->needs_push_properties()); \ - EXPECT_FALSE(grand_child->needs_push_properties()); \ - EXPECT_TRUE(root->LayerPropertyChanged()); \ - EXPECT_FALSE(child->LayerPropertyChanged()); \ +#define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test) \ + root->ResetAllChangeTrackingForSubtree(); \ + root->layer_tree_impl()->property_trees()->full_tree_damaged = false; \ + code_to_test; \ + EXPECT_TRUE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ + EXPECT_FALSE( \ + root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(child)); \ + EXPECT_FALSE(root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting( \ + grand_child)); \ + EXPECT_TRUE(root->LayerPropertyChanged()); \ + EXPECT_FALSE(child->LayerPropertyChanged()); \ EXPECT_FALSE(grand_child->LayerPropertyChanged()); #define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 8e823d9..a12fb282 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -140,7 +140,7 @@ // We always need to push properties. // See http://crbug.com/303943 // TODO(danakj): Stop always pushing properties since we don't swap tilings. - needs_push_properties_ = true; + layer_tree_impl()->AddLayerShouldPushProperties(this); } void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index c7bcf2c..adf570b5 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1983,8 +1983,14 @@ else active_tree_->root_layer()->PushLayerPropertyChangedForSubtree(); } - TreeSynchronizer::PushProperties(pending_tree_->root_layer(), - active_tree_->root_layer()); + + std::unordered_set<LayerImpl*> layers_that_should_push_properties = + pending_tree_->LayersThatShouldPushProperties(); + for (auto pending_layer : layers_that_should_push_properties) { + LayerImpl* active_layer = active_tree_->LayerById(pending_layer->id()); + DCHECK(active_layer); + pending_layer->PushPropertiesTo(active_layer); + } pending_tree_->PushPropertiesTo(active_tree_.get()); if (pending_tree_->root_layer()) pending_tree_->property_trees()->ResetAllChangeTracking(
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 89567a5e..87fe6cf6 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -956,6 +956,24 @@ return iter != layer_id_map_.end() ? iter->second : NULL; } +void LayerTreeImpl::AddLayerShouldPushProperties(LayerImpl* layer) { + layers_that_should_push_properties_.insert(layer); +} + +void LayerTreeImpl::RemoveLayerShouldPushProperties(LayerImpl* layer) { + layers_that_should_push_properties_.erase(layer); +} + +std::unordered_set<LayerImpl*>& +LayerTreeImpl::LayersThatShouldPushProperties() { + return layers_that_should_push_properties_; +} + +bool LayerTreeImpl::LayerNeedsPushPropertiesForTesting(LayerImpl* layer) { + return layers_that_should_push_properties_.find(layer) != + layers_that_should_push_properties_.end(); +} + void LayerTreeImpl::RegisterLayer(LayerImpl* layer) { DCHECK(!LayerById(layer->id())); layer_id_map_[layer->id()] = layer;
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 9f20b13..57523f97 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -299,6 +299,11 @@ LayerImpl* LayerById(int id) const; + void AddLayerShouldPushProperties(LayerImpl* layer); + void RemoveLayerShouldPushProperties(LayerImpl* layer); + std::unordered_set<LayerImpl*>& LayersThatShouldPushProperties(); + bool LayerNeedsPushPropertiesForTesting(LayerImpl* layer); + // These should be called by LayerImpl's ctor/dtor. void RegisterLayer(LayerImpl* layer); void UnregisterLayer(LayerImpl* layer); @@ -515,6 +520,8 @@ using LayerIdMap = std::unordered_map<int, LayerImpl*>; LayerIdMap layer_id_map_; + // Set of layers that need to push properties. + std::unordered_set<LayerImpl*> layers_that_should_push_properties_; std::unordered_map<uint64_t, ElementLayers> element_layers_map_;
diff --git a/cc/trees/tree_synchronizer.cc b/cc/trees/tree_synchronizer.cc index a257c57b..af87056 100644 --- a/cc/trees/tree_synchronizer.cc +++ b/cc/trees/tree_synchronizer.cc
@@ -129,10 +129,8 @@ new_layers, old_layers, layer, tree_impl); } -// static -template <typename LayerType> void TreeSynchronizer::PushPropertiesInternal( - LayerType* layer, + Layer* layer, LayerImpl* layer_impl, int* num_dependents_need_push_properties_for_parent) { if (!layer) { @@ -246,10 +244,4 @@ #endif } -void TreeSynchronizer::PushProperties(LayerImpl* layer, LayerImpl* layer_impl) { - int num_dependents_need_push_properties = 0; - PushPropertiesInternal( - layer, layer_impl, &num_dependents_need_push_properties); -} - } // namespace cc
diff --git a/cc/trees/tree_synchronizer.h b/cc/trees/tree_synchronizer.h index a580362c..2e6e8f09 100644 --- a/cc/trees/tree_synchronizer.h +++ b/cc/trees/tree_synchronizer.h
@@ -38,9 +38,8 @@ private: TreeSynchronizer(); // Not instantiable. - template <typename LayerType> static void PushPropertiesInternal( - LayerType* layer, + Layer* layer, LayerImpl* layer_impl, int* num_dependents_need_push_properties_for_parent);
diff --git a/chrome/VERSION b/chrome/VERSION index 8be6c9e2..e9cb17c0 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=51 MINOR=0 -BUILD=2671 +BUILD=2672 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java index 2780051..12f58378 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java
@@ -15,6 +15,7 @@ import android.text.style.ClickableSpan; import android.view.View; +import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer; @@ -35,14 +36,14 @@ implements ItemChooserDialog.ItemSelectedCallback, WindowAndroid.PermissionCallback { // These constants match BluetoothChooserAndroid::ShowDiscoveryState, and are used in // notifyDiscoveryState(). - private static final int DISCOVERY_FAILED_TO_START = 0; - private static final int DISCOVERING = 1; - private static final int DISCOVERY_IDLE = 2; + static final int DISCOVERY_FAILED_TO_START = 0; + static final int DISCOVERING = 1; + static final int DISCOVERY_IDLE = 2; // Values passed to nativeOnDialogFinished:eventType, and only used in the native function. - private static final int DIALOG_FINISHED_DENIED_PERMISSION = 0; - private static final int DIALOG_FINISHED_CANCELLED = 1; - private static final int DIALOG_FINISHED_SELECTED = 2; + static final int DIALOG_FINISHED_DENIED_PERMISSION = 0; + static final int DIALOG_FINISHED_CANCELLED = 1; + static final int DIALOG_FINISHED_SELECTED = 2; // The window that owns this dialog. final WindowAndroid mWindowAndroid; @@ -79,7 +80,8 @@ * * @param context Context which is used for launching a dialog. */ - private BluetoothChooserDialog(WindowAndroid windowAndroid, String origin, int securityLevel, + @VisibleForTesting + BluetoothChooserDialog(WindowAndroid windowAndroid, String origin, int securityLevel, long nativeBluetoothChooserDialogPtr) { mWindowAndroid = windowAndroid; mContext = windowAndroid.getActivity().get(); @@ -92,7 +94,8 @@ /** * Show the BluetoothChooserDialog. */ - private void show() { + @VisibleForTesting + void show() { // Emphasize the origin. Profile profile = Profile.getLastUsedProfile(); SpannableString origin = new SpannableString(mOrigin); @@ -287,27 +290,31 @@ return dialog; } + @VisibleForTesting @CalledByNative - private void addDevice(String deviceId, String deviceName) { + void addDevice(String deviceId, String deviceName) { List<ItemChooserDialog.ItemChooserRow> devices = new ArrayList<ItemChooserDialog.ItemChooserRow>(); devices.add(new ItemChooserDialog.ItemChooserRow(deviceId, deviceName)); mItemChooserDialog.addItemsToList(devices); } + @VisibleForTesting @CalledByNative - private void closeDialog() { + void closeDialog() { mNativeBluetoothChooserDialogPtr = 0; mItemChooserDialog.dismiss(); } + @VisibleForTesting @CalledByNative - private void removeDevice(String deviceId) { + void removeDevice(String deviceId) { mItemChooserDialog.setEnabled(deviceId, false); } + @VisibleForTesting @CalledByNative - private void notifyAdapterTurnedOff() { + void notifyAdapterTurnedOff() { SpannableString adapterOffMessage = SpanApplier.applySpans( mContext.getString(R.string.bluetooth_adapter_off), new SpanInfo("<link>", "</link>", @@ -328,8 +335,9 @@ } } + @VisibleForTesting @CalledByNative - private void notifyDiscoveryState(int discoveryState) { + void notifyDiscoveryState(int discoveryState) { switch (discoveryState) { case DISCOVERY_FAILED_TO_START: { // FAILED_TO_START might be caused by a missing Location permission. @@ -348,11 +356,16 @@ } } - private native void nativeOnDialogFinished( + @VisibleForTesting + native void nativeOnDialogFinished( long nativeBluetoothChooserAndroid, int eventType, String deviceId); - private native void nativeRestartSearch(long nativeBluetoothChooserAndroid); + @VisibleForTesting + native void nativeRestartSearch(long nativeBluetoothChooserAndroid); // Help links. - private native void nativeShowBluetoothOverviewLink(long nativeBluetoothChooserAndroid); - private native void nativeShowBluetoothAdapterOffLink(long nativeBluetoothChooserAndroid); - private native void nativeShowNeedLocationPermissionLink(long nativeBluetoothChooserAndroid); + @VisibleForTesting + native void nativeShowBluetoothOverviewLink(long nativeBluetoothChooserAndroid); + @VisibleForTesting + native void nativeShowBluetoothAdapterOffLink(long nativeBluetoothChooserAndroid); + @VisibleForTesting + native void nativeShowNeedLocationPermissionLink(long nativeBluetoothChooserAndroid); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index c7cc7ff0..9b44f6a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -181,13 +181,18 @@ @Override public void onStop() { - super.onStop(); - CustomTabsConnection.getInstance(getApplication()) - .dontKeepAliveForSession(mIntentDataProvider.getSession()); + // This happens before super.onStop() to maximize chances of getting the Tab while it's + // alive. + // TODO(dfalcantara): Once this is addressed on M50, consider transferring the Tab directly + // via Tab reparenting. if (mIntentDataProvider.isOpenedByBrowser()) { createHerbResultIntent(RESULT_STOPPED); finish(); } + + super.onStop(); + CustomTabsConnection.getInstance(getApplication()) + .dontKeepAliveForSession(mIntentDataProvider.getSession()); } @Override @@ -552,8 +557,7 @@ && TextUtils.equals(getPackageName(), creatorPackage)) { RecordUserAction.record( "TaskManagement.OpenInChromeActionButtonClicked"); - openCurrentUrlInBrowser(); - finish(); + if (openCurrentUrlInBrowser()) finish(); } else { mIntentDataProvider.sendButtonPendingIntentWithUrl( getApplicationContext(), getActivityTab().getUrl()); @@ -721,9 +725,12 @@ /** * Opens the URL currently being displayed in the Custom Tab in the regular browser. + * + * @return Whether or not the tab was sent over successfully. */ - void openCurrentUrlInBrowser() { - if (getActivityTab() == null) return; + boolean openCurrentUrlInBrowser() { + if (getActivityTab() == null) return false; + String url = getTabModelSelector().getCurrentTab().getUrl(); if (DomDistillerUrlUtils.isDistilledPage(url)) { url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); @@ -776,6 +783,7 @@ } finally { StrictMode.setThreadPolicy(oldPolicy); } + return true; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ClearBrowsingDataCheckBoxPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ClearBrowsingDataCheckBoxPreference.java index 05072296..a7d360c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ClearBrowsingDataCheckBoxPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ClearBrowsingDataCheckBoxPreference.java
@@ -17,6 +17,7 @@ * A preference representing one browsing data type in ClearBrowsingDataPreferences. */ public class ClearBrowsingDataCheckBoxPreference extends ChromeBaseCheckBoxPreference { + private LinearLayout mView; /** * Constructor for inflating from XML. @@ -27,18 +28,20 @@ @Override public View onCreateView(ViewGroup parent) { - LinearLayout view = (LinearLayout) super.onCreateView(parent); + if (mView != null) return mView; + + mView = (LinearLayout) super.onCreateView(parent); // Checkboxes in the Clear Browsing Data dialog will show and hide the results of // BrowsingDataCounter. It is important that they will not change height when doing so. // We will therefore set a fixed height. int height = getContext().getResources().getDimensionPixelSize( R.dimen.clear_browsing_data_checkbox_height); - view.setMinimumHeight(height); + mView.setMinimumHeight(height); // The title and summary are enclosed in a common RelativeLayout. We must remove // its vertical padding for it to be correctly vertically centered in the fixed-height view. - View textLayout = (View) view.findViewById(android.R.id.title).getParent(); + View textLayout = (View) mView.findViewById(android.R.id.title).getParent(); ApiCompatibilityUtils.setPaddingRelative( textLayout, ApiCompatibilityUtils.getPaddingStart(textLayout), @@ -46,6 +49,10 @@ ApiCompatibilityUtils.getPaddingEnd(textLayout), 0); - return view; + return mView; + } + + public void announceForAccessibility(CharSequence announcement) { + if (mView != null) mView.announceForAccessibility(announcement); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java index ff8b6e09..1ad2a640 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java
@@ -23,6 +23,7 @@ private Spinner mSpinner; private ArrayAdapter<Object> mAdapter; private int mSelectedIndex; + private View mView; /** * Constructor for inflating from XML. @@ -55,10 +56,11 @@ @Override public View onCreateView(ViewGroup parent) { - View view = super.onCreateView(parent); + if (mView != null) return mView; - ((TextView) view.findViewById(R.id.title)).setText(getTitle()); - mSpinner = (Spinner) view.findViewById(R.id.spinner); + mView = super.onCreateView(parent); + ((TextView) mView.findViewById(R.id.title)).setText(getTitle()); + mSpinner = (Spinner) mView.findViewById(R.id.spinner); mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected( @@ -76,12 +78,19 @@ } }); - return view; + return mView; } @Override protected void onBindView(View view) { - mSpinner.setAdapter(mAdapter); + super.onBindView(view); + + // Screen readers notice the setAdapter() call and announce it. We do not want the spinner + // to be announced every time the view is bound (e.g. when the user scrolls away from it + // and then back). Therefore, only update the adapter if it has actually changed. + if (mSpinner.getAdapter() != mAdapter) { + mSpinner.setAdapter(mAdapter); + } mSpinner.setSelection(mSelectedIndex); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java index 54e1914..ee0a710 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java
@@ -7,7 +7,6 @@ import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; -import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.widget.ListView; @@ -16,6 +15,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.BrowsingDataType; import org.chromium.chrome.browser.preferences.ButtonPreference; +import org.chromium.chrome.browser.preferences.ClearBrowsingDataCheckBoxPreference; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.SpinnerPreference; import org.chromium.chrome.browser.preferences.privacy.BrowsingDataCounterBridge.BrowsingDataCounterCallback; @@ -39,19 +39,20 @@ Preference.OnPreferenceClickListener { private final ClearBrowsingDataPreferences mParent; private final DialogOption mOption; - private final CheckBoxPreference mCheckbox; + private final ClearBrowsingDataCheckBoxPreference mCheckbox; private BrowsingDataCounterBridge mCounter; + private boolean mShouldAnnounceCounterResult; public Item(ClearBrowsingDataPreferences parent, DialogOption option, - CheckBoxPreference checkbox, + ClearBrowsingDataCheckBoxPreference checkbox, boolean selected, boolean enabled) { super(); mParent = parent; mOption = option; - mCounter = new BrowsingDataCounterBridge(this, mOption.getDataType()); mCheckbox = checkbox; + mCounter = new BrowsingDataCounterBridge(this, mOption.getDataType()); mCheckbox.setOnPreferenceClickListener(this); mCheckbox.setEnabled(enabled); @@ -76,6 +77,7 @@ assert mCheckbox == preference; mParent.updateButtonState(); + mShouldAnnounceCounterResult = true; PrefServiceBridge.getInstance().setBrowsingDataDeletionPreference( mOption.getDataType(), mCheckbox.isChecked()); return true; @@ -83,7 +85,19 @@ @Override public void onCounterFinished(String result) { - if (mCheckbox != null) mCheckbox.setSummaryOn(result); + mCheckbox.setSummaryOn(result); + if (mShouldAnnounceCounterResult) { + mCheckbox.announceForAccessibility(result); + } + } + + /** + * Sets whether the BrowsingDataCounter result should be announced. This is when the counter + * recalculation was caused by a checkbox state change (as opposed to fragment + * initialization or time period change). + */ + public void setShouldAnnounceCounterResult(boolean value) { + mShouldAnnounceCounterResult = value; } } @@ -272,6 +286,12 @@ @Override public boolean onPreferenceChange(Preference preference, Object value) { if (preference.getKey().equals(PREF_TIME_RANGE)) { + // Inform the items that a recalculation is going to happen as a result of the time + // period change. + for (Item item : mItems) { + item.setShouldAnnounceCounterResult(false); + } + PrefServiceBridge.getInstance().setBrowsingDataDeletionTimePeriod( ((TimePeriodSpinnerOption) value).getTimePeriod()); return true; @@ -310,7 +330,7 @@ mItems[i] = new Item( this, options[i], - (CheckBoxPreference) findPreference(options[i].getPreferenceKey()), + (ClearBrowsingDataCheckBoxPreference) findPreference(options[i].getPreferenceKey()), isOptionSelectedByDefault(options[i]), enabled); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java index f1cdf130..d960e737 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -186,28 +186,29 @@ CommandLine.addResetListener(sResetListener); } + private static boolean isHerbDisallowed(Context context) { + return isDocumentMode(context) || ChromeVersionInfo.isStableBuild() + || ChromeVersionInfo.isBetaBuild() || DeviceFormFactor.isTablet(context); + } + /** * @return Which flavor of Herb is being tested. See {@link ChromeSwitches#HERB_FLAVOR_ANISE} * and its related switches. */ public static String getHerbFlavor() { + Context context = ApplicationStatus.getApplicationContext(); + if (isHerbDisallowed(context)) return ChromeSwitches.HERB_FLAVOR_DISABLED; + if (!sIsHerbFlavorCached) { sCachedHerbFlavor = null; - Context context = ApplicationStatus.getApplicationContext(); - if (isDocumentMode(context) || ChromeVersionInfo.isStableBuild() - || ChromeVersionInfo.isBetaBuild() || DeviceFormFactor.isTablet(context)) { - // Disable Herb. - sCachedHerbFlavor = ChromeSwitches.HERB_FLAVOR_DISABLED; - } else { - // Allowing disk access for preferences while prototyping. - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - sCachedHerbFlavor = - ChromePreferenceManager.getInstance(context).getCachedHerbFlavor(); - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } + // Allowing disk access for preferences while prototyping. + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + try { + sCachedHerbFlavor = + ChromePreferenceManager.getInstance(context).getCachedHerbFlavor(); + } finally { + StrictMode.setThreadPolicy(oldPolicy); } sIsHerbFlavorCached = true; @@ -221,6 +222,9 @@ * Caches which flavor of Herb the user prefers from native. */ public static void cacheHerbFlavor() { + Context context = ApplicationStatus.getApplicationContext(); + if (isHerbDisallowed(context)) return; + String oldFlavor = getHerbFlavor(); // Check the experiment value before the command line to put the user in the correct group. @@ -258,7 +262,6 @@ sCachedHerbFlavor = newFlavor; if (!TextUtils.equals(oldFlavor, newFlavor)) { - Context context = ApplicationStatus.getApplicationContext(); ChromePreferenceManager.getInstance(context).setCachedHerbFlavor(newFlavor); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java new file mode 100644 index 0000000..5ab4b84d --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
@@ -0,0 +1,311 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser; + +import android.Manifest; +import android.app.Dialog; +import android.content.pm.PackageManager; +import android.test.MoreAsserts; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.View; +import android.widget.Button; +import android.widget.ListView; + +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.test.ChromeActivityTestCaseBase; +import org.chromium.components.security_state.ConnectionSecurityLevel; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; +import org.chromium.content.browser.test.util.TouchCommon; +import org.chromium.ui.base.ActivityWindowAndroid; +import org.chromium.ui.base.AndroidPermissionDelegate; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.base.WindowAndroid.PermissionCallback; +import org.chromium.ui.widget.TextViewWithClickableSpans; + +import java.util.concurrent.Callable; + +/** + * Tests for the BluetoothChooserDialog class. + */ +public class BluetoothChooserDialogTest extends ChromeActivityTestCaseBase<ChromeActivity> { + /** + * Works like the BluetoothChooserDialog class, but records calls to native methods instead of + * calling back to C++. + */ + static class BluetoothChooserDialogWithFakeNatives extends BluetoothChooserDialog { + int mFinishedEventType = -1; + String mFinishedDeviceId; + + BluetoothChooserDialogWithFakeNatives(WindowAndroid windowAndroid, String origin, + int securityLevel, long nativeBluetoothChooserDialogPtr) { + super(windowAndroid, origin, securityLevel, nativeBluetoothChooserDialogPtr); + } + + @Override + void nativeOnDialogFinished( + long nativeBluetoothChooserAndroid, int eventType, String deviceId) { + assertEquals(nativeBluetoothChooserAndroid, mNativeBluetoothChooserDialogPtr); + assertEquals(mFinishedEventType, -1); + mFinishedEventType = eventType; + mFinishedDeviceId = deviceId; + } + + @Override + void nativeRestartSearch(long nativeBluetoothChooserAndroid) {} + + @Override + void nativeShowBluetoothOverviewLink(long nativeBluetoothChooserAndroid) {} + + @Override + void nativeShowBluetoothAdapterOffLink(long nativeBluetoothChooserAndroid) {} + + @Override + void nativeShowNeedLocationPermissionLink(long nativeBluetoothChooserAndroid) {} + } + + private ActivityWindowAndroid mWindowAndroid; + private BluetoothChooserDialogWithFakeNatives mChooserDialog; + + public BluetoothChooserDialogTest() { + super(ChromeActivity.class); + } + + // ChromeActivityTestCaseBase: + + @Override + protected void setUp() throws Exception { + super.setUp(); + mChooserDialog = createDialog(); + } + + @Override + public void startMainActivity() throws InterruptedException { + startMainActivityOnBlankPage(); + } + + private BluetoothChooserDialogWithFakeNatives createDialog() { + return ThreadUtils.runOnUiThreadBlockingNoException( + new Callable<BluetoothChooserDialogWithFakeNatives>() { + @Override + public BluetoothChooserDialogWithFakeNatives call() { + mWindowAndroid = new ActivityWindowAndroid(getActivity()); + BluetoothChooserDialogWithFakeNatives dialog = + new BluetoothChooserDialogWithFakeNatives(mWindowAndroid, + "https://origin.example.com/", + ConnectionSecurityLevel.SECURE, 42); + dialog.show(); + return dialog; + } + }); + } + + private static void selectItem(final BluetoothChooserDialogWithFakeNatives chooserDialog, + int position) throws InterruptedException { + final Dialog dialog = chooserDialog.mItemChooserDialog.getDialogForTesting(); + final ListView items = (ListView) dialog.findViewById(R.id.items); + final Button button = (Button) dialog.findViewById(R.id.positive); + + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return items.getChildAt(0) != null; + } + }); + + assertEquals("Not all items have a view; positions may be incorrect.", + items.getChildCount(), items.getAdapter().getCount()); + + // Verify first item selected gets selected. + TouchCommon.singleClickView(items.getChildAt(position - 1)); + + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return button.isEnabled(); + } + }); + + TouchCommon.singleClickView(button); + + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return chooserDialog.mFinishedEventType != -1; + } + }); + } + + /** + * The messages include <link> ... </link> sections that are used to create + * clickable spans. For testing the messages, this function returns the raw + * string without the tags. + */ + private static String removeLinkTags(String message) { + return message.replaceAll("</?link>", ""); + } + + @SmallTest + public void testCancel() throws InterruptedException { + ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog; + Dialog dialog = itemChooser.getDialogForTesting(); + assertTrue(dialog.isShowing()); + + TextViewWithClickableSpans statusView = + (TextViewWithClickableSpans) dialog.findViewById(R.id.status); + final ListView items = (ListView) dialog.findViewById(R.id.items); + final Button button = (Button) dialog.findViewById(R.id.positive); + + // Before we add items to the dialog, the 'searching' message should be + // showing, the Commit button should be disabled and the list view hidden. + assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_searching)), + statusView.getText().toString()); + assertFalse(button.isEnabled()); + assertEquals(View.GONE, items.getVisibility()); + + dialog.dismiss(); + + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return mChooserDialog.mFinishedEventType != -1; + } + }); + + assertEquals(BluetoothChooserDialog.DIALOG_FINISHED_CANCELLED, + mChooserDialog.mFinishedEventType); + assertEquals("", mChooserDialog.mFinishedDeviceId); + } + + @SmallTest + public void testSelectItem() throws InterruptedException { + Dialog dialog = mChooserDialog.mItemChooserDialog.getDialogForTesting(); + + TextViewWithClickableSpans statusView = + (TextViewWithClickableSpans) dialog.findViewById(R.id.status); + final View items = dialog.findViewById(R.id.items); + final Button button = (Button) dialog.findViewById(R.id.positive); + final View progress = dialog.findViewById(R.id.progress); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + mChooserDialog.addDevice("id-1", "Name 1"); + mChooserDialog.addDevice("id-2", "Name 2"); + } + }); + + // After adding items to the dialog, the help message should be showing, + // the progress spinner should disappear, the Commit button should still + // be disabled (since nothing's selected), and the list view should + // show. + assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_not_seeing_it)), + statusView.getText().toString()); + assertFalse(button.isEnabled()); + assertEquals(View.VISIBLE, items.getVisibility()); + assertEquals(View.GONE, progress.getVisibility()); + + selectItem(mChooserDialog, 2); + + assertEquals( + BluetoothChooserDialog.DIALOG_FINISHED_SELECTED, mChooserDialog.mFinishedEventType); + assertEquals("id-2", mChooserDialog.mFinishedDeviceId); + } + + @SmallTest + public void testNoLocationPermission() throws InterruptedException { + ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog; + Dialog dialog = itemChooser.getDialogForTesting(); + assertTrue(dialog.isShowing()); + + final TextViewWithClickableSpans statusView = + (TextViewWithClickableSpans) dialog.findViewById(R.id.status); + final TextViewWithClickableSpans errorView = + (TextViewWithClickableSpans) dialog.findViewById(R.id.not_found_message); + final View items = dialog.findViewById(R.id.items); + final Button button = (Button) dialog.findViewById(R.id.positive); + final View progress = dialog.findViewById(R.id.progress); + + final TestAndroidPermissionDelegate permissionDelegate = + new TestAndroidPermissionDelegate(); + mWindowAndroid.setAndroidPermissionDelegate(permissionDelegate); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + mChooserDialog.notifyDiscoveryState( + BluetoothChooserDialog.DISCOVERY_FAILED_TO_START); + } + }); + + assertEquals(removeLinkTags( + getActivity().getString(R.string.bluetooth_need_location_permission)), + errorView.getText().toString()); + assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off_help)), + statusView.getText().toString()); + assertFalse(button.isEnabled()); + assertEquals(View.VISIBLE, errorView.getVisibility()); + assertEquals(View.GONE, items.getVisibility()); + assertEquals(View.GONE, progress.getVisibility()); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + errorView.getClickableSpans()[0].onClick(errorView); + } + }); + + // Permission was requested. + MoreAsserts.assertEquals(permissionDelegate.mPermissionsRequested, + new String[] {Manifest.permission.ACCESS_COARSE_LOCATION}); + assertNotNull(permissionDelegate.mCallback); + // Grant permission. + permissionDelegate.mLocationGranted = true; + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + permissionDelegate.mCallback.onRequestPermissionsResult( + new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, + new int[] {PackageManager.PERMISSION_GRANTED}); + } + }); + + assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off_help)), + statusView.getText().toString()); + + mChooserDialog.closeDialog(); + } + + // TODO(jyasskin): Test when the user denies Chrome the ability to ask for permission. + + private static class TestAndroidPermissionDelegate implements AndroidPermissionDelegate { + boolean mLocationGranted = false; + PermissionCallback mCallback = null; + String[] mPermissionsRequested = null; + + @Override + public boolean hasPermission(String permission) { + return permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION) + && mLocationGranted; + } + @Override + public boolean canRequestPermission(String permission) { + return true; + } + @Override + public boolean isPermissionRevokedByPolicy(String permission) { + return false; + } + @Override + public void requestPermissions(String[] permissions, PermissionCallback callback) { + mPermissionsRequested = permissions; + if (permissions.length == 1 + && permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) { + mCallback = callback; + } + } + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java index e7b57bc..2eddc55 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java
@@ -10,6 +10,7 @@ import android.test.suitebuilder.annotation.MediumTest; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.TestFileUtil; import org.chromium.base.test.util.UrlUtils; @@ -94,6 +95,7 @@ */ @MediumTest @Feature({"Navigation"}) + @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/592642") public void testContentUrlFromFile() throws InterruptedException, IOException { final String target = "content_from_file"; final File file = new File(Environment.getExternalStorageDirectory(), target + ".html"); @@ -113,6 +115,7 @@ */ @MediumTest @Feature({"Navigation"}) + @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/592642") public void testFileUrlNavigation() throws InterruptedException, IOException { final File file = new File(Environment.getExternalStorageDirectory(), "url_navigation_test.html");
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 8b3c691..5307661 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -998,6 +998,9 @@ <message name="IDS_FILE_BROWSER_SORT_BUTTON_TOOLTIP" desc="Tooltip for the button which provides sort options in Files.app."> Sort options </message> + <message name="IDS_FILE_BROWSER_DETAIL_BUTTON_TOOLTIP" desc="Tooltip for the detals button to show the details panel which provides information of selected files in Files.app."> + View details + </message> <message name="IDS_FILE_BROWSER_GEAR_BUTTON_TOOLTIP" desc="Tooltip for the gear button in Files.app."> Settings </message> @@ -6439,5 +6442,17 @@ <message name="IDS_OPTIONS_ARC_ENABLE" desc="Label for the checkbox that enables Android apps."> Enable Android Apps to run on your Chromebook. </message> + <message name="IDS_ARC_NOTIFICATION_TITLE" desc="Title of the first-run notification that enables Android apps."> + Google Play Store + </message> + <message name="IDS_ARC_NOTIFICATION_MESSAGE" desc="Description message of the first-run notification that enables Android apps."> + Over a million apps and games now avaialble on your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. + </message> + <message name="IDS_ARC_OPEN_PLAY_STORE_NOTIFICATION_BUTTON" desc="Label for the button in the first-run notification that enables Android apps."> + Open Play Store + </message> + <message name="IDS_ARC_CANCEL_NOTIFICATION_BUTTON" desc="Label for the button in the first-run notification that cancel running Android apps."> + Cancel + </message> </grit-part>
diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc index 11df4c05..2cde543 100644 --- a/chrome/app/mash/mash_runner.cc +++ b/chrome/app/mash/mash_runner.cc
@@ -21,9 +21,9 @@ #include "mash/wm/window_manager_application.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/shell/background/background_shell.h" -#include "mojo/shell/identity.h" #include "mojo/shell/native_runner_delegate.h" #include "mojo/shell/public/cpp/connector.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/cpp/shell_client.h" #include "mojo/shell/public/cpp/shell_connection.h" #include "mojo/shell/public/interfaces/shell_client_factory.mojom.h" @@ -136,7 +136,7 @@ private: // mojo::shell::NativeRunnerDelegate: void AdjustCommandLineArgumentsForTarget( - const mojo::shell::Identity& target, + const mojo::Identity& target, base::CommandLine* command_line) override { if (target.name() != "exe:chrome") { if (target.name() == "exe:chrome_mash")
diff --git a/chrome/app/theme/default_100_percent/cros/notification_play_store.png b/chrome/app/theme/default_100_percent/cros/notification_play_store.png new file mode 100644 index 0000000..6c7b7f7c --- /dev/null +++ b/chrome/app/theme/default_100_percent/cros/notification_play_store.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/cros/notification_play_store.png b/chrome/app/theme/default_200_percent/cros/notification_play_store.png new file mode 100644 index 0000000..03b4891 --- /dev/null +++ b/chrome/app/theme/default_200_percent/cros/notification_play_store.png Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 22ca374..86d7131 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -450,6 +450,7 @@ <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_DRIVE" file="cros/notification_drive.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_PERIPHERAL_BATTERY_LOW" file="cros/notification_peripheral_battery_low.png" /> <structure type="chrome_scaled_image" name="IDR_PORTAL_DETECTION_ALERT" file="cros/captive_portal_icon.png" /> + <structure type="chrome_scaled_image" name="IDR_ARC_PLAY_STORE_NOTIFICATION" file="cros/notification_play_store.png" /> </if> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_WELCOME_ICON" file="common/notification_welcome_icon.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_WELCOME_LEARN_MORE" file="common/notification_welcome_learn_more.png" />
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc index c0e6e3b..713d241 100644 --- a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc
@@ -61,18 +61,14 @@ online_url)); } -void OfflinePageTabHelper::DidFailProvisionalLoad( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) { +void OfflinePageTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { GURL last_redirect_from_url_copy = last_redirect_from_url_; last_redirect_from_url_ = GURL(); // Skips non-main frame or load failure other than no network. - if (error_code != net::ERR_INTERNET_DISCONNECTED || - render_frame_host->GetParent() != nullptr) { + if (navigation_handle->GetNetErrorCode() != net::ERR_INTERNET_DISCONNECTED || + !navigation_handle->IsInMainFrame()) { return; } @@ -83,14 +79,14 @@ // Skips if not loading an online version of saved page. GURL offline_url = offline_pages::OfflinePageUtils::GetOfflineURLForOnlineURL( - web_contents()->GetBrowserContext(), validated_url); + web_contents()->GetBrowserContext(), navigation_handle->GetURL()); if (!offline_url.is_valid()) return; // Avoids looping between online and offline redirections. if (last_redirect_from_url_copy == offline_url) return; - last_redirect_from_url_ = validated_url; + last_redirect_from_url_ = navigation_handle->GetURL(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE,
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper.h b/chrome/browser/android/offline_pages/offline_page_tab_helper.h index 2339197..041e510 100644 --- a/chrome/browser/android/offline_pages/offline_page_tab_helper.h +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper.h
@@ -33,12 +33,8 @@ // Overridden from content::WebContentsObserver: void DidStartNavigation( content::NavigationHandle* navigation_handle) override; - void DidFailProvisionalLoad( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; void RedirectFromOfflineToOnline(const GURL& online_url); void RedirectFromOnlineToOffline(const GURL& offline_url);
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc index ec0a852..796b062 100644 --- a/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc
@@ -139,13 +139,17 @@ void OfflinePageTabHelperTest::CommitLoad(const GURL& url) { int entry_id = controller().GetPendingEntry()->GetUniqueID(); - content::RenderFrameHostTester::For(main_rfh())->SendNavigate( - 0, entry_id, true, url); + content::RenderFrameHostTester::For(main_rfh()) + ->SendNavigate(0, entry_id, true, url); } void OfflinePageTabHelperTest::FailLoad(const GURL& url) { - content::RenderFrameHostTester::For(main_rfh())->SimulateNavigationError( - url, net::ERR_INTERNET_DISCONNECTED); + content::RenderFrameHostTester::For(main_rfh())->SimulateNavigationStart(url); + // Set up the error code for the failed navigation. + content::RenderFrameHostTester::For(main_rfh())-> + SimulateNavigationError(url, net::ERR_INTERNET_DISCONNECTED); + content::RenderFrameHostTester::For(main_rfh())-> + SimulateNavigationErrorPageCommit(); // Gives a chance to run delayed task to do redirection. RunUntilIdle(); }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index de94df9..9e57c22 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -195,6 +195,8 @@ <if expr="not is_android and not is_ios"> <include name="IDR_MD_HISTORY_HISTORY_HTML" file="resources\md_history\history.html" type="BINDATA" /> + <include name="IDR_MD_HISTORY_CONSTANTS_HTML" file="resources\md_history\constants.html" type="BINDATA" /> + <include name="IDR_MD_HISTORY_CONSTANTS_JS" file="resources\md_history\constants.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_ITEM_HTML" file="resources\md_history\history_item.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_ITEM_JS" file="resources\md_history\history_item.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_JS" file="resources\md_history\history.js" type="BINDATA" />
diff --git a/chrome/browser/chromeos/arc/arc_auth_notification.cc b/chrome/browser/chromeos/arc/arc_auth_notification.cc new file mode 100644 index 0000000..366fdd76 --- /dev/null +++ b/chrome/browser/chromeos/arc/arc_auth_notification.cc
@@ -0,0 +1,80 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/arc_auth_notification.h" + +#include "ash/system/chromeos/devicetype_utils.h" +#include "base/macros.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chromeos/arc/arc_auth_service.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/grit/theme_resources.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/message_center/message_center.h" +#include "ui/message_center/notification.h" +#include "ui/message_center/notification_delegate.h" +#include "url/gurl.h" + +namespace { + +// Ids of the notification shown on first run. +const char kNotifierId[] = "arc_auth"; +const char kDisplaySoruce[] = "arc_auth_source"; +const char kFirstRunNotificationId[] = "arc_auth/first_run"; + +class ArcAuthNotificationDelegate + : public message_center::NotificationDelegate { + public: + ArcAuthNotificationDelegate() {} + + // message_center::NotificationDelegate + void ButtonClick(int button_index) override { + if (button_index == 0) + arc::ArcAuthService::Get()->EnableArc(); + else + arc::ArcAuthService::Get()->DisableArc(); + } + + private: + ~ArcAuthNotificationDelegate() override {} + + DISALLOW_COPY_AND_ASSIGN(ArcAuthNotificationDelegate); +}; + +} // namespace + +namespace arc { + +// static +void ArcAuthNotification::Show() { + message_center::NotifierId notifier_id( + message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId); + + message_center::RichNotificationData data; + data.buttons.push_back(message_center::ButtonInfo( + l10n_util::GetStringUTF16(IDS_ARC_OPEN_PLAY_STORE_NOTIFICATION_BUTTON))); + data.buttons.push_back(message_center::ButtonInfo( + l10n_util::GetStringUTF16(IDS_ARC_CANCEL_NOTIFICATION_BUTTON))); + ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance(); + scoped_ptr<message_center::Notification> notification( + new message_center::Notification( + message_center::NOTIFICATION_TYPE_SIMPLE, kFirstRunNotificationId, + l10n_util::GetStringUTF16(IDS_ARC_NOTIFICATION_TITLE), + l10n_util::GetStringFUTF16(IDS_ARC_NOTIFICATION_MESSAGE, + ash::GetChromeOSDeviceName()), + resource_bundle.GetImageNamed(IDR_ARC_PLAY_STORE_NOTIFICATION), + base::UTF8ToUTF16(kDisplaySoruce), GURL(), notifier_id, data, + new ArcAuthNotificationDelegate())); + message_center::MessageCenter::Get()->AddNotification( + std::move(notification)); +} + +// static +void ArcAuthNotification::Hide() { + message_center::MessageCenter::Get()->RemoveNotification( + kFirstRunNotificationId, false); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/arc_auth_notification.h b/chrome/browser/chromeos/arc/arc_auth_notification.h new file mode 100644 index 0000000..8128c5c --- /dev/null +++ b/chrome/browser/chromeos/arc/arc_auth_notification.h
@@ -0,0 +1,19 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_ARC_AUTH_NOTIFICATION_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_ARC_AUTH_NOTIFICATION_H_ + +namespace arc { + +// First run notification that can enable Arc. +class ArcAuthNotification { + public: + static void Show(); + static void Hide(); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_ARC_AUTH_NOTIFICATION_H_
diff --git a/chrome/browser/chromeos/arc/arc_auth_service.cc b/chrome/browser/chromeos/arc/arc_auth_service.cc index 5085333a..ddb6e73 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service.cc +++ b/chrome/browser/chromeos/arc/arc_auth_service.cc
@@ -8,7 +8,9 @@ #include "base/command_line.h" #include "base/strings/stringprintf.h" +#include "chrome/browser/chromeos/arc/arc_auth_notification.h" #include "chrome/browser/extensions/extension_util.h" +#include "chrome/browser/prefs/pref_service_syncable_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -21,6 +23,7 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager_base.h" +#include "components/syncable_prefs/pref_service_syncable.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/url_constants.h" #include "extensions/browser/extension_registry.h" @@ -141,7 +144,14 @@ prefs::kArcEnabled, base::Bind(&ArcAuthService::OnOptInPreferenceChanged, base::Unretained(this))); - OnOptInPreferenceChanged(); + if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { + OnOptInPreferenceChanged(); + } else { + if (!disable_ui_for_testing && profile_->IsNewProfile()) { + PrefServiceSyncableFromProfile(profile_)->AddObserver(this); + OnIsSyncingChanged(); + } + } } else { auth_code_.clear(); ArcBridgeService::Get()->HandleStartup(); @@ -149,8 +159,21 @@ } } +void ArcAuthService::OnIsSyncingChanged() { + syncable_prefs::PrefServiceSyncable* const pref_service_syncable = + PrefServiceSyncableFromProfile(profile_); + if (!pref_service_syncable->IsSyncing()) + return; + + pref_service_syncable->RemoveObserver(this); + if (!profile_->GetPrefs()->HasPrefPath(prefs::kArcEnabled)) + arc::ArcAuthNotification::Show(); +} + void ArcAuthService::Shutdown() { ShutdownBridgeAndCloseUI(); + if (profile_) + PrefServiceSyncableFromProfile(profile_)->RemoveObserver(this); profile_ = nullptr; pref_change_registrar_.RemoveAll(); } @@ -261,8 +284,16 @@ if (state_ != State::FETCHING_CODE) return; - ShutdownBridgeAndCloseUI(); + DisableArc(); +} +void ArcAuthService::EnableArc() { + DCHECK(thread_checker_.CalledOnValidThread()); + profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); +} + +void ArcAuthService::DisableArc() { + DCHECK(thread_checker_.CalledOnValidThread()); profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false); }
diff --git a/chrome/browser/chromeos/arc/arc_auth_service.h b/chrome/browser/chromeos/arc/arc_auth_service.h index 15d83b5..74d03b83 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service.h +++ b/chrome/browser/chromeos/arc/arc_auth_service.h
@@ -15,6 +15,7 @@ #include "components/arc/auth/arc_auth_fetcher.h" #include "components/arc/common/auth.mojom.h" #include "components/prefs/pref_change_registrar.h" +#include "components/syncable_prefs/pref_service_syncable_observer.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/ubertoken_fetcher.h" #include "mojo/public/cpp/bindings/binding.h" @@ -43,7 +44,8 @@ public ArcBridgeService::Observer, public ArcAuthFetcher::Delegate, public UbertokenConsumer, - public GaiaAuthConsumer { + public GaiaAuthConsumer, + public syncable_prefs::PrefServiceSyncableObserver { public: enum class State { DISABLE, // ARC is not allowed to run (default). @@ -103,6 +105,9 @@ // Called from Arc support platform app when user cancels signing. void CancelAuthCode(); + void EnableArc(); + void DisableArc(); + // ArcAuthFetcher::Delegate: void OnAuthCodeFetched(const std::string& auth_code) override; void OnAuthCodeNeedUI() override; @@ -116,6 +121,9 @@ void OnMergeSessionSuccess(const std::string& data) override; void OnMergeSessionFailure(const GoogleServiceAuthError& error) override; + // syncable_prefs::PrefServiceSyncableObserver + void OnIsSyncingChanged() override; + private: void SetAuthCodeAndStartArc(const std::string& auth_code); void ShowUI();
diff --git a/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc b/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc index b251001..42d8ee1 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc
@@ -228,4 +228,19 @@ auth_service()->Shutdown(); } +TEST_F(ArcAuthServiceTest, EnableDisablesArc) { + PrepareURLResponse(net::HTTP_OK, false); + PrefService* pref = profile()->GetPrefs(); + auth_service()->OnPrimaryUserProfilePrepared(profile()); + + EXPECT_FALSE(pref->GetBoolean(prefs::kArcEnabled)); + auth_service()->EnableArc(); + EXPECT_TRUE(pref->GetBoolean(prefs::kArcEnabled)); + auth_service()->DisableArc(); + EXPECT_FALSE(pref->GetBoolean(prefs::kArcEnabled)); + + // Correctly stop service. + auth_service()->Shutdown(); +} + } // namespace arc
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc index 0dbfa19d2..4c7f171d 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -456,6 +456,7 @@ SET_STRING("FORMAT_DEVICE_BUTTON_LABEL", IDS_FILE_BROWSER_FORMAT_DEVICE_BUTTON_LABEL); SET_STRING("SORT_BUTTON_TOOLTIP", IDS_FILE_BROWSER_SORT_BUTTON_TOOLTIP); + SET_STRING("DETAIL_BUTTON_TOOLTIP", IDS_FILE_BROWSER_DETAIL_BUTTON_TOOLTIP); SET_STRING("GEAR_BUTTON_TOOLTIP", IDS_FILE_BROWSER_GEAR_BUTTON_TOOLTIP); SET_STRING("HOSTED_OFFLINE_MESSAGE", IDS_FILE_BROWSER_HOSTED_OFFLINE_MESSAGE); SET_STRING("HOSTED_OFFLINE_MESSAGE_PLURAL",
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index decf10d..ae0c2e0 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -106,7 +106,7 @@ ::switches::kEnableImageColorProfiles, ::switches::kEnableLogging, ::switches::kEnableLowResTiling, - ::switches::kEnablePartialRaster, + ::switches::kDisablePartialRaster, ::switches::kEnablePinch, ::switches::kEnablePreferCompositingToLCDText, ::switches::kEnableRGBA4444Textures,
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 6903f74..2173069 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -13,7 +13,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" -#include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -86,6 +86,19 @@ namespace { +// Enum types for Login.PasswordChangeFlow. +// Don't change the existing values and update LoginPasswordChangeFlow in +// histogram.xml when making changes here. +enum LoginPasswordChangeFlow { + // User is sent to the password changed flow. This is the normal case. + LOGIN_PASSWORD_CHANGE_FLOW_PASSWORD_CHANGED = 0, + // User is sent to the unrecoverable cryptohome failure flow. This is the + // case when http://crbug.com/547857 happens. + LOGIN_PASSWORD_CHANGE_FLOW_CRYPTOHOME_FAILURE = 1, + + LOGIN_PASSWORD_CHANGE_FLOW_COUNT, // Must be the last entry. +}; + // Delay for transferring the auth cache to the system profile. const long int kAuthCacheTransferDelayMs = 2000; @@ -139,6 +152,11 @@ !user_manager::UserManager::Get()->IsSessionStarted(); } +void RecordPasswordChangeFlow(LoginPasswordChangeFlow flow) { + UMA_HISTOGRAM_ENUMERATION("Login.PasswordChangeFlow", flow, + LOGIN_PASSWORD_CHANGE_FLOW_COUNT); +} + } // namespace // static @@ -498,6 +516,8 @@ } void ExistingUserController::ShowPasswordChangedDialog() { + RecordPasswordChangeFlow(LOGIN_PASSWORD_CHANGE_FLOW_PASSWORD_CHANGED); + VLOG(1) << "Show password changed dialog" << ", count=" << login_performer_->password_changed_callback_count(); @@ -1244,6 +1264,7 @@ // Otherwise, show the unrecoverable cryptohome error UI and ask user's // permission to collect a feedback. + RecordPasswordChangeFlow(LOGIN_PASSWORD_CHANGE_FLOW_CRYPTOHOME_FAILURE); VLOG(1) << "Show unrecoverable cryptohome error dialog."; login_display_->ShowUnrecoverableCrypthomeErrorDialog(); }
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc index f5f6b594..9aad594c 100644 --- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc +++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
@@ -318,8 +318,14 @@ } }; +// Flakily times out on ChromeOS MSAN bots. See https://crbug.com/592893. +#if defined(MEMORY_SANITIZER) +#define MAYBE_KeyEventOnLockScreen DISABLED_KeyEventOnLockScreen +#else +#define MAYBE_KeyEventOnLockScreen KeyEventOnLockScreen +#endif IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateAPIUserTest, - KeyEventOnLockScreen) { + MAYBE_KeyEventOnLockScreen) { scoped_ptr<ScreenLockerTester> tester(ScreenLocker::GetTester()); // Log in. user_manager::UserManager::Get()->UserLoggedIn(
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc index 7390dd9..ce3ed72 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc
@@ -239,4 +239,36 @@ return RespondNow(OneArgument(std::move(result))); } +ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() { + if (!IsInputImeEnabled()) + return RespondNow(Error(kErrorAPIDisabled)); + + InputMethodEngine* engine = + GetActiveEngine(browser_context(), extension_id()); + if (!engine) + return RespondNow(Error(kErrorNoActiveEngine)); + + scoped_ptr<api::input_ime::ShowWindow::Params> params( + api::input_ime::ShowWindow::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + engine->ShowImeWindow(params->window_id); + return RespondNow(NoArguments()); +} + +ExtensionFunction::ResponseAction InputImeHideWindowFunction::Run() { + if (!IsInputImeEnabled()) + return RespondNow(Error(kErrorAPIDisabled)); + + InputMethodEngine* engine = + GetActiveEngine(browser_context(), extension_id()); + if (!engine) + return RespondNow(Error(kErrorNoActiveEngine)); + + scoped_ptr<api::input_ime::HideWindow::Params> params( + api::input_ime::HideWindow::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + engine->HideImeWindow(params->window_id); + return RespondNow(NoArguments()); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h b/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h index 7a1eac0..d575cff 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h +++ b/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h
@@ -53,6 +53,28 @@ ExtensionFunction::ResponseAction Run() override; }; +class InputImeShowWindowFunction : public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("input.ime.showWindow", INPUT_IME_SHOWWINDOW) + + protected: + ~InputImeShowWindowFunction() override {} + + // ExtensionFunction: + ExtensionFunction::ResponseAction Run() override; +}; + +class InputImeHideWindowFunction : public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("input.ime.hideWindow", INPUT_IME_HIDEWINDOW) + + protected: + ~InputImeHideWindowFunction() override {} + + // ExtensionFunction: + ExtensionFunction::ResponseAction Run() override; +}; + class InputImeActivateFunction : public UIThreadExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("input.ime.activate", INPUT_IME_ACTIVATE)
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index bcad2bc..03fb9294 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -44,7 +44,6 @@ #include "components/gcm_driver/common/gcm_messages.h" #include "components/gcm_driver/gcm_client.h" #include "content/public/browser/web_contents.h" -#include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -100,13 +99,6 @@ InProcessBrowserTest::SetUp(); } - void SetUpCommandLine(base::CommandLine* command_line) override { - // Enable experiemntal features for subscription restrictions. - command_line->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - InProcessBrowserTest::SetUpCommandLine(command_line); - } - // InProcessBrowserTest: void SetUpOnMainThread() override { gcm_service_ = static_cast<gcm::FakeGCMProfileService*>( @@ -172,8 +164,7 @@ void RequestAndDenyPermission(); void TryToSubscribeSuccessfully( - const std::string& expected_push_subscription_info, - bool use_key = true); + const std::string& expected_push_subscription_id); std::string GetEndpointForSubscriptionId(const std::string& subscription_id) { return std::string(kPushMessagingEndpoint) + "/" + subscription_id; @@ -255,8 +246,7 @@ } void PushMessagingBrowserTest::TryToSubscribeSuccessfully( - const std::string& expected_push_subscription_info, - bool use_key) { + const std::string& expected_push_subscription_id) { std::string script_result; EXPECT_TRUE(RunScript("registerServiceWorker()", &script_result)); @@ -264,14 +254,8 @@ RequestAndAcceptPermission(); - if (use_key) { - EXPECT_TRUE(RunScript("subscribePush()", &script_result)); - } else { - // Test backwards compatibility with old ID based subscriptions. - EXPECT_TRUE(RunScript("subscribePushWithoutKey()", &script_result)); - } - - EXPECT_EQ(GetEndpointForSubscriptionId(expected_push_subscription_info), + EXPECT_TRUE(RunScript("subscribePush()", &script_result)); + EXPECT_EQ(GetEndpointForSubscriptionId(expected_push_subscription_id), script_result); } @@ -296,16 +280,6 @@ } IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, - SubscribeWithoutKeySuccessNotificationsGranted) { - TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */, false); - - PushMessagingAppIdentifier app_identifier = - GetAppIdentifierForServiceWorkerRegistration(0LL); - EXPECT_EQ(app_identifier.app_id(), gcm_service()->last_registered_app_id()); - EXPECT_EQ("1234567890", gcm_service()->last_registered_sender_ids()[0]); -} - -IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, SubscribeSuccessNotificationsGranted) { TryToSubscribeSuccessfully("1-0" /* expected_push_subscription_id */); @@ -333,21 +307,6 @@ EXPECT_EQ("1234567890", gcm_service()->last_registered_sender_ids()[0]); } -IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, SubscribeFailureBadKey) { - std::string script_result; - - ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result)); - ASSERT_EQ("ok - service worker registered", script_result); - - RequestAndAcceptPermission(); - - ASSERT_TRUE(RunScript("subscribePushBadKey()", &script_result)); - EXPECT_EQ( - "InvalidAccessError - Failed to execute 'subscribe' on 'PushManager': " - "The provided applicationServerKey is not valid.", - script_result); -} - IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, SubscribeFailureNotificationsBlocked) { std::string script_result;
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index 48959071..b5f409e 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -44,7 +44,6 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/content_switches.h" #include "content/public/common/push_messaging_status.h" -#include "content/public/common/push_subscription_options.h" #include "ui/base/l10n/l10n_util.h" #if BUILDFLAG(ENABLE_BACKGROUND) @@ -345,9 +344,10 @@ void PushMessagingServiceImpl::SubscribeFromDocument( const GURL& requesting_origin, int64_t service_worker_registration_id, + const std::string& sender_id, int renderer_id, int render_frame_id, - const content::PushSubscriptionOptions& options, + bool user_visible, const content::PushMessagingService::RegisterCallback& callback) { PushMessagingAppIdentifier app_identifier = PushMessagingAppIdentifier::Generate(requesting_origin, @@ -367,7 +367,7 @@ if (!web_contents) return; - if (!options.user_visible_only) { + if (!user_visible) { web_contents->GetMainFrame()->AddMessageToConsole( content::CONSOLE_MESSAGE_LEVEL_ERROR, kSilentPushUnsupportedMessage); @@ -381,14 +381,15 @@ content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(), requesting_origin, base::Bind(&PushMessagingServiceImpl::DidRequestPermission, - weak_factory_.GetWeakPtr(), app_identifier, options, + weak_factory_.GetWeakPtr(), app_identifier, sender_id, callback)); } void PushMessagingServiceImpl::SubscribeFromWorker( const GURL& requesting_origin, int64_t service_worker_registration_id, - const content::PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, const content::PushMessagingService::RegisterCallback& register_callback) { PushMessagingAppIdentifier app_identifier = PushMessagingAppIdentifier::Generate(requesting_origin, @@ -403,7 +404,7 @@ blink::WebPushPermissionStatus permission_status = PushMessagingServiceImpl::GetPermissionStatus(requesting_origin, - options.user_visible_only); + user_visible); if (permission_status != blink::WebPushPermissionStatusGranted) { SubscribeEndWithError(register_callback, @@ -412,7 +413,7 @@ } IncreasePushSubscriptionCount(1, true /* is_pending */); - std::vector<std::string> sender_ids(1, options.sender_info); + std::vector<std::string> sender_ids(1, sender_id); GetGCMDriver()->Register(app_identifier.app_id(), sender_ids, base::Bind(&PushMessagingServiceImpl::DidSubscribe, weak_factory_.GetWeakPtr(), @@ -515,7 +516,7 @@ void PushMessagingServiceImpl::DidRequestPermission( const PushMessagingAppIdentifier& app_identifier, - const content::PushSubscriptionOptions& options, + const std::string& sender_id, const content::PushMessagingService::RegisterCallback& register_callback, content::PermissionStatus permission_status) { if (permission_status != content::PermissionStatus::GRANTED) { @@ -525,7 +526,7 @@ } IncreasePushSubscriptionCount(1, true /* is_pending */); - std::vector<std::string> sender_ids(1, options.sender_info); + std::vector<std::string> sender_ids(1, sender_id); GetGCMDriver()->Register(app_identifier.app_id(), sender_ids, base::Bind(&PushMessagingServiceImpl::DidSubscribe, weak_factory_.GetWeakPtr(),
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.h b/chrome/browser/push_messaging/push_messaging_service_impl.h index a0b145a..3b95d2d5 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.h +++ b/chrome/browser/push_messaging/push_messaging_service_impl.h
@@ -35,7 +35,6 @@ class Profile; class PushMessagingAppIdentifier; class PushMessagingServiceObserver; -struct PushSubscriptionOptions; namespace gcm { class GCMDriver; @@ -75,14 +74,16 @@ void SubscribeFromDocument( const GURL& requesting_origin, int64_t service_worker_registration_id, + const std::string& sender_id, int renderer_id, int render_frame_id, - const content::PushSubscriptionOptions& options, + bool user_visible, const content::PushMessagingService::RegisterCallback& callback) override; void SubscribeFromWorker( const GURL& requesting_origin, int64_t service_worker_registration_id, - const content::PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, const content::PushMessagingService::RegisterCallback& callback) override; void GetEncryptionInfo( const GURL& origin, @@ -164,7 +165,7 @@ void DidRequestPermission( const PushMessagingAppIdentifier& app_identifier, - const content::PushSubscriptionOptions& options, + const std::string& sender_id, const content::PushMessagingService::RegisterCallback& callback, content::PermissionStatus permission_status);
diff --git a/chrome/browser/push_messaging/push_messaging_service_unittest.cc b/chrome/browser/push_messaging/push_messaging_service_unittest.cc index 19167e4..a68e0d1 100644 --- a/chrome/browser/push_messaging/push_messaging_service_unittest.cc +++ b/chrome/browser/push_messaging/push_messaging_service_unittest.cc
@@ -27,7 +27,6 @@ #include "components/gcm_driver/fake_gcm_client_factory.h" #include "components/gcm_driver/gcm_profile_service.h" #include "content/public/common/push_event_payload.h" -#include "content/public/common/push_subscription_options.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -154,11 +153,8 @@ // (2) Subscribe for Push Messaging, and verify that we've got the required // information in order to be able to create encrypted messages. - content::PushSubscriptionOptions options; - options.user_visible_only = true; - options.sender_info = kTestSenderId; push_service->SubscribeFromWorker( - origin, kTestServiceWorkerId, options, + origin, kTestServiceWorkerId, kTestSenderId, true /* user_visible */, base::Bind(&PushMessagingServiceTest::DidRegister, base::Unretained(this), &subscription_id, &p256dh, &auth));
diff --git a/chrome/browser/resources/md_history/compiled_resources2.gyp b/chrome/browser/resources/md_history/compiled_resources2.gyp new file mode 100644 index 0000000..c8fc26b8 --- /dev/null +++ b/chrome/browser/resources/md_history/compiled_resources2.gyp
@@ -0,0 +1,52 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'targets': [ + { + 'target_name': 'constants', + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'history_item', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'history_list', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp:cr_shared_menu', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', + 'constants', + 'history_item', + '../history/compiled_resources2.gyp:externs', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'history_toolbar', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp:cr_search_field', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'history', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', + 'constants', + 'history_list', + 'history_toolbar', + '<(EXTERNS_GYP):chrome_send', + '../history/compiled_resources2.gyp:externs', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + ], +}
diff --git a/chrome/browser/resources/md_history/constants.html b/chrome/browser/resources/md_history/constants.html new file mode 100644 index 0000000..7d01ff31 --- /dev/null +++ b/chrome/browser/resources/md_history/constants.html
@@ -0,0 +1 @@ +<script src="chrome://history/constants.js"></script>
diff --git a/chrome/browser/resources/md_history/constants.js b/chrome/browser/resources/md_history/constants.js new file mode 100644 index 0000000..54202c3 --- /dev/null +++ b/chrome/browser/resources/md_history/constants.js
@@ -0,0 +1,13 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Globals: +/** @const */ var RESULTS_PER_PAGE = 150; + +/** + * Amount of time between pageviews that we consider a 'break' in browsing, + * measured in milliseconds. + * @const + */ +var BROWSING_GAP_TIME = 15 * 60 * 1000;
diff --git a/chrome/browser/resources/md_history/history.html b/chrome/browser/resources/md_history/history.html index 182ac8f..44af7bee 100644 --- a/chrome/browser/resources/md_history/history.html +++ b/chrome/browser/resources/md_history/history.html
@@ -40,6 +40,7 @@ <link rel="import" href="chrome://resources/html/load_time_data.html"> <script src="strings.js"></script> + <link rel="import" href="chrome://history/constants.html"> <link rel="import" href="chrome://history/history_list.html"> <link rel="import" href="chrome://history/history_toolbar.html">
diff --git a/chrome/browser/resources/md_history/history.js b/chrome/browser/resources/md_history/history.js index dff27c6..8279522 100644 --- a/chrome/browser/resources/md_history/history.js +++ b/chrome/browser/resources/md_history/history.js
@@ -2,16 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Globals: -/** @const */ var RESULTS_PER_PAGE = 150; - -/** - * Amount of time between pageviews that we consider a 'break' in browsing, - * measured in milliseconds. - * @const - */ -var BROWSING_GAP_TIME = 15 * 60 * 1000; - window.addEventListener('load', function() { chrome.send('queryHistory', ['', 0, 0, 0, RESULTS_PER_PAGE]); }); @@ -19,9 +9,11 @@ /** * Listens for history-item being selected or deselected (through checkbox) * and changes the view of the top toolbar. + * @param {{detail: {countAddition: number}}} e */ window.addEventListener('history-checkbox-select', function(e) { - $('toolbar').count += e.detail.countAddition; + var toolbar = /** @type {HistoryToolbarElement} */($('toolbar')); + toolbar.count += e.detail.countAddition; }); /** @@ -29,8 +21,10 @@ * checkbox to be unselected. */ window.addEventListener('unselect-all', function() { - $('history-list').unselectAllItems($('toolbar').count); - $('toolbar').count = 0; + var historyList = /** @type {HistoryListElement} */($('history-list')); + var toolbar = /** @type {HistoryToolbarElement} */($('toolbar')); + historyList.unselectAllItems(toolbar.count); + toolbar.count = 0; }); /** @@ -38,15 +32,15 @@ * to determine which ones are selected and deletes these. */ window.addEventListener('delete-selected', function() { - if (!loadTimeData.getBoolean('allowDeletingHistory')) { + if (!loadTimeData.getBoolean('allowDeletingHistory')) return; - } // TODO(hsampson): add a popup to check whether the user definitely wants to // delete the selected items. - var toBeRemoved = - $('history-list').getSelectedItems($('toolbar').count); + var historyList = /** @type {HistoryListElement} */($('history-list')); + var toolbar = /** @type {HistoryToolbarElement} */($('toolbar')); + var toBeRemoved = historyList.getSelectedItems(toolbar.count); chrome.send('removeVisits', toBeRemoved); }); @@ -55,7 +49,7 @@ * When the search is changed refresh the results from the backend. */ window.addEventListener('search-changed', function(e) { - $('history-list').setLoading(); + /** @type {HistoryListElement} */($('history-list')).setLoading(); chrome.send('queryHistory', [e.detail.search, 0, 0, 0, RESULTS_PER_PAGE]); }); @@ -64,20 +58,23 @@ /** * Our history system calls this function with results from searches. * @param {HistoryQuery} info An object containing information about the query. - * @param {Array<HistoryEntry>} results A list of results. + * @param {!Array<HistoryEntry>} results A list of results. */ function historyResult(info, results) { - $('history-list').addNewResults(results, info.term); + var historyList = /** @type {HistoryListElement} */($('history-list')); + historyList.addNewResults(results, info.term); if (info.finished) - $('history-list').disableResultLoading(); + historyList.disableResultLoading(); } /** * Called by the history backend when deletion was succesful. */ function deleteComplete() { - $('history-list').removeDeletedHistory($('toolbar').count); - $('toolbar').count = 0; + var historyList = /** @type {HistoryListElement} */($('history-list')); + var toolbar = /** @type {HistoryToolbarElement} */($('toolbar')); + historyList.removeDeletedHistory(toolbar.count); + toolbar.count = 0; } /**
diff --git a/chrome/browser/resources/md_history/history_list.html b/chrome/browser/resources/md_history/history_list.html index 8bba131d..85b587e 100644 --- a/chrome/browser/resources/md_history/history_list.html +++ b/chrome/browser/resources/md_history/history_list.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> <link rel="import" href="chrome://resources/cr_elements/cr_shared_menu/cr_shared_menu.html"> +<link rel="import" href="chrome://history/constants.html"> <link rel="import" href="chrome://history/history_item.html"> <link rel="import" href="chrome://history/shared_style.html">
diff --git a/chrome/browser/resources/md_history/history_list.js b/chrome/browser/resources/md_history/history_list.js index 76caf44..8aaea2ec 100644 --- a/chrome/browser/resources/md_history/history_list.js +++ b/chrome/browser/resources/md_history/history_list.js
@@ -46,7 +46,7 @@ * @private */ closeMenu_: function() { - this.$.sharedMenu.closeMenu(); + /** @type {CrSharedMenuElement} */(this.$.sharedMenu).closeMenu(); }, /** @@ -63,7 +63,8 @@ * @private */ toggleMenu_: function(e) { - this.$.sharedMenu.toggleMenu(e.detail.target); + var target = e.detail.target; + /** @type {CrSharedMenuElement} */(this.$.sharedMenu).toggleMenu(target); }, /** @@ -86,9 +87,8 @@ this.searchTerm = searchTerm; } - if (historyResults.length == 0) { + if (historyResults.length == 0) return; - } // Creates a copy of historyResults to prevent accidentally modifying this // field.
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.html b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.html new file mode 100644 index 0000000..b3bccdf --- /dev/null +++ b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.html
@@ -0,0 +1 @@ +<script src="chrome://md-settings/certificate_manager_page/certificates_browser_proxy.js"></script>
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js new file mode 100644 index 0000000..26d6749 --- /dev/null +++ b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js
@@ -0,0 +1,254 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A helper object used from the "Manage certificates" section + * to interact with the browser. + */ + +/** + * @typedef {{ + * extractable: boolean, + * id: string, + * name: string, + * policy: boolean, + * readonly: boolean, + * untrusted: boolean, + * urlLocked: boolean + * }} + * @see chrome/browser/ui/webui/settings/certificates_handler.cc + */ +var CertificateSubnode; + +/** + * @typedef {{ + * id: string, + * name: string, + * subnodes: !Array<!CertificateSubnode> + * }} + * @see chrome/browser/ui/webui/settings/certificates_handler.cc + */ +var Certificate; + +/** + * @typedef {{ + * ssl: boolean, + * email: boolean, + * objSign: boolean + * }} + */ +var CaTrustInfo; + +/** + * Generic error returned from C++ via a Promise reject callback. + * @typedef {{ + * title: string, + * description: string + * }} + * @see chrome/browser/ui/webui/settings/certificates_handler.cc + */ +var CertificatesError; + + +/** + * Error returned from C++ via a Promise reject callback, when some certificates + * fail to be imported. + * @typedef {{ + * title: string, + * description: string + * certificateErrors: !Array<{certificateName: string, error: string}> + * }} + * @see chrome/browser/ui/webui/settings/certificates_handler.cc + */ +var CertificatesImportError; + +cr.define('settings', function() { + /** @interface */ + function CertificatesBrowserProxy() {} + + CertificatesBrowserProxy.prototype = { + /** + * Triggers two events in the following order + * 1) 'certificates-model-ready' event. + * 2) 'certificates-changed' event. + */ + refreshCertificates: function() {}, + + /** @param {string} id */ + viewCertificate: function(id) {}, + + /** @param {string} id */ + exportCertificate: function(id) {}, + + /** + * @param {string} id + * @return {!Promise} + */ + deleteCertificate: function(id) {}, + + /** + * @param {string} id + * @return {!Promise<!CaTrustInfo>} + */ + getCaCertificateTrust: function(id) {}, + + /** + * @param {string} id + * @param {boolean} ssl + * @param {boolean} email + * @param {boolean} objSign + * @return {!Promise} + */ + editCaCertificateTrust: function(id, ssl, email, objSign) {}, + + cancelImportExportCertificate: function() {}, + + /** + * @param {string} id + * @return {!Promise} A promise firing once the user has selected + * the export location. A prompt should be shown to asking for a + * password to use for encrypting the file. The password should be + * passed back via a call to + * exportPersonalCertificatePasswordSelected(). + */ + exportPersonalCertificate: function(id) {}, + + /** + * @param {string} password + * @return {!Promise} + */ + exportPersonalCertificatePasswordSelected: function(password) {}, + + /** + * @param {boolean} useHardwareBacked + * @return {!Promise<boolean>} A promise firing once the user has selected + * the file to be imported. If true a password prompt should be shown to + * the user, and the password should be passed back via a call to + * importPersonalCertificatePasswordSelected(). + */ + importPersonalCertificate: function(useHardwareBacked) {}, + + /** + * @param {string} password + * @return {!Promise} + */ + importPersonalCertificatePasswordSelected: function(password) {}, + + /** + * @return {!Promise} A promise firing once the user has selected + * the file to be imported, or failing with CertificatesError. + * Upon success, a prompt should be shown to the user to specify the + * trust levels, and that information should be passed back via a call + * to importCaCertificateTrustSelected(). + */ + importCaCertificate: function() {}, + + /** + * @param {boolean} ssl + * @param {boolean} email + * @param {boolean} objSign + * @return {!Promise} A promise firing once the trust level for the imported + * certificate has been successfully set. The promise is rejected if an + * error occurred with either a CertificatesError or + * CertificatesImportError. + */ + importCaCertificateTrustSelected: function(ssl, email, objSign) {}, + + /** + * @return {!Promise} A promise firing once the certificate has been + * imported. The promise is rejected if an error occurred, with either + * a CertificatesError or CertificatesImportError. + */ + importServerCertificate: function() {}, + }; + + /** + * @constructor + * @implements {settings.CertificatesBrowserProxy} + */ + function CertificatesBrowserProxyImpl() {} + // The singleton instance_ is replaced with a test version of this wrapper + // during testing. + cr.addSingletonGetter(CertificatesBrowserProxyImpl); + + CertificatesBrowserProxyImpl.prototype = { + /** @override */ + refreshCertificates: function() { + chrome.send('refreshCertificates'); + }, + + /** @override */ + viewCertificate: function(id) { + chrome.send('viewCertificate', [id]); + }, + + /** @override */ + exportCertificate: function(id) { + chrome.send('exportCertificate', [id]); + }, + + /** @override */ + deleteCertificate: function(id) { + return cr.sendWithPromise('deleteCertificate', id); + }, + + /** @override */ + exportPersonalCertificate: function(id) { + return cr.sendWithPromise('exportPersonalCertificate', id); + }, + + /** @override */ + exportPersonalCertificatePasswordSelected: function(password) { + return cr.sendWithPromise( + 'exportPersonalCertificatePasswordSelected', password); + }, + + /** @override */ + importPersonalCertificate: function(useHardwareBacked) { + return cr.sendWithPromise('importPersonalCertificate', useHardwareBacked); + }, + + /** @override */ + importPersonalCertificatePasswordSelected: function(password) { + return cr.sendWithPromise( + 'importPersonalCertificatePasswordSelected', password); + }, + + /** @override */ + getCaCertificateTrust: function(id) { + return cr.sendWithPromise('getCaCertificateTrust', id); + }, + + /** @override */ + editCaCertificateTrust: function(id, ssl, email, objSign) { + return cr.sendWithPromise( + 'editCaCertificateTrust', id, ssl, email, objSign); + }, + + /** @override */ + importCaCertificateTrustSelected: function(ssl, email, objSign) { + return cr.sendWithPromise( + 'importCaCertificateTrustSelected', ssl, email, objSign); + }, + + /** @override */ + cancelImportExportCertificate: function() { + chrome.send('cancelImportExportCertificate'); + }, + + /** @override */ + importCaCertificate: function() { + return cr.sendWithPromise('importCaCertificate'); + }, + + /** @override */ + importServerCertificate: function() { + return cr.sendWithPromise('importServerCertificate'); + }, + }; + + return { + CertificatesBrowserProxyImpl: CertificatesBrowserProxyImpl, + }; +});
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 8754c7bb..f0d587d0 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -171,6 +171,12 @@ <structure name="IDR_SETTINGS_CERTIFICATE_MANAGER_PAGE_JS" file="certificate_manager_page/certificate_manager_page.js" type="chrome_html" /> + <structure name="IDR_SETTINGS_CERTIFICATES_BROWSER_PROXY_HTML" + file="certificate_manager_page/certificates_browser_proxy.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CERTIFICATES_BROWSER_PROXY_JS" + file="certificate_manager_page/certificates_browser_proxy.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_CLEAR_BROWSING_DATA_PAGE_CSS" file="clear_browsing_data_page/clear_browsing_data_page.css" type="chrome_html" />
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index e4d5461..208f11fd 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -54,10 +54,6 @@ #include "chrome/browser/supervised_user/supervised_user_theme.h" #endif -#if defined(OS_WIN) -#include "ui/base/win/shell.h" -#endif - using base::UserMetricsAction; using content::BrowserThread; using extensions::Extension; @@ -413,6 +409,79 @@ return false; } +SkColor ThemeService::GetDefaultColor(int id, bool incognito) const { + // For backward compat with older themes, some newer colors are generated from + // older ones if they are missing. + const int kNtpText = ThemeProperties::COLOR_NTP_TEXT; + const int kLabelBackground = + ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND; + switch (id) { + case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON: + return color_utils::HSLShift( + gfx::kChromeIconGrey, + GetTint(ThemeProperties::TINT_BUTTONS, incognito)); + case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_INACTIVE: + // The active color is overridden in Gtk2UI. + return SkColorSetA( + GetColor(ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON, incognito), + 0x33); + case ThemeProperties::COLOR_BACKGROUND_TAB: { + // The tints here serve a different purpose than TINT_BACKGROUND_TAB. + // That tint is used to create background tab images for custom themes by + // lightening the frame images. The tints here create solid colors for + // background tabs by darkening the foreground tab (toolbar) color. + const color_utils::HSL kTint = {-1, -1, 0.4296875}; + const color_utils::HSL kTintIncognito = {-1, -1, 0.34375}; + return color_utils::HSLShift( + GetColor(ThemeProperties::COLOR_TOOLBAR, incognito), + incognito ? kTintIncognito : kTint); + } + case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND: + if (UsingDefaultTheme()) + break; + return GetColor(ThemeProperties::COLOR_TOOLBAR, incognito); + case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR: + if (UsingDefaultTheme()) + break; + // Use 50% of bookmark text color as separator color. + return SkColorSetA( + GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT, incognito), 128); + case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT: + return IncreaseLightness(GetColor(kNtpText, incognito), 0.30); + case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER: + return GetColor(kNtpText, incognito); + case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE: + return IncreaseLightness(GetColor(kNtpText, incognito), 0.70); + case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT: + return IncreaseLightness(GetColor(kNtpText, incognito), 0.86); + case ThemeProperties::COLOR_NTP_TEXT_LIGHT: + return IncreaseLightness(GetColor(kNtpText, incognito), 0.40); + case ThemeProperties::COLOR_TAB_THROBBER_SPINNING: + case ThemeProperties::COLOR_TAB_THROBBER_WAITING: { + SkColor base_color = + ui::GetAuraColor(id == ThemeProperties::COLOR_TAB_THROBBER_SPINNING + ? ui::NativeTheme::kColorId_ThrobberSpinningColor + : ui::NativeTheme::kColorId_ThrobberWaitingColor, + nullptr); + color_utils::HSL hsl = GetTint(ThemeProperties::TINT_BUTTONS, incognito); + return color_utils::HSLShift(base_color, hsl); + } +#if defined(ENABLE_SUPERVISED_USERS) + case ThemeProperties::COLOR_SUPERVISED_USER_LABEL: + return color_utils::GetReadableColor( + SK_ColorWHITE, GetColor(kLabelBackground, incognito)); + case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND: + return color_utils::BlendTowardOppositeLuma( + GetColor(ThemeProperties::COLOR_FRAME, incognito), 0x80); + case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BORDER: + return color_utils::AlphaBlend(GetColor(kLabelBackground, incognito), + SK_ColorBLACK, 230); +#endif + } + + return ThemeProperties::GetDefaultColor(id, incognito); +} + color_utils::HSL ThemeService::GetTint(int id, bool incognito) const { DCHECK(CalledOnValidThread()); @@ -513,6 +582,15 @@ } #endif +bool ThemeService::ShouldUseNativeFrame() const { + return false; +} + +bool ThemeService::HasCustomImage(int id) const { + return BrowserThemePack::IsPersistentImageID(id) && theme_supplier_ && + theme_supplier_->HasCustomImage(id); +} + gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id, bool incognito) const { gfx::Image image = GetImageNamed(id, incognito); if (image.IsEmpty()) @@ -539,76 +617,7 @@ if (theme_supplier_ && theme_supplier_->GetColor(theme_supplier_id, &color)) return color; - // For backward compat with older themes, some newer colors are generated from - // older ones if they are missing. - const int kNtpText = ThemeProperties::COLOR_NTP_TEXT; - const int kLabelBackground = - ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND; - switch (id) { - case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON: - return color_utils::HSLShift( - gfx::kChromeIconGrey, - GetTint(ThemeProperties::TINT_BUTTONS, incognito)); - case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_INACTIVE: - // The active color is overridden in Gtk2UI. - return SkColorSetA( - GetColor(ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON, incognito), - 0x33); - case ThemeProperties::COLOR_BACKGROUND_TAB: { - // The tints here serve a different purpose than TINT_BACKGROUND_TAB. - // That tint is used to create background tab images for custom themes by - // lightening the frame images. The tints here create solid colors for - // background tabs by darkening the foreground tab (toolbar) color. - const color_utils::HSL kTint = {-1, -1, 0.4296875}; - const color_utils::HSL kTintIncognito = {-1, -1, 0.34375}; - return color_utils::HSLShift( - GetColor(ThemeProperties::COLOR_TOOLBAR, incognito), - incognito ? kTintIncognito : kTint); - } - case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_BACKGROUND: - if (UsingDefaultTheme()) - break; - return GetColor(ThemeProperties::COLOR_TOOLBAR, incognito); - case ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR: - if (UsingDefaultTheme()) - break; - // Use 50% of bookmark text color as separator color. - return SkColorSetA( - GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT, incognito), 128); - case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT: - return IncreaseLightness(GetColor(kNtpText, incognito), 0.30); - case ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER: - return GetColor(kNtpText, incognito); - case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE: - return IncreaseLightness(GetColor(kNtpText, incognito), 0.70); - case ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT: - return IncreaseLightness(GetColor(kNtpText, incognito), 0.86); - case ThemeProperties::COLOR_NTP_TEXT_LIGHT: - return IncreaseLightness(GetColor(kNtpText, incognito), 0.40); - case ThemeProperties::COLOR_TAB_THROBBER_SPINNING: - case ThemeProperties::COLOR_TAB_THROBBER_WAITING: { - SkColor base_color = - ui::GetAuraColor(id == ThemeProperties::COLOR_TAB_THROBBER_SPINNING - ? ui::NativeTheme::kColorId_ThrobberSpinningColor - : ui::NativeTheme::kColorId_ThrobberWaitingColor, - nullptr); - color_utils::HSL hsl = GetTint(ThemeProperties::TINT_BUTTONS, incognito); - return color_utils::HSLShift(base_color, hsl); - } -#if defined(ENABLE_SUPERVISED_USERS) - case ThemeProperties::COLOR_SUPERVISED_USER_LABEL: - return color_utils::GetReadableColor( - SK_ColorWHITE, GetColor(kLabelBackground, incognito)); - case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BACKGROUND: - return color_utils::BlendTowardOppositeLuma( - GetColor(ThemeProperties::COLOR_FRAME, incognito), 0x80); - case ThemeProperties::COLOR_SUPERVISED_USER_LABEL_BORDER: - return color_utils::AlphaBlend(GetColor(kLabelBackground, incognito), - SK_ColorBLACK, 230); -#endif - } - - return ThemeProperties::GetDefaultColor(id, incognito); + return GetDefaultColor(id, incognito); } int ThemeService::GetDisplayProperty(int id) const { @@ -638,21 +647,6 @@ } } -bool ThemeService::ShouldUseNativeFrame() const { - if (HasCustomImage(IDR_THEME_FRAME)) - return false; -#if defined(OS_WIN) - return ui::win::IsAeroGlassEnabled(); -#else - return false; -#endif -} - -bool ThemeService::HasCustomImage(int id) const { - return BrowserThemePack::IsPersistentImageID(id) && theme_supplier_ && - theme_supplier_->HasCustomImage(id); -} - base::RefCountedMemory* ThemeService::GetRawData( int id, ui::ScaleFactor scale_factor) const {
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h index 9eea41a..7f4cf1e8 100644 --- a/chrome/browser/themes/theme_service.h +++ b/chrome/browser/themes/theme_service.h
@@ -136,6 +136,10 @@ // Returns true if the ThemeService should use the system theme on startup. virtual bool ShouldInitWithSystemTheme() const; + // Returns the color to use for |id| and |incognito| if the theme service does + // not provide an override. + virtual SkColor GetDefaultColor(int id, bool incognito) const; + // Get the specified tint - |id| is one of the TINT_* enum values. color_utils::HSL GetTint(int id, bool incognito) const; @@ -157,6 +161,11 @@ // from ClearAllThemeData(). virtual void FreePlatformCaches(); + // Implementation for ui::ThemeProvider (see block of functions in private + // section). + virtual bool ShouldUseNativeFrame() const; + bool HasCustomImage(int id) const; + Profile* profile() const { return profile_; } void set_ready() { ready_ = true; } @@ -211,8 +220,6 @@ gfx::ImageSkia* GetImageSkiaNamed(int id, bool incognito) const; SkColor GetColor(int id, bool incognito) const; int GetDisplayProperty(int id) const; - bool ShouldUseNativeFrame() const; - bool HasCustomImage(int id) const; base::RefCountedMemory* GetRawData(int id, ui::ScaleFactor scale_factor) const; #if defined(OS_MACOSX)
diff --git a/chrome/browser/themes/theme_service_factory.cc b/chrome/browser/themes/theme_service_factory.cc index 9f7ebbd..3e72af0e 100644 --- a/chrome/browser/themes/theme_service_factory.cc +++ b/chrome/browser/themes/theme_service_factory.cc
@@ -16,7 +16,9 @@ #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_factory.h" -#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(OS_WIN) +#include "chrome/browser/themes/theme_service_win.h" +#elif defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS) #include "chrome/browser/themes/theme_service_aurax11.h" #include "ui/views/linux_ui/linux_ui.h" #endif @@ -55,7 +57,9 @@ KeyedService* ThemeServiceFactory::BuildServiceInstanceFor( content::BrowserContext* profile) const { ThemeService* provider = NULL; -#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(OS_WIN) + provider = new ThemeServiceWin; +#elif defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS) provider = new ThemeServiceAuraX11; #else provider = new ThemeService;
diff --git a/chrome/browser/themes/theme_service_win.cc b/chrome/browser/themes/theme_service_win.cc new file mode 100644 index 0000000..6573ee8 --- /dev/null +++ b/chrome/browser/themes/theme_service_win.cc
@@ -0,0 +1,67 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/theme_service_win.h" + +#include "base/bind.h" +#include "base/win/windows_version.h" +#include "chrome/browser/themes/theme_properties.h" +#include "grit/theme_resources.h" +#include "skia/ext/skia_utils_win.h" +#include "ui/base/win/shell.h" + +ThemeServiceWin::ThemeServiceWin() { + // This just checks for Windows 10 instead of calling ShouldUseDwmFrameColor() + // because we want to monitor the frame color even when a custom frame is in + // use, so that it will be correct if at any time the user switches to the + // native frame. + if (base::win::GetVersion() >= base::win::VERSION_WIN10) { + dwm_key_.reset(new base::win::RegKey( + HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM", KEY_READ)); + OnDwmKeyUpdated(); + } +} + +ThemeServiceWin::~ThemeServiceWin() { +} + +bool ThemeServiceWin::ShouldUseNativeFrame() const { + return !HasCustomImage(IDR_THEME_FRAME) && ui::win::IsAeroGlassEnabled(); +} + +SkColor ThemeServiceWin::GetDefaultColor(int id, bool incognito) const { + if (ShouldUseDwmFrameColor()) { + // Active native windows on Windows 10 may have a custom frame color. + if (id == ThemeProperties::COLOR_FRAME) + return dwm_frame_color_; + + // Inactive native windows on Windows 10 always have a white frame. + if (id == ThemeProperties::COLOR_FRAME_INACTIVE) + return SK_ColorWHITE; + } + + return ThemeService::GetDefaultColor(id, incognito); +} + +bool ThemeServiceWin::ShouldUseDwmFrameColor() const { + return ShouldUseNativeFrame() && + (base::win::GetVersion() >= base::win::VERSION_WIN10); +} + +void ThemeServiceWin::OnDwmKeyUpdated() { + // Attempt to read the accent color. + DWORD accent_color, color_prevalence; + dwm_frame_color_ = + ((dwm_key_->ReadValueDW(L"ColorPrevalence", &color_prevalence) == + ERROR_SUCCESS) && + (color_prevalence == 1) && + (dwm_key_->ReadValueDW(L"AccentColor", &accent_color) == ERROR_SUCCESS)) + ? skia::COLORREFToSkColor(accent_color) + : SK_ColorWHITE; + + // Watch for future changes. + if (!dwm_key_->StartWatching(base::Bind( + &ThemeServiceWin::OnDwmKeyUpdated, base::Unretained(this)))) + dwm_key_.reset(); +}
diff --git a/chrome/browser/themes/theme_service_win.h b/chrome/browser/themes/theme_service_win.h new file mode 100644 index 0000000..0f0473d --- /dev/null +++ b/chrome/browser/themes/theme_service_win.h
@@ -0,0 +1,39 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_THEMES_THEME_SERVICE_WIN_H_ +#define CHROME_BROWSER_THEMES_THEME_SERVICE_WIN_H_ + +#include "base/win/registry.h" +#include "chrome/browser/themes/theme_service.h" + +class ThemeServiceWin : public ThemeService { + public: + ThemeServiceWin(); + ~ThemeServiceWin() override; + + private: + // ThemeService: + bool ShouldUseNativeFrame() const override; + SkColor GetDefaultColor(int id, bool incognito) const override; + + // Returns true if the window frame color is determined by the DWM, i.e. this + // is a native frame on Windows 10. + bool ShouldUseDwmFrameColor() const; + + // Callback executed when |dwm_key_| is updated. This re-reads the active + // frame color and updates |dwm_frame_color_|. + void OnDwmKeyUpdated(); + + // Registry key containing the params that determine the DWM frame color. + // This is only initialized on Windows 10. + scoped_ptr<base::win::RegKey> dwm_key_; + + // The DWM frame color, if available; white otherwise. + SkColor dwm_frame_color_; + + DISALLOW_COPY_AND_ASSIGN(ThemeServiceWin); +}; + +#endif // CHROME_BROWSER_THEMES_THEME_SERVICE_WIN_H_
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h index 9fcd262..27113dfc 100644 --- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_DIALOG_COCOA_H_ #include "base/mac/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/autofill/autofill_dialog_types.h" #include "chrome/browser/ui/autofill/autofill_dialog_view.h" @@ -64,7 +65,7 @@ // Closes the sheet and ends the modal loop. Triggers cleanup sequence. void CloseNow(); - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; base::scoped_nsobject<AutofillDialogWindowController> sheet_delegate_; // The delegate |this| queries for logic and state.
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm index 1731bb3..4a80bbd 100644 --- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
@@ -38,8 +38,8 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:[sheet_delegate_ window]]); - constrained_window_ = - CreateAndShowWebModalDialogMac(this, delegate_->GetWebContents(), sheet); + constrained_window_.reset( + new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet)); [sheet_delegate_ show]; }
diff --git a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h index e9358d3..64faef1 100644 --- a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h +++ b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_COCOA_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_BRIDGE_H_ #include "base/mac/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" #include "components/autofill/core/browser/ui/card_unmask_prompt_view.h" @@ -40,7 +41,7 @@ void PerformClose(); private: - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; base::scoped_nsobject<CardUnmaskPromptViewCocoa> view_controller_; // The controller |this| queries for logic and state.
diff --git a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm index b4f949e..2a9d770 100644 --- a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm +++ b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm
@@ -87,8 +87,8 @@ [window setContentView:[view_controller_ view]]; base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]); - constrained_window_ = - CreateAndShowWebModalDialogMac(this, web_contents_, sheet); + constrained_window_.reset( + new ConstrainedWindowMac(this, web_contents_, sheet)); } void CardUnmaskPromptViewBridge::ControllerGone() {
diff --git a/chrome/browser/ui/cocoa/certificate_viewer_mac.h b/chrome/browser/ui/cocoa/certificate_viewer_mac.h index 7990758..f33bef2d 100644 --- a/chrome/browser/ui/cocoa/certificate_viewer_mac.h +++ b/chrome/browser/ui/cocoa/certificate_viewer_mac.h
@@ -24,7 +24,7 @@ base::scoped_nsobject<NSArray> certificates_; scoped_ptr<SSLCertificateViewerCocoaBridge> observer_; base::scoped_nsobject<SFCertificatePanel> panel_; - std::unique_ptr<ConstrainedWindowMac> constrainedWindow_; + scoped_ptr<ConstrainedWindowMac> constrainedWindow_; base::scoped_nsobject<NSWindow> overlayWindow_; BOOL closePending_; // A copy of the sheet's frame used to restore on show.
diff --git a/chrome/browser/ui/cocoa/certificate_viewer_mac.mm b/chrome/browser/ui/cocoa/certificate_viewer_mac.mm index 1adb0f1..5c41b94f 100644 --- a/chrome/browser/ui/cocoa/certificate_viewer_mac.mm +++ b/chrome/browser/ui/cocoa/certificate_viewer_mac.mm
@@ -134,8 +134,8 @@ panel_.reset([[SFCertificatePanel alloc] init]); [panel_ setPolicies:(id) policies.get()]; - constrainedWindow_ = - CreateAndShowWebModalDialogMac(observer_.get(), webContents, self); + constrainedWindow_.reset( + new ConstrainedWindowMac(observer_.get(), webContents, self)); } - (NSWindow*)overlayWindow { @@ -189,10 +189,6 @@ // NOOP } -- (void)resizeWithNewSize:(NSSize)preferredSize { - // NOOP -} - - (NSWindow*)sheetWindow { return panel_; }
diff --git a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm index 5dc49ab..0ce4df8d 100644 --- a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm +++ b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
@@ -11,11 +11,7 @@ #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h" #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h" -#include "chrome/browser/ui/webui/chrome_web_contents_handler.h" -#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_observer.h" -#include "ui/base/cocoa/window_size_constants.h" #include "ui/gfx/geometry/size.h" #include "ui/web_dialogs/web_dialog_delegate.h" #include "ui/web_dialogs/web_dialog_ui.h" @@ -27,61 +23,19 @@ namespace { -class ConstrainedWebDialogDelegateMac; - -// This class is to trigger a resize to the dialog window when -// ResizeDueToAutoResize() is invoked. -class WebDialogWebContentsDelegateMac - : public ui::WebDialogWebContentsDelegate { - public: - WebDialogWebContentsDelegateMac(content::BrowserContext* browser_context, - content::WebContentsObserver* observer, - ConstrainedWebDialogDelegateBase* delegate) - : ui::WebDialogWebContentsDelegate(browser_context, - new ChromeWebContentsHandler()), - observer_(observer), - delegate_(delegate) { - } - ~WebDialogWebContentsDelegateMac() override {} - - void ResizeDueToAutoResize(content::WebContents* source, - const gfx::Size& preferred_size) override { - if (!observer_->web_contents()) - return; - delegate_->ResizeToGivenSize(preferred_size); - } - - private: - // These members must outlive the instance. - content::WebContentsObserver* const observer_; - ConstrainedWebDialogDelegateBase* delegate_; - - DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateMac); -}; - class ConstrainedWebDialogDelegateMac : public ConstrainedWebDialogDelegateBase { public: ConstrainedWebDialogDelegateMac( content::BrowserContext* browser_context, - WebDialogDelegate* delegate, - content::WebContentsObserver* observer) - : ConstrainedWebDialogDelegateBase(browser_context, delegate, - new WebDialogWebContentsDelegateMac(browser_context, observer, - this)) {} + WebDialogDelegate* delegate) + : ConstrainedWebDialogDelegateBase(browser_context, delegate, NULL) {} // WebDialogWebContentsDelegate interface. void CloseContents(WebContents* source) override { window_->CloseWebContentsModalDialog(); } - // ConstrainedWebDialogDelegateBase: - void ResizeToGivenSize(const gfx::Size size) override { - NSSize updated_preferred_size = NSMakeSize(size.width(), - size.height()); - [window_->sheet() resizeWithNewSize:updated_preferred_size]; - } - void set_window(ConstrainedWindowMac* window) { window_ = window; } ConstrainedWindowMac* window() const { return window_; } @@ -96,16 +50,13 @@ class ConstrainedWebDialogDelegateViewMac : public ConstrainedWindowMacDelegate, - public ConstrainedWebDialogDelegate, - public content::WebContentsObserver { + public ConstrainedWebDialogDelegate { public: ConstrainedWebDialogDelegateViewMac( content::BrowserContext* browser_context, WebDialogDelegate* delegate, - content::WebContents* web_contents, - const gfx::Size& min_size, - const gfx::Size& max_size); + content::WebContents* web_contents); ~ConstrainedWebDialogDelegateViewMac() override {} // ConstrainedWebDialogDelegate interface @@ -124,37 +75,16 @@ gfx::NativeWindow GetNativeDialog() override { return window_; } WebContents* GetWebContents() override { return impl_->GetWebContents(); } gfx::Size GetMinimumSize() const override { - return min_size_; + NOTIMPLEMENTED(); + return gfx::Size(); } gfx::Size GetMaximumSize() const override { - return max_size_; + NOTIMPLEMENTED(); + return gfx::Size(); } gfx::Size GetPreferredSize() const override { - gfx::Size size; - if (!impl_->closed_via_webui()) { - NSRect frame = [window_ frame]; - size = gfx::Size(frame.size.width, frame.size.height); - } - return size; - } - - // content::WebContentsObserver: - void RenderViewCreated(content::RenderViewHost* render_view_host) override { - if (IsDialogAutoResizable()) - EnableAutoResize(); - } - void RenderViewHostChanged(content::RenderViewHost* old_host, - content::RenderViewHost* new_host) override { - if (IsDialogAutoResizable()) - EnableAutoResize(); - } - void DocumentOnLoadCompletedInMainFrame() override { - if (!IsDialogAutoResizable()) - return; - - EnableAutoResize(); - if (GetWebContents()) - constrained_window_->ShowWebContentsModalDialog(); + NOTIMPLEMENTED(); + return gfx::Size(); } // ConstrainedWindowMacDelegate interface @@ -165,53 +95,25 @@ } private: - void EnableAutoResize() { - if (!GetWebContents()) - return; - - content::RenderViewHost* render_view_host = - GetWebContents()->GetRenderViewHost(); - render_view_host->EnableAutoResize(min_size_, max_size_); - } - - // Whether or not the dialog is autoresizable is determined based on whether - // |max_size_| was specified. - bool IsDialogAutoResizable() { - return !max_size_.IsEmpty(); - } - scoped_ptr<ConstrainedWebDialogDelegateMac> impl_; - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; base::scoped_nsobject<NSWindow> window_; - // Minimum and maximum sizes to determine dialog bounds for auto-resizing. - const gfx::Size min_size_; - const gfx::Size max_size_; - DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac); }; ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac( content::BrowserContext* browser_context, WebDialogDelegate* delegate, - content::WebContents* web_contents, - const gfx::Size& min_size, - const gfx::Size& max_size) - : content::WebContentsObserver(web_contents), - impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate, - this)), - min_size_(min_size), - max_size_(max_size) { - if (IsDialogAutoResizable()) - Observe(GetWebContents()); - + content::WebContents* web_contents) + : impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate)) { // Create a window to hold web_contents in the constrained sheet: gfx::Size size; delegate->GetDialogSize(&size); NSRect frame = NSMakeRect(0, 0, size.width(), size.height()); - window_.reset([[ConstrainedWindowCustomWindow alloc] - initWithContentRect:ui::kWindowSizeDeterminedLater]); + window_.reset( + [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]); [GetWebContents()->GetNativeView() setFrame:frame]; [GetWebContents()->GetNativeView() setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable]; @@ -220,14 +122,8 @@ base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet( [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_ webDialogDelegate:delegate]); - - if (IsDialogAutoResizable()) { - constrained_window_ = CreateWebModalDialogMac( - this, web_contents, sheet); - } else { - constrained_window_ = CreateAndShowWebModalDialogMac( - this, web_contents, sheet); - } + constrained_window_.reset(new ConstrainedWindowMac( + this, web_contents, sheet)); impl_->set_window(constrained_window_.get()); } @@ -239,23 +135,6 @@ // Deleted when the dialog closes. ConstrainedWebDialogDelegateViewMac* constrained_delegate = new ConstrainedWebDialogDelegateViewMac( - browser_context, delegate, web_contents, - gfx::Size(), gfx::Size()); - return constrained_delegate; -} - -ConstrainedWebDialogDelegate* ShowConstrainedWebDialogWithAutoResize( - content::BrowserContext* browser_context, - WebDialogDelegate* delegate, - content::WebContents* web_contents, - const gfx::Size& min_size, - const gfx::Size& max_size) { - DCHECK(!min_size.IsEmpty()); - DCHECK(!max_size.IsEmpty()); - // Deleted when the dialog closes. - ConstrainedWebDialogDelegateViewMac* constrained_delegate = - new ConstrainedWebDialogDelegateViewMac( - browser_context, delegate, web_contents, - min_size, max_size); + browser_context, delegate, web_contents); return constrained_delegate; }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm index ab67fc6..aac59467 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm
@@ -73,10 +73,6 @@ [customWindow_ setFrameOrigin:origin]; } -- (void)resizeWithNewSize:(NSSize)size { - // NOOP -} - - (NSWindow*)sheetWindow { return customWindow_; }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h index 3b60a39..e3d981e 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
@@ -7,9 +7,6 @@ #import <Cocoa/Cocoa.h> -#include "base/mac/scoped_nsobject.h" -#include "components/web_modal/web_contents_modal_dialog_manager.h" - namespace content { class WebContents; } @@ -24,18 +21,6 @@ virtual void OnConstrainedWindowClosed(ConstrainedWindowMac* window) = 0; }; -// Creates a ConstrainedWindowMac, shows the dialog, and returns it. -std::unique_ptr<ConstrainedWindowMac> CreateAndShowWebModalDialogMac( - ConstrainedWindowMacDelegate* delegate, - content::WebContents* web_contents, - id<ConstrainedWindowSheet> sheet); - -// Creates a ConstrainedWindowMac and returns it. -std::unique_ptr<ConstrainedWindowMac> CreateWebModalDialogMac( - ConstrainedWindowMacDelegate* delegate, - content::WebContents* web_contents, - id<ConstrainedWindowSheet> sheet); - // Constrained window implementation for Mac. // Normally an instance of this class is owned by the delegate. The delegate // should delete the instance when the window is closed. @@ -46,9 +31,6 @@ id<ConstrainedWindowSheet> sheet); ~ConstrainedWindowMac(); - // Shows the constrained window. - void ShowWebContentsModalDialog(); - // Closes the constrained window. void CloseWebContentsModalDialog(); @@ -56,24 +38,13 @@ void set_manager(SingleWebContentsDialogManagerCocoa* manager) { manager_ = manager; } - id<ConstrainedWindowSheet> sheet() const { return sheet_.get(); } // Called by |manager_| when the dialog is closing. void OnDialogClosing(); - // Whether or not the dialog was shown. If the dialog is auto-resizable, it - // is hidden until its WebContents initially loads. - bool DialogWasShown(); - - // Gets the dialog manager for |web_contents_|. - web_modal::WebContentsModalDialogManager* GetDialogManager(); - private: ConstrainedWindowMacDelegate* delegate_; // weak, owns us. SingleWebContentsDialogManagerCocoa* manager_; // weak, owned by WCMDM. - content::WebContents* web_contents_; // weak, owned by dialog initiator. - base::scoped_nsprotocol<id<ConstrainedWindowSheet>> sheet_; - scoped_ptr<SingleWebContentsDialogManagerCocoa> native_manager_; }; #endif // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_MAC_
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm index 510402e8..16f755c 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
@@ -11,59 +11,35 @@ #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h" #import "chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h" #include "components/guest_view/browser/guest_view_base.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/browser_thread.h" using web_modal::WebContentsModalDialogManager; -std::unique_ptr<ConstrainedWindowMac> CreateAndShowWebModalDialogMac( - ConstrainedWindowMacDelegate* delegate, - content::WebContents* web_contents, - id<ConstrainedWindowSheet> sheet) { - ConstrainedWindowMac* window = - new ConstrainedWindowMac(delegate, web_contents, sheet); - window->ShowWebContentsModalDialog(); - return std::unique_ptr<ConstrainedWindowMac>(window); -} - -std::unique_ptr<ConstrainedWindowMac> CreateWebModalDialogMac( - ConstrainedWindowMacDelegate* delegate, - content::WebContents* web_contents, - id<ConstrainedWindowSheet> sheet) { - return std::unique_ptr<ConstrainedWindowMac>( - new ConstrainedWindowMac(delegate, web_contents, sheet)); -} - ConstrainedWindowMac::ConstrainedWindowMac( ConstrainedWindowMacDelegate* delegate, content::WebContents* web_contents, id<ConstrainedWindowSheet> sheet) - : delegate_(delegate), - sheet_([sheet retain]) { + : delegate_(delegate) { DCHECK(sheet); // |web_contents| may be embedded within a chain of nested GuestViews. If it // is, follow the chain of embedders to the outermost WebContents and use it. - web_contents_ = + web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents); - native_manager_.reset( - new SingleWebContentsDialogManagerCocoa(this, sheet_.get(), - GetDialogManager())); + auto manager = WebContentsModalDialogManager::FromWebContents(web_contents); + scoped_ptr<SingleWebContentsDialogManagerCocoa> native_manager( + new SingleWebContentsDialogManagerCocoa(this, sheet, manager)); + manager->ShowDialogWithManager([sheet sheetWindow], + std::move(native_manager)); } ConstrainedWindowMac::~ConstrainedWindowMac() { CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - native_manager_.reset(); DCHECK(!manager_); } -void ConstrainedWindowMac::ShowWebContentsModalDialog() { - scoped_ptr<SingleWebContentsDialogManagerCocoa> dialog_manager; - dialog_manager.reset(native_manager_.release()); - GetDialogManager()->ShowDialogWithManager( - [sheet_.get() sheetWindow], std::move(dialog_manager)); -} - void ConstrainedWindowMac::CloseWebContentsModalDialog() { if (manager_) manager_->Close(); @@ -73,13 +49,3 @@ if (delegate_) delegate_->OnConstrainedWindowClosed(this); } - -bool ConstrainedWindowMac::DialogWasShown() { - // If the dialog was shown, |native_manager_| would have been released. - return !native_manager_; -} - -WebContentsModalDialogManager* ConstrainedWindowMac::GetDialogManager() { - DCHECK(web_contents_); - return WebContentsModalDialogManager::FromWebContents(web_contents_); -}
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm index d8ffb1e..8e6ceda 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
@@ -79,15 +79,14 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, ShowInInactiveTab) { // Show dialog in non active tab. NiceMock<ConstrainedWindowDelegateMock> delegate; - std::unique_ptr<ConstrainedWindowMac> dialog( - CreateAndShowWebModalDialogMac(&delegate, tab0_, sheet_)); + ConstrainedWindowMac dialog(&delegate, tab0_, sheet_); EXPECT_EQ(0.0, [sheet_window_ alphaValue]); // Switch to inactive tab. browser()->tab_strip_model()->ActivateTabAt(0, true); EXPECT_EQ(1.0, [sheet_window_ alphaValue]); - dialog->CloseWebContentsModalDialog(); + dialog.CloseWebContentsModalDialog(); } // If a tab has never been shown then the associated tab view for the web @@ -106,8 +105,7 @@ // Show dialog and verify that it's not visible yet. NiceMock<ConstrainedWindowDelegateMock> delegate; - std::unique_ptr<ConstrainedWindowMac> dialog( - CreateAndShowWebModalDialogMac(&delegate, tab2, sheet_)); + ConstrainedWindowMac dialog(&delegate, tab2, sheet_); EXPECT_FALSE([sheet_window_ isVisible]); // Activate the tab and verify that the constrained window is shown. @@ -116,27 +114,25 @@ EXPECT_TRUE([sheet_window_ isVisible]); EXPECT_EQ(1.0, [sheet_window_ alphaValue]); - dialog->CloseWebContentsModalDialog(); + dialog.CloseWebContentsModalDialog(); } // Test that adding a sheet disables tab dragging. IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabDragging) { NiceMock<ConstrainedWindowDelegateMock> delegate; - std::unique_ptr<ConstrainedWindowMac> dialog( - CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_)); + ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); // Verify that the dialog disables dragging. EXPECT_TRUE([controller_ isTabDraggable:tab_view0_]); EXPECT_FALSE([controller_ isTabDraggable:tab_view1_]); - dialog->CloseWebContentsModalDialog(); + dialog.CloseWebContentsModalDialog(); } // Test that closing a browser window with a sheet works. IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, BrowserWindowClose) { NiceMock<ConstrainedWindowDelegateMock> delegate; - std::unique_ptr<ConstrainedWindowMac> dialog( - CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_)); + ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); EXPECT_EQ(1.0, [sheet_window_ alphaValue]); // Close the browser window. @@ -150,8 +146,7 @@ // Test that closing a tab with a sheet works. IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabClose) { NiceMock<ConstrainedWindowDelegateMock> delegate; - std::unique_ptr<ConstrainedWindowMac> dialog( - CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_)); + ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); EXPECT_EQ(1.0, [sheet_window_ alphaValue]); // Close the tab. @@ -165,8 +160,7 @@ // Test that the sheet is still visible after entering and exiting fullscreen. IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, BrowserWindowFullscreen) { NiceMock<ConstrainedWindowDelegateMock> delegate; - std::unique_ptr<ConstrainedWindowMac> dialog( - CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_)); + ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); EXPECT_EQ(1.0, [sheet_window_ alphaValue]); // Toggle fullscreen twice: one for entering and one for exiting. @@ -186,5 +180,5 @@ EXPECT_EQ(1.0, [sheet_window_ alphaValue]); } - dialog->CloseWebContentsModalDialog(); + dialog.CloseWebContentsModalDialog(); }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h index cf24f7d..4549556 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h
@@ -24,8 +24,6 @@ - (void)updateSheetPosition; -- (void)resizeWithNewSize:(NSSize)size; - @property(readonly, nonatomic) NSWindow* sheetWindow; @end
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm index 6566d21..05038cf 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
@@ -59,10 +59,6 @@ - (void)updateSheetPosition { } -- (void)resizeWithNewSize:(NSSize)size { - // NOOP -} - - (NSWindow*)sheetWindow { return [alert_ window]; }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm index 6e7d3f19..3c71f00 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm
@@ -27,14 +27,4 @@ [super updateSheetPosition]; } -- (void)resizeWithNewSize:(NSSize)size { - [customWindow_ setContentSize:size]; - - // self's updateSheetPosition() sets |customWindow_|'s contentSize to a - // fixed dialog size. Here, we want to resize to |size| instead. Use - // super rather than self to bypass the setContentSize() call for the fixed - // size. - [super updateSheetPosition]; -} - @end
diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h index 55b55c9..e895491e 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h
@@ -47,7 +47,7 @@ content::NotificationRegistrar registrar_; - std::unique_ptr<ConstrainedWindowMac> window_; + scoped_ptr<ConstrainedWindowMac> window_; base::scoped_nsobject<CollectedCookiesWindowController> sheet_controller_;
diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm index 7c85ffe8..679c212 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
@@ -66,7 +66,8 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:[sheet_controller_ window]]); - window_ = CreateAndShowWebModalDialogMac(this, web_contents, sheet); + window_.reset(new ConstrainedWindowMac( + this, web_contents, sheet)); } CollectedCookiesMac::~CollectedCookiesMac() {
diff --git a/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.h b/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.h index 19e5f3c..73e04f7 100644 --- a/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.h +++ b/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.h
@@ -39,7 +39,7 @@ private: scoped_refptr<extensions::DevicePermissionsPrompt::Prompt> prompt_; base::scoped_nsobject<DevicePermissionsViewController> view_controller_; - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; }; #endif // CHROME_BROWSER_UI_COCOA_EXTENSIONS_DEVICE_PERMISSIONS_DIALOG_CONTROLER_H_
diff --git a/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm index 881aff0..6babaf28 100644 --- a/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm
@@ -33,8 +33,8 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]); - constrained_window_ = - CreateAndShowWebModalDialogMac(this, web_contents, sheet); + constrained_window_.reset( + new ConstrainedWindowMac(this, web_contents, sheet)); } DevicePermissionsDialogController::~DevicePermissionsDialogController() {
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h index 455062c6..26143ea 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h
@@ -57,7 +57,7 @@ ExtensionInstallPrompt::DoneCallback done_callback_; base::scoped_nsobject<ExtensionInstallViewController> view_controller_; - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_; DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogController);
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm index 4685a25b..826a3bc 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
@@ -60,8 +60,8 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]); - constrained_window_ = CreateAndShowWebModalDialogMac( - this, show_params->GetParentWebContents(), sheet); + constrained_window_.reset(new ConstrainedWindowMac( + this, show_params->GetParentWebContents(), sheet)); std::string event_name = ExperienceSamplingEvent::kExtensionInstallDialog; event_name.append(
diff --git a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h index 6faeff65..9b3553a 100644 --- a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h
@@ -69,7 +69,7 @@ CGFloat CreateCheckboxSeparator(CGFloat y_pos, NSString* header); MediaGalleriesDialogController* controller_; // weak - std::unique_ptr<ConstrainedWindowMac> window_; + scoped_ptr<ConstrainedWindowMac> window_; // The alert that the dialog is being displayed as. base::scoped_nsobject<ConstrainedWindowAlert> alert_;
diff --git a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm index e3fe7a8..01cf67c0 100644 --- a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm
@@ -102,8 +102,8 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:[alert_ window]]); - window_ = CreateAndShowWebModalDialogMac( - this, controller->WebContents(), sheet); + window_.reset(new ConstrainedWindowMac( + this, controller->WebContents(), sheet)); } }
diff --git a/chrome/browser/ui/cocoa/login_prompt_cocoa.mm b/chrome/browser/ui/cocoa/login_prompt_cocoa.mm index 4d72782..2c24253b 100644 --- a/chrome/browser/ui/cocoa/login_prompt_cocoa.mm +++ b/chrome/browser/ui/cocoa/login_prompt_cocoa.mm
@@ -80,8 +80,8 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:[sheet_controller_ window]]); - constrained_window_ = CreateAndShowWebModalDialogMac( - this, requesting_contents, sheet); + constrained_window_.reset(new ConstrainedWindowMac( + this, requesting_contents, sheet)); NotifyAuthNeeded(); } @@ -126,7 +126,7 @@ // The Cocoa controller of the GUI. base::scoped_nsobject<LoginHandlerSheet> sheet_controller_; - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; DISALLOW_COPY_AND_ASSIGN(LoginHandlerMac); };
diff --git a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h index b4f82d4..d56dfdd 100644 --- a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h +++ b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h
@@ -8,6 +8,7 @@ #import <Cocoa/Cocoa.h> #include "base/mac/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" @@ -41,7 +42,7 @@ private: void PerformClose(); - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; base::scoped_nsobject<OneClickSigninViewController> view_controller_; };
diff --git a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm index a8f9a84..f0156f2 100644 --- a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm +++ b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
@@ -30,15 +30,15 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]); - constrained_window_ = - CreateAndShowWebModalDialogMac(this, web_contents, sheet); + constrained_window_.reset(new ConstrainedWindowMac( + this, web_contents, sheet)); } OneClickSigninDialogController::~OneClickSigninDialogController() { } void OneClickSigninDialogController::OnConstrainedWindowClosed( - ConstrainedWindowMac* window) { + ConstrainedWindowMac* window) { [view_controller_ viewWillClose]; base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); }
diff --git a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.h b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.h index 192f6ce0..6f27470 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.h
@@ -13,6 +13,7 @@ #include "base/compiler_specific.h" #include "base/mac/scoped_nsobject.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" #include "chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_view_controller.h" @@ -59,7 +60,7 @@ base::scoped_nsobject<ProfileSigninConfirmationViewController> controller_; // The constrained window that contains the dialog view. - std::unique_ptr<ConstrainedWindowMac> window_; + scoped_ptr<ConstrainedWindowMac> window_; DISALLOW_COPY_AND_ASSIGN(ProfileSigninConfirmationDialogCocoa); };
diff --git a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm index e600717..a46b4eb 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm
@@ -59,7 +59,7 @@ [[window contentView] addSubview:[controller_ view]]; base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]); - window_ = CreateAndShowWebModalDialogMac(this, web_contents, sheet); + window_.reset(new ConstrainedWindowMac(this, web_contents, sheet)); } ProfileSigninConfirmationDialogCocoa::~ProfileSigninConfirmationDialogCocoa() {
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.h b/chrome/browser/ui/cocoa/profiles/user_manager_mac.h index d8346b8..dd1c1c6c 100644 --- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.h +++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.h
@@ -9,6 +9,7 @@ #include "base/mac/scoped_nsobject.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_window.h"
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm index cdae282..48a02249 100644 --- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm +++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
@@ -167,7 +167,7 @@ std::string emailAddress_; content::WebContents* webContents_; scoped_ptr<ReauthDialogDelegate> webContentsDelegate_; - std::unique_ptr<ConstrainedWindowMac> constrained_window_; + scoped_ptr<ConstrainedWindowMac> constrained_window_; scoped_ptr<content::WebContents> reauthWebContents_; } - (id)initWithProfile:(Profile*)profile @@ -203,9 +203,9 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:[self window]]); - constrained_window_ = - CreateAndShowWebModalDialogMac( - webContentsDelegate_.get(), webContents_, sheet); + constrained_window_.reset( + new ConstrainedWindowMac( + webContentsDelegate_.get(), webContents_, sheet)); // The close button needs to call CloseWebContentsModalDialog() on the // constrained window isntead of just [window close] so grab a reference to
diff --git a/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm index 1cbaec8..6b1d507 100644 --- a/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm +++ b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm
@@ -58,12 +58,8 @@ [[ConstrainedWindowSheetController controllerForSheet:sheet_] closeSheet:sheet_]; client_->set_manager(nullptr); - - bool dialog_was_open = client_->DialogWasShown(); client_->OnDialogClosing(); // |client_| might delete itself here. - - if (dialog_was_open) - delegate_->WillClose(dialog()); // Deletes |this|. + delegate_->WillClose(dialog()); // Deletes |this|. } void SingleWebContentsDialogManagerCocoa::Focus() {
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h index 4e3b307b..f1fe2e3 100644 --- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h +++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h
@@ -35,7 +35,7 @@ // A C++ object to bridge SSLClientAuthObserver notifications to us. scoped_ptr<SSLClientAuthObserverCocoaBridge> observer_; base::scoped_nsobject<SFChooseIdentityPanel> panel_; - std::unique_ptr<ConstrainedWindowMac> constrainedWindow_; + scoped_ptr<ConstrainedWindowMac> constrainedWindow_; base::scoped_nsobject<NSWindow> overlayWindow_; BOOL closePending_; // A copy of the sheet's frame used to restore on show.
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm index 4a06708..8c7d66d 100644 --- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm +++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
@@ -179,8 +179,8 @@ CFRelease(sslPolicy); } - constrainedWindow_ = - CreateAndShowWebModalDialogMac(observer_.get(), webContents, self); + constrainedWindow_.reset( + new ConstrainedWindowMac(observer_.get(), webContents, self)); observer_->StartObserving(); } @@ -260,10 +260,6 @@ // NOOP } -- (void)resizeWithNewSize:(NSSize)size { - // NOOP -} - - (NSWindow*)sheetWindow { return panel_; }
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h index c7e32951..1eed74f 100644 --- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h +++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h
@@ -48,7 +48,7 @@ bool closing_; - std::unique_ptr<ConstrainedWindowMac> window_; + scoped_ptr<ConstrainedWindowMac> window_; scoped_ptr<TabModalConfirmDialogDelegate> delegate_; base::scoped_nsobject<ConstrainedWindowAlert> alert_; base::scoped_nsobject<TabModalConfirmDialogMacBridge> bridge_;
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm index e0e7f547..6935ce1 100644 --- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm +++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
@@ -94,7 +94,7 @@ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:[alert_ window]]); - window_ = CreateAndShowWebModalDialogMac(this, web_contents, sheet); + window_.reset(new ConstrainedWindowMac(this, web_contents, sheet)); delegate_->set_close_delegate(this); }
diff --git a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm index 31f057fa..1eefbd15 100644 --- a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm +++ b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm
@@ -96,10 +96,6 @@ [customWindow_ setFrameOrigin:origin]; } -- (void)resizeWithNewSize:(NSSize)size { - // NOOP -} - - (NSWindow*)sheetWindow { return customWindow_; }
diff --git a/chrome/browser/ui/input_method/input_method_engine.cc b/chrome/browser/ui/input_method/input_method_engine.cc index 6d5a1595..11d44282c 100644 --- a/chrome/browser/ui/input_method/input_method_engine.cc +++ b/chrome/browser/ui/input_method/input_method_engine.cc
@@ -84,6 +84,18 @@ return ime_window->GetFrameId(); } +void InputMethodEngine::ShowImeWindow(int window_id) { + ui::ImeWindow* ime_window = FindWindowById(window_id); + if (ime_window) + ime_window->Show(); +} + +void InputMethodEngine::HideImeWindow(int window_id) { + ui::ImeWindow* ime_window = FindWindowById(window_id); + if (ime_window) + ime_window->Hide(); +} + void InputMethodEngine::CloseImeWindows() { if (follow_cursor_window_) follow_cursor_window_->Close(); @@ -166,4 +178,16 @@ } } +ui::ImeWindow* InputMethodEngine::FindWindowById(int window_id) const { + if (follow_cursor_window_ && + follow_cursor_window_->GetFrameId() == window_id) { + return follow_cursor_window_; + } + for (auto ime_window : normal_windows_) { + if (ime_window->GetFrameId() == window_id) + return ime_window; + } + return nullptr; +} + } // namespace input_method
diff --git a/chrome/browser/ui/input_method/input_method_engine.h b/chrome/browser/ui/input_method/input_method_engine.h index 14e5ac5e..9710ced 100644 --- a/chrome/browser/ui/input_method/input_method_engine.h +++ b/chrome/browser/ui/input_method/input_method_engine.h
@@ -39,7 +39,8 @@ ui::ImeWindow::Mode mode, const gfx::Rect& bounds, std::string* error); - + void ShowImeWindow(int window_id); + void HideImeWindow(int window_id); void CloseImeWindows(); private: @@ -57,6 +58,8 @@ // ui::ImeWindowObserver: void OnWindowDestroyed(ui::ImeWindow* ime_window) override; + ui::ImeWindow* FindWindowById(int window_id) const; + // Holds the IME window instances for properly closing in the destructor. // The follow-cursor window is singleton. // The normal windows cannot exceed the max count.
diff --git a/chrome/browser/ui/views/bar_control_button.cc b/chrome/browser/ui/views/bar_control_button.cc index 9d472bf1..eecd5186 100644 --- a/chrome/browser/ui/views/bar_control_button.cc +++ b/chrome/browser/ui/views/bar_control_button.cc
@@ -23,6 +23,8 @@ ink_drop_delegate_(new views::ButtonInkDropDelegate(this, this)) { set_ink_drop_delegate(ink_drop_delegate_.get()); set_has_ink_drop_action_on_click(true); + SetImageAlignment(views::ImageButton::ALIGN_CENTER, + views::ImageButton::ALIGN_MIDDLE); } BarControlButton::~BarControlButton() {} @@ -33,11 +35,11 @@ id_ = id; get_text_color_callback_ = get_text_color_callback; - SetBorder(views::Border::CreateEmptyBorder( - kButtonExtraTouchSize, kButtonExtraTouchSize, kButtonExtraTouchSize, - kButtonExtraTouchSize)); - SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); + if (!border()) { + SetBorder(views::Border::CreateEmptyBorder( + kButtonExtraTouchSize, kButtonExtraTouchSize, kButtonExtraTouchSize, + kButtonExtraTouchSize)); + } } void BarControlButton::OnThemeChanged() {
diff --git a/chrome/browser/ui/views/download/download_item_view_md.cc b/chrome/browser/ui/views/download/download_item_view_md.cc index 359bf407..ef6837cb 100644 --- a/chrome/browser/ui/views/download/download_item_view_md.cc +++ b/chrome/browser/ui/views/download/download_item_view_md.cc
@@ -57,6 +57,7 @@ #include "ui/gfx/text_elider.h" #include "ui/gfx/text_utils.h" #include "ui/gfx/vector_icons_public.h" +#include "ui/views/animation/ink_drop_delegate.h" #include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/label_button.h" @@ -92,7 +93,7 @@ // Padding before the icon and at end of the item. const int kStartPadding = 12; -const int kEndPadding = 19; +const int kEndPadding = 6; // Horizontal padding between progress indicator and filename/status text. const int kProgressTextPadding = 8; @@ -101,7 +102,10 @@ // download. const int kButtonPadding = 5; -// The space on the left and right side of the dangerous download label. +// The touchable space around the dropdown button's icon. +const int kDropdownBorderWidth = 10; + +// The space on the right side of the dangerous download label. const int kLabelPadding = 8; // Height/width of the warning icon, also in dp. @@ -167,6 +171,9 @@ download()->AddObserver(this); set_context_menu_controller(this); + dropdown_button_->SetBorder( + views::Border::CreateEmptyBorder(gfx::Insets(kDropdownBorderWidth))); + dropdown_button_->set_ink_drop_size(gfx::Size(32, 32)); AddChildView(dropdown_button_); LoadIcon(); @@ -317,53 +324,55 @@ UpdateColorsFromTheme(); if (IsShowingWarningDialog()) { - int x = kStartPadding + kWarningIconSize + kStartPadding; - int y = (height() - dangerous_download_label_->height()) / 2; - dangerous_download_label_->SetBounds(x, y, - dangerous_download_label_->width(), - dangerous_download_label_->height()); + gfx::Point child_origin( + kStartPadding + kWarningIconSize + kStartPadding, + (height() - dangerous_download_label_->height()) / 2); + dangerous_download_label_->SetPosition(child_origin); + + child_origin.Offset(dangerous_download_label_->width() + kLabelPadding, 0); gfx::Size button_size = GetButtonSize(); - x += dangerous_download_label_->width() + kLabelPadding; - y = (height() - button_size.height()) / 2; + child_origin.set_y((height() - button_size.height()) / 2); if (save_button_) { - save_button_->SetBounds(x, y, button_size.width(), button_size.height()); - x += button_size.width() + kButtonPadding; + save_button_->SetBoundsRect(gfx::Rect(child_origin, button_size)); + child_origin.Offset(button_size.width() + kButtonPadding, 0); } - discard_button_->SetBounds(x, y, button_size.width(), button_size.height()); + discard_button_->SetBoundsRect(gfx::Rect(child_origin, button_size)); + DCHECK_EQ(GetPreferredSize().width(), + discard_button_->bounds().right() + kEndPadding); } else { dropdown_button_->SizeToPreferredSize(); dropdown_button_->SetPosition( - gfx::Point(width() - dropdown_button_->width(), + gfx::Point(width() - dropdown_button_->width() - kEndPadding, (height() - dropdown_button_->height()) / 2)); } } gfx::Size DownloadItemViewMd::GetPreferredSize() const { - int width, height; - - // First, we set the height to the height of two rows or text plus margins. - height = std::max(kDefaultHeight, - 2 * kMinimumVerticalPadding + font_list_.GetBaseline() + - kVerticalTextPadding + status_font_list_.GetHeight()); + int width = 0; + // We set the height to the height of two rows or text plus margins. + int child_height = font_list_.GetBaseline() + kVerticalTextPadding + + status_font_list_.GetHeight(); if (IsShowingWarningDialog()) { - width = kStartPadding + kWarningIconSize + kLabelPadding + + // Width. + width = kStartPadding + kWarningIconSize + kStartPadding + dangerous_download_label_->width() + kLabelPadding; gfx::Size button_size = GetButtonSize(); - // Make sure the button fits. - height = std::max<int>(height, - 2 * kMinimumVerticalPadding + button_size.height()); - // Then we make sure the warning icon fits. - height = std::max<int>( - height, 2 * kMinimumVerticalPadding + kWarningIconSize); if (save_button_) width += button_size.width() + kButtonPadding; width += button_size.width() + kEndPadding; + + // Height: make sure the button fits and the warning icon fits. + child_height = + std::max({child_height, button_size.height(), kWarningIconSize}); } else { width = kStartPadding + DownloadShelf::kProgressIndicatorSize + - kProgressTextPadding + kTextWidth + kEndPadding; + kProgressTextPadding + kTextWidth + + dropdown_button_->GetPreferredSize().width() + kEndPadding; } - return gfx::Size(width, height); + + return gfx::Size(width, std::max(kDefaultHeight, + 2 * kMinimumVerticalPadding + child_height)); } // Handle a mouse click and open the context menu if the mouse is @@ -815,6 +824,9 @@ new_state == PUSHED ? gfx::VectorIconId::FIND_NEXT : gfx::VectorIconId::FIND_PREV, base::Bind(&DownloadItemViewMd::GetTextColor, base::Unretained(this))); + dropdown_button_->ink_drop_delegate()->OnAction( + new_state == PUSHED ? views::InkDropState::ACTIVATED + : views::InkDropState::DEACTIVATED); dropdown_button_->OnThemeChanged(); dropdown_state_ = new_state; SchedulePaint(); @@ -1010,7 +1022,7 @@ prev_text = current_text; } - dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); + dangerous_download_label_->SetSize(size); dangerous_download_label_sized_ = true; }
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc index e88ab5c..a3b7640c 100644 --- a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc +++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
@@ -259,9 +259,12 @@ views::Widget* bubble_widget = parent_->delegate()->CreateViewsBubble(bubble_view_); bubble_widget->AddObserver(this); - // This is triggered by an input event, the icon will be in an active state - // so the bubble doesn't need an arrow. - if (ui::MaterialDesignController::IsModeMaterial()) + // This is triggered by an input event. If the user clicks the icon while + // it's not animating, the icon will be placed in an active state, so the + // bubble doesn't need an arrow. If the user clicks during an animation, + // the animation simply pauses and no other visible state change occurs, so + // show the arrow in this case. + if (ui::MaterialDesignController::IsModeMaterial() && !pause_animation_) bubble_view_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT); bubble_widget->Show(); }
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc index db4c547..fd60a4b 100644 --- a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc +++ b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc
@@ -113,8 +113,3 @@ NOTREACHED(); return gfx::Size(); } - -void ConstrainedWebDialogDelegateBase::ResizeToGivenSize( - const gfx::Size size) { - NOTREACHED(); -}
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h index a43814a..fee4931 100644 --- a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h +++ b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h
@@ -24,8 +24,6 @@ : public ConstrainedWebDialogDelegate, public ui::WebDialogWebContentsDelegate { public: - // |browser_context| and |delegate| must outlive |this| instance, whereas - // |this| will take ownership of |tab_delegate|. ConstrainedWebDialogDelegateBase(content::BrowserContext* browser_context, ui::WebDialogDelegate* delegate, WebDialogWebContentsDelegate* tab_delegate); @@ -49,9 +47,6 @@ content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - // Resize the dialog to the given size. - virtual void ResizeToGivenSize(const gfx::Size size); - private: scoped_ptr<ui::WebDialogDelegate> web_dialog_delegate_;
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui.h b/chrome/browser/ui/webui/constrained_web_dialog_ui.h index 39cc74b..4f7159e5 100644 --- a/chrome/browser/ui/webui/constrained_web_dialog_ui.h +++ b/chrome/browser/ui/webui/constrained_web_dialog_ui.h
@@ -51,8 +51,6 @@ // Returns the maximum size for the dialog. virtual gfx::Size GetMaximumSize() const = 0; - // Returns the preferred size for the dialog, or an empty size if - // the dialog has been closed. virtual gfx::Size GetPreferredSize() const = 0; protected:
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc index f7d39e55..fbdf04f8 100644 --- a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc +++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
@@ -26,6 +26,7 @@ namespace { +#if !defined(OS_MACOSX) static const char kTestDataURL[] = "data:text/html,<!doctype html>" "<body></body>" "<style>" @@ -41,6 +42,7 @@ return base::StringPrintf("window.document.body.style.width = %d + 'px';" "window.document.body.style.height = %d + 'px';", dimension, dimension); } +#endif class ConstrainedWebDialogBrowserTestObserver : public content::WebContentsObserver { @@ -145,6 +147,7 @@ EXPECT_TRUE(observer.contents_destroyed()); } +#if !defined(OS_MACOSX) // Tests that dialog autoresizes based on web contents when autoresizing // is enabled. IN_PROC_BROWSER_TEST_F(ConstrainedWebDialogBrowserTest, @@ -170,12 +173,6 @@ gfx::Size min_size = gfx::Size(100, 100); gfx::Size max_size = gfx::Size(200, 200); gfx::Size initial_dialog_size; -// OSX windows are initially created with non-empty dimensions. The -// autoresizeable dialog's window dimensions are determined after initial -// creation. -#if defined(OS_MACOSX) - initial_dialog_size = gfx::Size(1, 1); -#endif delegate->GetDialogSize(&initial_dialog_size); ConstrainedWebDialogDelegate* dialog_delegate = @@ -189,6 +186,7 @@ EXPECT_EQ(max_size, dialog_delegate->GetMaximumSize()); // Check for initial sizing. Dialog was created as a 400x400 dialog. + EXPECT_EQ(gfx::Size(), web_contents->GetPreferredSize()); ASSERT_EQ(initial_dialog_size, dialog_delegate->GetPreferredSize()); observer.Wait(); @@ -252,6 +250,7 @@ delegate->GetDialogSize(&initial_dialog_size); // Check for initial sizing. Dialog was created as a 400x400 dialog. + EXPECT_EQ(gfx::Size(), web_contents->GetPreferredSize()); ASSERT_EQ(initial_dialog_size, dialog_delegate->GetPreferredSize()); // Resize <body> to dimension smaller than dialog. @@ -270,3 +269,4 @@ initial_dialog_size, dialog_delegate))); } +#endif // !OS_MACOSX
diff --git a/chrome/browser/ui/webui/md_history_ui.cc b/chrome/browser/ui/webui/md_history_ui.cc index e0f82545..d52d1e6 100644 --- a/chrome/browser/ui/webui/md_history_ui.cc +++ b/chrome/browser/ui/webui/md_history_ui.cc
@@ -52,6 +52,8 @@ bool allow_deleting_history = prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory); source->AddBoolean("allowDeletingHistory", allow_deleting_history); + source->AddResourcePath("constants.html", IDR_MD_HISTORY_CONSTANTS_HTML); + source->AddResourcePath("constants.js", IDR_MD_HISTORY_CONSTANTS_JS); source->AddResourcePath("history_item.html", IDR_MD_HISTORY_HISTORY_ITEM_HTML); source->AddResourcePath("history_item.js", IDR_MD_HISTORY_HISTORY_ITEM_JS);
diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc index ebf57fde..bf57e82 100644 --- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc +++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
@@ -41,8 +41,12 @@ using ui::WebDialogDelegate; namespace { +#if defined(OS_MACOSX) +const int kFixedHeight = 350; +#else const int kMaxHeight = 2000; const int kMinHeight = 80; +#endif const int kWidth = 340; } @@ -110,10 +114,15 @@ void MediaRouterDialogDelegate::GetDialogSize(gfx::Size* size) const { DCHECK(size); + // TODO(apacible): Remove after autoresizing is implemented for OSX. +#if defined(OS_MACOSX) + *size = gfx::Size(kWidth, kFixedHeight); +#else // GetDialogSize() is called when the browser window resizes. We may want to // update the maximum height of the dialog and scale the WebUI to the new // height. |size| is not set because the dialog is auto-resizeable. controller_->UpdateMaxDialogSize(); +#endif } } // namespace @@ -234,21 +243,29 @@ Profile::FromBrowserContext(initiator()->GetBrowserContext()); DCHECK(profile); - // |web_dialog_delegate|'s owner is |constrained_delegate|. - // |constrained_delegate| is owned by the parent |views::View|. WebDialogDelegate* web_dialog_delegate = new MediaRouterDialogDelegate(action_, weak_ptr_factory_.GetWeakPtr()); + // |web_dialog_delegate|'s owner is |constrained_delegate|. + // |constrained_delegate| is owned by the parent |views::View|. + // TODO(apacible): Remove after autoresizing is implemented for OSX. +#if defined(OS_MACOSX) + ConstrainedWebDialogDelegate* constrained_delegate = + ShowConstrainedWebDialog(profile, web_dialog_delegate, initiator()); +#else + // TODO(apacible): Adjust min and max sizes based on new WebUI design. + gfx::Size min_size = gfx::Size(kWidth, kMinHeight); + gfx::Size max_size = gfx::Size(kWidth, kMaxHeight); // |ShowConstrainedWebDialogWithAutoResize()| will end up creating // ConstrainedWebDialogDelegateViewViews containing a WebContents containing // the MediaRouterUI, using the provided |web_dialog_delegate|. Then, the // view is shown as a modal dialog constrained to the |initiator| WebContents. - // The dialog will resize between the given minimum and maximum size bounds - // based on the currently rendered contents. + // The dialog will resize between the |min_size| and |max_size| bounds based + // on the currently rendered contents. ConstrainedWebDialogDelegate* constrained_delegate = ShowConstrainedWebDialogWithAutoResize( - profile, web_dialog_delegate, initiator(), - gfx::Size(kWidth, kMinHeight), gfx::Size(kWidth, kMaxHeight)); + profile, web_dialog_delegate, initiator(), min_size, max_size); +#endif WebContents* media_router_dialog = constrained_delegate->GetWebContents(); TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("media_router", "UI", initiator(),
diff --git a/chrome/browser/ui/webui/settings/certificates_handler.cc b/chrome/browser/ui/webui/settings/certificates_handler.cc new file mode 100644 index 0000000..66883412c --- /dev/null +++ b/chrome/browser/ui/webui/settings/certificates_handler.cc
@@ -0,0 +1,1146 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/certificates_handler.h" + +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <algorithm> +#include <map> +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/files/file_util.h" // for FileAccessProvider +#include "base/i18n/string_compare.h" +#include "base/id_map.h" +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "base/posix/safe_strerror.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/certificate_viewer.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/certificate_dialogs.h" +#include "chrome/browser/ui/chrome_select_file_policy.h" +#include "chrome/browser/ui/crypto_module_password_dialog_nss.h" +#include "chrome/browser/ui/webui/certificate_viewer_webui.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" +#include "grit/components_strings.h" +#include "net/base/crypto_module.h" +#include "net/base/net_errors.h" +#include "net/cert/x509_certificate.h" +#include "net/der/input.h" +#include "net/der/parser.h" +#include "ui/base/l10n/l10n_util.h" + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/policy/user_network_configuration_updater.h" +#include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h" +#endif + +using base::UTF8ToUTF16; +using content::BrowserThread; + +namespace { + +// Field names for communicating certificate info to JS. +static const char kEmailField[] = "email"; +static const char kExtractableField[] = "extractable"; +static const char kKeyField[] = "id"; +static const char kNameField[] = "name"; +static const char kObjSignField[] = "objSign"; +static const char kPolicyField[] = "policy"; +static const char kReadonlyField[] = "readonly"; +static const char kSslField[] = "ssl"; +static const char kSubnodesField[] = "subnodes"; +static const char kUntrustedField[] = "untrusted"; + +// Field names for communicating erros to JS. +static const char kCertificateErrors[] = "certificateErrors"; +static const char kErrorDescription[] = "description"; +static const char kErrorField[] = "error"; +static const char kErrorTitle[] = "title"; + +// Enumeration of different callers of SelectFile. (Start counting at 1 so +// if SelectFile is accidentally called with params=NULL it won't match any.) +enum { + EXPORT_PERSONAL_FILE_SELECTED = 1, + IMPORT_PERSONAL_FILE_SELECTED, + IMPORT_SERVER_FILE_SELECTED, + IMPORT_CA_FILE_SELECTED, +}; + +std::string OrgNameToId(const std::string& org) { + return "org-" + org; +} + +struct DictionaryIdComparator { + explicit DictionaryIdComparator(icu::Collator* collator) + : collator_(collator) { + } + + bool operator()(const base::Value* a, + const base::Value* b) const { + DCHECK(a->GetType() == base::Value::TYPE_DICTIONARY); + DCHECK(b->GetType() == base::Value::TYPE_DICTIONARY); + const base::DictionaryValue* a_dict = + reinterpret_cast<const base::DictionaryValue*>(a); + const base::DictionaryValue* b_dict = + reinterpret_cast<const base::DictionaryValue*>(b); + base::string16 a_str; + base::string16 b_str; + a_dict->GetString(kNameField, &a_str); + b_dict->GetString(kNameField, &b_str); + if (collator_ == NULL) + return a_str < b_str; + return base::i18n::CompareString16WithCollator(*collator_, a_str, b_str) == + UCOL_LESS; + } + + icu::Collator* collator_; +}; + +std::string NetErrorToString(int net_error) { + switch (net_error) { + // TODO(mattm): handle more cases. + case net::ERR_IMPORT_CA_CERT_NOT_CA: + return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_ERROR_NOT_CA); + case net::ERR_IMPORT_CERT_ALREADY_EXISTS: + return l10n_util::GetStringUTF8( + IDS_CERT_MANAGER_ERROR_CERT_ALREADY_EXISTS); + default: + return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR); + } +} + +// Struct to bind the Equals member function to an object for use in find_if. +struct CertEquals { + explicit CertEquals(const net::X509Certificate* cert) : cert_(cert) {} + bool operator()(const scoped_refptr<net::X509Certificate> cert) const { + return cert_->Equals(cert.get()); + } + const net::X509Certificate* cert_; +}; + +// Determine whether a certificate was stored with web trust by a policy. +bool IsPolicyInstalledWithWebTrust( + const net::CertificateList& web_trust_certs, + net::X509Certificate* cert) { + return std::find_if(web_trust_certs.begin(), web_trust_certs.end(), + CertEquals(cert)) != web_trust_certs.end(); +} + +#if defined(OS_CHROMEOS) +void ShowCertificateViewerModalDialog(content::WebContents* web_contents, + gfx::NativeWindow parent, + net::X509Certificate* cert) { + CertificateViewerModalDialog* dialog = new CertificateViewerModalDialog(cert); + dialog->Show(web_contents, parent); +} +#endif + +// Determine if |data| could be a PFX Protocol Data Unit. +// This only does the minimum parsing necessary to distinguish a PFX file from a +// DER encoded Certificate. +// +// From RFC 7292 section 4: +// PFX ::= SEQUENCE { +// version INTEGER {v3(3)}(v3,...), +// authSafe ContentInfo, +// macData MacData OPTIONAL +// } +// From RFC 5280 section 4.1: +// Certificate ::= SEQUENCE { +// tbsCertificate TBSCertificate, +// signatureAlgorithm AlgorithmIdentifier, +// signatureValue BIT STRING } +// +// Certificate must be DER encoded, while PFX may be BER encoded. +// Therefore PFX can be distingushed by checking if the file starts with an +// indefinite SEQUENCE, or a definite SEQUENCE { INTEGER, ... }. +bool CouldBePFX(const std::string& data) { + if (data.size() < 4) + return false; + + // Indefinite length SEQUENCE. + if (data[0] == 0x30 && static_cast<uint8_t>(data[1]) == 0x80) + return true; + + // If the SEQUENCE is definite length, it can be parsed through the version + // tag using DER parser, since INTEGER must be definite length, even in BER. + net::der::Parser parser((net::der::Input(&data))); + net::der::Parser sequence_parser; + if (!parser.ReadSequence(&sequence_parser)) + return false; + if (!sequence_parser.SkipTag(net::der::kInteger)) + return false; + return true; +} + +} // namespace + +namespace settings { + +/////////////////////////////////////////////////////////////////////////////// +// CertIdMap + +class CertIdMap { + public: + CertIdMap() {} + ~CertIdMap() {} + + std::string CertToId(net::X509Certificate* cert); + net::X509Certificate* IdToCert(const std::string& id); + net::X509Certificate* CallbackArgsToCert(const base::ListValue* args); + + private: + typedef std::map<net::X509Certificate*, int32_t> CertMap; + + // Creates an ID for cert and looks up the cert for an ID. + IDMap<net::X509Certificate>id_map_; + + // Finds the ID for a cert. + CertMap cert_map_; + + DISALLOW_COPY_AND_ASSIGN(CertIdMap); +}; + +std::string CertIdMap::CertToId(net::X509Certificate* cert) { + CertMap::const_iterator iter = cert_map_.find(cert); + if (iter != cert_map_.end()) + return base::IntToString(iter->second); + + int32_t new_id = id_map_.Add(cert); + cert_map_[cert] = new_id; + return base::IntToString(new_id); +} + +net::X509Certificate* CertIdMap::IdToCert(const std::string& id) { + int32_t cert_id = 0; + if (!base::StringToInt(id, &cert_id)) + return NULL; + + return id_map_.Lookup(cert_id); +} + +net::X509Certificate* CertIdMap::CallbackArgsToCert( + const base::ListValue* args) { + std::string node_id; + if (!args->GetString(0, &node_id)) + return NULL; + + net::X509Certificate* cert = IdToCert(node_id); + if (!cert) { + NOTREACHED(); + return NULL; + } + + return cert; +} + +/////////////////////////////////////////////////////////////////////////////// +// FileAccessProvider + +// TODO(mattm): Move to some shared location? +class FileAccessProvider + : public base::RefCountedThreadSafe<FileAccessProvider> { + public: + // The first parameter is 0 on success or errno on failure. The second + // parameter is read result. + typedef base::Callback<void(const int*, const std::string*)> ReadCallback; + + // The first parameter is 0 on success or errno on failure. The second + // parameter is the number of bytes written on success. + typedef base::Callback<void(const int*, const int*)> WriteCallback; + + base::CancelableTaskTracker::TaskId StartRead( + const base::FilePath& path, + const ReadCallback& callback, + base::CancelableTaskTracker* tracker); + base::CancelableTaskTracker::TaskId StartWrite( + const base::FilePath& path, + const std::string& data, + const WriteCallback& callback, + base::CancelableTaskTracker* tracker); + + private: + friend class base::RefCountedThreadSafe<FileAccessProvider>; + virtual ~FileAccessProvider() {} + + // Reads file at |path|. |saved_errno| is 0 on success or errno on failure. + // When success, |data| has file content. + void DoRead(const base::FilePath& path, + int* saved_errno, + std::string* data); + // Writes data to file at |path|. |saved_errno| is 0 on success or errno on + // failure. When success, |bytes_written| has number of bytes written. + void DoWrite(const base::FilePath& path, + const std::string& data, + int* saved_errno, + int* bytes_written); +}; + +base::CancelableTaskTracker::TaskId FileAccessProvider::StartRead( + const base::FilePath& path, + const ReadCallback& callback, + base::CancelableTaskTracker* tracker) { + // Owned by reply callback posted below. + int* saved_errno = new int(0); + std::string* data = new std::string(); + + // Post task to file thread to read file. + return tracker->PostTaskAndReply( + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(), + FROM_HERE, + base::Bind(&FileAccessProvider::DoRead, this, path, saved_errno, data), + base::Bind(callback, base::Owned(saved_errno), base::Owned(data))); +} + +base::CancelableTaskTracker::TaskId FileAccessProvider::StartWrite( + const base::FilePath& path, + const std::string& data, + const WriteCallback& callback, + base::CancelableTaskTracker* tracker) { + // Owned by reply callback posted below. + int* saved_errno = new int(0); + int* bytes_written = new int(0); + + // Post task to file thread to write file. + return tracker->PostTaskAndReply( + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(), + FROM_HERE, + base::Bind(&FileAccessProvider::DoWrite, + this, + path, + data, + saved_errno, + bytes_written), + base::Bind( + callback, base::Owned(saved_errno), base::Owned(bytes_written))); +} + +void FileAccessProvider::DoRead(const base::FilePath& path, + int* saved_errno, + std::string* data) { + bool success = base::ReadFileToString(path, data); + *saved_errno = success ? 0 : errno; +} + +void FileAccessProvider::DoWrite(const base::FilePath& path, + const std::string& data, + int* saved_errno, + int* bytes_written) { + *bytes_written = base::WriteFile(path, data.data(), data.size()); + *saved_errno = *bytes_written >= 0 ? 0 : errno; +} + +/////////////////////////////////////////////////////////////////////////////// +// CertificatesHandler + +CertificatesHandler::CertificatesHandler( + bool show_certs_in_modal_dialog) + : show_certs_in_modal_dialog_(show_certs_in_modal_dialog), + requested_certificate_manager_model_(false), + use_hardware_backed_(false), + file_access_provider_(new FileAccessProvider()), + cert_id_map_(new CertIdMap), + weak_ptr_factory_(this) {} + +CertificatesHandler::~CertificatesHandler() { +} + +void CertificatesHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "viewCertificate", + base::Bind(&CertificatesHandler::HandleViewCertificate, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "getCaCertificateTrust", + base::Bind(&CertificatesHandler::HandleGetCATrust, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "editCaCertificateTrust", + base::Bind(&CertificatesHandler::HandleEditCATrust, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "cancelImportExportCertificate", + base::Bind(&CertificatesHandler::HandleCancelImportExportProcess, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "exportPersonalCertificate", + base::Bind(&CertificatesHandler::HandleExportPersonal, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "exportPersonalCertificatePasswordSelected", + base::Bind(&CertificatesHandler::HandleExportPersonalPasswordSelected, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "importPersonalCertificate", + base::Bind(&CertificatesHandler::HandleImportPersonal, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "importPersonalCertificatePasswordSelected", + base::Bind(&CertificatesHandler::HandleImportPersonalPasswordSelected, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "importCaCertificate", + base::Bind(&CertificatesHandler::HandleImportCA, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "importCaCertificateTrustSelected", + base::Bind(&CertificatesHandler::HandleImportCATrustSelected, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "importServerCertificate", + base::Bind(&CertificatesHandler::HandleImportServer, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "exportCertificate", + base::Bind(&CertificatesHandler::HandleExportCertificate, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "deleteCertificate", + base::Bind(&CertificatesHandler::HandleDeleteCertificate, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "refreshCertificates", + base::Bind(&CertificatesHandler::HandleRefreshCertificates, + base::Unretained(this))); +} + +void CertificatesHandler::CertificatesRefreshed() { + net::CertificateList web_trusted_certs; +#if defined(OS_CHROMEOS) + policy::UserNetworkConfigurationUpdater* service = + policy::UserNetworkConfigurationUpdaterFactory::GetForProfile( + Profile::FromWebUI(web_ui())); + if (service) + service->GetWebTrustedCertificates(&web_trusted_certs); +#endif + PopulateTree("personalCerts", net::USER_CERT, web_trusted_certs); + PopulateTree("serverCerts", net::SERVER_CERT, web_trusted_certs); + PopulateTree("caCerts", net::CA_CERT, web_trusted_certs); + PopulateTree("otherCerts", net::OTHER_CERT, web_trusted_certs); +} + +void CertificatesHandler::FileSelected(const base::FilePath& path, + int index, + void* params) { + switch (reinterpret_cast<intptr_t>(params)) { + case EXPORT_PERSONAL_FILE_SELECTED: + ExportPersonalFileSelected(path); + break; + case IMPORT_PERSONAL_FILE_SELECTED: + ImportPersonalFileSelected(path); + break; + case IMPORT_SERVER_FILE_SELECTED: + ImportServerFileSelected(path); + break; + case IMPORT_CA_FILE_SELECTED: + ImportCAFileSelected(path); + break; + default: + NOTREACHED(); + } +} + +void CertificatesHandler::FileSelectionCanceled(void* params) { + switch (reinterpret_cast<intptr_t>(params)) { + case EXPORT_PERSONAL_FILE_SELECTED: + case IMPORT_PERSONAL_FILE_SELECTED: + case IMPORT_SERVER_FILE_SELECTED: + case IMPORT_CA_FILE_SELECTED: + ImportExportCleanup(); + RejectCallback(*base::Value::CreateNullValue()); + break; + default: + NOTREACHED(); + } +} + +void CertificatesHandler::HandleViewCertificate(const base::ListValue* args) { + net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); + if (!cert) + return; +#if defined(OS_CHROMEOS) + if (show_certs_in_modal_dialog_) { + ShowCertificateViewerModalDialog(web_ui()->GetWebContents(), + GetParentWindow(), + cert); + return; + } +#endif + ShowCertificateViewer(web_ui()->GetWebContents(), GetParentWindow(), cert); +} + +void CertificatesHandler::AssignWebUICallbackId(const base::ListValue* args) { + CHECK_LE(1U, args->GetSize()); + CHECK(webui_callback_id_.empty()); + CHECK(args->GetString(0, &webui_callback_id_)); +} + +void CertificatesHandler::HandleGetCATrust(const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + AssignWebUICallbackId(args); + std::string node_id; + CHECK(args->GetString(1, &node_id)); + + net::X509Certificate* cert = cert_id_map_->IdToCert(node_id); + CHECK(cert); + + net::NSSCertDatabase::TrustBits trust_bits = + certificate_manager_model_->cert_db()->GetCertTrust(cert, net::CA_CERT); + scoped_ptr<base::DictionaryValue> ca_trust_info(new base::DictionaryValue); + ca_trust_info->SetBoolean( + kSslField, + static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_SSL)); + ca_trust_info->SetBoolean( + kEmailField, + static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_EMAIL)); + ca_trust_info->SetBoolean( + kObjSignField, + static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN)); + ResolveCallback(*ca_trust_info); +} + +void CertificatesHandler::HandleEditCATrust(const base::ListValue* args) { + CHECK_EQ(5U, args->GetSize()); + AssignWebUICallbackId(args); + std::string node_id; + CHECK(args->GetString(1, &node_id)); + + net::X509Certificate* cert = cert_id_map_->IdToCert(node_id); + CHECK(cert); + + bool trust_ssl = false; + bool trust_email = false; + bool trust_obj_sign = false; + CHECK(args->GetBoolean(2, &trust_ssl)); + CHECK(args->GetBoolean(3, &trust_email)); + CHECK(args->GetBoolean(4, &trust_obj_sign)); + + bool result = certificate_manager_model_->SetCertTrust( + cert, + net::CA_CERT, + trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + + trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + + trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN); + if (!result) { + // TODO(mattm): better error messages? + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SET_TRUST_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); + } else { + ResolveCallback(*base::Value::CreateNullValue()); + } +} + +void CertificatesHandler::HandleExportPersonal(const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + AssignWebUICallbackId(args); + std::string node_id; + CHECK(args->GetString(1, &node_id)); + + net::X509Certificate* cert = cert_id_map_->IdToCert(node_id); + CHECK(cert); + selected_cert_list_.push_back(cert); + + ui::SelectFileDialog::FileTypeInfo file_type_info; + file_type_info.extensions.resize(1); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12")); + file_type_info.extension_description_overrides.push_back( + l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES)); + file_type_info.include_all_files = true; + select_file_dialog_ = ui::SelectFileDialog::Create( + this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); + select_file_dialog_->SelectFile( + ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(), + base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"), + GetParentWindow(), + reinterpret_cast<void*>(EXPORT_PERSONAL_FILE_SELECTED)); +} + +void CertificatesHandler::ExportPersonalFileSelected( + const base::FilePath& path) { + file_path_ = path; + ResolveCallback(*base::Value::CreateNullValue()); +} + +void CertificatesHandler::HandleExportPersonalPasswordSelected( + const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + AssignWebUICallbackId(args); + CHECK(args->GetString(1, &password_)); + + // Currently, we don't support exporting more than one at a time. If we do, + // this would need to either change this to use UnlockSlotsIfNecessary or + // change UnlockCertSlotIfNecessary to take a CertificateList. + DCHECK_EQ(selected_cert_list_.size(), 1U); + + // TODO(mattm): do something smarter about non-extractable keys + chrome::UnlockCertSlotIfNecessary( + selected_cert_list_[0].get(), + chrome::kCryptoModulePasswordCertExport, + net::HostPortPair(), // unused. + GetParentWindow(), + base::Bind(&CertificatesHandler::ExportPersonalSlotsUnlocked, + base::Unretained(this))); +} + +void CertificatesHandler::ExportPersonalSlotsUnlocked() { + std::string output; + int num_exported = certificate_manager_model_->cert_db()->ExportToPKCS12( + selected_cert_list_, + password_, + &output); + if (!num_exported) { + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); + ImportExportCleanup(); + return; + } + file_access_provider_->StartWrite( + file_path_, + output, + base::Bind(&CertificatesHandler::ExportPersonalFileWritten, + base::Unretained(this)), + &tracker_); +} + +void CertificatesHandler::ExportPersonalFileWritten( + const int* write_errno, const int* bytes_written) { + ImportExportCleanup(); + if (*write_errno) { + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE), + l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_WRITE_ERROR_FORMAT, + UTF8ToUTF16( + base::safe_strerror(*write_errno)))); + } else { + ResolveCallback(*base::Value::CreateNullValue()); + } +} + +void CertificatesHandler::HandleImportPersonal(const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + AssignWebUICallbackId(args); + CHECK(args->GetBoolean(1, &use_hardware_backed_)); + + ui::SelectFileDialog::FileTypeInfo file_type_info; + file_type_info.extensions.resize(1); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12")); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pfx")); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt")); + file_type_info.extension_description_overrides.push_back( + l10n_util::GetStringUTF16(IDS_CERT_USAGE_SSL_CLIENT)); + file_type_info.include_all_files = true; + select_file_dialog_ = ui::SelectFileDialog::Create( + this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); + select_file_dialog_->SelectFile( + ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), + base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"), + GetParentWindow(), + reinterpret_cast<void*>(IMPORT_PERSONAL_FILE_SELECTED)); +} + +void CertificatesHandler::ImportPersonalFileSelected( + const base::FilePath& path) { + file_access_provider_->StartRead( + path, base::Bind(&CertificatesHandler::ImportPersonalFileRead, + base::Unretained(this)), + &tracker_); +} + +void CertificatesHandler::ImportPersonalFileRead( + const int* read_errno, const std::string* data) { + if (*read_errno) { + ImportExportCleanup(); + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ERROR_TITLE), + l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, + UTF8ToUTF16( + base::safe_strerror(*read_errno)))); + return; + } + + file_data_ = *data; + + if (CouldBePFX(file_data_)) { + ResolveCallback(base::FundamentalValue(true)); + return; + } + + // Non .p12/.pfx files are assumed to be single/chain certificates without + // private key data. The default extension according to spec is '.crt', + // however other extensions are also used in some places to represent these + // certificates. + int result = certificate_manager_model_->ImportUserCert(file_data_); + ImportExportCleanup(); + int string_id; + switch (result) { + case net::OK: + ResolveCallback(base::FundamentalValue(false)); + return; + case net::ERR_NO_PRIVATE_KEY_FOR_CERT: + string_id = IDS_CERT_MANAGER_IMPORT_MISSING_KEY; + break; + case net::ERR_CERT_INVALID: + string_id = IDS_CERT_MANAGER_IMPORT_INVALID_FILE; + break; + default: + string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR; + break; + } + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(string_id)); +} + +void CertificatesHandler::HandleImportPersonalPasswordSelected( + const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + AssignWebUICallbackId(args); + CHECK(args->GetString(1, &password_)); + + if (use_hardware_backed_) { + module_ = certificate_manager_model_->cert_db()->GetPrivateModule(); + } else { + module_ = certificate_manager_model_->cert_db()->GetPublicModule(); + } + + net::CryptoModuleList modules; + modules.push_back(module_); + chrome::UnlockSlotsIfNecessary( + modules, + chrome::kCryptoModulePasswordCertImport, + net::HostPortPair(), // unused. + GetParentWindow(), + base::Bind(&CertificatesHandler::ImportPersonalSlotUnlocked, + base::Unretained(this))); +} + +void CertificatesHandler::ImportPersonalSlotUnlocked() { + // Determine if the private key should be unextractable after the import. + // We do this by checking the value of |use_hardware_backed_| which is set + // to true if importing into a hardware module. Currently, this only happens + // for Chrome OS when the "Import and Bind" option is chosen. + bool is_extractable = !use_hardware_backed_; + int result = certificate_manager_model_->ImportFromPKCS12( + module_.get(), file_data_, password_, is_extractable); + ImportExportCleanup(); + int string_id; + switch (result) { + case net::OK: + ResolveCallback(*base::Value::CreateNullValue()); + return; + case net::ERR_PKCS12_IMPORT_BAD_PASSWORD: + // TODO(mattm): if the error was a bad password, we should reshow the + // password dialog after the user dismisses the error dialog. + string_id = IDS_CERT_MANAGER_BAD_PASSWORD; + break; + case net::ERR_PKCS12_IMPORT_INVALID_MAC: + string_id = IDS_CERT_MANAGER_IMPORT_INVALID_MAC; + break; + case net::ERR_PKCS12_IMPORT_INVALID_FILE: + string_id = IDS_CERT_MANAGER_IMPORT_INVALID_FILE; + break; + case net::ERR_PKCS12_IMPORT_UNSUPPORTED: + string_id = IDS_CERT_MANAGER_IMPORT_UNSUPPORTED; + break; + default: + string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR; + break; + } + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(string_id)); +} + +void CertificatesHandler::HandleCancelImportExportProcess( + const base::ListValue* args) { + ImportExportCleanup(); +} + +void CertificatesHandler::ImportExportCleanup() { + file_path_.clear(); + password_.clear(); + file_data_.clear(); + use_hardware_backed_ = false; + selected_cert_list_.clear(); + module_ = NULL; + tracker_.TryCancelAll(); + + // There may be pending file dialogs, we need to tell them that we've gone + // away so they don't try and call back to us. + if (select_file_dialog_.get()) + select_file_dialog_->ListenerDestroyed(); + select_file_dialog_ = NULL; +} + +void CertificatesHandler::HandleImportServer(const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + AssignWebUICallbackId(args); + + select_file_dialog_ = ui::SelectFileDialog::Create( + this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); + ShowCertSelectFileDialog( + select_file_dialog_.get(), + ui::SelectFileDialog::SELECT_OPEN_FILE, + base::FilePath(), + GetParentWindow(), + reinterpret_cast<void*>(IMPORT_SERVER_FILE_SELECTED)); +} + +void CertificatesHandler::ImportServerFileSelected( + const base::FilePath& path) { + file_access_provider_->StartRead( + path, base::Bind(&CertificatesHandler::ImportServerFileRead, + base::Unretained(this)), + &tracker_); +} + +void CertificatesHandler::ImportServerFileRead(const int* read_errno, + const std::string* data) { + if (*read_errno) { + ImportExportCleanup(); + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, + UTF8ToUTF16( + base::safe_strerror(*read_errno)))); + return; + } + + selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( + data->data(), data->size(), net::X509Certificate::FORMAT_AUTO); + if (selected_cert_list_.empty()) { + ImportExportCleanup(); + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); + return; + } + + net::NSSCertDatabase::ImportCertFailureList not_imported; + // TODO(mattm): Add UI for trust. http://crbug.com/76274 + bool result = certificate_manager_model_->ImportServerCert( + selected_cert_list_, + net::NSSCertDatabase::TRUST_DEFAULT, + ¬_imported); + if (!result) { + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); + } else if (!not_imported.empty()) { + RejectCallbackWithImportError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + not_imported); + } else { + ResolveCallback(*base::Value::CreateNullValue()); + } + ImportExportCleanup(); +} + +void CertificatesHandler::HandleImportCA(const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + AssignWebUICallbackId(args); + + select_file_dialog_ = ui::SelectFileDialog::Create( + this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); + ShowCertSelectFileDialog(select_file_dialog_.get(), + ui::SelectFileDialog::SELECT_OPEN_FILE, + base::FilePath(), + GetParentWindow(), + reinterpret_cast<void*>(IMPORT_CA_FILE_SELECTED)); +} + +void CertificatesHandler::ImportCAFileSelected( + const base::FilePath& path) { + file_access_provider_->StartRead( + path, base::Bind(&CertificatesHandler::ImportCAFileRead, + base::Unretained(this)), + &tracker_); +} + +void CertificatesHandler::ImportCAFileRead(const int* read_errno, + const std::string* data) { + if (*read_errno) { + ImportExportCleanup(); + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), + l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, + UTF8ToUTF16( + base::safe_strerror(*read_errno)))); + return; + } + + selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( + data->data(), data->size(), net::X509Certificate::FORMAT_AUTO); + if (selected_cert_list_.empty()) { + ImportExportCleanup(); + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); + return; + } + + scoped_refptr<net::X509Certificate> root_cert = + certificate_manager_model_->cert_db()->FindRootInList( + selected_cert_list_); + + // TODO(mattm): check here if root_cert is not a CA cert and show error. + + base::StringValue cert_name(root_cert->subject().GetDisplayName()); + ResolveCallback(cert_name); +} + +void CertificatesHandler::HandleImportCATrustSelected( + const base::ListValue* args) { + CHECK_EQ(4U, args->GetSize()); + AssignWebUICallbackId(args); + + bool trust_ssl = false; + bool trust_email = false; + bool trust_obj_sign = false; + CHECK(args->GetBoolean(1, &trust_ssl)); + CHECK(args->GetBoolean(2, &trust_email)); + CHECK(args->GetBoolean(3, &trust_obj_sign)); + + // TODO(mattm): add UI for setting explicit distrust, too. + // http://crbug.com/128411 + net::NSSCertDatabase::ImportCertFailureList not_imported; + bool result = certificate_manager_model_->ImportCACerts( + selected_cert_list_, + trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + + trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + + trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN, + ¬_imported); + if (!result) { + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); + } else if (!not_imported.empty()) { + RejectCallbackWithImportError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), + not_imported); + } else { + ResolveCallback(*base::Value::CreateNullValue()); + } + ImportExportCleanup(); +} + +void CertificatesHandler::HandleExportCertificate(const base::ListValue* args) { + net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); + if (!cert) + return; + ShowCertExportDialog(web_ui()->GetWebContents(), GetParentWindow(), cert); +} + +void CertificatesHandler::HandleDeleteCertificate(const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + AssignWebUICallbackId(args); + std::string node_id; + CHECK(args->GetString(1, &node_id)); + + net::X509Certificate* cert = cert_id_map_->IdToCert(node_id); + CHECK(cert); + + bool result = certificate_manager_model_->Delete(cert); + if (!result) { + // TODO(mattm): better error messages? + RejectCallbackWithError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_DELETE_CERT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); + } else { + ResolveCallback(*base::Value::CreateNullValue()); + } +} + +void CertificatesHandler::OnCertificateManagerModelCreated( + scoped_ptr<CertificateManagerModel> model) { + certificate_manager_model_ = std::move(model); + CertificateManagerModelReady(); +} + +void CertificatesHandler::CertificateManagerModelReady() { + base::FundamentalValue user_db_available_value( + certificate_manager_model_->is_user_db_available()); + base::FundamentalValue tpm_available_value( + certificate_manager_model_->is_tpm_available()); + web_ui()->CallJavascriptFunction( + "cr.webUIListenerCallback", + base::StringValue("certificates-model-ready"), + user_db_available_value, + tpm_available_value); + certificate_manager_model_->Refresh(); +} + +void CertificatesHandler::HandleRefreshCertificates( + const base::ListValue* args) { + if (certificate_manager_model_) { + // Already have a model, the webui must be re-loading. Just re-run the + // webui initialization. + CertificateManagerModelReady(); + return; + } + + if (!requested_certificate_manager_model_) { + // Request that a model be created. + CertificateManagerModel::Create( + Profile::FromWebUI(web_ui()), + this, + base::Bind(&CertificatesHandler::OnCertificateManagerModelCreated, + weak_ptr_factory_.GetWeakPtr())); + requested_certificate_manager_model_ = true; + return; + } + + // We are already waiting for a CertificateManagerModel to be created, no need + // to do anything. +} + +void CertificatesHandler::PopulateTree( + const std::string& tab_name, + net::CertType type, + const net::CertificateList& web_trust_certs) { + scoped_ptr<icu::Collator> collator; + UErrorCode error = U_ZERO_ERROR; + collator.reset( + icu::Collator::createInstance( + icu::Locale(g_browser_process->GetApplicationLocale().c_str()), + error)); + if (U_FAILURE(error)) + collator.reset(NULL); + DictionaryIdComparator comparator(collator.get()); + CertificateManagerModel::OrgGroupingMap map; + + certificate_manager_model_->FilterAndBuildOrgGroupingMap(type, &map); + + { + scoped_ptr<base::ListValue> nodes = make_scoped_ptr(new base::ListValue()); + for (CertificateManagerModel::OrgGroupingMap::iterator i = map.begin(); + i != map.end(); ++i) { + // Populate first level (org name). + base::DictionaryValue* dict = new base::DictionaryValue; + dict->SetString(kKeyField, OrgNameToId(i->first)); + dict->SetString(kNameField, i->first); + + // Populate second level (certs). + base::ListValue* subnodes = new base::ListValue; + for (net::CertificateList::const_iterator org_cert_it = i->second.begin(); + org_cert_it != i->second.end(); ++org_cert_it) { + base::DictionaryValue* cert_dict = new base::DictionaryValue; + net::X509Certificate* cert = org_cert_it->get(); + cert_dict->SetString(kKeyField, cert_id_map_->CertToId(cert)); + cert_dict->SetString( + kNameField, certificate_manager_model_->GetColumnText( + *cert, CertificateManagerModel::COL_SUBJECT_NAME)); + cert_dict->SetBoolean( + kReadonlyField, + certificate_manager_model_->cert_db()->IsReadOnly(cert)); + // Policy-installed certificates with web trust are trusted. + bool policy_trusted = + IsPolicyInstalledWithWebTrust(web_trust_certs, cert); + cert_dict->SetBoolean( + kUntrustedField, + !policy_trusted && + certificate_manager_model_->cert_db()->IsUntrusted(cert)); + cert_dict->SetBoolean(kPolicyField, policy_trusted); + // TODO(hshi): This should be determined by testing for PKCS #11 + // CKA_EXTRACTABLE attribute. We may need to use the NSS function + // PK11_ReadRawAttribute to do that. + cert_dict->SetBoolean( + kExtractableField, + !certificate_manager_model_->IsHardwareBacked(cert)); + // TODO(mattm): Other columns. + subnodes->Append(cert_dict); + } + std::sort(subnodes->begin(), subnodes->end(), comparator); + + dict->Set(kSubnodesField, subnodes); + nodes->Append(dict); + } + std::sort(nodes->begin(), nodes->end(), comparator); + + web_ui()->CallJavascriptFunction("cr.webUIListenerCallback", + base::StringValue("certificates-changed"), + base::StringValue(tab_name), + *nodes); + } +} + +void CertificatesHandler::ResolveCallback(const base::Value& response) { + DCHECK(!webui_callback_id_.empty()); + ResolveJavascriptCallback(base::StringValue(webui_callback_id_), response); + webui_callback_id_.clear(); +} + +void CertificatesHandler::RejectCallback(const base::Value& response) { + DCHECK(!webui_callback_id_.empty()); + RejectJavascriptCallback(base::StringValue(webui_callback_id_), response); + webui_callback_id_.clear(); +} + +void CertificatesHandler::RejectCallbackWithError( + const std::string& title, + const std::string& error) { + scoped_ptr<base::DictionaryValue> error_info(new base::DictionaryValue); + error_info->SetString(kErrorTitle, title); + error_info->SetString(kErrorDescription, error); + RejectCallback(*error_info); +} + +void CertificatesHandler::RejectCallbackWithImportError( + const std::string& title, + const net::NSSCertDatabase::ImportCertFailureList& not_imported) { + std::string error; + if (selected_cert_list_.size() == 1) + error = l10n_util::GetStringUTF8( + IDS_CERT_MANAGER_IMPORT_SINGLE_NOT_IMPORTED); + else if (not_imported.size() == selected_cert_list_.size()) + error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ALL_NOT_IMPORTED); + else + error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_SOME_NOT_IMPORTED); + + scoped_ptr<base::ListValue> cert_error_list = + make_scoped_ptr(new base::ListValue()); + for (size_t i = 0; i < not_imported.size(); ++i) { + const net::NSSCertDatabase::ImportCertFailure& failure = not_imported[i]; + base::DictionaryValue* dict = new base::DictionaryValue; + dict->SetString( + kNameField, failure.certificate->subject().GetDisplayName()); + dict->SetString(kErrorField, NetErrorToString(failure.net_error)); + cert_error_list->Append(dict); + } + + scoped_ptr<base::DictionaryValue> error_info(new base::DictionaryValue); + error_info->SetString(kErrorTitle, title); + error_info->SetString(kErrorDescription, error); + error_info->Set( + kCertificateErrors, make_scoped_ptr(cert_error_list.release())); + RejectCallback(*error_info); +} + +gfx::NativeWindow CertificatesHandler::GetParentWindow() const { + return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); +} + +} // namespace settings
diff --git a/chrome/browser/ui/webui/settings/certificates_handler.h b/chrome/browser/ui/webui/settings/certificates_handler.h new file mode 100644 index 0000000..99607f2 --- /dev/null +++ b/chrome/browser/ui/webui/settings/certificates_handler.h
@@ -0,0 +1,201 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CERTIFICATES_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CERTIFICATES_HANDLER_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/certificate_manager_model.h" +#include "chrome/browser/ui/webui/settings/md_settings_ui.h" +#include "net/cert/nss_cert_database.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/shell_dialogs/select_file_dialog.h" + +namespace settings { + +class CertIdMap; +class FileAccessProvider; + +class CertificatesHandler + : public SettingsPageUIHandler, + public CertificateManagerModel::Observer, + public ui::SelectFileDialog::Listener { + public: + explicit CertificatesHandler(bool show_certs_in_modal_dialog); + ~CertificatesHandler() override; + + // SettingsPageUIHandler implementation. + void RegisterMessages() override; + + // CertificateManagerModel::Observer implementation. + void CertificatesRefreshed() override; + + // SelectFileDialog::Listener implementation. + void FileSelected(const base::FilePath& path, + int index, + void* params) override; + void FileSelectionCanceled(void* params) override; + + private: + // View certificate. + void HandleViewCertificate(const base::ListValue* args); + + // Edit certificate authority trust values. The sequence goes like: + // 1. user clicks edit button -> Edit dialog is shown -> + // HandleGetCATrust -> Edit dialog is populated. + // 2. User checks/unchecks boxes, and clicks ok -> HandleEditCATrust -> + // edit dialog is dismissed upon success. + void HandleGetCATrust(const base::ListValue* args); + void HandleEditCATrust(const base::ListValue* args); + + // Cleanup state stored during import or export process. + void HandleCancelImportExportProcess(const base::ListValue* args); + void ImportExportCleanup(); + + // Export to PKCS #12 file. The sequence goes like: + // 1. user click on export button -> HandleExportPersonal -> launches file + // selector + // 2. user selects file -> ExportPersonalFileSelected -> launches password + // dialog + // 3. user enters password -> HandleExportPersonalPasswordSelected -> + // unlock slots + // 4. slots unlocked -> ExportPersonalSlotsUnlocked -> exports to memory + // buffer -> starts async write operation + // 5. write finishes (or fails) -> ExportPersonalFileWritten + void HandleExportPersonal(const base::ListValue* args); + void ExportPersonalFileSelected(const base::FilePath& path); + void HandleExportPersonalPasswordSelected(const base::ListValue* args); + void ExportPersonalSlotsUnlocked(); + void ExportPersonalFileWritten(const int* write_errno, + const int* bytes_written); + + // Import from PKCS #12 or cert file. The sequence goes like: + // 1. user click on import button -> HandleImportPersonal -> + // launches file selector + // 2. user selects file -> ImportPersonalFileSelected -> starts async + // read operation + // 3. read operation completes -> ImportPersonalFileRead -> + // If file is PFX -> launches password dialog, goto step 4 + // Else -> import as certificate, goto step 6 + // 4. user enters password -> HandleImportPersonalPasswordSelected -> + // unlock slot + // 5. slot unlocked -> ImportPersonalSlotUnlocked attempts to + // import with previously entered password + // 6a. if import succeeds -> ImportExportCleanup + // 6b. if import fails -> show error, ImportExportCleanup + // TODO(mattm): allow retrying with different password + void HandleImportPersonal(const base::ListValue* args); + void ImportPersonalFileSelected(const base::FilePath& path); + void ImportPersonalFileRead(const int* read_errno, const std::string* data); + void HandleImportPersonalPasswordSelected(const base::ListValue* args); + void ImportPersonalSlotUnlocked(); + + // Import Server certificates from file. Sequence goes like: + // 1. user clicks on import button -> HandleImportServer -> launches file + // selector + // 2. user selects file -> ImportServerFileSelected -> starts async read + // 3. read completes -> ImportServerFileRead -> parse certs -> attempt import + // 4a. if import succeeds -> ImportExportCleanup + // 4b. if import fails -> show error, ImportExportCleanup + void HandleImportServer(const base::ListValue* args); + void ImportServerFileSelected(const base::FilePath& path); + void ImportServerFileRead(const int* read_errno, const std::string* data); + + // Import Certificate Authorities from file. Sequence goes like: + // 1. user clicks on import button -> HandleImportCA -> launches file + // selector + // 2. user selects file -> ImportCAFileSelected -> starts async read + // 3. read completes -> ImportCAFileRead -> parse certs -> Certificate trust + // level dialog is shown. + // 4. user clicks ok -> HandleImportCATrustSelected -> attempt import + // 5a. if import succeeds -> ImportExportCleanup + // 5b. if import fails -> show error, ImportExportCleanup + void HandleImportCA(const base::ListValue* args); + void ImportCAFileSelected(const base::FilePath& path); + void ImportCAFileRead(const int* read_errno, const std::string* data); + void HandleImportCATrustSelected(const base::ListValue* args); + + // Export a certificate. + void HandleExportCertificate(const base::ListValue* args); + + // Delete certificate and private key (if any). + void HandleDeleteCertificate(const base::ListValue* args); + + // Model initialization methods. + void OnCertificateManagerModelCreated( + scoped_ptr<CertificateManagerModel> model); + void CertificateManagerModelReady(); + + // Populate the trees in all the tabs. + void HandleRefreshCertificates(const base::ListValue* args); + + // Populate the given tab's tree. + void PopulateTree(const std::string& tab_name, + net::CertType type, + const net::CertificateList& web_trust_certs); + + // Populate the tree after retrieving the list of policy-installed + // web-trusted certificates. + void OnPolicyWebTrustCertsRetrieved( + const net::CertificateList& web_trust_certs); + + void ResolveCallback(const base::Value& response); + void RejectCallback(const base::Value& response); + + // Reject the pending JS callback with a generic error. + void RejectCallbackWithError( + const std::string& title, const std::string& error); + + // Reject the pending JS callback with a certificate import error. + void RejectCallbackWithImportError( + const std::string& title, + const net::NSSCertDatabase::ImportCertFailureList& not_imported); + + // Assigns a new |webui_callback_id_|. Ensures that previous in-flight request + // has been fulfilled. + void AssignWebUICallbackId(const base::ListValue* args); + + gfx::NativeWindow GetParentWindow() const; + + // True if certificate viewer should be shown in modal instead of constrianed + // dialog. + bool show_certs_in_modal_dialog_; + // The Certificates Manager model + bool requested_certificate_manager_model_; + scoped_ptr<CertificateManagerModel> certificate_manager_model_; + + // For multi-step import or export processes, we need to store the path, + // password, etc the user chose while we wait for them to enter a password, + // wait for file to be read, etc. + base::FilePath file_path_; + base::string16 password_; + // The WebUI callback ID of the last in-flight async request. There is always + // only one in-flight such request. + std::string webui_callback_id_; + bool use_hardware_backed_; + std::string file_data_; + net::CertificateList selected_cert_list_; + scoped_refptr<ui::SelectFileDialog> select_file_dialog_; + scoped_refptr<net::CryptoModule> module_; + + // Used in reading and writing certificate files. + base::CancelableTaskTracker tracker_; + scoped_refptr<FileAccessProvider> file_access_provider_; + + scoped_ptr<CertIdMap> cert_id_map_; + + base::WeakPtrFactory<CertificatesHandler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CertificatesHandler); +}; + +} // namespace settings + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CERTIFICATES_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 2c8dae88..592759e 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -37,6 +37,10 @@ #include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h" #endif // defined(OS_CHROMEOS) +#if defined(USE_NSS_CERTS) +#include "chrome/browser/ui/webui/settings/certificates_handler.h" +#endif // defined(USE_NSS_CERTS) + namespace settings { SettingsPageUIHandler::SettingsPageUIHandler() { @@ -68,6 +72,11 @@ WebContentsObserver(web_ui->GetWebContents()) { Profile* profile = Profile::FromWebUI(web_ui); AddSettingsPageUIHandler(new AppearanceHandler(web_ui)); + +#if defined(USE_NSS_CERTS) + AddSettingsPageUIHandler(new CertificatesHandler(false)); +#endif // defined(USE_NSS_CERTS) + AddSettingsPageUIHandler(new ClearBrowsingDataHandler(web_ui)); AddSettingsPageUIHandler(new DownloadsHandler()); AddSettingsPageUIHandler(new FontHandler(web_ui));
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 81e4906..01b4820 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -1402,6 +1402,8 @@ 'browser/hang_monitor/hung_window_detector.h', 'browser/password_manager/password_manager_util_win.cc', 'browser/password_manager/password_manager_util_win.h', + 'browser/themes/theme_service_win.cc', + 'browser/themes/theme_service_win.h', ], 'chrome_browser_non_win_sources': [ 'browser/profile_resetter/triggered_profile_resetter_stub.cc',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 9d170c5..d407c6c 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -52,6 +52,8 @@ 'browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h', 'browser/chromeos/app_mode/startup_app_launcher.cc', 'browser/chromeos/app_mode/startup_app_launcher.h', + 'browser/chromeos/arc/arc_auth_notification.cc', + 'browser/chromeos/arc/arc_auth_notification.h', 'browser/chromeos/arc/arc_auth_service.cc', 'browser/chromeos/arc/arc_auth_service.h', 'browser/chromeos/arc/arc_intent_helper_bridge.cc',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 6bd841f..ac8a862c 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -2785,6 +2785,8 @@ 'browser/ui/crypto_module_password_dialog_nss.h', 'browser/ui/webui/options/certificate_manager_handler.cc', 'browser/ui/webui/options/certificate_manager_handler.h', + 'browser/ui/webui/settings/certificates_handler.cc', + 'browser/ui/webui/settings/certificates_handler.h', ], 'chrome_browser_ui_omnibox_non_mobile_sources': [ 'browser/ui/omnibox/alternate_nav_infobar_delegate.cc',
diff --git a/chrome/common/extensions/api/input_ime.json b/chrome/common/extensions/api/input_ime.json index 8faf98f..0f981fc 100644 --- a/chrome/common/extensions/api/input_ime.json +++ b/chrome/common/extensions/api/input_ime.json
@@ -593,13 +593,53 @@ "name": "windowObject", "type": "object", "isInstanceOf": "Window", - "description": "The JavaScript 'window' object of the newly created IME window." + "description": "The JavaScript 'window' object of the newly created IME window. It contains the additional 'id' property for the parameters of the other functions like showWindow/hideWindow." } ] } ] }, { + "name": "showWindow", + "type": "function", + "description": "Shows the IME window. This makes the hidden window visible.", + "platforms": ["win", "linux"], + "parameters": [ + { + "type": "integer", + "name": "windowId", + "description": "The ID of the IME window." + }, + { + "type": "function", + "name": "callback", + "optional": true, + "description": "Called when the operation completes.", + "parameters": [] + } + ] + }, + { + "name": "hideWindow", + "type": "function", + "description": "Hides the IME window. This doesn't close the window. Instead, it makes the window invisible. The extension can cache the window and show/hide it for better performance.", + "platforms": ["win", "linux"], + "parameters": [ + { + "type": "integer", + "name": "windowId", + "description": "The ID of the IME window." + }, + { + "type": "function", + "name": "callback", + "optional": true, + "description": "Called when the operation completes.", + "parameters": [] + } + ] + }, + { "name": "activate", "type": "function", "description": "Activates the IME extension so that it can receive events.",
diff --git a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js index f114124e..9f4d9acb 100644 --- a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js +++ b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js
@@ -51,6 +51,7 @@ if (windowParams && windowParams.frameId) { view = appWindowNatives.GetFrame( windowParams.frameId, false /* notifyBrowser */); + view.id = windowParams.frameId; } callback(view); });
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc index 392ff45b..9f52f06 100644 --- a/chrome/test/base/v8_unit_test.cc +++ b/chrome/test/base/v8_unit_test.cc
@@ -11,7 +11,6 @@ #include "base/strings/stringprintf.h" #include "chrome/common/chrome_paths.h" #include "third_party/WebKit/public/web/WebKit.h" -#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" namespace { @@ -96,7 +95,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; v8::Local<v8::Value> function_property = context->Global()->Get(v8::String::NewFromUtf8(isolate, "runTest")); @@ -211,7 +209,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, script_source.data(), @@ -260,7 +257,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; v8::Local<v8::Value> function_property = context->Global()->Get( v8::String::NewFromUtf8(isolate, function_name.c_str()));
diff --git a/chrome/test/data/push_messaging/push_test.js b/chrome/test/data/push_messaging/push_test.js index 73a307e..c1fe6aa 100644 --- a/chrome/test/data/push_messaging/push_test.js +++ b/chrome/test/data/push_messaging/push_test.js
@@ -7,16 +7,6 @@ var resultQueue = new ResultQueue(); var pushSubscription = null; -// NIST P-256 public key made available to tests. Must be an uncompressed -// point in accordance with SEC1 2.3.3. -var applicationServerKey = new Uint8Array([ - 0x04, 0x55, 0x52, 0x6A, 0xA5, 0x6E, 0x8E, 0xAA, 0x47, 0x97, 0x36, 0x10, 0xC1, - 0x66, 0x3C, 0x1E, 0x65, 0xBF, 0xA1, 0x7B, 0xEE, 0x48, 0xC9, 0xC6, 0xBB, 0xBF, - 0x02, 0x18, 0x53, 0x72, 0x1D, 0x0C, 0x7B, 0xA9, 0xE3, 0x11, 0xB7, 0x03, 0x52, - 0x21, 0xD3, 0x71, 0x90, 0x13, 0xA8, 0xC1, 0xCF, 0xED, 0x20, 0xF7, 0x1F, 0xD1, - 0x7F, 0xF2, 0x76, 0xB6, 0x01, 0x20, 0xD8, 0x35, 0xA5, 0xD9, 0x3C, 0x43, 0xFD -]); - var pushSubscriptionOptions = { userVisibleOnly: true }; @@ -116,36 +106,8 @@ } } -// This is the old style of push subscriptions which we are phasing away -// from, where the subscription used a sender ID instead of public key. -function subscribePushWithoutKey() { - navigator.serviceWorker.ready.then(function(swRegistration) { - return swRegistration.pushManager.subscribe( - pushSubscriptionOptions) - .then(function(subscription) { - pushSubscription = subscription; - sendResultToTest(subscription.endpoint); - }); - }).catch(sendErrorToTest); -} - function subscribePush() { navigator.serviceWorker.ready.then(function(swRegistration) { - pushSubscriptionOptions.applicationServerKey = applicationServerKey.buffer; - return swRegistration.pushManager.subscribe(pushSubscriptionOptions) - .then(function(subscription) { - pushSubscription = subscription; - sendResultToTest(subscription.endpoint); - }); - }).catch(sendErrorToTest); -} - -function subscribePushBadKey() { - navigator.serviceWorker.ready.then(function(swRegistration) { - var invalidApplicationServerKey = Uint8Array.from(applicationServerKey); - invalidApplicationServerKey[0] = 0x05; - pushSubscriptionOptions.applicationServerKey = - invalidApplicationServerKey.buffer; return swRegistration.pushManager.subscribe(pushSubscriptionOptions) .then(function(subscription) { pushSubscription = subscription;
diff --git a/chrome/test/data/webui/splitter_test.html b/chrome/test/data/webui/splitter_test.html index 9d4a567..0d9dd7a 100644 --- a/chrome/test/data/webui/splitter_test.html +++ b/chrome/test/data/webui/splitter_test.html
@@ -1,9 +1,9 @@ <!doctype html> <html> <body> -<div></div> +<div id="previous"></div> <div id="splitter"></div> -<div></div> +<div id="next"></div> <script> function testSplitter_IgnoresRightMouse() { var splitter = document.getElementById('splitter'); @@ -17,6 +17,63 @@ assertFalse(splitter.dispatchEvent(downLeft)); assertTrue(downLeft.defaultPrevented); } + +function testSplitter_ResizePreviousElement() { + var splitter = document.getElementById('splitter'); + cr.ui.decorate(splitter, cr.ui.Splitter); + splitter.resizeNextElement = false; + + var previousElement = document.getElementById('previous'); + previousElement.style.width = '0px'; + var beforeWidth = parseFloat(previousElement.style.width); + + var down = new MouseEvent('mousedown', + {button: 0, cancelable: true, clientX: 0}); + splitter.dispatchEvent(down); + + var move = new MouseEvent('mousemove', + {button: 0, cancelable: true, clientX: 50}); + splitter.dispatchEvent(move); + + move = new MouseEvent('mousemove', + {button: 0, cancelable: true, clientX: 100}); + splitter.dispatchEvent(move); + + var up = new MouseEvent('mouseup', + {button: 0, cancelable: true, clientX: 100}); + splitter.dispatchEvent(up); + + var afterWidth = parseFloat(previousElement.style.width); + assertEquals(100, afterWidth - beforeWidth); +} + +function testSplitter_ResizeNextElement() { + var splitter = document.getElementById('splitter'); + cr.ui.decorate(splitter, cr.ui.Splitter, true); + splitter.resizeNextElement = true; + var nextElement = document.getElementById('next'); + nextElement.style.width = '0px'; + var beforeWidth = parseFloat(nextElement.style.width); + + var down = new MouseEvent('mousedown', + {button: 0, cancelable: true, clientX: 100}); + splitter.dispatchEvent(down); + + var move = new MouseEvent('mousemove', + {button: 0, cancelable: true, clientX: 50}); + splitter.dispatchEvent(move); + + move = new MouseEvent('mousemove', + {button: 0, cancelable: true, clientX: 0}); + splitter.dispatchEvent(move); + + var up = new MouseEvent('mouseup', + {button: 0, cancelable: true, clientX: 0}); + splitter.dispatchEvent(up); + + var afterWidth = parseFloat(nextElement.style.width); + assertEquals(100, afterWidth - beforeWidth); +} </script> </body> </html>
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc index f6b7a77..c06c618 100644 --- a/chromecast/renderer/cast_content_renderer_client.cc +++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -25,7 +25,6 @@ #include "content/public/common/content_switches.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" -#include "content/public/renderer/render_view_observer.h" #include "third_party/WebKit/public/platform/WebColor.h" #include "third_party/WebKit/public/web/WebFrameWidget.h" #include "third_party/WebKit/public/web/WebSettings.h" @@ -72,31 +71,6 @@ // though the comment of WebColor says it is in RGBA. const blink::WebColor kColorBlack = 0xFF000000; -class CastRenderViewObserver : content::RenderViewObserver { - public: - CastRenderViewObserver(CastContentRendererClient* client, - content::RenderView* render_view); - ~CastRenderViewObserver() override {} - - void DidClearWindowObject(blink::WebLocalFrame* frame) override; - - private: - CastContentRendererClient* const client_; - - DISALLOW_COPY_AND_ASSIGN(CastRenderViewObserver); -}; - -CastRenderViewObserver::CastRenderViewObserver( - CastContentRendererClient* client, - content::RenderView* render_view) - : content::RenderViewObserver(render_view), - client_(client) { -} - -void CastRenderViewObserver::DidClearWindowObject(blink::WebLocalFrame* frame) { - client_->AddRendererNativeBindings(frame); -} - } // namespace CastContentRendererClient::CastContentRendererClient() @@ -108,10 +82,6 @@ CastContentRendererClient::~CastContentRendererClient() { } -void CastContentRendererClient::AddRendererNativeBindings( - blink::WebLocalFrame* frame) { -} - void CastContentRendererClient::RenderThreadStarted() { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -168,9 +138,6 @@ // application running. webview->settings()->setOfflineWebApplicationCacheEnabled(false); } - - // Note: RenderView will own the lifetime of its observer. - new CastRenderViewObserver(this, render_view); } void CastContentRendererClient::AddKeySystems(
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h index 6350038..470e8a8 100644 --- a/chromecast/renderer/cast_content_renderer_client.h +++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -31,9 +31,6 @@ ~CastContentRendererClient() override; - // Adds any platform-specific bindings to the current frame. - virtual void AddRendererNativeBindings(blink::WebLocalFrame* frame); - // ContentRendererClient implementation: void RenderThreadStarted() override; void RenderViewCreated(content::RenderView* render_view) override;
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index e895bb6b..e97faf4 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -8025.0.0 \ No newline at end of file +8031.0.0 \ No newline at end of file
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 37762723..1fbad80 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -119,6 +119,9 @@ // locate the device. const char kEnableConsumerManagement[] = "enable-consumer-management"; +// Enables details panel in Files app. +const char kEnableFilesDetailsPanel[] = "enable-files-details-panel"; + // If this switch is set, the device cannot be remotely disabled by its owner. const char kDisableDeviceDisabling[] = "disable-device-disabling";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 92c24fcf..0124dd4 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -61,6 +61,7 @@ CHROMEOS_EXPORT extern const char kEnableArc[]; CHROMEOS_EXPORT extern const char kEnableConsumerManagement[]; CHROMEOS_EXPORT extern const char kEnableExtensionAssetsSharing[]; +CHROMEOS_EXPORT extern const char kEnableFilesDetailsPanel[]; CHROMEOS_EXPORT extern const char kEnableFirstRunUITransitions[]; CHROMEOS_EXPORT extern const char kEnableImeMenu[]; CHROMEOS_EXPORT extern const char kEnableKioskMode[];
diff --git a/components/filesystem/file_system_app.cc b/components/filesystem/file_system_app.cc index e4620ba8..011f74d 100644 --- a/components/filesystem/file_system_app.cc +++ b/components/filesystem/file_system_app.cc
@@ -38,10 +38,9 @@ FileSystemApp::~FileSystemApp() {} void FileSystemApp::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); } bool FileSystemApp::AcceptConnection(mojo::Connection* connection) {
diff --git a/components/filesystem/file_system_app.h b/components/filesystem/file_system_app.h index 9a5983cb..91c18bc 100644 --- a/components/filesystem/file_system_app.h +++ b/components/filesystem/file_system_app.h
@@ -31,8 +31,8 @@ static base::FilePath GetUserDataDir(); // |mojo::ShellClient| override: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // |InterfaceFactory<Files>| implementation:
diff --git a/components/filesystem/file_system_impl.cc b/components/filesystem/file_system_impl.cc index d64427a..f8b9594d 100644 --- a/components/filesystem/file_system_impl.cc +++ b/components/filesystem/file_system_impl.cc
@@ -24,7 +24,7 @@ mojo::InterfaceRequest<FileSystem> request, base::FilePath persistent_dir, LockTable* lock_table) - : remote_application_name_(connection->GetRemoteApplicationName()), + : remote_application_name_(connection->GetRemoteIdentity().name()), binding_(this, std::move(request)), lock_table_(lock_table), persistent_dir_(persistent_dir) {}
diff --git a/components/font_service/font_service_app.cc b/components/font_service/font_service_app.cc index d0c0c1c5..6e73b99 100644 --- a/components/font_service/font_service_app.cc +++ b/components/font_service/font_service_app.cc
@@ -59,9 +59,9 @@ FontServiceApp::~FontServiceApp() {} void FontServiceApp::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, uint32_t id) { - tracing_.Initialize(connector, url); + const mojo::Identity& identity, + uint32_t id) { + tracing_.Initialize(connector, identity.name()); } bool FontServiceApp::AcceptConnection(mojo::Connection* connection) {
diff --git a/components/font_service/font_service_app.h b/components/font_service/font_service_app.h index 52b1f03..957f231f 100644 --- a/components/font_service/font_service_app.h +++ b/components/font_service/font_service_app.h
@@ -27,8 +27,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // mojo::InterfaceFactory<FontService>:
diff --git a/components/leveldb/leveldb_app.cc b/components/leveldb/leveldb_app.cc index 3dfd509d..4ac0ca0 100644 --- a/components/leveldb/leveldb_app.cc +++ b/components/leveldb/leveldb_app.cc
@@ -14,10 +14,9 @@ LevelDBApp::~LevelDBApp() {} void LevelDBApp::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); service_.reset(new LevelDBServiceImpl); }
diff --git a/components/leveldb/leveldb_app.h b/components/leveldb/leveldb_app.h index 886f349..4b87fc89 100644 --- a/components/leveldb/leveldb_app.h +++ b/components/leveldb/leveldb_app.h
@@ -22,8 +22,7 @@ private: // |ShellClient| override: void Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override;
diff --git a/components/mus/mus_app.cc b/components/mus/mus_app.cc index f04ac9bc..2d714799 100644 --- a/components/mus/mus_app.cc +++ b/components/mus/mus_app.cc
@@ -96,8 +96,7 @@ } void MandolineUIServicesApp::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { connector_ = connector; surfaces_state_ = new SurfacesState; @@ -135,7 +134,7 @@ gpu_state_ = new GpuState(); connection_manager_.reset(new ws::ConnectionManager(this, surfaces_state_)); - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); } bool MandolineUIServicesApp::AcceptConnection(Connection* connection) { @@ -184,7 +183,7 @@ mojom::DisplayManagerRequest request) { // TODO(sky): validate id. connection_manager_->display_manager() - ->GetUserDisplayManager(connection->GetRemoteUserID()) + ->GetUserDisplayManager(connection->GetRemoteIdentity().user_id()) ->AddDisplayManagerBinding(std::move(request)); } @@ -192,7 +191,7 @@ mojo::Connection* connection, mojom::WindowManagerFactoryServiceRequest request) { connection_manager_->window_manager_factory_registry()->Register( - connection->GetRemoteUserID(), std::move(request)); + connection->GetRemoteIdentity().user_id(), std::move(request)); } void MandolineUIServicesApp::Create(Connection* connection,
diff --git a/components/mus/mus_app.h b/components/mus/mus_app.h index b94ea536..e82f7d6 100644 --- a/components/mus/mus_app.h +++ b/components/mus/mus_app.h
@@ -63,8 +63,8 @@ void InitializeResources(mojo::Connector* connector); // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // ConnectionManagerDelegate:
diff --git a/components/profile_service/profile_app.cc b/components/profile_service/profile_app.cc index 5be0fd9..27491db 100644 --- a/components/profile_service/profile_app.cc +++ b/components/profile_service/profile_app.cc
@@ -36,13 +36,12 @@ } void ProfileApp::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); leveldb_service_.reset(new leveldb::LevelDBServiceImpl); - auto it = g_user_id_to_data_dir.Get().find(user_id); + auto it = g_user_id_to_data_dir.Get().find(identity.user_id()); DCHECK(it != g_user_id_to_data_dir.Get().end()); profile_data_dir_ = it->second; }
diff --git a/components/profile_service/profile_app.h b/components/profile_service/profile_app.h index 12f0d4e..8da3f56 100644 --- a/components/profile_service/profile_app.h +++ b/components/profile_service/profile_app.h
@@ -56,8 +56,7 @@ private: // |ShellClient| override: void Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override;
diff --git a/components/resource_provider/resource_provider_app.cc b/components/resource_provider/resource_provider_app.cc index 43412393..cd16a98894 100644 --- a/components/resource_provider/resource_provider_app.cc +++ b/components/resource_provider/resource_provider_app.cc
@@ -22,15 +22,14 @@ } void ResourceProviderApp::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); } bool ResourceProviderApp::AcceptConnection(mojo::Connection* connection) { const base::FilePath app_path( - GetPathForApplicationName(connection->GetRemoteApplicationName())); + GetPathForApplicationName(connection->GetRemoteIdentity().name())); if (app_path.empty()) return false; // The specified app has no resources. @@ -42,7 +41,7 @@ mojo::Connection* connection, mojo::InterfaceRequest<ResourceProvider> request) { const base::FilePath app_path( - GetPathForApplicationName(connection->GetRemoteApplicationName())); + GetPathForApplicationName(connection->GetRemoteIdentity().name())); // We validated path at AcceptConnection() time, so it should still // be valid. CHECK(!app_path.empty());
diff --git a/components/resource_provider/resource_provider_app.h b/components/resource_provider/resource_provider_app.h index 14b867a..10f7602 100644 --- a/components/resource_provider/resource_provider_app.h +++ b/components/resource_provider/resource_provider_app.h
@@ -25,8 +25,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // mojo::InterfaceFactory<ResourceProvider>:
diff --git a/content/browser/accessibility/accessibility_event_recorder_win.cc b/content/browser/accessibility/accessibility_event_recorder_win.cc index fa76749..cb40bfb 100644 --- a/content/browser/accessibility/accessibility_event_recorder_win.cc +++ b/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -287,7 +287,7 @@ if (accessibility_hwnd != hwnd) return E_FAIL; - IAccessible* obj = manager_->GetRoot()->ToBrowserAccessibilityWin(); + IAccessible* obj = ToBrowserAccessibilityWin(manager_->GetRoot()); obj->AddRef(); *ppv_object = obj; return S_OK;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc index 4ebb1c0..ef954c9 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -46,8 +46,7 @@ base::DictionaryValue* dict) { dict->SetInteger("id", node.GetId()); BrowserAccessibilityAuraLinux* acc_obj = - const_cast<BrowserAccessibility*>(&node) - ->ToBrowserAccessibilityAuraLinux(); + ToBrowserAccessibilityAuraLinux(const_cast<BrowserAccessibility*>(&node)); AtkObject* atk_object = acc_obj->GetAtkObject(); AtkRole role = acc_obj->atk_role();
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm index 2c08e72..48b9d88 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -42,14 +42,14 @@ // confusing, convert it to local window coordinates using the top-left // corner when dumping the position. BrowserAccessibility* root = node.manager()->GetRootManager()->GetRoot(); - BrowserAccessibilityCocoa* cocoa_root = root->ToBrowserAccessibilityCocoa(); + BrowserAccessibilityCocoa* cocoa_root = ToBrowserAccessibilityCocoa(root); NSPoint root_position = [[cocoa_root position] pointValue]; NSSize root_size = [[cocoa_root size] sizeValue]; int root_top = -static_cast<int>(root_position.y + root_size.height); int root_left = static_cast<int>(root_position.x); BrowserAccessibilityCocoa* cocoa_node = - const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa(); + ToBrowserAccessibilityCocoa(const_cast<BrowserAccessibility*>(&node)); NSPoint node_position = [[cocoa_node position] pointValue]; NSSize node_size = [[cocoa_node size] sizeValue]; @@ -221,7 +221,7 @@ base::DictionaryValue* dict) { dict->SetInteger("id", node.GetId()); BrowserAccessibilityCocoa* cocoa_node = - const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa(); + ToBrowserAccessibilityCocoa(const_cast<BrowserAccessibility*>(&node)); NSArray* supportedAttributes = [cocoa_node accessibilityAttributeNames]; string role = SysNSStringToUTF8(
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc index 6947938..c799846 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_win.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -157,7 +157,7 @@ const BrowserAccessibility& node, base::DictionaryValue* dict) { dict->SetInteger("id", node.GetId()); BrowserAccessibilityWin* ax_object = - const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(const_cast<BrowserAccessibility*>(&node)); DCHECK(ax_object); VARIANT variant_self; @@ -247,7 +247,7 @@ LONG root_left, root_top, root_width, root_height; if (SUCCEEDED(ax_object->accLocation( &left, &top, &width, &height, variant_self)) && - SUCCEEDED(root->ToBrowserAccessibilityWin()->accLocation( + SUCCEEDED(ToBrowserAccessibilityWin(root)->accLocation( &root_left, &root_top, &root_width, &root_height, variant_self))) { base::DictionaryValue* location = new base::DictionaryValue; location->SetInteger("x", left - root_left);
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 7bb165b6..ee3874a 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -15,9 +15,18 @@ #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/common/accessibility_messages.h" #include "ui/accessibility/ax_text_utils.h" +#include "ui/accessibility/platform/ax_platform_node.h" namespace content { +namespace { + +// Map from unique_id to BrowserAccessibility +using UniqueIDMap = base::hash_map<int32_t, BrowserAccessibility*>; +base::LazyInstance<UniqueIDMap> g_unique_id_map = LAZY_INSTANCE_INITIALIZER; + +} + #if !defined(PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL) // static BrowserAccessibility* BrowserAccessibility::Create() { @@ -27,10 +36,23 @@ BrowserAccessibility::BrowserAccessibility() : manager_(NULL), - node_(NULL) { + node_(NULL), + unique_id_(ui::AXPlatformNode::GetNextUniqueId()) { + g_unique_id_map.Get()[unique_id_] = this; } BrowserAccessibility::~BrowserAccessibility() { + if (unique_id_) + g_unique_id_map.Get().erase(unique_id_); +} + +// static +BrowserAccessibility* BrowserAccessibility::GetFromUniqueID(int32_t unique_id) { + auto iter = g_unique_id_map.Get().find(unique_id); + if (iter == g_unique_id_map.Get().end()) + return nullptr; + + return iter->second; } void BrowserAccessibility::Init(BrowserAccessibilityManager* manager, @@ -594,6 +616,10 @@ node_ = NULL; manager_ = NULL; + if (unique_id_) + g_unique_id_map.Get().erase(unique_id_); + unique_id_ = 0; + NativeReleaseReference(); }
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index edef50d..b2f14f9 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -75,6 +75,8 @@ virtual ~BrowserAccessibility(); + static BrowserAccessibility* GetFromUniqueID(int32_t unique_id); + // Called only once, immediately after construction. The constructor doesn't // take any arguments because in the Windows subclass we use a special // function to construct a COM object. @@ -194,6 +196,7 @@ BrowserAccessibilityManager* manager() const { return manager_; } bool instance_active() const { return node_ != NULL; } ui::AXNode* node() const { return node_; } + int32_t unique_id() const { return unique_id_; } // These access the internal accessibility tree, which doesn't necessarily // reflect the accessibility tree that should be exposed on each platform. @@ -220,17 +223,6 @@ // IsNative returns false. virtual bool IsNative() const; -#if defined(OS_MACOSX) && __OBJC__ - const BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa() const; - BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa(); -#elif defined(OS_WIN) - const BrowserAccessibilityWin* ToBrowserAccessibilityWin() const; - BrowserAccessibilityWin* ToBrowserAccessibilityWin(); -#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11) - const BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux() const; - BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(); -#endif - // Accessing accessibility attributes: // // There are dozens of possible attributes for an accessibility node, @@ -328,6 +320,9 @@ // The underlying node. ui::AXNode* node_; + // A unique ID, since node IDs are frame-local. + int32_t unique_id_; + private: // |GetInnerText| recursively includes all the text from descendants such as // text found in any embedded object. In contrast, |GetText| might include a
diff --git a/content/browser/accessibility/browser_accessibility_auralinux.cc b/content/browser/accessibility/browser_accessibility_auralinux.cc index 6b5a4f97..231a3dd7 100644 --- a/content/browser/accessibility/browser_accessibility_auralinux.cc +++ b/content/browser/accessibility/browser_accessibility_auralinux.cc
@@ -23,6 +23,18 @@ return atk_object->m_object; } +const BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux( + const BrowserAccessibility* obj) { + DCHECK(!obj || obj->IsNative()); + return static_cast<const BrowserAccessibilityAuraLinux*>(obj); +} + +BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux( + BrowserAccessibility* obj) { + DCHECK(!obj || obj->IsNative()); + return static_cast<BrowserAccessibilityAuraLinux*>(obj); +} + // // AtkAction interface. // @@ -140,7 +152,7 @@ return NULL; AtkObject* atk_result = - result->ToBrowserAccessibilityAuraLinux()->GetAtkObject(); + ToBrowserAccessibilityAuraLinux(result)->GetAtkObject(); g_object_ref(atk_result); return atk_result; } @@ -474,7 +486,7 @@ if (!obj) return NULL; if (obj->GetParent()) - return obj->GetParent()->ToBrowserAccessibilityAuraLinux()->GetAtkObject(); + return ToBrowserAccessibilityAuraLinux(obj->GetParent())->GetAtkObject(); BrowserAccessibilityManagerAuraLinux* manager = static_cast<BrowserAccessibilityManagerAuraLinux*>(obj->manager()); @@ -500,9 +512,8 @@ if (index < 0 || index >= static_cast<gint>(obj->PlatformChildCount())) return NULL; - AtkObject* result = obj->InternalGetChild(index) - ->ToBrowserAccessibilityAuraLinux() - ->GetAtkObject(); + AtkObject* result = ToBrowserAccessibilityAuraLinux( + obj->InternalGetChild(index))->GetAtkObject(); g_object_ref(result); return result; } @@ -735,16 +746,6 @@ return new BrowserAccessibilityAuraLinux(); } -const BrowserAccessibilityAuraLinux* -BrowserAccessibility::ToBrowserAccessibilityAuraLinux() const { - return static_cast<const BrowserAccessibilityAuraLinux*>(this); -} - -BrowserAccessibilityAuraLinux* -BrowserAccessibility::ToBrowserAccessibilityAuraLinux() { - return static_cast<BrowserAccessibilityAuraLinux*>(this); -} - BrowserAccessibilityAuraLinux::BrowserAccessibilityAuraLinux() : atk_object_(NULL) { } @@ -782,7 +783,7 @@ if (this->GetParent()) { atk_object_set_parent( atk_object_, - this->GetParent()->ToBrowserAccessibilityAuraLinux()->GetAtkObject()); + ToBrowserAccessibilityAuraLinux(this->GetParent())->GetAtkObject()); } } }
diff --git a/content/browser/accessibility/browser_accessibility_auralinux.h b/content/browser/accessibility/browser_accessibility_auralinux.h index 43a9c3f..773e79f 100644 --- a/content/browser/accessibility/browser_accessibility_auralinux.h +++ b/content/browser/accessibility/browser_accessibility_auralinux.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "content/browser/accessibility/browser_accessibility.h" +#include "content/common/content_export.h" namespace content { @@ -88,6 +89,12 @@ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityAuraLinux); }; +CONTENT_EXPORT const BrowserAccessibilityAuraLinux* +ToBrowserAccessibilityAuraLinux(const BrowserAccessibility* obj); + +CONTENT_EXPORT BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux( + BrowserAccessibility* obj); + } // namespace content #endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_AURALINUX_H_
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 947575e..80af6fd3 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -16,6 +16,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "content/app/strings/grit/content_strings.h" +#include "content/browser/accessibility/browser_accessibility_mac.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "content/browser/accessibility/one_shot_accessibility_tree_search.h" @@ -539,8 +540,8 @@ children_.reset([[NSMutableArray alloc] initWithCapacity:childCount]); for (uint32_t index = 0; index < childCount; ++index) { BrowserAccessibilityCocoa* child = - browserAccessibility_->PlatformGetChild(index)-> - ToBrowserAccessibilityCocoa(); + ToBrowserAccessibilityCocoa( + browserAccessibility_->PlatformGetChild(index)); if ([child isIgnored]) [children_ addObjectsFromArray:[child children]]; else @@ -560,7 +561,7 @@ // a DCHECK in the future. if (child) { BrowserAccessibilityCocoa* child_cocoa = - child->ToBrowserAccessibilityCocoa(); + ToBrowserAccessibilityCocoa(child); [children_ addObject:child_cocoa]; } } @@ -572,8 +573,8 @@ if (![self isIgnored]) { children_.reset(); } else { - [browserAccessibility_->GetParent()->ToBrowserAccessibilityCocoa() - childrenChanged]; + [ToBrowserAccessibilityCocoa(browserAccessibility_->GetParent()) + childrenChanged]; } } @@ -591,7 +592,7 @@ BrowserAccessibility* cell = browserAccessibility_->manager()->GetFromID(id); if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) - [ret addObject:cell->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(cell)]; } return ret; } @@ -807,7 +808,7 @@ BrowserAccessibility* headerObject = browserAccessibility_->manager()->GetFromID(headerElementId); if (headerObject) - return headerObject->ToBrowserAccessibilityCocoa(); + return ToBrowserAccessibilityCocoa(headerObject); } return nil; } @@ -896,7 +897,7 @@ BrowserAccessibility* element = browserAccessibility_->manager()->GetFromID(attributeValues[i]); if (element) - [outArray addObject:element->ToBrowserAccessibilityCocoa()]; + [outArray addObject:ToBrowserAccessibilityCocoa(element)]; } } @@ -957,7 +958,7 @@ // A nil parent means we're the root. if (browserAccessibility_->GetParent()) { return NSAccessibilityUnignoredAncestor( - browserAccessibility_->GetParent()->ToBrowserAccessibilityCocoa()); + ToBrowserAccessibilityCocoa(browserAccessibility_->GetParent())); } else { // Hook back up to RenderWidgetHostViewCocoa. BrowserAccessibilityManagerMac* manager = @@ -1185,7 +1186,7 @@ BrowserAccessibility* cell = browserAccessibility_->manager()->GetFromID(id); if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) - [ret addObject:cell->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(cell)]; } return ret; } @@ -1223,7 +1224,7 @@ BrowserAccessibility* rowElement = browserAccessibility_->manager()->GetFromID(id); if (rowElement) - [ret addObject:rowElement->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(rowElement)]; } } @@ -1242,7 +1243,7 @@ if (!GetState(browserAccessibility_, ui::AX_STATE_MULTISELECTABLE)) { // First try the focused child. if (focusedChild && focusedChild != browserAccessibility_) { - [ret addObject:focusedChild->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(focusedChild)]; return ret; } @@ -1253,7 +1254,7 @@ BrowserAccessibility* activeDescendant = manager->GetFromID(activeDescendantId); if (activeDescendant) { - [ret addObject:activeDescendant->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(activeDescendant)]; return ret; } } @@ -1267,14 +1268,14 @@ BrowserAccessibility* child = browserAccessibility_->PlatformGetChild(index); if (child->HasState(ui::AX_STATE_SELECTED)) - [ret addObject:child->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(child)]; } // And if nothing's selected but one has focus, use the focused one. if ([ret count] == 0 && focusedChild && focusedChild != browserAccessibility_) { - [ret addObject:focusedChild->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(focusedChild)]; } return ret; @@ -1437,7 +1438,7 @@ BrowserAccessibility* titleElement = browserAccessibility_->manager()->GetFromID(labelledby_ids[0]); if (titleElement) - return titleElement->ToBrowserAccessibilityCocoa(); + return ToBrowserAccessibilityCocoa(titleElement); } return nil; @@ -1539,7 +1540,7 @@ BrowserAccessibility* cell = browserAccessibility_->manager()->GetFromID(id); if (cell) - [ret addObject:cell->ToBrowserAccessibilityCocoa()]; + [ret addObject:ToBrowserAccessibilityCocoa(cell)]; } return ret; } @@ -1548,9 +1549,8 @@ NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; uint32_t childCount = browserAccessibility_->PlatformChildCount(); for (uint32_t index = 0; index < childCount; ++index) { - BrowserAccessibilityCocoa* child = - browserAccessibility_->PlatformGetChild(index)-> - ToBrowserAccessibilityCocoa(); + BrowserAccessibilityCocoa* child = ToBrowserAccessibilityCocoa( + browserAccessibility_->PlatformGetChild(index)); [ret addObject:child]; } return ret; @@ -1737,7 +1737,7 @@ continue; } if (colIndex == column) - return cell->ToBrowserAccessibilityCocoa(); + return ToBrowserAccessibilityCocoa(cell); if (colIndex > column) break; } @@ -1749,7 +1749,7 @@ BrowserAccessibility* object; int offset; if (GetTextMarkerData(parameter, &object, &offset)) - return object->ToBrowserAccessibilityCocoa(); + return ToBrowserAccessibilityCocoa(object); return nil; } @@ -1864,7 +1864,7 @@ NSMutableArray* result = [NSMutableArray arrayWithCapacity:count]; for (size_t i = 0; i < count; ++i) { BrowserAccessibility* match = search.GetMatchAtIndex(i); - [result addObject:match->ToBrowserAccessibilityCocoa()]; + [result addObject:ToBrowserAccessibilityCocoa(match)]; } return result; }
diff --git a/content/browser/accessibility/browser_accessibility_mac.h b/content/browser/accessibility/browser_accessibility_mac.h index aed8fd4..d516024 100644 --- a/content/browser/accessibility/browser_accessibility_mac.h +++ b/content/browser/accessibility/browser_accessibility_mac.h
@@ -11,11 +11,19 @@ #include "base/macros.h" #include "content/browser/accessibility/browser_accessibility.h" +#include "content/common/content_export.h" @class BrowserAccessibilityCocoa; namespace content { +#if __OBJC__ +CONTENT_EXPORT const BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa( + const BrowserAccessibility* obj); +CONTENT_EXPORT BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa( + BrowserAccessibility* obj); +#endif + class BrowserAccessibilityMac : public BrowserAccessibility { public: // BrowserAccessibility overrides.
diff --git a/content/browser/accessibility/browser_accessibility_mac.mm b/content/browser/accessibility/browser_accessibility_mac.mm index da1f55e..34475bd 100644 --- a/content/browser/accessibility/browser_accessibility_mac.mm +++ b/content/browser/accessibility/browser_accessibility_mac.mm
@@ -64,13 +64,17 @@ } const BrowserAccessibilityCocoa* -BrowserAccessibility::ToBrowserAccessibilityCocoa() const { - return static_cast<const BrowserAccessibilityMac*>(this)->native_view(); +ToBrowserAccessibilityCocoa(const BrowserAccessibility* obj) { + DCHECK(obj); + DCHECK(obj->IsNative()); + return static_cast<const BrowserAccessibilityMac*>(obj)->native_view(); } -BrowserAccessibilityCocoa* BrowserAccessibility::ToBrowserAccessibilityCocoa() { - return static_cast<BrowserAccessibilityMac*>(this)-> - native_view(); +BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa( + BrowserAccessibility* obj) { + DCHECK(obj); + DCHECK(obj->IsNative()); + return static_cast<BrowserAccessibilityMac*>(obj)->native_view(); } } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_mac_unittest.mm b/content/browser/accessibility/browser_accessibility_mac_unittest.mm index c85957f..0b2511d 100644 --- a/content/browser/accessibility/browser_accessibility_mac_unittest.mm +++ b/content/browser/accessibility/browser_accessibility_mac_unittest.mm
@@ -8,6 +8,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_cocoa.h" +#include "content/browser/accessibility/browser_accessibility_mac.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "testing/gtest/include/gtest/gtest.h" @@ -53,7 +54,7 @@ nil, MakeAXTreeUpdate(root, child1, child2), NULL)); - accessibility_.reset([manager_->GetRoot()->ToBrowserAccessibilityCocoa() + accessibility_.reset([ToBrowserAccessibilityCocoa(manager_->GetRoot()) retain]); }
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index 9c7a316..e527963 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -208,32 +208,32 @@ // the Android system that the accessibility hierarchy rooted at this // node has changed. Java_BrowserAccessibilityManager_handleContentChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); switch (event_type) { case ui::AX_EVENT_LOAD_COMPLETE: Java_BrowserAccessibilityManager_handlePageLoaded( - env, obj.obj(), GetFocus()->GetId()); + env, obj.obj(), GetFocus()->unique_id()); break; case ui::AX_EVENT_FOCUS: Java_BrowserAccessibilityManager_handleFocusChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); break; case ui::AX_EVENT_CHECKED_STATE_CHANGED: Java_BrowserAccessibilityManager_handleCheckStateChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); break; case ui::AX_EVENT_CLICKED: Java_BrowserAccessibilityManager_handleClicked(env, obj.obj(), - node->GetId()); + node->unique_id()); break; case ui::AX_EVENT_SCROLL_POSITION_CHANGED: Java_BrowserAccessibilityManager_handleScrollPositionChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); break; case ui::AX_EVENT_SCROLLED_TO_ANCHOR: Java_BrowserAccessibilityManager_handleScrolledToAnchor( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); break; case ui::AX_EVENT_ALERT: // An alert is a special case of live region. Fall through to the @@ -249,16 +249,16 @@ } case ui::AX_EVENT_TEXT_SELECTION_CHANGED: Java_BrowserAccessibilityManager_handleTextSelectionChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); break; case ui::AX_EVENT_TEXT_CHANGED: case ui::AX_EVENT_VALUE_CHANGED: if (android_node->IsEditableText() && GetFocus() == node) { Java_BrowserAccessibilityManager_handleEditableTextChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); } else if (android_node->IsSlider()) { Java_BrowserAccessibilityManager_handleSliderChanged( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); } break; default: @@ -291,7 +291,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj) { if (GetRoot()) - return static_cast<jint>(GetRoot()->GetId()); + return static_cast<jint>(GetRoot()->unique_id()); else return -1; } @@ -300,7 +300,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - return GetFromID(id) != NULL; + return GetFromUniqueID(id) != NULL; } void BrowserAccessibilityManagerAndroid::HitTest( @@ -316,8 +316,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -328,8 +327,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -340,8 +338,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -353,18 +350,17 @@ const JavaParamRef<jobject>& obj, const JavaParamRef<jobject>& info, jint id) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; if (node->GetParent()) { Java_BrowserAccessibilityManager_setAccessibilityNodeInfoParent( - env, obj, info, node->GetParent()->GetId()); + env, obj, info, node->GetParent()->unique_id()); } for (unsigned i = 0; i < node->PlatformChildCount(); ++i) { Java_BrowserAccessibilityManager_addAccessibilityNodeInfoChild( - env, obj, info, node->InternalGetChild(i)->GetId()); + env, obj, info, node->InternalGetChild(i)->unique_id()); } Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes( env, obj, info, @@ -472,8 +468,7 @@ const JavaParamRef<jobject>& event, jint id, jint event_type) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -575,7 +570,7 @@ void BrowserAccessibilityManagerAndroid::Click(JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibility* node = GetFromID(id); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (node) DoDefaultAction(*node); } @@ -583,7 +578,7 @@ void BrowserAccessibilityManagerAndroid::Focus(JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibility* node = GetFromID(id); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (node) SetFocus(*node); } @@ -598,7 +593,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibility* node = GetFromID(id); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (node) ScrollToMakeVisible(*node, gfx::Rect(node->GetLocation().size())); } @@ -608,7 +603,7 @@ const JavaParamRef<jobject>& obj, jint id, const JavaParamRef<jstring>& value) { - BrowserAccessibility* node = GetFromID(id); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (node) { BrowserAccessibilityManager::SetValue( *node, base::android::ConvertJavaStringToUTF16(env, value)); @@ -621,7 +616,7 @@ jint id, jint start, jint end) { - BrowserAccessibility* node = GetFromID(id); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (node) SetTextSelection(*node, start, end); } @@ -631,7 +626,7 @@ const JavaParamRef<jobject>& obj, jint id, jboolean increment) { - BrowserAccessibility* node = GetFromID(id); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -681,7 +676,7 @@ } Java_BrowserAccessibilityManager_handleHover( - env, obj.obj(), node->GetId()); + env, obj.obj(), node->unique_id()); } jint BrowserAccessibilityManagerAndroid::FindElementType( @@ -690,7 +685,7 @@ jint start_id, const JavaParamRef<jstring>& element_type_str, jboolean forwards) { - BrowserAccessibility* start_node = GetFromID(start_id); + BrowserAccessibilityAndroid* start_node = GetFromUniqueID(start_id); if (!start_node) return 0; @@ -719,7 +714,7 @@ if (tree_search.CountMatches() == 0) return 0; - return tree_search.GetMatchAtIndex(0)->GetId(); + return tree_search.GetMatchAtIndex(0)->unique_id(); } jboolean BrowserAccessibilityManagerAndroid::NextAtGranularity( @@ -729,8 +724,7 @@ jboolean extend_selection, jint id, jint cursor_index) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -759,8 +753,7 @@ jboolean extend_selection, jint id, jint cursor_index) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -880,8 +873,7 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jint id) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -893,8 +885,7 @@ const JavaParamRef<jobject>& obj, jint id, int direction) { - BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( - GetFromID(id)); + BrowserAccessibilityAndroid* node = GetFromUniqueID(id); if (!node) return false; @@ -921,6 +912,12 @@ return false; } +BrowserAccessibilityAndroid* +BrowserAccessibilityManagerAndroid::GetFromUniqueID(int32_t unique_id) { + return static_cast<BrowserAccessibilityAndroid*>( + BrowserAccessibility::GetFromUniqueID(unique_id)); +} + bool RegisterBrowserAccessibilityManager(JNIEnv* env) { return RegisterNativesImpl(env); }
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h index 4bc42b5..816bf0c7 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.h +++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -224,6 +224,8 @@ bool UseRootScrollOffsetsWhenComputingBounds() override; private: + BrowserAccessibilityAndroid* GetFromUniqueID(int32_t unique_id); + // This gives BrowserAccessibilityManager::Create access to the class // constructor. friend class BrowserAccessibilityManager;
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 712de43..0df142e5 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -140,7 +140,7 @@ } } - auto native_node = node->ToBrowserAccessibilityCocoa(); + auto native_node = ToBrowserAccessibilityCocoa(node); DCHECK(native_node); // Refer to |AXObjectCache::postPlatformNotification| in WebKit source code. @@ -187,7 +187,7 @@ BrowserAccessibility* focus = GetFocus(); if (!focus) break; - NSAccessibilityPostNotification(focus->ToBrowserAccessibilityCocoa(), + NSAccessibilityPostNotification(ToBrowserAccessibilityCocoa(focus), mac_notification); if (base::mac::IsOSElCapitanOrLater()) { @@ -203,9 +203,9 @@ return; NSAccessibilityPostNotificationWithUserInfo( - focus->ToBrowserAccessibilityCocoa(), mac_notification, user_info); + ToBrowserAccessibilityCocoa(focus), mac_notification, user_info); NSAccessibilityPostNotificationWithUserInfo( - root->ToBrowserAccessibilityCocoa(), mac_notification, user_info); + ToBrowserAccessibilityCocoa(root), mac_notification, user_info); return; } break; @@ -318,7 +318,7 @@ BrowserAccessibility* focus_object = GetFromID(focus_id); if (focus_object) { focus_object = focus_object->GetClosestPlatformObject(); - auto native_focus_object = focus_object->ToBrowserAccessibilityCocoa(); + auto native_focus_object = ToBrowserAccessibilityCocoa(focus_object); if (native_focus_object) { [user_info setObject:[native_focus_object selectedTextMarkerRange] forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index a60b749..7c2165cb 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -20,10 +20,6 @@ namespace content { -// Map from unique_id_win to BrowserAccessibility -using UniqueIDWinMap = base::hash_map<LONG, BrowserAccessibility*>; -base::LazyInstance<UniqueIDWinMap> g_unique_id_map = LAZY_INSTANCE_INITIALIZER; - // static BrowserAccessibilityManager* BrowserAccessibilityManager::Create( const ui::AXTreeUpdate& initial_tree, @@ -149,7 +145,11 @@ else if (focus_event_on_root_needed_) OnWindowFocused(); - LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); + // Pass the negation of this node's unique id in the |child_id| + // argument to NotifyWinEvent; the AT client will then call get_accChild + // on the HWND's accessibility object and pass it that same id, which + // we can use to retrieve the IAccessible for this node. + LONG child_id = -node->unique_id(); ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id); } @@ -293,13 +293,9 @@ if (!node) return; - if (event_id != EVENT_MIN) { - // Pass the node's unique id in the |child_id| argument to NotifyWinEvent; - // the AT client will then call get_accChild on the HWND's accessibility - // object and pass it that same id, which we can use to retrieve the - // IAccessible for this node. + if (event_id != EVENT_MIN) MaybeCallNotifyWinEvent(event_id, node); - } + // If this is a layout complete notification (sent when a container scrolls) // and there is a descendant tracked object, send a notification on it. @@ -323,8 +319,6 @@ return; if (!obj->IsNative()) return; - LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win(); - g_unique_id_map.Get()[unique_id_win] = obj; } void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXTree* tree, @@ -332,8 +326,6 @@ DCHECK(node); BrowserAccessibility* obj = GetFromAXNode(node); if (obj && obj->IsNative()) { - g_unique_id_map.Get().erase( - obj->ToBrowserAccessibilityWin()->unique_id_win()); if (obj == tracked_scroll_object_) { tracked_scroll_object_->Release(); tracked_scroll_object_ = NULL; @@ -367,7 +359,7 @@ DCHECK(changed_node); BrowserAccessibility* obj = GetFromAXNode(changed_node); if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) - obj->ToBrowserAccessibilityWin()->UpdateStep1ComputeWinAttributes(); + ToBrowserAccessibilityWin(obj)->UpdateStep1ComputeWinAttributes(); } // The next step updates the hypertext of each node, which is a @@ -378,7 +370,7 @@ DCHECK(changed_node); BrowserAccessibility* obj = GetFromAXNode(changed_node); if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) - obj->ToBrowserAccessibilityWin()->UpdateStep2ComputeHypertext(); + ToBrowserAccessibilityWin(obj)->UpdateStep2ComputeHypertext(); } // The third step fires events on nodes based on what's changed - like @@ -394,7 +386,7 @@ DCHECK(changed_node); BrowserAccessibility* obj = GetFromAXNode(changed_node); if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) { - obj->ToBrowserAccessibilityWin()->UpdateStep3FireEvents( + ToBrowserAccessibilityWin(obj)->UpdateStep3FireEvents( changes[i].type == AXTreeDelegate::SUBTREE_CREATED); } } @@ -408,13 +400,4 @@ tracked_scroll_object_->AddRef(); } -BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin( - LONG unique_id_win) { - auto iter = g_unique_id_map.Get().find(unique_id_win); - if (iter == g_unique_id_map.Get().end()) - return nullptr; - - return iter->second->ToBrowserAccessibilityWin(); -} - } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h index b505a63..be0b5d9 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.h +++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -53,10 +53,6 @@ // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed. void TrackScrollingObject(BrowserAccessibilityWin* node); - // Return a pointer to the object corresponding to the given windows-specific - // unique id, does not make a new reference. - BrowserAccessibilityWin* GetFromUniqueIdWin(LONG unique_id_win); - // Called when |accessible_hwnd_| is deleted by its parent. void OnAccessibleHwndDeleted();
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index a78d8b2..bf3b0af 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -42,10 +42,6 @@ const base::char16 BrowserAccessibilityWin::kEmbeddedCharacter = L'\xfffc'; -// static -LONG BrowserAccessibilityWin::next_unique_id_win_ = - base::win::kFirstBrowserAccessibilityManagerAccessibilityId; - // // BrowserAccessibilityRelation // @@ -150,7 +146,7 @@ return E_FAIL; *target = static_cast<IAccessible*>( - result->ToBrowserAccessibilityWin()->NewReference()); + ToBrowserAccessibilityWin(result)->NewReference()); return S_OK; } @@ -207,29 +203,10 @@ return instance->NewReference(); } -const BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() - const { - return static_cast<const BrowserAccessibilityWin*>(this); -} - -BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() { - return static_cast<BrowserAccessibilityWin*>(this); -} - BrowserAccessibilityWin::BrowserAccessibilityWin() : win_attributes_(new WinAttributes()), previous_scroll_x_(0), previous_scroll_y_(0) { - // Start unique IDs at -1 and decrement each time, because get_accChild - // uses positive IDs to enumerate children, so we use negative IDs to - // clearly distinguish between indices and unique IDs. - unique_id_win_ = next_unique_id_win_; - if (next_unique_id_win_ == - base::win::kLastBrowserAccessibilityManagerAccessibilityId) { - next_unique_id_win_ = - base::win::kFirstBrowserAccessibilityManagerAccessibilityId; - } - next_unique_id_win_--; } BrowserAccessibilityWin::~BrowserAccessibilityWin() { @@ -281,7 +258,7 @@ child->lVal = CHILDID_SELF; } else { child->vt = VT_DISPATCH; - child->pdispVal = result->ToBrowserAccessibilityWin()->NewReference(); + child->pdispVal = ToBrowserAccessibilityWin(result)->NewReference(); } return S_OK; } @@ -355,7 +332,7 @@ } end->vt = VT_DISPATCH; - end->pdispVal = result->ToBrowserAccessibilityWin()->NewReference(); + end->pdispVal = ToBrowserAccessibilityWin(result)->NewReference(); return S_OK; } @@ -511,7 +488,7 @@ if (!disp_parent) return E_INVALIDARG; - IAccessible* parent_obj = GetParent()->ToBrowserAccessibilityWin(); + IAccessible* parent_obj = ToBrowserAccessibilityWin(GetParent()); if (parent_obj == NULL) { // This happens if we're the root of the tree; // return the IAccessible for the window. @@ -646,7 +623,7 @@ if (InternalGetChild(i)->HasState(ui::AX_STATE_SELECTED)) { selected->vt = VT_DISPATCH; selected->pdispVal = - InternalGetChild(i)->ToBrowserAccessibilityWin()->NewReference(); + ToBrowserAccessibilityWin(InternalGetChild(i))->NewReference(); return S_OK; } } @@ -661,7 +638,7 @@ if (InternalGetChild(i)->HasState(ui::AX_STATE_SELECTED)) { enum_variant->ItemAt(index)->vt = VT_DISPATCH; enum_variant->ItemAt(index)->pdispVal = - InternalGetChild(i)->ToBrowserAccessibilityWin()->NewReference(); + ToBrowserAccessibilityWin(InternalGetChild(i))->NewReference(); ++index; } } @@ -751,7 +728,7 @@ if (!unique_id) return E_INVALIDARG; - *unique_id = unique_id_win_; + *unique_id = -unique_id_; return S_OK; } @@ -1289,7 +1266,7 @@ int cell_id = unique_cell_ids[cell_index]; BrowserAccessibilityWin* cell = - manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); int col_index; if (cell && cell->GetIntAttribute( @@ -1394,7 +1371,7 @@ for (int i = 0; i < columns; ++i) { int cell_id = cell_ids[row * columns + i]; BrowserAccessibilityWin* cell = - manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) { base::string16 cell_name = cell->GetString16Attribute( ui::AX_ATTR_NAME); @@ -1439,7 +1416,7 @@ GetIntListAttribute(ui::AX_ATTR_CELL_IDS); int cell_id = cell_ids[row * columns + column]; BrowserAccessibilityWin* cell = - manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); int rowspan; if (cell && cell->GetIntAttribute( @@ -1477,7 +1454,7 @@ int cell_id = unique_cell_ids[cell_index]; BrowserAccessibilityWin* cell = - manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); int cell_row_index; if (cell && cell->GetIntAttribute( @@ -1606,7 +1583,7 @@ int cell_id = unique_cell_ids[index]; BrowserAccessibilityWin* cell = - manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); int rowspan; int colspan; if (cell && @@ -1765,7 +1742,7 @@ for (int i = 0; i < rows; ++i) { int cell_id = cell_ids[i * columns + column]; BrowserAccessibilityWin* cell = - manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) (*n_column_header_cells)++; } @@ -1778,7 +1755,7 @@ BrowserAccessibility* cell = manager()->GetFromID(cell_id); if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) { (*cell_accessibles)[index] = static_cast<IAccessible*>( - cell->ToBrowserAccessibilityWin()->NewReference()); + ToBrowserAccessibilityWin(cell)->NewReference()); ++index; } } @@ -1875,7 +1852,7 @@ BrowserAccessibility* cell = manager()->GetFromID(cell_id); if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) { (*cell_accessibles)[index] = static_cast<IAccessible*>( - cell->ToBrowserAccessibilityWin()->NewReference()); + ToBrowserAccessibilityWin(cell)->NewReference()); ++index; } } @@ -1970,7 +1947,7 @@ } *table = static_cast<IAccessibleTable*>( - find_table->ToBrowserAccessibilityWin()->NewReference()); + ToBrowserAccessibilityWin(find_table)->NewReference()); return S_OK; } @@ -2412,7 +2389,7 @@ int32_t id = hyperlinks()[index]; BrowserAccessibilityWin* child = - manager()->GetFromID(id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(id)); if (child) { *hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference()); return S_OK; @@ -2510,7 +2487,7 @@ const auto parent = GetParent(); if (parent) { hypertext_offset = - parent->ToBrowserAccessibilityWin()->GetHypertextOffsetFromChild(*this); + ToBrowserAccessibilityWin(parent)->GetHypertextOffsetFromChild(*this); } *index = static_cast<LONG>(hypertext_offset); return S_OK; @@ -2751,7 +2728,7 @@ *name_space_id = 0; *node_value = SysAllocString(value().c_str()); *num_children = PlatformChildCount(); - *unique_id = unique_id_win_; + *unique_id = -unique_id_; if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || GetRole() == ui::AX_ROLE_WEB_AREA) { @@ -2889,7 +2866,7 @@ if (!node) return E_INVALIDARG; - *node = GetParent()->ToBrowserAccessibilityWin()->NewReference(); + *node = ToBrowserAccessibilityWin(GetParent())->NewReference(); return S_OK; } @@ -2905,7 +2882,7 @@ return S_FALSE; } - *node = PlatformGetChild(0)->ToBrowserAccessibilityWin()->NewReference(); + *node = ToBrowserAccessibilityWin(PlatformGetChild(0))->NewReference(); return S_OK; } @@ -2921,8 +2898,8 @@ return S_FALSE; } - *node = PlatformGetChild(PlatformChildCount() - 1) - ->ToBrowserAccessibilityWin()->NewReference(); + *node = ToBrowserAccessibilityWin( + PlatformGetChild(PlatformChildCount() - 1))->NewReference(); return S_OK; } @@ -2939,8 +2916,8 @@ return S_FALSE; } - *node = GetParent()->InternalGetChild(GetIndexInParent() - 1)-> - ToBrowserAccessibilityWin()->NewReference(); + *node = ToBrowserAccessibilityWin( + GetParent()->InternalGetChild(GetIndexInParent() - 1))->NewReference(); return S_OK; } @@ -2959,8 +2936,8 @@ return S_FALSE; } - *node = GetParent()->InternalGetChild(GetIndexInParent() + 1)-> - ToBrowserAccessibilityWin()->NewReference(); + *node = ToBrowserAccessibilityWin( + GetParent()->InternalGetChild(GetIndexInParent() + 1))->NewReference(); return S_OK; } @@ -2982,7 +2959,7 @@ return S_FALSE; } - *node = child->ToBrowserAccessibilityWin()->NewReference(); + *node = ToBrowserAccessibilityWin(child)->NewReference(); return S_OK; } @@ -3101,7 +3078,7 @@ BrowserAccessibility* node = this; while (node->GetParent()) node = node->GetParent()->manager()->GetRoot(); - return node->ToBrowserAccessibilityWin()->QueryInterface( + return ToBrowserAccessibilityWin(node)->QueryInterface( IID_IAccessible2, object); } @@ -3458,7 +3435,7 @@ // child object it points to. for (unsigned int i = 0; i < PlatformChildCount(); ++i) { BrowserAccessibilityWin* child = - PlatformGetChild(i)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(PlatformGetChild(i)); DCHECK(child); // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. if (child->IsTextOnlyObject()) { @@ -3562,7 +3539,7 @@ // Changing a static text node can affect the IAccessibleText hypertext // of the parent node, so force an update on the parent. - BrowserAccessibilityWin* parent = GetParent()->ToBrowserAccessibilityWin(); + BrowserAccessibilityWin* parent = ToBrowserAccessibilityWin(GetParent()); if (parent && IsTextOnlyObject() && name() != old_win_attributes_->name) { parent->UpdateStep1ComputeWinAttributes(); @@ -3611,10 +3588,10 @@ return this; if (child_id >= 1 && child_id <= static_cast<LONG>(PlatformChildCount())) - return PlatformGetChild(child_id - 1)->ToBrowserAccessibilityWin(); + return ToBrowserAccessibilityWin(PlatformGetChild(child_id - 1)); - return manager()->ToBrowserAccessibilityManagerWin()-> - GetFromUniqueIdWin(child_id); + return ToBrowserAccessibilityWin( + BrowserAccessibility::GetFromUniqueID(-child_id)); } HRESULT BrowserAccessibilityWin::GetStringAttributeAsBstr( @@ -3687,7 +3664,7 @@ const auto parent = GetParent(); if (parent) { hyperlink_index = - parent->ToBrowserAccessibilityWin()->GetHyperlinkIndexFromChild(*this); + ToBrowserAccessibilityWin(parent)->GetHyperlinkIndexFromChild(*this); } if (hyperlink_index >= 0) @@ -3734,7 +3711,7 @@ DCHECK_LT(index_in_parent, static_cast<int32_t>(InternalChildCount())); for (uint32_t i = 0; i < static_cast<uint32_t>(index_in_parent); ++i) { const BrowserAccessibilityWin* sibling = - InternalGetChild(i)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(InternalGetChild(i)); DCHECK(sibling); if (sibling->IsTextOnlyObject()) hypertextOffset += sibling->GetText().size(); @@ -3753,11 +3730,11 @@ int32_t BrowserAccessibilityWin::GetHypertextOffsetFromDescendant( const BrowserAccessibilityWin& descendant) const { - auto parent_object = descendant.GetParent()->ToBrowserAccessibilityWin(); + auto parent_object = ToBrowserAccessibilityWin(descendant.GetParent()); auto current_object = const_cast<BrowserAccessibilityWin*>(&descendant); while (parent_object && parent_object != this) { current_object = parent_object; - parent_object = current_object->GetParent()->ToBrowserAccessibilityWin(); + parent_object = ToBrowserAccessibilityWin(current_object->GetParent()); } if (!parent_object) return -1; @@ -3839,7 +3816,7 @@ int BrowserAccessibilityWin::GetSelectionAnchor() const { int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id; const auto anchor_object = - manager()->GetFromID(anchor_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(anchor_id)); if (!anchor_object) return -1; @@ -3850,7 +3827,7 @@ int BrowserAccessibilityWin::GetSelectionFocus() const { int32_t focus_id = manager()->GetTreeData().sel_focus_object_id; const auto focus_object = - manager()->GetFromID(focus_id)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager()->GetFromID(focus_id)); if (!focus_object) return -1; @@ -4048,7 +4025,7 @@ } BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) { - return manager()->GetFromID(id)->ToBrowserAccessibilityWin(); + return ToBrowserAccessibilityWin(manager()->GetFromID(id)); } bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { @@ -4703,4 +4680,15 @@ win_attributes_->ia2_state = ia2_state; } +BrowserAccessibilityWin* ToBrowserAccessibilityWin(BrowserAccessibility* obj) { + DCHECK(!obj || obj->IsNative()); + return static_cast<BrowserAccessibilityWin*>(obj); +} + +const BrowserAccessibilityWin* +ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { + DCHECK(!obj || obj->IsNative()); + return static_cast<const BrowserAccessibilityWin*>(obj); +} + } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h index adeb16b4..b237be9 100644 --- a/content/browser/accessibility/browser_accessibility_win.h +++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -97,10 +97,6 @@ CONTENT_EXPORT ~BrowserAccessibilityWin() override; - // The Windows-specific unique ID, used as the child ID for MSAA methods - // like NotifyWinEvent, and as the unique ID for IAccessible2 and ISimpleDOM. - LONG unique_id_win() const { return unique_id_win_; } - // Called after an atomic tree update completes. See // BrowserAccessibilityManagerWin::OnAtomicUpdateFinished for more // details on what these do. @@ -867,11 +863,6 @@ void AddRelations(ui::AXIntListAttribute src_attr, const base::string16& iaccessiblerelation_type); - // Windows-specific unique ID (unique within the browser process), - // used for get_accChild, NotifyWinEvent, and as the unique ID for - // IAccessible2 and ISimpleDOM. - LONG unique_id_win_; - struct WinAttributes { WinAttributes(); ~WinAttributes(); @@ -918,9 +909,6 @@ int previous_scroll_x_; int previous_scroll_y_; - // The next unique id to use. - static LONG next_unique_id_win_; - // Give BrowserAccessibility::Create access to our constructor. friend class BrowserAccessibility; friend class BrowserAccessibilityRelation; @@ -928,6 +916,12 @@ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityWin); }; +CONTENT_EXPORT BrowserAccessibilityWin* +ToBrowserAccessibilityWin(BrowserAccessibility* obj); + +CONTENT_EXPORT const BrowserAccessibilityWin* +ToBrowserAccessibilityWin(const BrowserAccessibility* obj); + } // namespace content #endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_WIN_H_
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc index d86b380..b8b3e77 100644 --- a/content/browser/accessibility/browser_accessibility_win_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -161,8 +161,7 @@ MakeAXTreeUpdate(root, button, checkbox), NULL, new CountedBrowserAccessibilityFactory())); ASSERT_EQ(3, CountedBrowserAccessibility::num_instances()); - IAccessible* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); + IAccessible* root_accessible = ToBrowserAccessibilityWin(manager->GetRoot()); IDispatch* root_iaccessible = NULL; IDispatch* child1_iaccessible = NULL; base::win::ScopedVariant childid_self(CHILDID_SELF); @@ -215,7 +214,7 @@ // value. base::win::ScopedVariant one(1); base::win::ScopedComPtr<IDispatch> text_dispatch; - HRESULT hr = manager->GetRoot()->ToBrowserAccessibilityWin()->get_accChild( + HRESULT hr = ToBrowserAccessibilityWin(manager->GetRoot())->get_accChild( one, text_dispatch.Receive()); ASSERT_EQ(S_OK, hr); @@ -249,7 +248,7 @@ // Query for the text IAccessible and verify that it now returns "new text" // as its value. - hr = manager->GetRoot()->ToBrowserAccessibilityWin()->get_accChild( + hr = ToBrowserAccessibilityWin(manager->GetRoot())->get_accChild( one, text_dispatch.Receive()); ASSERT_EQ(S_OK, hr); @@ -396,12 +395,12 @@ ASSERT_EQ(7, CountedBrowserAccessibility::num_instances()); BrowserAccessibilityWin* root_obj = - manager->GetRoot()->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager->GetRoot()); ASSERT_NE(nullptr, root_obj); ASSERT_EQ(1U, root_obj->PlatformChildCount()); BrowserAccessibilityWin* text_field_obj = - root_obj->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_obj->PlatformGetChild(0)); ASSERT_NE(nullptr, text_field_obj); long text_len; @@ -516,7 +515,7 @@ ASSERT_EQ(3, CountedBrowserAccessibility::num_instances()); BrowserAccessibilityWin* root_obj = - manager->GetRoot()->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager->GetRoot()); long text_len; EXPECT_EQ(S_OK, root_obj->get_nCharacters(&text_len)); @@ -637,7 +636,7 @@ ASSERT_EQ(9, CountedBrowserAccessibility::num_instances()); BrowserAccessibilityWin* root_obj = - manager->GetRoot()->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager->GetRoot()); long text_len; EXPECT_EQ(S_OK, root_obj->get_nCharacters(&text_len)); @@ -821,8 +820,8 @@ 1 << ui::AX_STATE_ENABLED, root->GetState()); - LONG unique_id_win = root->ToBrowserAccessibilityWin()->unique_id_win(); - ASSERT_EQ(root, manager->GetFromUniqueIdWin(unique_id_win)); + int32_t unique_id = ToBrowserAccessibilityWin(root)->unique_id(); + ASSERT_EQ(root, BrowserAccessibility::GetFromUniqueID(unique_id)); } TEST_F(BrowserAccessibilityTest, TestIA2Attributes) { @@ -855,13 +854,13 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); - ASSERT_NE(nullptr, root_accessible); - ASSERT_EQ(2U, root_accessible->PlatformChildCount()); + ToBrowserAccessibilityWin(manager->GetRoot()); + ASSERT_NE(nullptr, root_accessible); + ASSERT_EQ(2U, root_accessible->PlatformChildCount()); - BrowserAccessibilityWin* pseudo_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); - ASSERT_NE(nullptr, pseudo_accessible); + BrowserAccessibilityWin* pseudo_accessible = + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); + ASSERT_NE(nullptr, pseudo_accessible); base::win::ScopedBstr attributes; HRESULT hr = pseudo_accessible->get_attributes(attributes.Receive()); @@ -871,7 +870,7 @@ EXPECT_EQ(L"display:none;tag:<pseudo\\:before>;", attributes_str); BrowserAccessibilityWin* checkbox_accessible = - root_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, checkbox_accessible); attributes.Reset(); @@ -962,27 +961,27 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager->GetRoot()); ASSERT_NE(nullptr, root_accessible); ASSERT_EQ(5U, root_accessible->PlatformChildCount()); BrowserAccessibilityWin* combo_box_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, combo_box_accessible); manager->SetFocusLocallyForTesting(combo_box_accessible); ASSERT_EQ(combo_box_accessible, - manager->GetFocus()->ToBrowserAccessibilityWin()); + ToBrowserAccessibilityWin(manager->GetFocus())); BrowserAccessibilityWin* search_box_accessible = - root_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, search_box_accessible); BrowserAccessibilityWin* text_field_accessible = - root_accessible->PlatformGetChild(2)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(2)); ASSERT_NE(nullptr, text_field_accessible); BrowserAccessibilityWin* link_accessible = - root_accessible->PlatformGetChild(3)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(3)); ASSERT_NE(nullptr, link_accessible); BrowserAccessibilityWin* slider_accessible = - root_accessible->PlatformGetChild(4)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(4)); ASSERT_NE(nullptr, slider_accessible); base::win::ScopedVariant childid_self(CHILDID_SELF); @@ -1124,15 +1123,15 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager->GetRoot()); ASSERT_NE(nullptr, root_accessible); ASSERT_EQ(2U, root_accessible->PlatformChildCount()); BrowserAccessibilityWin* textarea_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, textarea_accessible); BrowserAccessibilityWin* text_field_accessible = - root_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, text_field_accessible); base::win::ScopedComPtr<IAccessibleText> textarea_object; @@ -1223,18 +1222,18 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); - ASSERT_NE(nullptr, root_accessible); - ASSERT_EQ(2U, root_accessible->PlatformChildCount()); + ToBrowserAccessibilityWin(manager->GetRoot()); + ASSERT_NE(nullptr, root_accessible); + ASSERT_EQ(2U, root_accessible->PlatformChildCount()); BrowserAccessibilityWin* combo_box_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, combo_box_accessible); manager->SetFocusLocallyForTesting(combo_box_accessible); ASSERT_EQ(combo_box_accessible, - manager->GetFocus()->ToBrowserAccessibilityWin()); + ToBrowserAccessibilityWin(manager->GetFocus())); BrowserAccessibilityWin* text_field_accessible = - root_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, text_field_accessible); // -2 is never a valid offset. @@ -1255,7 +1254,7 @@ // Move the focus to the text field. manager->SetFocusLocallyForTesting(text_field_accessible); ASSERT_EQ(text_field_accessible, - manager->GetFocus()->ToBrowserAccessibilityWin()); + ToBrowserAccessibilityWin(manager->GetFocus())); // The caret should not have moved. hr = text_field_accessible->get_caretOffset(&caret_offset); @@ -1343,12 +1342,12 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); - ASSERT_NE(nullptr, root_accessible); - ASSERT_EQ(1U, root_accessible->PlatformChildCount()); + ToBrowserAccessibilityWin(manager->GetRoot()); + ASSERT_NE(nullptr, root_accessible); + ASSERT_EQ(1U, root_accessible->PlatformChildCount()); BrowserAccessibilityWin* div_editable_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, div_editable_accessible); ASSERT_EQ(2U, div_editable_accessible->PlatformChildCount()); @@ -1369,18 +1368,18 @@ // Move the focus to the content editable. manager->SetFocusLocallyForTesting(div_editable_accessible); ASSERT_EQ(div_editable_accessible, - manager->GetFocus()->ToBrowserAccessibilityWin()); + ToBrowserAccessibilityWin(manager->GetFocus())); BrowserAccessibilityWin* text_accessible = - div_editable_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(div_editable_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, text_accessible); BrowserAccessibilityWin* link_accessible = - div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(div_editable_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, link_accessible); ASSERT_EQ(1U, link_accessible->PlatformChildCount()); BrowserAccessibilityWin* link_text_accessible = - link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(link_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, link_text_accessible); // The caret should not have moved. @@ -1461,12 +1460,12 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); - ASSERT_NE(nullptr, root_accessible); - ASSERT_EQ(1U, root_accessible->PlatformChildCount()); + ToBrowserAccessibilityWin(manager->GetRoot()); + ASSERT_NE(nullptr, root_accessible); + ASSERT_EQ(1U, root_accessible->PlatformChildCount()); BrowserAccessibilityWin* div_editable_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, div_editable_accessible); ASSERT_EQ(2U, div_editable_accessible->PlatformChildCount()); @@ -1477,15 +1476,15 @@ LONG selection_end = -2; BrowserAccessibilityWin* text_accessible = - div_editable_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(div_editable_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, text_accessible); BrowserAccessibilityWin* link_accessible = - div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(div_editable_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, link_accessible); ASSERT_EQ(1U, link_accessible->PlatformChildCount()); BrowserAccessibilityWin* link_text_accessible = - link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(link_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, link_text_accessible); // get_nSelections should work on all objects. @@ -1535,7 +1534,7 @@ // Move the focus to the content editable. manager->SetFocusLocallyForTesting(div_editable_accessible); ASSERT_EQ(div_editable_accessible, - manager->GetFocus()->ToBrowserAccessibilityWin()); + ToBrowserAccessibilityWin(manager->GetFocus())); // The caret should not have moved. hr = div_editable_accessible->get_caretOffset(&caret_offset); @@ -1597,20 +1596,20 @@ ASSERT_NE(nullptr, manager->GetRoot()); BrowserAccessibilityWin* root_accessible = - manager->GetRoot()->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(manager->GetRoot()); ASSERT_NE(nullptr, root_accessible); ASSERT_EQ(1U, root_accessible->PlatformChildCount()); BrowserAccessibilityWin* div_accessible = - root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, div_accessible); ASSERT_EQ(2U, div_accessible->PlatformChildCount()); BrowserAccessibilityWin* text_accessible = - div_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(div_accessible->PlatformGetChild(0)); ASSERT_NE(nullptr, text_accessible); BrowserAccessibilityWin* link_accessible = - div_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin(); + ToBrowserAccessibilityWin(div_accessible->PlatformGetChild(1)); ASSERT_NE(nullptr, link_accessible); // -1 is never a valid value. @@ -1817,9 +1816,9 @@ new CountedBrowserAccessibilityFactory())); BrowserAccessibility* root = manager->GetRoot(); - LONG root_unique_id = root->ToBrowserAccessibilityWin()->unique_id_win(); + int32_t root_unique_id = root->unique_id(); BrowserAccessibility* child = root->PlatformGetChild(0); - LONG child_unique_id = child->ToBrowserAccessibilityWin()->unique_id_win(); + int32_t child_unique_id = child->unique_id(); // Now destroy that original tree and create a new tree. manager.reset( @@ -1828,37 +1827,37 @@ nullptr, new CountedBrowserAccessibilityFactory())); root = manager->GetRoot(); - LONG root_unique_id_2 = root->ToBrowserAccessibilityWin()->unique_id_win(); + int32_t root_unique_id_2 = root->unique_id(); child = root->PlatformGetChild(0); - LONG child_unique_id_2 = child->ToBrowserAccessibilityWin()->unique_id_win(); + int32_t child_unique_id_2 = child->unique_id(); // The nodes in the new tree should not have the same ids. EXPECT_NE(root_unique_id, root_unique_id_2); EXPECT_NE(child_unique_id, child_unique_id_2); // Trying to access the unique IDs of the old, deleted objects should fail. - base::win::ScopedVariant old_root_variant(root_unique_id); + base::win::ScopedVariant old_root_variant(-root_unique_id); base::win::ScopedComPtr<IDispatch> old_root_dispatch; - HRESULT hr = root->ToBrowserAccessibilityWin()->get_accChild( + HRESULT hr = ToBrowserAccessibilityWin(root)->get_accChild( old_root_variant, old_root_dispatch.Receive()); EXPECT_EQ(E_INVALIDARG, hr); - base::win::ScopedVariant old_child_variant(child_unique_id); + base::win::ScopedVariant old_child_variant(-child_unique_id); base::win::ScopedComPtr<IDispatch> old_child_dispatch; - hr = root->ToBrowserAccessibilityWin()->get_accChild( + hr = ToBrowserAccessibilityWin(root)->get_accChild( old_child_variant, old_child_dispatch.Receive()); EXPECT_EQ(E_INVALIDARG, hr); // Trying to access the unique IDs of the new objects should succeed. - base::win::ScopedVariant new_root_variant(root_unique_id_2); + base::win::ScopedVariant new_root_variant(-root_unique_id_2); base::win::ScopedComPtr<IDispatch> new_root_dispatch; - hr = root->ToBrowserAccessibilityWin()->get_accChild( + hr = ToBrowserAccessibilityWin(root)->get_accChild( new_root_variant, new_root_dispatch.Receive()); EXPECT_EQ(S_OK, hr); - base::win::ScopedVariant new_child_variant(child_unique_id_2); + base::win::ScopedVariant new_child_variant(-child_unique_id_2); base::win::ScopedComPtr<IDispatch> new_child_dispatch; - hr = root->ToBrowserAccessibilityWin()->get_accChild( + hr = ToBrowserAccessibilityWin(root)->get_accChild( new_child_variant, new_child_dispatch.Receive()); EXPECT_EQ(S_OK, hr); }
diff --git a/content/browser/appcache/appcache_url_request_job.cc b/content/browser/appcache/appcache_url_request_job.cc index 05fe008b..35728e66 100644 --- a/content/browser/appcache/appcache_url_request_job.cc +++ b/content/browser/appcache/appcache_url_request_job.cc
@@ -433,6 +433,12 @@ return net::ERR_IO_PENDING; } +net::HostPortPair AppCacheURLRequestJob::GetSocketAddress() const { + if (!http_info()) + return net::HostPortPair(); + return http_info()->socket_address; +} + void AppCacheURLRequestJob::SetExtraRequestHeaders( const net::HttpRequestHeaders& headers) { std::string value;
diff --git a/content/browser/appcache/appcache_url_request_job.h b/content/browser/appcache/appcache_url_request_job.h index 057c13b..5b872376 100644 --- a/content/browser/appcache/appcache_url_request_job.h +++ b/content/browser/appcache/appcache_url_request_job.h
@@ -152,6 +152,7 @@ bool GetCharset(std::string* charset) override; void GetResponseInfo(net::HttpResponseInfo* info) override; int ReadRawData(net::IOBuffer* buf, int buf_size) override; + net::HostPortPair GetSocketAddress() const override; // Sets extra request headers for Job types that support request headers. // This is how we get informed of range-requests.
diff --git a/content/browser/frame_host/frame_mojo_shell.cc b/content/browser/frame_host/frame_mojo_shell.cc index 8b54af6..de37229 100644 --- a/content/browser/frame_host/frame_mojo_shell.cc +++ b/content/browser/frame_host/frame_mojo_shell.cc
@@ -48,8 +48,7 @@ // drop it and replace it with services we provide in the browser. In the // future we may need to support both. void FrameMojoShell::Connect( - const mojo::String& application_name, - const mojo::String& user_id, + mojo::shell::mojom::IdentityPtr target, mojo::shell::mojom::InterfaceProviderRequest services, mojo::shell::mojom::InterfaceProviderPtr /* exposed_services */, const mojo::shell::mojom::Connector::ConnectCallback& callback) { @@ -60,7 +59,7 @@ GetProxy(&frame_services)); MojoShellContext::ConnectToApplication( - application_name, + target->name, frame_host_->GetSiteInstance()->GetSiteURL().spec(), std::move(services), std::move(frame_services), callback); }
diff --git a/content/browser/frame_host/frame_mojo_shell.h b/content/browser/frame_host/frame_mojo_shell.h index c243345..f0827e57 100644 --- a/content/browser/frame_host/frame_mojo_shell.h +++ b/content/browser/frame_host/frame_mojo_shell.h
@@ -29,8 +29,7 @@ private: // mojo::Connector: void Connect( - const mojo::String& application_name, - const mojo::String& user_id, + mojo::shell::mojom::IdentityPtr target, mojo::shell::mojom::InterfaceProviderRequest services, mojo::shell::mojom::InterfaceProviderPtr exposed_services, const mojo::shell::mojom::Connector::ConnectCallback& callback) override;
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 7ef7ca4..f9b793f 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -14,7 +14,6 @@ #include "content/browser/frame_host/navigation_request.h" #include "content/browser/frame_host/navigator.h" #include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/browser/frame_host/traced_frame_tree_node.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/frame_messages.h" #include "content/common/site_isolation_policy.h" @@ -106,12 +105,6 @@ g_frame_tree_node_id_map.Get().insert( std::make_pair(frame_tree_node_id_, this)); CHECK(result.second); - - TRACE_EVENT_OBJECT_CREATED_WITH_ID( - "navigation", "FrameTreeNode", - TRACE_ID_WITH_SCOPE("FrameTreeNode", frame_tree_node_id_)); - TraceSnapshot(); - base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this); } FrameTreeNode::~FrameTreeNode() { @@ -123,11 +116,6 @@ opener_->RemoveObserver(opener_observer_.get()); g_frame_tree_node_id_map.Get().erase(frame_tree_node_id_); - - TRACE_EVENT_OBJECT_DELETED_WITH_ID( - "navigation", "FrameTreeNode", - TRACE_ID_WITH_SCOPE("FrameTreeNode", frame_tree_node_id_)); - base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(this); } void FrameTreeNode::AddObserver(Observer* observer) { @@ -184,7 +172,6 @@ void FrameTreeNode::ResetForNewProcess() { current_frame_host()->set_last_committed_url(GURL()); - TraceSnapshot(); // Remove child nodes from the tree, then delete them. This destruction // operation will notify observers. @@ -210,7 +197,6 @@ if (!has_committed_real_load_ && url != GURL(url::kAboutBlankURL)) has_committed_real_load_ = true; current_frame_host()->set_last_committed_url(url); - TraceSnapshot(); } void FrameTreeNode::SetCurrentOrigin(const url::Origin& origin) { @@ -462,16 +448,4 @@ } } -void FrameTreeNode::OnTraceLogEnabled() { - TraceSnapshot(); -} - -void FrameTreeNode::TraceSnapshot() const { - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( - "navigation", "FrameTreeNode", - TRACE_ID_WITH_SCOPE("FrameTreeNode", frame_tree_node_id_), - scoped_ptr<base::trace_event::ConvertableToTraceFormat>( - new TracedFrameTreeNode(*this))); -} - } // namespace content
diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h index fda8ecd..c108da5 100644 --- a/content/browser/frame_host/frame_tree_node.h +++ b/content/browser/frame_host/frame_tree_node.h
@@ -32,8 +32,7 @@ // of those frames. We are mirroring this tree in the browser process. This // class represents a node in this tree and is a wrapper for all objects that // are frame-specific (as opposed to page-specific). -class CONTENT_EXPORT FrameTreeNode : - public base::trace_event::TraceLog::EnabledStateObserver { +class CONTENT_EXPORT FrameTreeNode { public: class Observer { public: @@ -65,7 +64,7 @@ const std::string& unique_name, const blink::WebFrameOwnerProperties& frame_owner_properties); - ~FrameTreeNode() override; + ~FrameTreeNode(); void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -268,17 +267,11 @@ // FrameTreeNode. void BeforeUnloadCanceled(); - // TraceLog::EnabledStateObserver - void OnTraceLogEnabled() override; - void OnTraceLogDisabled() override {} - private: class OpenerDestroyedObserver; void set_parent(FrameTreeNode* parent) { parent_ = parent; } - void TraceSnapshot() const; - // The next available browser-global FrameTreeNode ID. static int next_frame_tree_node_id_;
diff --git a/content/browser/frame_host/traced_frame_tree_node.cc b/content/browser/frame_host/traced_frame_tree_node.cc deleted file mode 100644 index fc27dc5d..0000000 --- a/content/browser/frame_host/traced_frame_tree_node.cc +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/frame_host/traced_frame_tree_node.h" - -#include "base/command_line.h" -#include "base/json/json_writer.h" -#include "base/strings/stringprintf.h" -#include "content/browser/frame_host/frame_tree.h" -#include "content/public/common/content_switches.h" -#include "url/gurl.h" - -namespace content { - -TracedFrameTreeNode::TracedFrameTreeNode(const FrameTreeNode& node) - : parent_node_id_(-1), - process_id_(-1), - routing_id_(-1) { - FrameTreeNode* parent = node.parent(); - if (parent) - parent_node_id_ = parent->frame_tree_node_id(); - - RenderFrameHostImpl* current_frame_host = node.current_frame_host(); - if (!current_frame_host) - return; - - if (current_frame_host->last_committed_url().is_valid()) - url_ = current_frame_host->last_committed_url().spec(); - - base::ProcessHandle process_handle = - current_frame_host->GetProcess()->GetHandle(); - if (process_handle == base::kNullProcessHandle) - return; - - // On Windows, |rph->GetHandle()| does not duplicate ownership - // of the process handle and the render host still retains it. Therefore, we - // cannot create a base::Process object, which provides a proper way to get a - // process id, from the handle. For a stopgap, we use this deprecated - // function that does not require the ownership (http://crbug.com/417532). - process_id_ = base::GetProcId(process_handle); - - routing_id_ = current_frame_host->GetRoutingID(); - DCHECK_NE(routing_id_, MSG_ROUTING_NONE); -} - -TracedFrameTreeNode::~TracedFrameTreeNode() { -} - -void TracedFrameTreeNode::AppendAsTraceFormat(std::string* out) const { - scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); - - if (parent_node_id_ >= 0) { - scoped_ptr<base::DictionaryValue> ref(new base::DictionaryValue()); - ref->SetString("id_ref", base::StringPrintf("0x%x", parent_node_id_)); - ref->SetString("scope", "FrameTreeNode"); - value->Set("parent", std::move(ref)); - } - - if (process_id_ >= 0) { - scoped_ptr<base::DictionaryValue> ref(new base::DictionaryValue()); - ref->SetInteger("pid_ref", process_id_); - ref->SetString("id_ref", base::StringPrintf("0x%x", routing_id_)); - ref->SetString("scope", "RenderFrame"); - value->Set("RenderFrame", std::move(ref)); - } - - if (!url_.empty()) - value->SetString("url", url_); - - std::string tmp; - base::JSONWriter::Write(*value, &tmp); - *out += tmp; -} - -} // content
diff --git a/content/browser/frame_host/traced_frame_tree_node.h b/content/browser/frame_host/traced_frame_tree_node.h deleted file mode 100644 index 79c2a80..0000000 --- a/content/browser/frame_host/traced_frame_tree_node.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/macros.h" -#include "base/memory/scoped_vector.h" -#include "base/trace_event/trace_event_impl.h" -#include "base/values.h" -#include "content/common/content_export.h" - -namespace content { - -class FrameTree; -class FrameTreeNode; - -// This is a temporary container used when tracing snapshots of FrameTree -// objects. When a snapshot of a FrameTree is taken, a TracedFrameTreeNode is -// created and stored by the tracing system until the trace is dumped. -class CONTENT_EXPORT TracedFrameTreeNode : - public base::trace_event::ConvertableToTraceFormat { - public: - TracedFrameTreeNode(const FrameTreeNode& node); - void AppendAsTraceFormat(std::string* out) const override; - - private: - ~TracedFrameTreeNode() override; - - int parent_node_id_; - std::string url_; - int process_id_; - int routing_id_; - - DISALLOW_COPY_AND_ASSIGN(TracedFrameTreeNode); -}; - -} // content
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 5530aaa..eb2d69b81 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -220,7 +220,7 @@ if (IsZeroCopyUploadEnabled()) return false; const auto& command_line = *base::CommandLine::ForCurrentProcess(); - return command_line.HasSwitch(switches::kEnablePartialRaster); + return !command_line.HasSwitch(switches::kDisablePartialRaster); } bool IsGpuMemoryBufferCompositorResourcesEnabled() {
diff --git a/content/browser/mojo/mojo_shell_client_host.cc b/content/browser/mojo/mojo_shell_client_host.cc index 69f1cc5c..e762c225 100644 --- a/content/browser/mojo/mojo_shell_client_host.cc +++ b/content/browser/mojo/mojo_shell_client_host.cc
@@ -124,8 +124,11 @@ factory.Bind(mojo::InterfacePtrInfo<mojo::shell::mojom::ShellClientFactory>( std::move(request_pipe), 0u)); - shell->CreateInstance(std::move(factory), url, - mojo::shell::mojom::kInheritUserID, + mojo::shell::mojom::IdentityPtr target(mojo::shell::mojom::Identity::New()); + target->name = url; + target->user_id = mojo::shell::mojom::kInheritUserID; + target->instance = ""; + shell->CreateInstance(std::move(factory), std::move(target), CreateCapabilityFilterForRenderer(), std::move(request), base::Bind(&OnConnectionComplete));
diff --git a/content/browser/mojo/mojo_shell_context.cc b/content/browser/mojo/mojo_shell_context.cc index 134db56..19b53fa 100644 --- a/content/browser/mojo/mojo_shell_context.cc +++ b/content/browser/mojo/mojo_shell_context.cc
@@ -26,9 +26,9 @@ #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/string.h" #include "mojo/shell/connect_params.h" -#include "mojo/shell/identity.h" #include "mojo/shell/loader.h" #include "mojo/shell/native_runner.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/cpp/shell_client.h" #include "mojo/shell/public/interfaces/connector.mojom.h" #include "mojo/shell/runner/host/in_process_native_runner.h" @@ -285,15 +285,9 @@ const mojo::shell::mojom::Connector::ConnectCallback& callback) { scoped_ptr<mojo::shell::ConnectParams> params(new mojo::shell::ConnectParams); // TODO(beng): kRootUserID is obviously wrong. - // TODO(beng): We need to set a permissive filter here temporarily because - // content is known as a bogus system: name that the application - // manager doesn't understand. - mojo::shell::Identity source_id( - requestor_name, std::string(), mojo::shell::mojom::kRootUserID); - source_id.set_filter(mojo::shell::GetPermissiveCapabilityFilter()); + mojo::Identity source_id(requestor_name, mojo::shell::mojom::kRootUserID); params->set_source(source_id); - params->set_target(mojo::shell::Identity( - name, std::string(), mojo::shell::mojom::kRootUserID)); + params->set_target(mojo::Identity(name, mojo::shell::mojom::kRootUserID)); params->set_remote_interfaces(std::move(request)); params->set_local_interfaces(std::move(exposed_services)); params->set_connect_callback(callback);
diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc index ef75724..a2eb895 100644 --- a/content/browser/push_messaging/push_messaging_message_filter.cc +++ b/content/browser/push_messaging/push_messaging_message_filter.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram.h" @@ -28,7 +27,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/child_process_host.h" #include "content/public/common/console_message_level.h" -#include "content/public/common/content_switches.h" #include "content/public/common/push_messaging_status.h" #include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" @@ -252,7 +250,8 @@ void PushMessagingMessageFilter::OnSubscribeFromDocument( int render_frame_id, int request_id, - const PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, int64_t service_worker_registration_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // TODO(mvanouwerkerk): Validate arguments? @@ -260,7 +259,7 @@ data.request_id = request_id; data.service_worker_registration_id = service_worker_registration_id; data.render_frame_id = render_frame_id; - data.user_visible = options.user_visible_only; + data.user_visible = user_visible; ServiceWorkerRegistration* service_worker_registration = service_worker_context_->GetLiveRegistration( @@ -274,20 +273,20 @@ service_worker_context_->StoreRegistrationUserData( service_worker_registration_id, data.requesting_origin, - kPushSenderIdServiceWorkerKey, options.sender_info, - base::Bind(&PushMessagingMessageFilter::DidPersistSenderInfo, - weak_factory_io_to_io_.GetWeakPtr(), data, options)); + kPushSenderIdServiceWorkerKey, sender_id, + base::Bind(&PushMessagingMessageFilter::DidPersistSenderId, + weak_factory_io_to_io_.GetWeakPtr(), data, sender_id)); } void PushMessagingMessageFilter::OnSubscribeFromWorker( int request_id, int64_t service_worker_registration_id, - const PushSubscriptionOptions& options) { + bool user_visible) { DCHECK_CURRENTLY_ON(BrowserThread::IO); RegisterData data; data.request_id = request_id; data.service_worker_registration_id = service_worker_registration_id; - data.user_visible = options.user_visible_only; + data.user_visible = user_visible; ServiceWorkerRegistration* service_worker_registration = service_worker_context_->GetLiveRegistration( @@ -298,35 +297,34 @@ } data.requesting_origin = service_worker_registration->pattern().GetOrigin(); - // If there is a sender_info in the subscription options, it will be used, - // otherwise the registration sender_info will be used. - CheckForExistingRegistration(data, options); + // This sender_id will be ignored; instead it will be fetched from storage. + CheckForExistingRegistration(data, std::string() /* sender_id */); } -void PushMessagingMessageFilter::DidPersistSenderInfo( +void PushMessagingMessageFilter::DidPersistSenderId( const RegisterData& data, - const PushSubscriptionOptions& options, + const std::string& sender_id, ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (service_worker_status != SERVICE_WORKER_OK) SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_STORAGE_ERROR); else - CheckForExistingRegistration(data, options); + CheckForExistingRegistration(data, sender_id); } void PushMessagingMessageFilter::CheckForExistingRegistration( const RegisterData& data, - const PushSubscriptionOptions& options) { + const std::string& sender_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); service_worker_context_->GetRegistrationUserData( data.service_worker_registration_id, kPushRegistrationIdServiceWorkerKey, base::Bind(&PushMessagingMessageFilter::DidCheckForExistingRegistration, - weak_factory_io_to_io_.GetWeakPtr(), data, options)); + weak_factory_io_to_io_.GetWeakPtr(), data, sender_id)); } void PushMessagingMessageFilter::DidCheckForExistingRegistration( const RegisterData& data, - const PushSubscriptionOptions& options, + const std::string& sender_id, const std::string& push_registration_id, ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -347,11 +345,11 @@ // service_worker_status != SERVICE_WORKER_ERROR_NOT_FOUND instead of // attempting to do a fresh registration? // https://w3c.github.io/push-api/#widl-PushRegistrationManager-register-Promise-PushRegistration - if (!options.sender_info.empty()) { + if (data.FromDocument()) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()), data, - options.sender_info)); + sender_id)); } else { service_worker_context_->GetRegistrationUserData( data.service_worker_registration_id, kPushSenderIdServiceWorkerKey, @@ -394,7 +392,7 @@ void PushMessagingMessageFilter::Core::RegisterOnUI( const PushMessagingMessageFilter::RegisterData& data, - const std::string& sender_info) { + const std::string& sender_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); PushMessagingService* push_service = service(); if (!push_service) { @@ -440,18 +438,16 @@ return; } - PushSubscriptionOptions options; - options.user_visible_only = data.user_visible; - options.sender_info = sender_info; if (data.FromDocument()) { push_service->SubscribeFromDocument( - data.requesting_origin, data.service_worker_registration_id, - render_process_id_, data.render_frame_id, options, + data.requesting_origin, data.service_worker_registration_id, sender_id, + render_process_id_, data.render_frame_id, data.user_visible, base::Bind(&Core::DidRegister, weak_factory_ui_to_ui_.GetWeakPtr(), data)); } else { push_service->SubscribeFromWorker( - data.requesting_origin, data.service_worker_registration_id, options, + data.requesting_origin, data.service_worker_registration_id, sender_id, + data.user_visible, base::Bind(&Core::DidRegister, weak_factory_ui_to_ui_.GetWeakPtr(), data)); }
diff --git a/content/browser/push_messaging/push_messaging_message_filter.h b/content/browser/push_messaging/push_messaging_message_filter.h index d2db18a..aba0b34 100644 --- a/content/browser/push_messaging/push_messaging_message_filter.h +++ b/content/browser/push_messaging/push_messaging_message_filter.h
@@ -23,7 +23,6 @@ class PushMessagingService; class ServiceWorkerContextWrapper; -struct PushSubscriptionOptions; extern const char kPushSenderIdServiceWorkerKey[]; extern const char kPushRegistrationIdServiceWorkerKey[]; @@ -51,25 +50,26 @@ void OnSubscribeFromDocument(int render_frame_id, int request_id, - const PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, int64_t service_worker_registration_id); void OnSubscribeFromWorker(int request_id, int64_t service_worker_registration_id, - const PushSubscriptionOptions& options); + bool user_visible); - void DidPersistSenderInfo(const RegisterData& data, - const PushSubscriptionOptions& options, - ServiceWorkerStatusCode service_worker_status); + void DidPersistSenderId(const RegisterData& data, + const std::string& sender_id, + ServiceWorkerStatusCode service_worker_status); // sender_id is ignored if data.FromDocument() is false. void CheckForExistingRegistration(const RegisterData& data, - const PushSubscriptionOptions& options); + const std::string& sender_id); // sender_id is ignored if data.FromDocument() is false. void DidCheckForExistingRegistration( const RegisterData& data, - const PushSubscriptionOptions& options, + const std::string& sender_id, const std::string& push_registration_id, ServiceWorkerStatusCode service_worker_status);
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc index 9e230574..f99cb38 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.cc +++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -181,7 +181,7 @@ return static_cast<LRESULT>(0L); base::win::ScopedComPtr<IAccessible> root( - manager->GetRoot()->ToBrowserAccessibilityWin()); + ToBrowserAccessibilityWin(manager->GetRoot())); return LresultFromObject(IID_IAccessible, w_param, static_cast<IAccessible*>(root.Detach())); }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 17ce1b5..34f50aa 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1283,8 +1283,8 @@ if (IsZeroCopyUploadEnabled()) command_line->AppendSwitch(switches::kEnableZeroCopy); - if (IsPartialRasterEnabled()) - command_line->AppendSwitch(switches::kEnablePartialRaster); + if (!IsPartialRasterEnabled()) + command_line->AppendSwitch(switches::kDisablePartialRaster); if (IsForceGpuRasterizationEnabled()) command_line->AppendSwitch(switches::kForceGpuRasterization);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 3a46b4c..27e1809f 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -747,7 +747,7 @@ BrowserAccessibilityManager* manager = host_->GetOrCreateRootBrowserAccessibilityManager(); if (manager) - return manager->GetRoot()->ToBrowserAccessibilityWin(); + return ToBrowserAccessibilityWin(manager->GetRoot()); #endif NOTIMPLEMENTED();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 7baa14a..1675b98 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -31,6 +31,7 @@ #include "base/sys_info.h" #include "base/trace_event/trace_event.h" #import "content/browser/accessibility/browser_accessibility_cocoa.h" +#import "content/browser/accessibility/browser_accessibility_mac.h" #include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "content/browser/bad_message.h" #import "content/browser/cocoa/system_hotkey_helper_mac.h" @@ -2823,8 +2824,8 @@ if (([attribute isEqualToString:NSAccessibilityChildrenAttribute] || [attribute isEqualToString:NSAccessibilityContentsAttribute]) && manager) { - return [NSArray arrayWithObjects:manager-> - GetRoot()->ToBrowserAccessibilityCocoa(), nil]; + return [NSArray arrayWithObjects:ToBrowserAccessibilityCocoa( + manager->GetRoot()), nil]; } else if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { return NSAccessibilityScrollAreaRole; } @@ -2849,7 +2850,7 @@ NSPoint localPoint = [self convertPoint:pointInWindow fromView:nil]; localPoint.y = NSHeight([self bounds]) - localPoint.y; BrowserAccessibilityCocoa* root = - manager->GetRoot()->ToBrowserAccessibilityCocoa(); + ToBrowserAccessibilityCocoa(manager->GetRoot()); id obj = [root accessibilityHitTest:localPoint]; return obj; } @@ -2867,7 +2868,7 @@ ->GetRootBrowserAccessibilityManager(); // Only child is root. if (manager && - manager->GetRoot()->ToBrowserAccessibilityCocoa() == child) { + ToBrowserAccessibilityCocoa(manager->GetRoot()) == child) { return 0; } else { return NSNotFound; @@ -2883,7 +2884,7 @@ DCHECK(focused_item); if (focused_item) { BrowserAccessibilityCocoa* focused_item_cocoa = - focused_item->ToBrowserAccessibilityCocoa(); + ToBrowserAccessibilityCocoa(focused_item); DCHECK(focused_item_cocoa); if (focused_item_cocoa) return focused_item_cocoa;
diff --git a/content/child/push_messaging/push_provider.cc b/content/child/push_messaging/push_provider.cc index 254d855..f8e807de 100644 --- a/content/child/push_messaging/push_provider.cc +++ b/content/child/push_messaging/push_provider.cc
@@ -75,11 +75,8 @@ subscription_callbacks_.AddWithID(callbacks, request_id); int64_t service_worker_registration_id = GetServiceWorkerRegistrationId(service_worker_registration); - PushSubscriptionOptions content_options; - content_options.user_visible_only = options.userVisibleOnly; - content_options.sender_info = options.applicationServerKey.utf8(); thread_safe_sender_->Send(new PushMessagingHostMsg_SubscribeFromWorker( - request_id, service_worker_registration_id, content_options)); + request_id, service_worker_registration_id, options.userVisibleOnly)); } void PushProvider::unsubscribe(
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index ee780bc7..cbda6c4 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -572,6 +572,7 @@ response->devtools_info = result.devtools_info; response->data.swap(result.data); response->download_file_path = result.download_file_path; + response->socket_address = result.socket_address; } int ResourceDispatcher::StartAsync(const RequestInfo& request_info,
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc index 435ea30..311fa7f4 100644 --- a/content/child/v8_value_converter_impl_unittest.cc +++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -14,7 +14,6 @@ #include "base/values.h" #include "content/child/v8_value_converter_impl.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" #include "v8/include/v8.h" namespace content { @@ -288,7 +287,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; // Set up objects to throw when reading or writing 'foo'. const char* source = @@ -331,7 +329,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; const char* source = "(function() {" "var arr = [];" @@ -408,7 +405,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; const char* source = "(function() {" "Object.prototype.foo = 'foo';" @@ -433,7 +429,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; const char* source = "(function() {" "return { foo: undefined, bar: null };" @@ -492,7 +487,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; const char* source = "(function() {" "return {" @@ -531,7 +525,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; const char* source = "(function() {" "var a = [0];" @@ -556,7 +549,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; v8::Local<v8::Object> object; {
diff --git a/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc b/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc index f431ad9..05cdb8d 100644 --- a/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc +++ b/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc
@@ -180,7 +180,8 @@ decode_params.coded_size = video_frame->coded_size(); decode_params.output_video_frame_handle = output_handle; - decode_params.output_buffer_size = output_buffer_size; + decode_params.output_buffer_size = + base::checked_cast<uint32_t>(output_buffer_size); Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params)); }
diff --git a/content/common/gpu/media/android_copying_backing_strategy.cc b/content/common/gpu/media/android_copying_backing_strategy.cc index cf166af..e81c9eb0 100644 --- a/content/common/gpu/media/android_copying_backing_strategy.cc +++ b/content/common/gpu/media/android_copying_backing_strategy.cc
@@ -18,10 +18,6 @@ namespace content { -const static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - AndroidCopyingBackingStrategy::AndroidCopyingBackingStrategy( AVDAStateProvider* state_provider) : state_provider_(state_provider), @@ -114,8 +110,11 @@ surface_texture_->UpdateTexImage(); } - float transfrom_matrix[16]; - surface_texture_->GetTransformMatrix(transfrom_matrix); + float transform_matrix[16]; + surface_texture_->GetTransformMatrix(transform_matrix); + // add y-flip to correct UV coordinate systems. + transform_matrix[13] += transform_matrix[5]; + transform_matrix[5] = -transform_matrix[5]; uint32_t picture_buffer_texture_id = picture_buffer.texture_id(); @@ -135,13 +134,11 @@ // attached. // 2. SurfaceTexture requires us to apply a transform matrix when we show // the texture. - // TODO(hkuang): get the StreamTexture transform matrix in GPU process - // instead of using default matrix crbug.com/226218. copier_->DoCopyTextureWithTransform( state_provider_->GetGlDecoder().get(), GL_TEXTURE_EXTERNAL_OES, surface_texture_id_, GL_TEXTURE_2D, picture_buffer_texture_id, state_provider_->GetSize().width(), state_provider_->GetSize().height(), - false, false, false, kIdentityMatrix); + false, false, false, transform_matrix); } void AndroidCopyingBackingStrategy::CodecChanged(
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc index 1de68a2e..dd3e75e 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.cc +++ b/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -19,6 +19,7 @@ #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/media/android_copying_backing_strategy.h" #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/public/common/content_switches.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gpu_switches.h" @@ -476,17 +477,16 @@ return true; } - scoped_ptr<base::SharedMemory> shm; + scoped_ptr<SharedMemoryRegion> shm; - if (pending_input_buf_index_ != -1) { - // The buffer is already dequeued from MediaCodec, filled with data and - // bitstream_buffer.handle() is closed. - shm.reset(new base::SharedMemory()); - } else { - shm.reset(new base::SharedMemory(bitstream_buffer.handle(), true)); + if (pending_input_buf_index_ == -1) { + // When |pending_input_buf_index_| is not -1, the buffer is already dequeued + // from MediaCodec, filled with data and bitstream_buffer.handle() is + // closed. + shm.reset(new SharedMemoryRegion(bitstream_buffer, true)); - if (!shm->Map(bitstream_buffer.size())) { - POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemory::Map()"); + if (!shm->Map()) { + POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemoryRegion::Map()"); return false; } } @@ -506,7 +506,8 @@ // Notice that |memory| will be null if we repeatedly enqueue the same buffer, // this happens after MEDIA_CODEC_NO_KEY. - const uint8_t* memory = static_cast<const uint8_t*>(shm->memory()); + const uint8_t* memory = + shm ? static_cast<const uint8_t*>(shm->memory()) : nullptr; const std::string& key_id = bitstream_buffer.key_id(); const std::string& iv = bitstream_buffer.iv(); const std::vector<media::SubsampleEntry>& subsamples =
diff --git a/content/common/gpu/media/android_video_encode_accelerator.cc b/content/common/gpu/media/android_video_encode_accelerator.cc index 5b70bd3..406c1bc 100644 --- a/content/common/gpu/media/android_video_encode_accelerator.cc +++ b/content/common/gpu/media/android_video_encode_accelerator.cc
@@ -12,6 +12,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "content/common/gpu/gpu_channel.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/public/common/content_switches.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "media/base/android/media_codec_util.h" @@ -421,14 +422,11 @@ media::BitstreamBuffer bitstream_buffer = available_bitstream_buffers_.back(); available_bitstream_buffers_.pop_back(); - scoped_ptr<base::SharedMemory> shm( - new base::SharedMemory(bitstream_buffer.handle(), false)); - RETURN_ON_FAILURE(shm->Map(bitstream_buffer.size()), - "Failed to map SHM", - kPlatformFailureError); - RETURN_ON_FAILURE(size <= shm->mapped_size(), - "Encoded buffer too large: " << size << ">" - << shm->mapped_size(), + scoped_ptr<SharedMemoryRegion> shm( + new SharedMemoryRegion(bitstream_buffer, false)); + RETURN_ON_FAILURE(shm->Map(), "Failed to map SHM", kPlatformFailureError); + RETURN_ON_FAILURE(size <= shm->size(), + "Encoded buffer too large: " << size << ">" << shm->size(), kPlatformFailureError); media::MediaCodecStatus status = media_codec_->CopyFromOutputBuffer(
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index c0ef547..7ce14e9 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -486,6 +486,17 @@ video_decode_accelerator_->SetCdm(cdm_id); } +void GpuVideoDecodeAccelerator::CallOrPostNotifyError( + media::VideoDecodeAccelerator::Error error) { + if (child_task_runner_->BelongsToCurrentThread()) { + NotifyError(error); + } else { + child_task_runner_->PostTask( + FROM_HERE, base::Bind(&GpuVideoDecodeAccelerator::NotifyError, + base::Unretained(this), error)); + } +} + // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is // true, otherwise on the main thread. void GpuVideoDecodeAccelerator::OnDecode(
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index aa36bf17..ac9b118 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -109,6 +109,9 @@ uint32_t texture_target, scoped_refptr<gl::GLImage> image); + // Helper function to call NotifyError in the |child_task_runner_| thread. + void CallOrPostNotifyError(media::VideoDecodeAccelerator::Error error); + // Route ID to communicate with the host. const int32_t host_route_id_;
diff --git a/content/common/gpu/media/media_messages.cc b/content/common/gpu/media/media_messages.cc index 88364d9..6b9648d 100644 --- a/content/common/gpu/media/media_messages.cc +++ b/content/common/gpu/media/media_messages.cc
@@ -16,6 +16,8 @@ const param_type& p) { WriteParam(m, p.id()); WriteParam(m, static_cast<uint64_t>(p.size())); + DCHECK_GE(p.offset(), 0); + WriteParam(m, static_cast<uint64_t>(p.offset())); WriteParam(m, p.presentation_timestamp()); WriteParam(m, p.key_id()); if (!p.key_id().empty()) { @@ -30,7 +32,9 @@ param_type* r) { DCHECK(r); uint64_t size = 0; + uint64_t offset = 0; if (!(ReadParam(m, iter, &r->id_) && ReadParam(m, iter, &size) && + ReadParam(m, iter, &offset) && ReadParam(m, iter, &r->presentation_timestamp_) && ReadParam(m, iter, &r->key_id_))) return false; @@ -42,6 +46,13 @@ } r->size_ = checked_size.ValueOrDie(); + base::CheckedNumeric<off_t> checked_offset(offset); + if (!checked_offset.IsValid()) { + DLOG(ERROR) << "Invalid offset: " << offset; + return false; + } + r->offset_ = checked_offset.ValueOrDie(); + if (!r->key_id_.empty()) { if (!(ReadParam(m, iter, &r->iv_) && ReadParam(m, iter, &r->subsamples_))) return false;
diff --git a/content/common/gpu/media/shared_memory_region.cc b/content/common/gpu/media/shared_memory_region.cc new file mode 100644 index 0000000..4ee6a24 --- /dev/null +++ b/content/common/gpu/media/shared_memory_region.cc
@@ -0,0 +1,42 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/sys_info.h" +#include "content/common/gpu/media/shared_memory_region.h" + +namespace content { + +SharedMemoryRegion::SharedMemoryRegion(const base::SharedMemoryHandle& handle, + off_t offset, + size_t size, + bool read_only) + : shm_(handle, read_only), + offset_(offset), + size_(size), + alignment_size_(offset % base::SysInfo::VMAllocationGranularity()) { + DCHECK_GE(offset_, 0) << "Invalid offset: " << offset_; +} + +SharedMemoryRegion::SharedMemoryRegion( + const media::BitstreamBuffer& bitstream_buffer, + bool read_only) + : SharedMemoryRegion(bitstream_buffer.handle(), + bitstream_buffer.offset(), + bitstream_buffer.size(), + read_only) {} + +bool SharedMemoryRegion::Map() { + if (offset_ < 0) { + DVLOG(1) << "Invalid offset: " << offset_; + return false; + } + return shm_.MapAt(offset_ - alignment_size_, size_ + alignment_size_); +} + +void* SharedMemoryRegion::memory() { + int8_t* addr = reinterpret_cast<int8_t*>(shm_.memory()); + return addr ? addr + alignment_size_ : nullptr; +} + +} // namespace content
diff --git a/content/common/gpu/media/shared_memory_region.h b/content/common/gpu/media/shared_memory_region.h new file mode 100644 index 0000000..f7c5db29 --- /dev/null +++ b/content/common/gpu/media/shared_memory_region.h
@@ -0,0 +1,57 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_GPU_MEDIA_SHARED_MEMORY_REGION_H_ +#define CONTENT_COMMON_GPU_MEDIA_SHARED_MEMORY_REGION_H_ + +#include "base/memory/shared_memory.h" +#include "media/base/bitstream_buffer.h" + +namespace content { + +// Helper class to access a region of a SharedMemory. Different from +// SharedMemory, in which the |offset| of function MapAt() must be aligned to +// the value of |SysInfo::VMAllocationGranularity()|, the |offset| of a +// SharedMemoryRegion needs not to be aligned, this class hides the details +// and returns the mapped address of the given offset. +class SharedMemoryRegion { + public: + // Creates a SharedMemoryRegion. + // The mapped memory region begins at |offset| bytes from the start of the + // shared memory and the length is |size|. It will take the ownership of + // the |handle| and release the resource when being destroyed. Different + // from SharedMemory, the |offset| needs not to be aligned to the value of + // |SysInfo::VMAllocationGranularity()|. + SharedMemoryRegion(const base::SharedMemoryHandle& handle, + off_t offset, + size_t size, + bool read_only); + + // Creates a SharedMemoryRegion from the given |bistream_buffer|. + SharedMemoryRegion(const media::BitstreamBuffer& bitstream_buffer, + bool read_only); + + // Maps the shared memory into the caller's address space. + // Return true on success, false otherwise. + bool Map(); + + // Gets a pointer to the mapped region if it has been mapped via Map(). + // Returns |nullptr| if it is not mapped. The returned pointer points + // to the memory at the offset previously passed to the constructor. + void* memory(); + + size_t size() const { return size_; } + + private: + base::SharedMemory shm_; + off_t offset_; + size_t size_; + size_t alignment_size_; + + DISALLOW_COPY_AND_ASSIGN(SharedMemoryRegion); +}; + +} // namespace content + +#endif // CONTENT_COMMON_GPU_MEDIA_SHARED_MEMORY_REGION_H_
diff --git a/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc b/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc index 7f6e9ba..0121ead 100644 --- a/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc
@@ -112,10 +112,11 @@ } V4L2JpegDecodeAccelerator::JobRecord::JobRecord( - media::BitstreamBuffer bitstream_buffer, + const media::BitstreamBuffer& bitstream_buffer, scoped_refptr<media::VideoFrame> video_frame) - : bitstream_buffer(bitstream_buffer), out_frame(video_frame) { -} + : bitstream_buffer_id(bitstream_buffer.id()), + shm(bitstream_buffer, true), + out_frame(video_frame) {} V4L2JpegDecodeAccelerator::JobRecord::~JobRecord() { } @@ -268,11 +269,9 @@ void V4L2JpegDecodeAccelerator::DecodeTask(scoped_ptr<JobRecord> job_record) { DCHECK(decoder_task_runner_->BelongsToCurrentThread()); - job_record->shm.reset( - new base::SharedMemory(job_record->bitstream_buffer.handle(), true)); - if (!job_record->shm->Map(job_record->bitstream_buffer.size())) { + if (!job_record->shm.Map()) { PLOG(ERROR) << __func__ << ": could not map bitstream_buffer"; - PostNotifyError(job_record->bitstream_buffer.id(), UNREADABLE_INPUT); + PostNotifyError(job_record->bitstream_buffer_id, UNREADABLE_INPUT); return; } input_jobs_.push(make_linked_ptr(job_record.release())); @@ -296,7 +295,7 @@ linked_ptr<JobRecord> job_record = input_jobs_.front(); // Check input buffer size is enough return (input_buffer_map_.empty() || - (job_record->bitstream_buffer.size() + sizeof(kDefaultDhtSeg)) > + (job_record->shm.size() + sizeof(kDefaultDhtSeg)) > input_buffer_map_.front().length); } @@ -341,8 +340,7 @@ // The input image may miss huffman table. We didn't parse the image before, // so we create more to avoid the situation of not enough memory. // Reserve twice size to avoid recreating input buffer frequently. - size_t reserve_size = - (job_record->bitstream_buffer.size() + sizeof(kDefaultDhtSeg)) * 2; + size_t reserve_size = (job_record->shm.size() + sizeof(kDefaultDhtSeg)) * 2; struct v4l2_format format; memset(&format, 0, sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; @@ -719,17 +717,16 @@ // V4L2_PIX_FMT_YUV420. if (!CopyOutputImage(output_buffer_pixelformat_, output_record.address, output_buffer_coded_size_, job_record->out_frame)) { - PostNotifyError(job_record->bitstream_buffer.id(), PLATFORM_FAILURE); + PostNotifyError(job_record->bitstream_buffer_id, PLATFORM_FAILURE); return; } DVLOG(3) << "Decoding finished, returning bitstream buffer, id=" - << job_record->bitstream_buffer.id(); + << job_record->bitstream_buffer_id; child_task_runner_->PostTask( - FROM_HERE, - base::Bind(&V4L2JpegDecodeAccelerator::VideoFrameReady, weak_ptr_, - job_record->bitstream_buffer.id())); + FROM_HERE, base::Bind(&V4L2JpegDecodeAccelerator::VideoFrameReady, + weak_ptr_, job_record->bitstream_buffer_id)); } } } @@ -827,10 +824,9 @@ DCHECK(!input_record.at_device); // It will add default huffman segment if it's missing. - if (!AddHuffmanTable(job_record->shm->memory(), - job_record->bitstream_buffer.size(), + if (!AddHuffmanTable(job_record->shm.memory(), job_record->shm.size(), input_record.address, input_record.length)) { - PostNotifyError(job_record->bitstream_buffer.id(), PARSE_JPEG_FAILED); + PostNotifyError(job_record->bitstream_buffer_id, PARSE_JPEG_FAILED); return false; } @@ -844,8 +840,9 @@ running_jobs_.push(job_record); free_input_buffers_.pop_back(); - DVLOG(3) << __func__ << ": enqueued frame id=" - << job_record->bitstream_buffer.id() << " to device."; + DVLOG(3) << __func__ + << ": enqueued frame id=" << job_record->bitstream_buffer_id + << " to device."; return true; }
diff --git a/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h b/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h index 4358080..bef33b22 100644 --- a/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h
@@ -18,6 +18,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" #include "content/common/content_export.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/v4l2_device.h" #include "media/base/bitstream_buffer.h" #include "media/base/video_frame.h" @@ -58,16 +59,16 @@ // the time of submission we may not have one available (and don't need one // to submit input to the device). struct JobRecord { - JobRecord(media::BitstreamBuffer bitstream_buffer, + JobRecord(const media::BitstreamBuffer& bitstream_buffer, scoped_refptr<media::VideoFrame> video_frame); ~JobRecord(); - // Input image buffer. - media::BitstreamBuffer bitstream_buffer; + // Input image buffer ID. + int32_t bitstream_buffer_id; + // Memory mapped from |bitstream_buffer|. + SharedMemoryRegion shm; // Output frame buffer. scoped_refptr<media::VideoFrame> out_frame; - // Memory mapped from |bitstream_buffer|. - scoped_ptr<base::SharedMemory> shm; }; void EnqueueInput();
diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc index f48fc93..a338cc26 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
@@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" #include "media/base/bind_to_current_loop.h" #include "media/base/media_switches.h" @@ -169,14 +170,12 @@ BitstreamBufferRef( base::WeakPtr<VideoDecodeAccelerator::Client>& client, const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, - base::SharedMemory* shm, - size_t size, + SharedMemoryRegion* shm, int32_t input_id); ~BitstreamBufferRef(); const base::WeakPtr<VideoDecodeAccelerator::Client> client; const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; - const scoped_ptr<base::SharedMemory> shm; - const size_t size; + const scoped_ptr<SharedMemoryRegion> shm; off_t bytes_used; const int32_t input_id; }; @@ -184,13 +183,11 @@ V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( base::WeakPtr<VideoDecodeAccelerator::Client>& client, const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, - base::SharedMemory* shm, - size_t size, + SharedMemoryRegion* shm, int32_t input_id) : client(client), client_task_runner(client_task_runner), shm(shm), - size(size), bytes_used(0), input_id(input_id) {} @@ -1211,9 +1208,8 @@ scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( io_client_, io_task_runner_, - new base::SharedMemory(bitstream_buffer.handle(), true), - bitstream_buffer.size(), bitstream_buffer.id())); - if (!bitstream_record->shm->Map(bitstream_buffer.size())) { + new SharedMemoryRegion(bitstream_buffer, true), bitstream_buffer.id())); + if (!bitstream_record->shm->Map()) { LOGF(ERROR) << "Could not map bitstream_buffer"; NOTIFY_ERROR(UNREADABLE_INPUT); return; @@ -1245,7 +1241,7 @@ const uint8_t* const data = reinterpret_cast<const uint8_t*>( decoder_current_bitstream_buffer_->shm->memory()); - const size_t data_size = decoder_current_bitstream_buffer_->size; + const size_t data_size = decoder_current_bitstream_buffer_->shm->size(); decoder_->SetStream(data, data_size); return true; @@ -1645,7 +1641,7 @@ // which - when reached - will trigger flush sequence. decoder_input_queue_.push( linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( - io_client_, io_task_runner_, nullptr, 0, kFlushBufferId))); + io_client_, io_task_runner_, nullptr, kFlushBufferId))); return; }
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc index 3ed7f9621..3554be5 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -15,12 +15,12 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" -#include "base/memory/shared_memory.h" #include "base/message_loop/message_loop.h" #include "base/numerics/safe_conversions.h" #include "base/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" #include "media/base/media_switches.h" #include "media/filters/h264_parser.h" @@ -65,14 +65,12 @@ BitstreamBufferRef( base::WeakPtr<Client>& client, scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, - base::SharedMemory* shm, - size_t size, + scoped_ptr<SharedMemoryRegion> shm, int32_t input_id); ~BitstreamBufferRef(); const base::WeakPtr<Client> client; const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner; - const scoped_ptr<base::SharedMemory> shm; - const size_t size; + const scoped_ptr<SharedMemoryRegion> shm; size_t bytes_used; const int32_t input_id; }; @@ -94,13 +92,11 @@ V4L2VideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( base::WeakPtr<Client>& client, scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner, - base::SharedMemory* shm, - size_t size, + scoped_ptr<SharedMemoryRegion> shm, int32_t input_id) : client(client), client_task_runner(client_task_runner), - shm(shm), - size(size), + shm(std::move(shm)), bytes_used(0), input_id(input_id) {} @@ -482,9 +478,10 @@ scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( io_client_, io_task_runner_, - new base::SharedMemory(bitstream_buffer.handle(), true), - bitstream_buffer.size(), bitstream_buffer.id())); - if (!bitstream_record->shm->Map(bitstream_buffer.size())) { + scoped_ptr<SharedMemoryRegion>( + new SharedMemoryRegion(bitstream_buffer, true)), + bitstream_buffer.id())); + if (!bitstream_record->shm->Map()) { LOG(ERROR) << "Decode(): could not map bitstream_buffer"; NOTIFY_ERROR(UNREADABLE_INPUT); return; @@ -543,54 +540,51 @@ // Setup to use the next buffer. decoder_current_bitstream_buffer_.reset(buffer_ref.release()); decoder_input_queue_.pop(); - DVLOG(3) << "DecodeBufferTask(): reading input_id=" - << decoder_current_bitstream_buffer_->input_id - << ", addr=" << (decoder_current_bitstream_buffer_->shm ? - decoder_current_bitstream_buffer_->shm->memory() : - NULL) - << ", size=" << decoder_current_bitstream_buffer_->size; + const auto& shm = decoder_current_bitstream_buffer_->shm; + if (shm) { + DVLOG(3) << "DecodeBufferTask(): reading input_id=" + << decoder_current_bitstream_buffer_->input_id + << ", addr=" << shm->memory() << ", size=" << shm->size(); + } else { + DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId); + DVLOG(3) << "DecodeBufferTask(): reading input_id=kFlushBufferId"; + } } bool schedule_task = false; - const size_t size = decoder_current_bitstream_buffer_->size; size_t decoded_size = 0; - if (size == 0) { - const int32_t input_id = decoder_current_bitstream_buffer_->input_id; - if (input_id >= 0) { - // This is a buffer queued from the client that has zero size. Skip. + const auto& shm = decoder_current_bitstream_buffer_->shm; + if (!shm) { + // This is a dummy buffer, queued to flush the pipe. Flush. + DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId); + // Enqueue a buffer guaranteed to be empty. To do that, we flush the + // current input, enqueue no data to the next frame, then flush that down. + schedule_task = true; + if (decoder_current_input_buffer_ != -1 && + input_buffer_map_[decoder_current_input_buffer_].input_id != + kFlushBufferId) + schedule_task = FlushInputFrame(); + + if (schedule_task && AppendToInputFrame(NULL, 0) && FlushInputFrame()) { + DVLOG(2) << "DecodeBufferTask(): enqueued flush buffer"; + decoder_partial_frame_pending_ = false; schedule_task = true; } else { - // This is a buffer of zero size, queued to flush the pipe. Flush. - DCHECK_EQ(decoder_current_bitstream_buffer_->shm.get(), - static_cast<base::SharedMemory*>(NULL)); - // Enqueue a buffer guaranteed to be empty. To do that, we flush the - // current input, enqueue no data to the next frame, then flush that down. - schedule_task = true; - if (decoder_current_input_buffer_ != -1 && - input_buffer_map_[decoder_current_input_buffer_].input_id != - kFlushBufferId) - schedule_task = FlushInputFrame(); - - if (schedule_task && AppendToInputFrame(NULL, 0) && FlushInputFrame()) { - DVLOG(2) << "DecodeBufferTask(): enqueued flush buffer"; - decoder_partial_frame_pending_ = false; - schedule_task = true; - } else { - // If we failed to enqueue the empty buffer (due to pipeline - // backpressure), don't advance the bitstream buffer queue, and don't - // schedule the next task. This bitstream buffer queue entry will get - // reprocessed when the pipeline frees up. - schedule_task = false; - } + // If we failed to enqueue the empty buffer (due to pipeline + // backpressure), don't advance the bitstream buffer queue, and don't + // schedule the next task. This bitstream buffer queue entry will get + // reprocessed when the pipeline frees up. + schedule_task = false; } + } else if (shm->size() == 0) { + // This is a buffer queued from the client that has zero size. Skip. + schedule_task = true; } else { // This is a buffer queued from the client, with actual contents. Decode. const uint8_t* const data = - reinterpret_cast<const uint8_t*>( - decoder_current_bitstream_buffer_->shm->memory()) + + reinterpret_cast<const uint8_t*>(shm->memory()) + decoder_current_bitstream_buffer_->bytes_used; const size_t data_size = - decoder_current_bitstream_buffer_->size - - decoder_current_bitstream_buffer_->bytes_used; + shm->size() - decoder_current_bitstream_buffer_->bytes_used; if (!AdvanceFrameFragment(data, data_size, &decoded_size)) { NOTIFY_ERROR(UNREADABLE_INPUT); return; @@ -619,8 +613,8 @@ if (schedule_task) { decoder_current_bitstream_buffer_->bytes_used += decoded_size; - if (decoder_current_bitstream_buffer_->bytes_used == - decoder_current_bitstream_buffer_->size) { + if ((shm ? shm->size() : 0) == + decoder_current_bitstream_buffer_->bytes_used) { // Our current bitstream buffer is done; return it. int32_t input_id = decoder_current_bitstream_buffer_->input_id; DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id; @@ -1276,7 +1270,7 @@ // Queue up an empty buffer -- this triggers the flush. decoder_input_queue_.push( linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( - io_client_, io_task_runner_, NULL, 0, kFlushBufferId))); + io_client_, io_task_runner_, nullptr, kFlushBufferId))); decoder_flushing_ = true; SendPictureReady(); // Send all pending PictureReady.
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/content/common/gpu/media/v4l2_video_encode_accelerator.cc index 9f62cc5..4cc8f26 100644 --- a/content/common/gpu/media/v4l2_video_encode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
@@ -17,6 +17,7 @@ #include "base/numerics/safe_conversions.h" #include "base/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" #include "content/public/common/content_switches.h" #include "media/base/bitstream_buffer.h" @@ -51,13 +52,10 @@ namespace content { struct V4L2VideoEncodeAccelerator::BitstreamBufferRef { - BitstreamBufferRef(int32_t id, - scoped_ptr<base::SharedMemory> shm, - size_t size) - : id(id), shm(std::move(shm)), size(size) {} + BitstreamBufferRef(int32_t id, scoped_ptr<SharedMemoryRegion> shm) + : id(id), shm(std::move(shm)) {} const int32_t id; - const scoped_ptr<base::SharedMemory> shm; - const size_t size; + const scoped_ptr<SharedMemoryRegion> shm; }; V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) { @@ -224,15 +222,14 @@ return; } - scoped_ptr<base::SharedMemory> shm( - new base::SharedMemory(buffer.handle(), false)); - if (!shm->Map(buffer.size())) { + scoped_ptr<SharedMemoryRegion> shm(new SharedMemoryRegion(buffer, false)); + if (!shm->Map()) { NOTIFY_ERROR(kPlatformFailureError); return; } scoped_ptr<BitstreamBufferRef> buffer_ref( - new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size())); + new BitstreamBufferRef(buffer.id(), std::move(shm))); encoder_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
diff --git a/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc b/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc index d294ae5..f6d555b 100644 --- a/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc
@@ -14,6 +14,7 @@ #include "base/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "content/common/gpu/gpu_channel.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/vaapi_picture.h" #include "media/base/video_frame.h" #include "media/filters/jpeg_parser.h" @@ -76,10 +77,10 @@ } // namespace VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( - const media::BitstreamBuffer& bitstream_buffer, - scoped_ptr<base::SharedMemory> shm, + int32_t bitstream_buffer_id, + scoped_ptr<SharedMemoryRegion> shm, const scoped_refptr<media::VideoFrame>& video_frame) - : bitstream_buffer(bitstream_buffer), + : bitstream_buffer_id(bitstream_buffer_id), shm(std::move(shm)), video_frame(video_frame) {} @@ -226,9 +227,9 @@ media::JpegParseResult parse_result; if (!media::ParseJpegPicture( reinterpret_cast<const uint8_t*>(request->shm->memory()), - request->bitstream_buffer.size(), &parse_result)) { + request->shm->size(), &parse_result)) { DLOG(ERROR) << "ParseJpegPicture failed"; - NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), + NotifyErrorFromDecoderThread(request->bitstream_buffer_id, PARSE_JPEG_FAILED); return; } @@ -237,7 +238,7 @@ VaSurfaceFormatForJpeg(parse_result.frame_header); if (!new_va_rt_format) { DLOG(ERROR) << "Unsupported subsampling"; - NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), + NotifyErrorFromDecoderThread(request->bitstream_buffer_id, UNSUPPORTED_JPEG); return; } @@ -255,7 +256,7 @@ if (!vaapi_wrapper_->CreateSurfaces(va_rt_format_, new_coded_size, 1, &va_surfaces)) { LOG(ERROR) << "Create VA surface failed"; - NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), + NotifyErrorFromDecoderThread(request->bitstream_buffer_id, PLATFORM_FAILURE); return; } @@ -266,15 +267,15 @@ if (!VaapiJpegDecoder::Decode(vaapi_wrapper_.get(), parse_result, va_surface_id_)) { LOG(ERROR) << "Decode JPEG failed"; - NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), + NotifyErrorFromDecoderThread(request->bitstream_buffer_id, PLATFORM_FAILURE); return; } - if (!OutputPicture(va_surface_id_, request->bitstream_buffer.id(), + if (!OutputPicture(va_surface_id_, request->bitstream_buffer_id, request->video_frame)) { LOG(ERROR) << "Output picture failed"; - NotifyErrorFromDecoderThread(request->bitstream_buffer.id(), + NotifyErrorFromDecoderThread(request->bitstream_buffer_id, PLATFORM_FAILURE); return; } @@ -290,25 +291,24 @@ DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() << " size: " << bitstream_buffer.size(); + // SharedMemoryRegion will take over the |bitstream_buffer.handle()|. + scoped_ptr<SharedMemoryRegion> shm( + new SharedMemoryRegion(bitstream_buffer, true)); + if (bitstream_buffer.id() < 0) { LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); - if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) - base::SharedMemory::CloseHandle(bitstream_buffer.handle()); NotifyErrorFromDecoderThread(bitstream_buffer.id(), INVALID_ARGUMENT); return; } - scoped_ptr<base::SharedMemory> shm( - new base::SharedMemory(bitstream_buffer.handle(), true)); - - if (!shm->Map(bitstream_buffer.size())) { + if (!shm->Map()) { LOG(ERROR) << "Failed to map input buffer"; NotifyErrorFromDecoderThread(bitstream_buffer.id(), UNREADABLE_INPUT); return; } scoped_ptr<DecodeRequest> request( - new DecodeRequest(bitstream_buffer, std::move(shm), video_frame)); + new DecodeRequest(bitstream_buffer.id(), std::move(shm), video_frame)); decoder_task_runner_->PostTask( FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask,
diff --git a/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h b/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h index 7d78a55..232b04d 100644 --- a/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h
@@ -15,6 +15,7 @@ #include "base/threading/non_thread_safe.h" #include "base/threading/thread.h" #include "content/common/content_export.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/vaapi_jpeg_decoder.h" #include "content/common/gpu/media/vaapi_wrapper.h" #include "media/base/bitstream_buffer.h" @@ -47,13 +48,13 @@ // An input buffer and the corresponding output video frame awaiting // consumption, provided by the client. struct DecodeRequest { - DecodeRequest(const media::BitstreamBuffer& bitstream_buffer, - scoped_ptr<base::SharedMemory> shm, + DecodeRequest(int32_t bitstream_buffer_id, + scoped_ptr<SharedMemoryRegion> shm, const scoped_refptr<media::VideoFrame>& video_frame); ~DecodeRequest(); - media::BitstreamBuffer bitstream_buffer; - scoped_ptr<base::SharedMemory> shm; + int32_t bitstream_buffer_id; + scoped_ptr<SharedMemoryRegion> shm; scoped_refptr<media::VideoFrame> video_frame; };
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index a430438..147ac53e 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -256,8 +256,7 @@ DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator); }; -VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0), size(0) { -} +VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0) {} VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { } @@ -447,10 +446,10 @@ DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() << " size: " << (int)bitstream_buffer.size(); - scoped_ptr<base::SharedMemory> shm( - new base::SharedMemory(bitstream_buffer.handle(), true)); - RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(bitstream_buffer.size()), - "Failed to map input buffer", UNREADABLE_INPUT,); + scoped_ptr<SharedMemoryRegion> shm( + new SharedMemoryRegion(bitstream_buffer, true)); + RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(), "Failed to map input buffer", + UNREADABLE_INPUT, ); base::AutoLock auto_lock(lock_); @@ -458,7 +457,6 @@ linked_ptr<InputBuffer> input_buffer(new InputBuffer()); input_buffer->shm.reset(shm.release()); input_buffer->id = bitstream_buffer.id(); - input_buffer->size = bitstream_buffer.size(); ++num_stream_bufs_at_decoder_; TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder", @@ -497,13 +495,12 @@ curr_input_buffer_ = input_buffers_.front(); input_buffers_.pop(); - DVLOG(4) << "New current bitstream buffer, id: " - << curr_input_buffer_->id - << " size: " << curr_input_buffer_->size; + DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id + << " size: " << curr_input_buffer_->shm->size(); decoder_->SetStream( static_cast<uint8_t*>(curr_input_buffer_->shm->memory()), - curr_input_buffer_->size); + curr_input_buffer_->shm->size()); return true; default:
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index 11cc082..c38feeb 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h
@@ -20,13 +20,13 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" -#include "base/memory/shared_memory.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "base/threading/thread.h" #include "content/common/content_export.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/vaapi_wrapper.h" #include "media/base/bitstream_buffer.h" #include "media/video/picture.h" @@ -210,8 +210,7 @@ ~InputBuffer(); int32_t id; - size_t size; - scoped_ptr<base::SharedMemory> shm; + scoped_ptr<SharedMemoryRegion> shm; }; // Queue for incoming input buffers.
diff --git a/content/common/gpu/media/vaapi_video_encode_accelerator.cc b/content/common/gpu/media/vaapi_video_encode_accelerator.cc index 049cd7a..4e2a06e 100644 --- a/content/common/gpu/media/vaapi_video_encode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_encode_accelerator.cc
@@ -13,6 +13,7 @@ #include "base/metrics/histogram.h" #include "base/numerics/safe_conversions.h" #include "content/common/gpu/media/h264_dpb.h" +#include "content/common/gpu/media/shared_memory_region.h" #include "media/base/bind_to_current_loop.h" #include "third_party/libva/va/va_enc_h264.h" @@ -100,13 +101,10 @@ }; struct VaapiVideoEncodeAccelerator::BitstreamBufferRef { - BitstreamBufferRef(int32_t id, - scoped_ptr<base::SharedMemory> shm, - size_t size) - : id(id), shm(std::move(shm)), size(size) {} + BitstreamBufferRef(int32_t id, scoped_ptr<SharedMemoryRegion> shm) + : id(id), shm(std::move(shm)) {} const int32_t id; - const scoped_ptr<base::SharedMemory> shm; - const size_t size; + const scoped_ptr<SharedMemoryRegion> shm; }; media::VideoEncodeAccelerator::SupportedProfiles @@ -546,11 +544,8 @@ size_t data_size = 0; if (!vaapi_wrapper_->DownloadAndDestroyCodedBuffer( - encode_job->coded_buffer, - encode_job->input_surface->id(), - target_data, - buffer->size, - &data_size)) { + encode_job->coded_buffer, encode_job->input_surface->id(), + target_data, buffer->shm->size(), &data_size)) { NOTIFY_ERROR(kPlatformFailureError, "Failed downloading coded buffer"); return; } @@ -669,15 +664,14 @@ return; } - scoped_ptr<base::SharedMemory> shm( - new base::SharedMemory(buffer.handle(), false)); - if (!shm->Map(buffer.size())) { + scoped_ptr<SharedMemoryRegion> shm(new SharedMemoryRegion(buffer, false)); + if (!shm->Map()) { NOTIFY_ERROR(kPlatformFailureError, "Failed mapping shared memory."); return; } scoped_ptr<BitstreamBufferRef> buffer_ref( - new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size())); + new BitstreamBufferRef(buffer.id(), std::move(shm))); encoder_thread_task_runner_->PostTask( FROM_HERE,
diff --git a/content/common/mojo/mojo_shell_connection_impl.cc b/content/common/mojo/mojo_shell_connection_impl.cc index eb11c96..839e206 100644 --- a/content/common/mojo/mojo_shell_connection_impl.cc +++ b/content/common/mojo/mojo_shell_connection_impl.cc
@@ -95,8 +95,7 @@ } void MojoShellConnectionImpl::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { initialized_ = true; }
diff --git a/content/common/mojo/mojo_shell_connection_impl.h b/content/common/mojo/mojo_shell_connection_impl.h index c63b174..5f53363 100644 --- a/content/common/mojo/mojo_shell_connection_impl.h +++ b/content/common/mojo/mojo_shell_connection_impl.h
@@ -56,8 +56,8 @@ ~MojoShellConnectionImpl() override; // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // MojoShellConnection:
diff --git a/content/common/push_messaging_messages.h b/content/common/push_messaging_messages.h index df88b2f..38a39e8 100644 --- a/content/common/push_messaging_messages.h +++ b/content/common/push_messaging_messages.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include "content/public/common/push_messaging_status.h" -#include "content/public/common/push_subscription_options.h" #include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h" #include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" @@ -30,11 +29,6 @@ blink::WebPushError::ErrorType, blink::WebPushError::ErrorType::ErrorTypeLast) -IPC_STRUCT_TRAITS_BEGIN(content::PushSubscriptionOptions) - IPC_STRUCT_TRAITS_MEMBER(user_visible_only) - IPC_STRUCT_TRAITS_MEMBER(sender_info) -IPC_STRUCT_TRAITS_END() - // Messages sent from the browser to the child process. IPC_MESSAGE_ROUTED4(PushMessagingMsg_SubscribeFromDocumentSuccess, @@ -86,16 +80,17 @@ // Messages sent from the child process to the browser. -IPC_MESSAGE_CONTROL4(PushMessagingHostMsg_SubscribeFromDocument, +IPC_MESSAGE_CONTROL5(PushMessagingHostMsg_SubscribeFromDocument, int32_t /* render_frame_id */, int32_t /* request_id */, - content::PushSubscriptionOptions /* options */, + std::string /* sender_id */, + bool /* user_visible */, int64_t /* service_worker_registration_id */) IPC_MESSAGE_CONTROL3(PushMessagingHostMsg_SubscribeFromWorker, int32_t /* request_id */, int64_t /* service_worker_registration_id */, - content::PushSubscriptionOptions /* options */) + bool /* user_visible */) IPC_MESSAGE_CONTROL2(PushMessagingHostMsg_Unsubscribe, int32_t /* request_id */,
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 4f5c244..01e33ec 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi
@@ -780,8 +780,6 @@ 'browser/frame_host/render_widget_host_view_child_frame.h', 'browser/frame_host/render_widget_host_view_guest.cc', 'browser/frame_host/render_widget_host_view_guest.h', - 'browser/frame_host/traced_frame_tree_node.cc', - 'browser/frame_host/traced_frame_tree_node.h', 'browser/gamepad/gamepad_consumer.h', 'browser/gamepad/gamepad_data_fetcher.cc', 'browser/gamepad/gamepad_data_fetcher.h',
diff --git a/content/content_common.gypi b/content/content_common.gypi index 0400de30..07dcea9 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi
@@ -432,6 +432,8 @@ 'common/gpu/media/media_messages.h', 'common/gpu/media/media_service.cc', 'common/gpu/media/media_service.h', + 'common/gpu/media/shared_memory_region.cc', + 'common/gpu/media/shared_memory_region.h', 'common/gpu/stream_texture_android.cc', 'common/gpu/stream_texture_android.h', 'common/host_discardable_shared_memory_manager.cc',
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java index a5b0ed0..7a739095 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -128,8 +128,12 @@ assertTrue(mContentViewCore.hasSelection()); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupNotShownOnLongPressingNonEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); @@ -139,8 +143,12 @@ waitForPastePopupStatus(false); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupClearedOnTappingEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); @@ -149,8 +157,12 @@ waitForPastePopupStatus(false); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupClearedOnTappingNonEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); @@ -159,8 +171,12 @@ waitForPastePopupStatus(false); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupClearedOnTappingOutsideInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); @@ -169,8 +185,12 @@ waitForPastePopupStatus(false); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupClearedOnLongPressingOutsideInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); @@ -179,8 +199,12 @@ waitForPastePopupStatus(false); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupNotShownOnLongPressingDisabledInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); @@ -191,8 +215,12 @@ assertFalse(mContentViewCore.hasInsertion()); } + /* @SmallTest @Feature({"TextInput"}) + https://crbug.com/592428 + */ + @FlakyTest public void testPastePopupDismissedOnDestroy() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text");
diff --git a/content/public/browser/push_messaging_service.h b/content/public/browser/push_messaging_service.h index 993e2816..86aa34e 100644 --- a/content/public/browser/push_messaging_service.h +++ b/content/public/browser/push_messaging_service.h
@@ -19,7 +19,6 @@ class BrowserContext; class ServiceWorkerContext; -struct PushSubscriptionOptions; // A push service-agnostic interface that the Push API uses for talking to // push messaging services like GCM. Must only be used on the UI thread. @@ -50,22 +49,24 @@ // origins and push registrations. virtual GURL GetPushEndpoint() = 0; - // Subscribe the given |options.sender_info| with the push messaging service - // in a document context. The frame is known and a permission UI may be - // displayed to the user. + // Subscribe the given |sender_id| with the push messaging service in a + // document context. The frame is known and a permission UI may be displayed + // to the user. virtual void SubscribeFromDocument(const GURL& requesting_origin, int64_t service_worker_registration_id, + const std::string& sender_id, int renderer_id, int render_frame_id, - const PushSubscriptionOptions& options, + bool user_visible, const RegisterCallback& callback) = 0; - // Subscribe the given |options.sender_info| with the push messaging service. - // The frame is not known so if permission was not previously granted by the - // user this request should fail. + // Subscribe the given |sender_id| with the push messaging service. The frame + // is not known so if permission was not previously granted by the user this + // request should fail. virtual void SubscribeFromWorker(const GURL& requesting_origin, int64_t service_worker_registration_id, - const PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, const RegisterCallback& callback) = 0; // Retrieves the encryption information associated with the subscription
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 50b2d6f..01a3a57 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -222,6 +222,10 @@ // Disables the Web Notification and the Push APIs. const char kDisableNotifications[] = "disable-notifications"; +// Disable partial raster in renderer. Disabling this switch also disables +// the use of persistent gpu memory buffers. +const char kDisablePartialRaster[] = "disable-partial-raster"; + // Disable Pepper3D. const char kDisablePepper3d[] = "disable-pepper-3d"; @@ -395,10 +399,6 @@ const char kEnableNotificationActionIcons[] = "enable-notification-action-icons"; -// Enables partial raster. Enabling this switch also enables the use of -// persistent gpu memory buffers. -const char kEnablePartialRaster[] = "enable-partial-raster"; - // Enables compositor-accelerated touch-screen pinch gestures. const char kEnablePinch[] = "enable-pinch";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 3a1b104..c5843ffa 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -73,6 +73,7 @@ CONTENT_EXPORT extern const char kDisableNamespaceSandbox[]; CONTENT_EXPORT extern const char kDisableNativeGpuMemoryBuffers[]; CONTENT_EXPORT extern const char kDisableNotifications[]; +CONTENT_EXPORT extern const char kDisablePartialRaster[]; extern const char kDisablePepper3d[]; CONTENT_EXPORT extern const char kDisablePermissionsAPI[]; CONTENT_EXPORT extern const char kDisablePinch[]; @@ -122,7 +123,6 @@ extern const char kEnableMemoryBenchmarking[]; CONTENT_EXPORT extern const char kEnableNetworkInformation[]; CONTENT_EXPORT extern const char kEnableNotificationActionIcons[]; -CONTENT_EXPORT extern const char kEnablePartialRaster[]; CONTENT_EXPORT extern const char kEnablePinch[]; CONTENT_EXPORT extern const char kEnablePluginPlaceholderTesting[]; CONTENT_EXPORT extern const char kEnablePreciseMemoryInfo[];
diff --git a/content/public/common/push_subscription_options.h b/content/public/common/push_subscription_options.h deleted file mode 100644 index 1a2da0a..0000000 --- a/content/public/common/push_subscription_options.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_COMMON_PUSH_SUBSCRIPTION_OPTIONS_H_ -#define CONTENT_PUBLIC_COMMON_PUSH_SUBSCRIPTION_OPTIONS_H_ - -#include <string> - -#include "content/common/content_export.h" - -namespace content { - -// Structure to hold the options provided from the web app developer as -// part of asking for a new push subscription. -struct CONTENT_EXPORT PushSubscriptionOptions { - PushSubscriptionOptions() {} - ~PushSubscriptionOptions() {} - - // Whether or not the app developer agrees to provide user visible - // notifications whenever they receive a push message. - bool user_visible_only = false; - - // The unique identifier of the application service which is used to - // verify the push message before delivery. This could either be an ID - // assigned by the developer console or the app server's public key. - std::string sender_info; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_COMMON_CONTENT_PUSH_SUBSCRIPTION_OPTIONS_H_
diff --git a/content/public/test/test_mojo_app.cc b/content/public/test/test_mojo_app.cc index 7c5fdb9..253c64f 100644 --- a/content/public/test/test_mojo_app.cc +++ b/content/public/test/test_mojo_app.cc
@@ -22,7 +22,7 @@ } bool TestMojoApp::AcceptConnection(mojo::Connection* connection) { - requestor_name_ = connection->GetRemoteApplicationName(); + requestor_name_ = connection->GetRemoteIdentity().name(); connection->AddInterface<TestMojoService>(this); return true; }
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index 7252043..8831cf0 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -794,14 +794,14 @@ return 0; } -unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const { +size_t WebMediaPlayerAndroid::audioDecodedByteCount() const { if (media_source_delegate_) return media_source_delegate_->AudioDecodedByteCount(); NOTIMPLEMENTED(); return 0; } -unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { +size_t WebMediaPlayerAndroid::videoDecodedByteCount() const { if (media_source_delegate_) return media_source_delegate_->VideoDecodedByteCount(); NOTIMPLEMENTED();
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index a25a75d..932b521 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -174,8 +174,8 @@ // Provide statistics. unsigned decodedFrameCount() const override; unsigned droppedFrameCount() const override; - unsigned audioDecodedByteCount() const override; - unsigned videoDecodedByteCount() const override; + size_t audioDecodedByteCount() const override; + size_t videoDecodedByteCount() const override; // cc::VideoFrameProvider implementation. These methods are running on the // compositor thread.
diff --git a/content/renderer/media/html_video_element_capturer_source_unittest.cc b/content/renderer/media/html_video_element_capturer_source_unittest.cc index 89e518bf..56401b8 100644 --- a/content/renderer/media/html_video_element_capturer_source_unittest.cc +++ b/content/renderer/media/html_video_element_capturer_source_unittest.cc
@@ -67,8 +67,8 @@ unsigned decodedFrameCount() const override { return 0; } unsigned droppedFrameCount() const override { return 0; } unsigned corruptedFrameCount() const override { return 0; } - unsigned audioDecodedByteCount() const override { return 0; } - unsigned videoDecodedByteCount() const override { return 0; } + size_t audioDecodedByteCount() const override { return 0; } + size_t videoDecodedByteCount() const override { return 0; } void paint(blink::WebCanvas* canvas, const blink::WebRect& paint_rectangle,
diff --git a/content/renderer/media/rtc_video_decoder.cc b/content/renderer/media/rtc_video_decoder.cc index 7274869..069f4182 100644 --- a/content/renderer/media/rtc_video_decoder.cc +++ b/content/renderer/media/rtc_video_decoder.cc
@@ -508,7 +508,7 @@ // Create a BitstreamBuffer and send to VDA to decode. media::BitstreamBuffer bitstream_buffer( buffer_data.bitstream_buffer_id, shm_buffer->handle(), buffer_data.size, - base::TimeDelta::FromInternalValue(buffer_data.timestamp)); + 0, base::TimeDelta::FromInternalValue(buffer_data.timestamp)); const bool inserted = bitstream_buffers_in_decoder_.insert( std::make_pair(bitstream_buffer.id(), shm_buffer.release())).second;
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc index 0a726303..9f59a76 100644 --- a/content/renderer/media/webmediaplayer_ms.cc +++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -368,13 +368,13 @@ return compositor_->dropped_frame_count(); } -unsigned WebMediaPlayerMS::audioDecodedByteCount() const { +size_t WebMediaPlayerMS::audioDecodedByteCount() const { DCHECK(thread_checker_.CalledOnValidThread()); NOTIMPLEMENTED(); return 0; } -unsigned WebMediaPlayerMS::videoDecodedByteCount() const { +size_t WebMediaPlayerMS::videoDecodedByteCount() const { DCHECK(thread_checker_.CalledOnValidThread()); NOTIMPLEMENTED(); return 0;
diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h index e43afba3..28e7a160 100644 --- a/content/renderer/media/webmediaplayer_ms.h +++ b/content/renderer/media/webmediaplayer_ms.h
@@ -131,8 +131,8 @@ unsigned decodedFrameCount() const override; unsigned droppedFrameCount() const override; - unsigned audioDecodedByteCount() const override; - unsigned videoDecodedByteCount() const override; + size_t audioDecodedByteCount() const override; + size_t videoDecodedByteCount() const override; // WebMediaPlayerDelegate::Observer implementation. void OnHidden(bool must_suspend) override;
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc index c513c11..eb49d9d 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -473,9 +473,9 @@ switches::kEnforceWebRtcIPPermissionCheck); create_media_permission = create_media_permission || - StartsWith(base::FieldTrialList::FindFullName( - "WebRTC-LocalIPPermissionCheck"), - "Enabled", base::CompareCase::SENSITIVE); + !StartsWith(base::FieldTrialList::FindFullName( + "WebRTC-LocalIPPermissionCheck"), + "Disabled", base::CompareCase::SENSITIVE); if (create_media_permission) { content::RenderFrameImpl* render_frame = content::RenderFrameImpl::FromWebFrame(web_frame);
diff --git a/content/renderer/pepper/v8_var_converter_unittest.cc b/content/renderer/pepper/v8_var_converter_unittest.cc index e030ffdb..cd07abb 100644 --- a/content/renderer/pepper/v8_var_converter_unittest.cc +++ b/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -29,7 +29,6 @@ #include "ppapi/shared_impl/var.h" #include "ppapi/shared_impl/var_tracker.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" #include "v8/include/v8.h" using ppapi::ArrayBufferVar; @@ -404,7 +403,6 @@ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - blink::WebScopedMicrotaskSuppression microtasks_scope; const char* source = "(function() {"
diff --git a/content/renderer/push_messaging/push_messaging_dispatcher.cc b/content/renderer/push_messaging/push_messaging_dispatcher.cc index ef35db5..d1070432 100644 --- a/content/renderer/push_messaging/push_messaging_dispatcher.cc +++ b/content/renderer/push_messaging/push_messaging_dispatcher.cc
@@ -44,63 +44,46 @@ blink::WebPushSubscriptionCallbacks* callbacks) { DCHECK(service_worker_registration); DCHECK(callbacks); - // If a developer provided an application server key in |options|, skip - // fetching the manifest. - if (options.applicationServerKey.isEmpty()) { - RenderFrameImpl::FromRoutingID(routing_id()) - ->manifest_manager() - ->GetManifest(base::Bind( - &PushMessagingDispatcher::DidGetManifest, base::Unretained(this), - service_worker_registration, options, callbacks)); - } else { - PushSubscriptionOptions content_options; - content_options.user_visible_only = options.userVisibleOnly; - content_options.sender_info = options.applicationServerKey.utf8(); - DoSubscribe(service_worker_registration, content_options, callbacks); - } -} - -void PushMessagingDispatcher::DidGetManifest( - blink::WebServiceWorkerRegistration* service_worker_registration, - const blink::WebPushSubscriptionOptions& options, - blink::WebPushSubscriptionCallbacks* callbacks, - const Manifest& manifest) { - int request_id = subscription_callbacks_.Add(callbacks); - // Get the sender_info from the manifest since it wasn't provided by - // the caller. - if (manifest.IsEmpty()) { - OnSubscribeFromDocumentError( - request_id, PUSH_REGISTRATION_STATUS_MANIFEST_EMPTY_OR_MISSING); - return; - } - - PushSubscriptionOptions content_options; - content_options.user_visible_only = options.userVisibleOnly; - if (!manifest.gcm_sender_id.is_null()) { - content_options.sender_info = - base::UTF16ToUTF8(manifest.gcm_sender_id.string()); - } - - DoSubscribe(service_worker_registration, content_options, callbacks); + RenderFrameImpl::FromRoutingID(routing_id()) + ->manifest_manager() + ->GetManifest(base::Bind( + &PushMessagingDispatcher::DoSubscribe, base::Unretained(this), + service_worker_registration, options, callbacks)); } void PushMessagingDispatcher::DoSubscribe( blink::WebServiceWorkerRegistration* service_worker_registration, - const PushSubscriptionOptions& options, - blink::WebPushSubscriptionCallbacks* callbacks) { + const blink::WebPushSubscriptionOptions& options, + blink::WebPushSubscriptionCallbacks* callbacks, + const Manifest& manifest) { int request_id = subscription_callbacks_.Add(callbacks); int64_t service_worker_registration_id = static_cast<WebServiceWorkerRegistrationImpl*>( service_worker_registration) ->registration_id(); - if (options.sender_info.empty()) { + if (manifest.IsEmpty()) { + OnSubscribeFromDocumentError( + request_id, PUSH_REGISTRATION_STATUS_MANIFEST_EMPTY_OR_MISSING); + return; + } + + std::string sender_id = + manifest.gcm_sender_id.is_null() + ? std::string() + : base::UTF16ToUTF8(manifest.gcm_sender_id.string()); + if (sender_id.empty()) { OnSubscribeFromDocumentError(request_id, PUSH_REGISTRATION_STATUS_NO_SENDER_ID); return; } + Send(new PushMessagingHostMsg_SubscribeFromDocument( - routing_id(), request_id, options, service_worker_registration_id)); + routing_id(), request_id, + manifest.gcm_sender_id.is_null() + ? std::string() + : base::UTF16ToUTF8(manifest.gcm_sender_id.string()), + options.userVisibleOnly, service_worker_registration_id)); } void PushMessagingDispatcher::OnSubscribeFromDocumentSuccess(
diff --git a/content/renderer/push_messaging/push_messaging_dispatcher.h b/content/renderer/push_messaging/push_messaging_dispatcher.h index 71294e2..ca6610b 100644 --- a/content/renderer/push_messaging/push_messaging_dispatcher.h +++ b/content/renderer/push_messaging/push_messaging_dispatcher.h
@@ -29,7 +29,6 @@ namespace content { struct Manifest; -struct PushSubscriptionOptions; class PushMessagingDispatcher : public RenderFrameObserver, public blink::WebPushClient { @@ -47,17 +46,12 @@ const blink::WebPushSubscriptionOptions& options, blink::WebPushSubscriptionCallbacks* callbacks) override; - void DidGetManifest( + void DoSubscribe( blink::WebServiceWorkerRegistration* service_worker_registration, const blink::WebPushSubscriptionOptions& options, blink::WebPushSubscriptionCallbacks* callbacks, const Manifest& manifest); - void DoSubscribe( - blink::WebServiceWorkerRegistration* service_worker_registration, - const PushSubscriptionOptions& options, - blink::WebPushSubscriptionCallbacks* callbacks); - void OnSubscribeFromDocumentSuccess(int32_t request_id, const GURL& endpoint, const std::vector<uint8_t>& p256dh,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 82e5f3c7..6b89e3b6 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -6088,8 +6088,11 @@ if (!connector_) GetServiceRegistry()->ConnectToRemoteService(mojo::GetProxy(&connector_)); mojo::shell::mojom::InterfaceProviderPtr interface_provider; - connector_->Connect(url.spec(), mojo::shell::mojom::kInheritUserID, - GetProxy(&interface_provider), nullptr, + mojo::shell::mojom::IdentityPtr target(mojo::shell::mojom::Identity::New()); + target->name = url.spec(); + target->user_id = mojo::shell::mojom::kInheritUserID; + target->instance = ""; + connector_->Connect(std::move(target), GetProxy(&interface_provider), nullptr, base::Bind(&OnGotInstanceID)); return interface_provider; }
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 24a12685..8a45ff8 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -743,7 +743,7 @@ is_zero_copy_enabled_ = command_line.HasSwitch(switches::kEnableZeroCopy); is_partial_raster_enabled_ = - command_line.HasSwitch(switches::kEnablePartialRaster); + !command_line.HasSwitch(switches::kDisablePartialRaster); is_gpu_memory_buffer_compositor_resources_enabled_ = command_line.HasSwitch( switches::kEnableGpuMemoryBufferCompositorResources);
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 78360857..be020d4c 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -1419,7 +1419,6 @@ // Retrieve the content of this page and compare it with the expected // result. const int kMaxOutputCharacters = 128; - view()->GetWebView()->updateAllLifecyclePhases(); base::string16 output = WebFrameContentDumper::dumpFrameTreeAsText( GetMainFrame(), kMaxOutputCharacters); EXPECT_EQ(base::WideToUTF16(ime_message->result), output); @@ -1470,7 +1469,6 @@ // Copy the document content to std::wstring and compare with the // expected result. const int kMaxOutputCharacters = 16; - view()->GetWebView()->updateAllLifecyclePhases(); base::string16 output = WebFrameContentDumper::dumpFrameTreeAsText( GetMainFrame(), kMaxOutputCharacters); EXPECT_EQ(base::WideToUTF16(kTextDirection[i].expected_result), output); @@ -1801,7 +1799,6 @@ // Copy the document content to std::wstring and compare with the // expected result. const int kMaxOutputCharacters = 256; - view()->GetWebView()->updateAllLifecyclePhases(); std::string output = base::UTF16ToUTF8( base::StringPiece16(WebFrameContentDumper::dumpFrameTreeAsText( GetMainFrame(), kMaxOutputCharacters))); @@ -1924,7 +1921,6 @@ main_frame->didFailProvisionalLoad(web_frame, error, blink::WebStandardCommit); const int kMaxOutputCharacters = 22; - view()->GetWebView()->updateAllLifecyclePhases(); EXPECT_EQ("", base::UTF16ToASCII(base::StringPiece16( WebFrameContentDumper::dumpFrameTreeAsText( web_frame, kMaxOutputCharacters)))); @@ -1960,7 +1956,6 @@ // The error page itself is loaded asynchronously. FrameLoadWaiter(main_frame).Wait(); const int kMaxOutputCharacters = 22; - view()->GetWebView()->updateAllLifecyclePhases(); EXPECT_EQ("A suffusion of yellow.", base::UTF16ToASCII( base::StringPiece16(WebFrameContentDumper::dumpFrameTreeAsText( @@ -1996,7 +1991,6 @@ // The error page itself is loaded asynchronously. FrameLoadWaiter(main_frame).Wait(); const int kMaxOutputCharacters = 22; - view()->GetWebView()->updateAllLifecyclePhases(); EXPECT_EQ("A suffusion of yellow.", base::UTF16ToASCII( base::StringPiece16(WebFrameContentDumper::dumpFrameTreeAsText(
diff --git a/content/renderer/render_view_browsertest_mac.mm b/content/renderer/render_view_browsertest_mac.mm index ce96f13..2b89084 100644 --- a/content/renderer/render_view_browsertest_mac.mm +++ b/content/renderer/render_view_browsertest_mac.mm
@@ -12,7 +12,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/web/WebFrameContentDumper.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebView.h" #include <Carbon/Carbon.h> // for the kVK_* constants. #include <Cocoa/Cocoa.h> @@ -108,7 +107,6 @@ SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown)); ProcessPendingMessages(); ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset"); - view->GetWebView()->updateAllLifecyclePhases(); output = WebFrameContentDumper::dumpFrameTreeAsText(GetMainFrame(), kMaxOutputCharacters); EXPECT_EQ(kArrowDownScrollDown, base::UTF16ToASCII(output)); @@ -119,7 +117,6 @@ SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown)); ProcessPendingMessages(); ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset"); - view->GetWebView()->updateAllLifecyclePhases(); output = WebFrameContentDumper::dumpFrameTreeAsText(GetMainFrame(), kMaxOutputCharacters); EXPECT_EQ(kArrowUpScrollUp, base::UTF16ToASCII(output)); @@ -135,7 +132,6 @@ SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown)); ProcessPendingMessages(); ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset"); - view->GetWebView()->updateAllLifecyclePhases(); output = WebFrameContentDumper::dumpFrameTreeAsText(GetMainFrame(), kMaxOutputCharacters); EXPECT_EQ(kArrowDownNoScroll, base::UTF16ToASCII(output)); @@ -146,7 +142,6 @@ SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown)); ProcessPendingMessages(); ExecuteJavaScriptForTests("scroll.textContent = window.pageYOffset"); - view->GetWebView()->updateAllLifecyclePhases(); output = WebFrameContentDumper::dumpFrameTreeAsText(GetMainFrame(), kMaxOutputCharacters); EXPECT_EQ(kArrowUpNoScroll, base::UTF16ToASCII(output));
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 9ce9869..4014147b 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1254,7 +1254,6 @@ // sends text in the wrong order. See http://crbug.com/584798. // TODO(dglazkov): WebFrameContentDumper should only be used for // testing purposes. See http://crbug.com/585164. - webview()->updateAllLifecyclePhases(); std::string text = WebFrameContentDumper::dumpFrameTreeAsText( webview()->mainFrame()->toWebLocalFrame(), kMaximumMessageSize)
diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.cc b/content/shell/browser/layout_test/layout_test_push_messaging_service.cc index c346a08..11554e94 100644 --- a/content/shell/browser/layout_test/layout_test_push_messaging_service.cc +++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/macros.h" #include "content/public/browser/permission_type.h" -#include "content/public/common/push_subscription_options.h" #include "content/shell/browser/layout_test/layout_test_browser_context.h" #include "content/shell/browser/layout_test/layout_test_content_browser_client.h" #include "content/shell/browser/layout_test/layout_test_permission_manager.h" @@ -68,20 +67,22 @@ void LayoutTestPushMessagingService::SubscribeFromDocument( const GURL& requesting_origin, int64_t service_worker_registration_id, + const std::string& sender_id, int renderer_id, int render_frame_id, - const PushSubscriptionOptions& options, + bool user_visible, const PushMessagingService::RegisterCallback& callback) { SubscribeFromWorker(requesting_origin, service_worker_registration_id, - options, callback); + sender_id, user_visible, callback); } void LayoutTestPushMessagingService::SubscribeFromWorker( const GURL& requesting_origin, int64_t service_worker_registration_id, - const PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, const PushMessagingService::RegisterCallback& callback) { - if (GetPermissionStatus(requesting_origin, options.user_visible_only) == + if (GetPermissionStatus(requesting_origin, user_visible) == blink::WebPushPermissionStatusGranted) { std::vector<uint8_t> p256dh( kTestP256Key, kTestP256Key + arraysize(kTestP256Key));
diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.h b/content/shell/browser/layout_test/layout_test_push_messaging_service.h index 5e5a7a48..eb5e7e4 100644 --- a/content/shell/browser/layout_test/layout_test_push_messaging_service.h +++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.h
@@ -17,8 +17,6 @@ namespace content { -struct PushSubscriptionOptions; - class LayoutTestPushMessagingService : public PushMessagingService { public: LayoutTestPushMessagingService(); @@ -29,14 +27,16 @@ void SubscribeFromDocument( const GURL& requesting_origin, int64_t service_worker_registration_id, + const std::string& sender_id, int renderer_id, int render_frame_id, - const PushSubscriptionOptions& options, + bool user_visible, const PushMessagingService::RegisterCallback& callback) override; void SubscribeFromWorker( const GURL& requesting_origin, int64_t service_worker_registration_id, - const PushSubscriptionOptions& options, + const std::string& sender_id, + bool user_visible, const PushMessagingService::RegisterCallback& callback) override; void GetEncryptionInfo( const GURL& origin,
diff --git a/content/test/data/web_ui_mojo_shell_test.js b/content/test/data/web_ui_mojo_shell_test.js index ab0661d5..b43a4f4c 100644 --- a/content/test/data/web_ui_mojo_shell_test.js +++ b/content/test/data/web_ui_mojo_shell_test.js
@@ -34,8 +34,12 @@ var connector = new connectorMojom.Connector.proxyClass( new router.Router(connectorPipe)); + var identity = {}; + identity.name = TEST_APP_URL; + identity.user_id = connectorMojom.kInheritUserID; + identity.instance = ""; connector.connect( - TEST_APP_URL, connectorMojom.kInheritUserID, + identity, function (services) { var test = connectToService(services, testMojom.TestMojoService); test.getRequestorName().then(function(response) {
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 9d9b366..7ff3f55b 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1169,6 +1169,8 @@ ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY, ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY, INPUTMETHODPRIVATE_NOTIFYIMEMENUITEMACTIVATED, + INPUT_IME_SHOWWINDOW, + INPUT_IME_HIDEWINDOW, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/common/features/base_feature_provider.cc b/extensions/common/features/base_feature_provider.cc index 8bcec82c..069de38 100644 --- a/extensions/common/features/base_feature_provider.cc +++ b/extensions/common/features/base_feature_provider.cc
@@ -149,19 +149,12 @@ BaseFeatureProvider::~BaseFeatureProvider() { } -const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() - const { - if (feature_names_.empty()) { - for (const auto& feature : features_) - feature_names_.push_back(feature.first); - // A std::map is sorted by its keys, so we don't need to sort feature_names_ - // now. - } - return feature_names_; +const FeatureMap& BaseFeatureProvider::GetAllFeatures() const { + return features_; } Feature* BaseFeatureProvider::GetFeature(const std::string& name) const { - const auto iter = features_.find(name); + FeatureMap::const_iterator iter = features_.find(name); if (iter != features_.end()) return iter->second.get(); else @@ -186,15 +179,17 @@ std::vector<Feature*> BaseFeatureProvider::GetChildren(const Feature& parent) const { std::string prefix = parent.name() + "."; - const auto first_child = features_.lower_bound(prefix); + const FeatureMap::const_iterator first_child = features_.lower_bound(prefix); // All children have names before (parent.name() + ('.'+1)). ++prefix[prefix.size() - 1]; - const auto after_children = features_.lower_bound(prefix); + const FeatureMap::const_iterator after_children = + features_.lower_bound(prefix); std::vector<Feature*> result; result.reserve(std::distance(first_child, after_children)); - for (auto it = first_child; it != after_children; ++it) { + for (FeatureMap::const_iterator it = first_child; it != after_children; + ++it) { result.push_back(it->second.get()); } return result;
diff --git a/extensions/common/features/base_feature_provider.h b/extensions/common/features/base_feature_provider.h index 3b766c8..0d61292 100644 --- a/extensions/common/features/base_feature_provider.h +++ b/extensions/common/features/base_feature_provider.h
@@ -35,7 +35,7 @@ Feature* GetParent(Feature* feature) const override; std::vector<Feature*> GetChildren(const Feature& parent) const override; - const std::vector<std::string>& GetAllFeatureNames() const override; + const FeatureMap& GetAllFeatures() const override; private: std::map<std::string, scoped_ptr<Feature>> features_;
diff --git a/extensions/common/features/feature_provider.h b/extensions/common/features/feature_provider.h index 40d8ab8..ae97513 100644 --- a/extensions/common/features/feature_provider.h +++ b/extensions/common/features/feature_provider.h
@@ -5,13 +5,18 @@ #ifndef EXTENSIONS_COMMON_FEATURES_FEATURE_PROVIDER_H_ #define EXTENSIONS_COMMON_FEATURES_FEATURE_PROVIDER_H_ +#include <map> #include <string> #include <vector> +#include "base/memory/scoped_ptr.h" + namespace extensions { class Feature; +using FeatureMap = std::map<std::string, scoped_ptr<Feature>>; + // Implemented by classes that can vend features. class FeatureProvider { public: @@ -52,8 +57,8 @@ // Returns the features inside the |parent| namespace, recursively. virtual std::vector<Feature*> GetChildren(const Feature& parent) const = 0; - // Returns all features described by this instance, in asciibetical order. - virtual const std::vector<std::string>& GetAllFeatureNames() const = 0; + // Returns a map containing all features described by this instance. + virtual const FeatureMap& GetAllFeatures() const = 0; }; } // namespace extensions
diff --git a/extensions/common/manifest.cc b/extensions/common/manifest.cc index 112628f7..8bc2e28 100644 --- a/extensions/common/manifest.cc +++ b/extensions/common/manifest.cc
@@ -146,20 +146,15 @@ const FeatureProvider* manifest_feature_provider = FeatureProvider::GetManifestFeatures(); - const std::vector<std::string>& feature_names = - manifest_feature_provider->GetAllFeatureNames(); - for (std::vector<std::string>::const_iterator feature_name = - feature_names.begin(); - feature_name != feature_names.end(); ++feature_name) { + for (const auto& map_entry : manifest_feature_provider->GetAllFeatures()) { // Use Get instead of HasKey because the former uses path expansion. - if (!value_->Get(*feature_name, NULL)) + if (!value_->Get(map_entry.first, nullptr)) continue; - Feature* feature = manifest_feature_provider->GetFeature(*feature_name); - Feature::Availability result = feature->IsAvailableToManifest( + Feature::Availability result = map_entry.second->IsAvailableToManifest( extension_id_, type_, location_, GetManifestVersion()); if (!result.is_available()) - warnings->push_back(InstallWarning(result.message(), *feature_name)); + warnings->push_back(InstallWarning(result.message(), map_entry.first)); } // Also generate warnings for keys that are not features.
diff --git a/extensions/renderer/activity_log_converter_strategy_unittest.cc b/extensions/renderer/activity_log_converter_strategy_unittest.cc index aa80447..9237cad 100644 --- a/extensions/renderer/activity_log_converter_strategy_unittest.cc +++ b/extensions/renderer/activity_log_converter_strategy_unittest.cc
@@ -6,7 +6,6 @@ #include "base/values.h" #include "extensions/renderer/activity_log_converter_strategy.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" #include "v8/include/v8.h" using content::V8ValueConverter; @@ -123,7 +122,6 @@ "};" "})();"; - blink::WebScopedMicrotaskSuppression microtasks_scope; v8::Local<v8::Script> script( v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); v8::Local<v8::Object> v8_object = script->Run().As<v8::Object>();
diff --git a/extensions/renderer/api_definitions_natives.cc b/extensions/renderer/api_definitions_natives.cc index 61ea7109..96f1f2c 100644 --- a/extensions/renderer/api_definitions_natives.cc +++ b/extensions/renderer/api_definitions_natives.cc
@@ -24,14 +24,10 @@ const v8::FunctionCallbackInfo<v8::Value>& args) { std::vector<std::string> apis; const FeatureProvider* feature_provider = FeatureProvider::GetAPIFeatures(); - const std::vector<std::string>& feature_names = - feature_provider->GetAllFeatureNames(); - for (std::vector<std::string>::const_iterator i = feature_names.begin(); - i != feature_names.end(); - ++i) { - if (!feature_provider->GetParent(feature_provider->GetFeature(*i)) && - context()->GetAvailability(*i).is_available()) { - apis.push_back(*i); + for (const auto& map_entry : feature_provider->GetAllFeatures()) { + if (!feature_provider->GetParent(map_entry.second.get()) && + context()->GetAvailability(map_entry.first).is_available()) { + apis.push_back(map_entry.first); } } args.GetReturnValue().Set(
diff --git a/extensions/renderer/api_test_base.cc b/extensions/renderer/api_test_base.cc index 79f95e27..abf868b 100644 --- a/extensions/renderer/api_test_base.cc +++ b/extensions/renderer/api_test_base.cc
@@ -214,7 +214,7 @@ } void ApiTestEnvironment::RunPromisesAgain() { - v8::MicrotasksScope::PerformCheckpoint(env()->isolate()); + env()->isolate()->RunMicrotasks(); base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&ApiTestEnvironment::RunPromisesAgain, base::Unretained(this)));
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index c3718d9..5ff2616e 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -1345,31 +1345,26 @@ // ones. const FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures(); - const std::vector<std::string>& apis = - api_feature_provider->GetAllFeatureNames(); - for (const std::string& api_name : apis) { - Feature* feature = api_feature_provider->GetFeature(api_name); - DCHECK(feature); - + for (const auto& map_entry : api_feature_provider->GetAllFeatures()) { // Internal APIs are included via require(api_name) from internal code // rather than chrome[api_name]. - if (feature->IsInternal()) + if (map_entry.second->IsInternal()) continue; // If this API has a parent feature (and isn't marked 'noparent'), // then this must be a function or event, so we should not register. - if (api_feature_provider->GetParent(feature) != NULL) + if (api_feature_provider->GetParent(map_entry.second.get()) != nullptr) continue; // Skip chrome.test if this isn't a test. - if (api_name == "test" && + if (map_entry.first == "test" && !base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kTestType)) { continue; } - if (context->IsAnyFeatureAvailableToContext(*feature)) - RegisterBinding(api_name, context); + if (context->IsAnyFeatureAvailableToContext(*map_entry.second.get())) + RegisterBinding(map_entry.first, context); } break; }
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc index 06a4d55..68c4bd1 100644 --- a/extensions/renderer/module_system_test.cc +++ b/extensions/renderer/module_system_test.cc
@@ -253,7 +253,7 @@ } void ModuleSystemTest::RunResolvedPromises() { - v8::MicrotasksScope::PerformCheckpoint(isolate_); + isolate_->RunMicrotasks(); } } // namespace extensions
diff --git a/extensions/renderer/safe_builtins.cc b/extensions/renderer/safe_builtins.cc index 3a66eaf1..3bfa01a 100644 --- a/extensions/renderer/safe_builtins.cc +++ b/extensions/renderer/safe_builtins.cc
@@ -9,7 +9,6 @@ #include "base/strings/stringprintf.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/v8_helpers.h" -#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" namespace extensions { @@ -201,7 +200,6 @@ return; } - blink::WebScopedMicrotaskSuppression microtasks_scope; v8::Local<v8::Value> return_value; if (function->Call(context, recv, argc, argv.get()).ToLocal(&return_value)) info.GetReturnValue().Set(return_value);
diff --git a/gin/run_microtasks_observer.cc b/gin/run_microtasks_observer.cc index 0ca0078..f453a66 100644 --- a/gin/run_microtasks_observer.cc +++ b/gin/run_microtasks_observer.cc
@@ -15,7 +15,7 @@ void RunMicrotasksObserver::DidProcessTask(const base::PendingTask& task) { v8::Isolate::Scope scope(isolate_); - v8::MicrotasksScope::PerformCheckpoint(isolate_); + isolate_->RunMicrotasks(); } } // namespace gin
diff --git a/gin/run_microtasks_observer.h b/gin/run_microtasks_observer.h index ca160be..7f1431f 100644 --- a/gin/run_microtasks_observer.h +++ b/gin/run_microtasks_observer.h
@@ -12,7 +12,7 @@ // Runs any pending v8 Microtasks each time a task is completed. // TODO(hansmuller); At some point perhaps this can be replaced with -// the (currently experimental) v8::MicrotasksPolicy::kAuto method. +// the (currently experimental) Isolate::SetAutorunMicrotasks() method. class RunMicrotasksObserver : public base::MessageLoop::TaskObserver { public:
diff --git a/ipc/attachment_broker_mac_unittest.cc b/ipc/attachment_broker_mac_unittest.cc index 9736c025..9442324 100644 --- a/ipc/attachment_broker_mac_unittest.cc +++ b/ipc/attachment_broker_mac_unittest.cc
@@ -9,6 +9,8 @@ #include <stddef.h> #include <sys/mman.h> +#include <tuple> + #include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" @@ -111,7 +113,7 @@ return base::SharedMemoryHandle(); } - return base::get<1>(p); + return std::get<1>(p); } // |message| must be deserializable as a TestSharedMemoryHandleMsg2. Returns @@ -132,8 +134,8 @@ return false; } - *handle1 = base::get<0>(p); - *handle2 = base::get<1>(p); + *handle1 = std::get<0>(p); + *handle2 = std::get<1>(p); return true; } @@ -868,16 +870,16 @@ return; } - base::SharedMemoryHandle handle1 = base::get<1>(p); - base::SharedMemoryHandle handle2 = base::get<3>(p); + base::SharedMemoryHandle handle1 = std::get<1>(p); + base::SharedMemoryHandle handle2 = std::get<3>(p); bool success1 = CheckContentsOfSharedMemoryHandle(handle1, kDataBuffer1) && CheckContentsOfSharedMemoryHandle(handle2, kDataBuffer2); if (!success1) LOG(ERROR) << "SharedMemoryHandles have wrong contents."; bool success2 = - CheckContentsOfFileDescriptor(base::get<0>(p), kDataBuffer3) && - CheckContentsOfFileDescriptor(base::get<2>(p), kDataBuffer4); + CheckContentsOfFileDescriptor(std::get<0>(p), kDataBuffer3) && + CheckContentsOfFileDescriptor(std::get<2>(p), kDataBuffer4); if (!success2) LOG(ERROR) << "FileDescriptors have wrong contents.";
diff --git a/ipc/attachment_broker_privileged_mac.cc b/ipc/attachment_broker_privileged_mac.cc index c5bed27c..725085b 100644 --- a/ipc/attachment_broker_privileged_mac.cc +++ b/ipc/attachment_broker_privileged_mac.cc
@@ -6,6 +6,8 @@ #include <stdint.h> +#include <tuple> + #include "base/mac/scoped_mach_port.h" #include "base/memory/shared_memory.h" #include "base/process/port_provider_mac.h" @@ -183,7 +185,7 @@ return; } IPC::internal::MachPortAttachmentMac::WireFormat wire_format = - base::get<0>(param); + std::get<0>(param); if (wire_format.destination_process == base::kNullProcessId) { LogError(NO_DESTINATION);
diff --git a/ipc/attachment_broker_privileged_win.cc b/ipc/attachment_broker_privileged_win.cc index c749a09..3ce3ec5 100644 --- a/ipc/attachment_broker_privileged_win.cc +++ b/ipc/attachment_broker_privileged_win.cc
@@ -6,6 +6,8 @@ #include <windows.h> +#include <tuple> + #include "base/process/process.h" #include "ipc/attachment_broker_messages.h" #include "ipc/brokerable_attachment.h" @@ -59,7 +61,7 @@ if (!AttachmentBrokerMsg_DuplicateWinHandle::Read(&message, ¶m)) return; IPC::internal::HandleAttachmentWin::WireFormat wire_format = - base::get<0>(param); + std::get<0>(param); if (wire_format.destination_process == base::kNullProcessId) { LogError(NO_DESTINATION);
diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc index 870e262..9f720c8 100644 --- a/ipc/attachment_broker_privileged_win_unittest.cc +++ b/ipc/attachment_broker_privileged_win_unittest.cc
@@ -6,6 +6,8 @@ #include <windows.h> +#include <tuple> + #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -76,7 +78,7 @@ return ScopedHandle(nullptr); } - IPC::HandleWin handle_win = base::get<1>(p); + IPC::HandleWin handle_win = std::get<1>(p); return ScopedHandle(handle_win.get_handle()); } @@ -97,7 +99,7 @@ return nullptr; } - base::SharedMemoryHandle handle = base::get<0>(p); + base::SharedMemoryHandle handle = std::get<0>(p); scoped_ptr<base::SharedMemory> shared_memory( new base::SharedMemory(handle, false)); @@ -123,9 +125,9 @@ return false; } - IPC::HandleWin handle_win = base::get<0>(p); + IPC::HandleWin handle_win = std::get<0>(p); *h1 = handle_win.get_handle(); - handle_win = base::get<1>(p); + handle_win = std::get<1>(p); *h2 = handle_win.get_handle(); return true; }
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h index 6126b59..ea28d0c 100644 --- a/ipc/ipc_message_macros.h +++ b/ipc/ipc_message_macros.h
@@ -201,8 +201,9 @@ #include <stdint.h> +#include <tuple> + #include "base/profiler/scoped_profile.h" -#include "base/tuple.h" #include "ipc/export_template.h" #include "ipc/ipc_message_templates.h" #include "ipc/ipc_message_utils.h" @@ -248,7 +249,7 @@ #define IPC_SYNC_MESSAGE_ROUTED(msg_class, in, out) \ IPC_MESSAGE_DECL(msg_class, ROUTED, IPC_TUPLE in, IPC_TUPLE out) -#define IPC_TUPLE(...) base::Tuple<__VA_ARGS__> +#define IPC_TUPLE(...) std::tuple<__VA_ARGS__> #define IPC_MESSAGE_DECL(msg_name, kind, in_tuple, out_tuple) \ struct IPC_MESSAGE_EXPORT msg_name##_Meta { \
diff --git a/ipc/ipc_message_templates.h b/ipc/ipc_message_templates.h index 17dfc1b..ac627dd5 100644 --- a/ipc/ipc_message_templates.h +++ b/ipc/ipc_message_templates.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <tuple> #include <type_traits> #include "base/logging.h" @@ -35,7 +36,7 @@ const Tuple& tuple, base::IndexSequence<Ns...>) { // TODO(mdempsky): Apply UnwrapTraits like base::DispatchToMethod? - (obj->*method)(parameter, base::get<Ns>(tuple)...); + (obj->*method)(parameter, std::get<Ns>(tuple)...); } // The following function is for async IPCs which have a dispatcher with an @@ -45,7 +46,7 @@ DispatchToMethod(ObjT* obj, void (ObjT::*method)(P*, Args...), P* parameter, - const base::Tuple<Ts...>& tuple) { + const std::tuple<Ts...>& tuple) { DispatchToMethodImpl(obj, method, parameter, tuple, base::MakeIndexSequence<sizeof...(Ts)>()); } @@ -84,9 +85,9 @@ // Asynchronous message partial specialization. template <typename Meta, typename... Ins> -class MessageT<Meta, base::Tuple<Ins...>, void> : public Message { +class MessageT<Meta, std::tuple<Ins...>, void> : public Message { public: - using Param = base::Tuple<Ins...>; + using Param = std::tuple<Ins...>; enum { ID = Meta::ID }; // TODO(mdempsky): Remove. Uses of MyMessage::Schema::Param can be replaced @@ -127,11 +128,11 @@ // Synchronous message partial specialization. template <typename Meta, typename... Ins, typename... Outs> -class MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>> +class MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>> : public SyncMessage { public: - using SendParam = base::Tuple<Ins...>; - using ReplyParam = base::Tuple<Outs...>; + using SendParam = std::tuple<Ins...>; + using ReplyParam = std::tuple<Outs...>; enum { ID = Meta::ID }; // TODO(mdempsky): Remove. Uses of MyMessage::Schema::{Send,Reply}Param can @@ -186,7 +187,7 @@ bool ok = ReadSendParam(msg, &send_params); Message* reply = SyncMessage::GenerateReply(msg); if (ok) { - base::Tuple<Message&> t = base::MakeRefTuple(*reply); + std::tuple<Message&> t = std::tie(*reply); ConnectMessageAndReply(msg, reply); base::DispatchToMethod(obj, func, send_params, &t); } else {
diff --git a/ipc/ipc_message_templates_impl.h b/ipc/ipc_message_templates_impl.h index bfcdad0..192d2efb 100644 --- a/ipc/ipc_message_templates_impl.h +++ b/ipc/ipc_message_templates_impl.h
@@ -5,37 +5,39 @@ #ifndef IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_ #define IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_ +#include <tuple> + namespace IPC { template <typename... Ts> class ParamDeserializer : public MessageReplyDeserializer { public: - explicit ParamDeserializer(const base::Tuple<Ts&...>& out) : out_(out) {} + explicit ParamDeserializer(const std::tuple<Ts&...>& out) : out_(out) {} bool SerializeOutputParameters(const IPC::Message& msg, base::PickleIterator iter) override { return ReadParam(&msg, &iter, &out_); } - base::Tuple<Ts&...> out_; + std::tuple<Ts&...> out_; }; template <typename Meta, typename... Ins> -MessageT<Meta, base::Tuple<Ins...>, void>::MessageT(Routing routing, +MessageT<Meta, std::tuple<Ins...>, void>::MessageT(Routing routing, const Ins&... ins) : Message(routing.id, ID, PRIORITY_NORMAL) { - WriteParam(this, base::MakeRefTuple(ins...)); + WriteParam(this, std::tie(ins...)); } template <typename Meta, typename... Ins> -bool MessageT<Meta, base::Tuple<Ins...>, void>::Read(const Message* msg, +bool MessageT<Meta, std::tuple<Ins...>, void>::Read(const Message* msg, Param* p) { base::PickleIterator iter(*msg); return ReadParam(msg, &iter, p); } template <typename Meta, typename... Ins> -void MessageT<Meta, base::Tuple<Ins...>, void>::Log(std::string* name, +void MessageT<Meta, std::tuple<Ins...>, void>::Log(std::string* name, const Message* msg, std::string* l) { if (name) @@ -48,7 +50,7 @@ } template <typename Meta, typename... Ins, typename... Outs> -MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>>::MessageT( +MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::MessageT( Routing routing, const Ins&... ins, Outs*... outs) @@ -56,12 +58,12 @@ routing.id, ID, PRIORITY_NORMAL, - new ParamDeserializer<Outs...>(base::MakeRefTuple(*outs...))) { - WriteParam(this, base::MakeRefTuple(ins...)); + new ParamDeserializer<Outs...>(std::tie(*outs...))) { + WriteParam(this, std::tie(ins...)); } template <typename Meta, typename... Ins, typename... Outs> -bool MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>>::ReadSendParam( +bool MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::ReadSendParam( const Message* msg, SendParam* p) { base::PickleIterator iter = SyncMessage::GetDataIterator(msg); @@ -69,7 +71,7 @@ } template <typename Meta, typename... Ins, typename... Outs> -bool MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>>::ReadReplyParam( +bool MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::ReadReplyParam( const Message* msg, ReplyParam* p) { base::PickleIterator iter = SyncMessage::GetDataIterator(msg); @@ -78,14 +80,14 @@ template <typename Meta, typename... Ins, typename... Outs> void MessageT<Meta, - base::Tuple<Ins...>, - base::Tuple<Outs...>>::WriteReplyParams(Message* reply, + std::tuple<Ins...>, + std::tuple<Outs...>>::WriteReplyParams(Message* reply, const Outs&... outs) { - WriteParam(reply, base::MakeRefTuple(outs...)); + WriteParam(reply, std::tie(outs...)); } template <typename Meta, typename... Ins, typename... Outs> -void MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>>::Log( +void MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::Log( std::string* name, const Message* msg, std::string* l) {
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index 971370a2..d92d833 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h
@@ -13,6 +13,7 @@ #include <map> #include <set> #include <string> +#include <tuple> #include <vector> #include "base/containers/small_map.h" @@ -24,7 +25,6 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/tuple.h" #include "build/build_config.h" #include "ipc/brokerable_attachment.h" #include "ipc/ipc_message_start.h" @@ -666,18 +666,18 @@ struct ParamTraits<std::tuple<A>> { typedef std::tuple<A> param_type; static void GetSize(base::PickleSizer* sizer, const param_type& p) { - GetParamSize(sizer, base::get<0>(p)); + GetParamSize(sizer, std::get<0>(p)); } static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, base::get<0>(p)); + WriteParam(m, std::get<0>(p)); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { - return ReadParam(m, iter, &base::get<0>(*r)); + return ReadParam(m, iter, &std::get<0>(*r)); } static void Log(const param_type& p, std::string* l) { - LogParam(base::get<0>(p), l); + LogParam(std::get<0>(p), l); } }; @@ -685,23 +685,23 @@ struct ParamTraits<std::tuple<A, B>> { typedef std::tuple<A, B> param_type; static void GetSize(base::PickleSizer* sizer, const param_type& p) { - GetParamSize(sizer, base::get<0>(p)); - GetParamSize(sizer, base::get<1>(p)); + GetParamSize(sizer, std::get<0>(p)); + GetParamSize(sizer, std::get<1>(p)); } static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, base::get<0>(p)); - WriteParam(m, base::get<1>(p)); + WriteParam(m, std::get<0>(p)); + WriteParam(m, std::get<1>(p)); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &base::get<0>(*r)) && - ReadParam(m, iter, &base::get<1>(*r))); + return (ReadParam(m, iter, &std::get<0>(*r)) && + ReadParam(m, iter, &std::get<1>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(base::get<0>(p), l); + LogParam(std::get<0>(p), l); l->append(", "); - LogParam(base::get<1>(p), l); + LogParam(std::get<1>(p), l); } }; @@ -709,28 +709,28 @@ struct ParamTraits<std::tuple<A, B, C>> { typedef std::tuple<A, B, C> param_type; static void GetSize(base::PickleSizer* sizer, const param_type& p) { - GetParamSize(sizer, base::get<0>(p)); - GetParamSize(sizer, base::get<1>(p)); - GetParamSize(sizer, base::get<2>(p)); + GetParamSize(sizer, std::get<0>(p)); + GetParamSize(sizer, std::get<1>(p)); + GetParamSize(sizer, std::get<2>(p)); } static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, base::get<0>(p)); - WriteParam(m, base::get<1>(p)); - WriteParam(m, base::get<2>(p)); + WriteParam(m, std::get<0>(p)); + WriteParam(m, std::get<1>(p)); + WriteParam(m, std::get<2>(p)); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &base::get<0>(*r)) && - ReadParam(m, iter, &base::get<1>(*r)) && - ReadParam(m, iter, &base::get<2>(*r))); + return (ReadParam(m, iter, &std::get<0>(*r)) && + ReadParam(m, iter, &std::get<1>(*r)) && + ReadParam(m, iter, &std::get<2>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(base::get<0>(p), l); + LogParam(std::get<0>(p), l); l->append(", "); - LogParam(base::get<1>(p), l); + LogParam(std::get<1>(p), l); l->append(", "); - LogParam(base::get<2>(p), l); + LogParam(std::get<2>(p), l); } }; @@ -738,33 +738,33 @@ struct ParamTraits<std::tuple<A, B, C, D>> { typedef std::tuple<A, B, C, D> param_type; static void GetSize(base::PickleSizer* sizer, const param_type& p) { - GetParamSize(sizer, base::get<0>(p)); - GetParamSize(sizer, base::get<1>(p)); - GetParamSize(sizer, base::get<2>(p)); - GetParamSize(sizer, base::get<3>(p)); + GetParamSize(sizer, std::get<0>(p)); + GetParamSize(sizer, std::get<1>(p)); + GetParamSize(sizer, std::get<2>(p)); + GetParamSize(sizer, std::get<3>(p)); } static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, base::get<0>(p)); - WriteParam(m, base::get<1>(p)); - WriteParam(m, base::get<2>(p)); - WriteParam(m, base::get<3>(p)); + WriteParam(m, std::get<0>(p)); + WriteParam(m, std::get<1>(p)); + WriteParam(m, std::get<2>(p)); + WriteParam(m, std::get<3>(p)); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &base::get<0>(*r)) && - ReadParam(m, iter, &base::get<1>(*r)) && - ReadParam(m, iter, &base::get<2>(*r)) && - ReadParam(m, iter, &base::get<3>(*r))); + return (ReadParam(m, iter, &std::get<0>(*r)) && + ReadParam(m, iter, &std::get<1>(*r)) && + ReadParam(m, iter, &std::get<2>(*r)) && + ReadParam(m, iter, &std::get<3>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(base::get<0>(p), l); + LogParam(std::get<0>(p), l); l->append(", "); - LogParam(base::get<1>(p), l); + LogParam(std::get<1>(p), l); l->append(", "); - LogParam(base::get<2>(p), l); + LogParam(std::get<2>(p), l); l->append(", "); - LogParam(base::get<3>(p), l); + LogParam(std::get<3>(p), l); } }; @@ -772,38 +772,38 @@ struct ParamTraits<std::tuple<A, B, C, D, E>> { typedef std::tuple<A, B, C, D, E> param_type; static void GetSize(base::PickleSizer* sizer, const param_type& p) { - GetParamSize(sizer, base::get<0>(p)); - GetParamSize(sizer, base::get<1>(p)); - GetParamSize(sizer, base::get<2>(p)); - GetParamSize(sizer, base::get<3>(p)); - GetParamSize(sizer, base::get<4>(p)); + GetParamSize(sizer, std::get<0>(p)); + GetParamSize(sizer, std::get<1>(p)); + GetParamSize(sizer, std::get<2>(p)); + GetParamSize(sizer, std::get<3>(p)); + GetParamSize(sizer, std::get<4>(p)); } static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, base::get<0>(p)); - WriteParam(m, base::get<1>(p)); - WriteParam(m, base::get<2>(p)); - WriteParam(m, base::get<3>(p)); - WriteParam(m, base::get<4>(p)); + WriteParam(m, std::get<0>(p)); + WriteParam(m, std::get<1>(p)); + WriteParam(m, std::get<2>(p)); + WriteParam(m, std::get<3>(p)); + WriteParam(m, std::get<4>(p)); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &base::get<0>(*r)) && - ReadParam(m, iter, &base::get<1>(*r)) && - ReadParam(m, iter, &base::get<2>(*r)) && - ReadParam(m, iter, &base::get<3>(*r)) && - ReadParam(m, iter, &base::get<4>(*r))); + return (ReadParam(m, iter, &std::get<0>(*r)) && + ReadParam(m, iter, &std::get<1>(*r)) && + ReadParam(m, iter, &std::get<2>(*r)) && + ReadParam(m, iter, &std::get<3>(*r)) && + ReadParam(m, iter, &std::get<4>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(base::get<0>(p), l); + LogParam(std::get<0>(p), l); l->append(", "); - LogParam(base::get<1>(p), l); + LogParam(std::get<1>(p), l); l->append(", "); - LogParam(base::get<2>(p), l); + LogParam(std::get<2>(p), l); l->append(", "); - LogParam(base::get<3>(p), l); + LogParam(std::get<3>(p), l); l->append(", "); - LogParam(base::get<4>(p), l); + LogParam(std::get<4>(p), l); } };
diff --git a/mash/browser_driver/browser_driver_application_delegate.cc b/mash/browser_driver/browser_driver_application_delegate.cc index 1e14d16..64ee8e4 100644 --- a/mash/browser_driver/browser_driver_application_delegate.cc +++ b/mash/browser_driver/browser_driver_application_delegate.cc
@@ -50,10 +50,10 @@ BrowserDriverApplicationDelegate::~BrowserDriverApplicationDelegate() {} -void BrowserDriverApplicationDelegate::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, - uint32_t id) { +void BrowserDriverApplicationDelegate::Initialize( + mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) { connector_ = connector; AddAccelerators(); }
diff --git a/mash/browser_driver/browser_driver_application_delegate.h b/mash/browser_driver/browser_driver_application_delegate.h index 03d67d38..2d722f4 100644 --- a/mash/browser_driver/browser_driver_application_delegate.h +++ b/mash/browser_driver/browser_driver_application_delegate.h
@@ -27,8 +27,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // mus::mojom::AcceleratorHandler:
diff --git a/mash/example/views_examples/views_examples_application_delegate.cc b/mash/example/views_examples/views_examples_application_delegate.cc index b3b87e9..8bc5678d 100644 --- a/mash/example/views_examples/views_examples_application_delegate.cc +++ b/mash/example/views_examples/views_examples_application_delegate.cc
@@ -16,11 +16,11 @@ ViewsExamplesApplicationDelegate::~ViewsExamplesApplicationDelegate() { } -void ViewsExamplesApplicationDelegate::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, - uint32_t id) { - tracing_.Initialize(connector, url); +void ViewsExamplesApplicationDelegate::Initialize( + mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) { + tracing_.Initialize(connector, identity.name()); aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); views::WindowManagerConnection::Create(connector);
diff --git a/mash/example/views_examples/views_examples_application_delegate.h b/mash/example/views_examples/views_examples_application_delegate.h index cb1ab50c..3b4fb112 100644 --- a/mash/example/views_examples/views_examples_application_delegate.h +++ b/mash/example/views_examples/views_examples_application_delegate.h
@@ -21,8 +21,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; mojo::TracingImpl tracing_;
diff --git a/mash/example/window_type_launcher/window_type_launcher.cc b/mash/example/window_type_launcher/window_type_launcher.cc index 141bb3f..106dfc10 100644 --- a/mash/example/window_type_launcher/window_type_launcher.cc +++ b/mash/example/window_type_launcher/window_type_launcher.cc
@@ -356,8 +356,7 @@ WindowTypeLauncher::~WindowTypeLauncher() {} void WindowTypeLauncher::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
diff --git a/mash/example/window_type_launcher/window_type_launcher.h b/mash/example/window_type_launcher/window_type_launcher.h index c5bad8a..dbbf40f 100644 --- a/mash/example/window_type_launcher/window_type_launcher.h +++ b/mash/example/window_type_launcher/window_type_launcher.h
@@ -20,8 +20,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; scoped_ptr<views::AuraInit> aura_init_;
diff --git a/mash/init/init.cc b/mash/init/init.cc index c7197dd..98aea78 100644 --- a/mash/init/init.cc +++ b/mash/init/init.cc
@@ -15,8 +15,9 @@ Init::Init() : connector_(nullptr) {} Init::~Init() {} -void Init::Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) { +void Init::Initialize(mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) { connector_ = connector; mus_connection_ = connector_->Connect("mojo:mus"); StartWindowManager(); @@ -26,8 +27,8 @@ void Init::LoginAs(const mojo::String& user_id) { connections_["mojo:mash_login"].reset(); connections_["mojo:desktop_wm"].reset(); - mojo::Connector::ConnectParams params("mojo:mash_shell"); - params.set_user_id(user_id); + mojo::Connector::ConnectParams params( + mojo::Identity("mojo:mash_shell", user_id)); connector_->Connect(¶ms); } @@ -36,16 +37,14 @@ } void Init::StartWindowManager() { - mojo::Connector::ConnectParams params("mojo:desktop_wm"); - params.set_user_id("2"); + mojo::Connector::ConnectParams params(mojo::Identity("mojo:desktop_wm", "2")); StartRestartableService( ¶ms, base::Bind(&Init::StartWindowManager, base::Unretained(this))); } void Init::StartLogin() { - mojo::Connector::ConnectParams params("mojo:mash_login"); - params.set_user_id("2"); + mojo::Connector::ConnectParams params(mojo::Identity("mojo:mash_login", "2")); StartRestartableService( ¶ms, base::Bind(&Init::StartLogin, base::Unretained(this))); @@ -60,7 +59,7 @@ if (connection) { connection->SetConnectionLostClosure(restart_callback); connection->AddInterface<mojom::Login>(this); - connections_[params->name()] = std::move(connection); + connections_[params->target().name()] = std::move(connection); } }
diff --git a/mash/init/init.h b/mash/init/init.h index 812967a..04812c10 100644 --- a/mash/init/init.h +++ b/mash/init/init.h
@@ -31,8 +31,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; // mojom::Login: void LoginAs(const mojo::String& user_id) override;
diff --git a/mash/login/login.cc b/mash/login/login.cc index 2e26b4a..49bfd34 100644 --- a/mash/login/login.cc +++ b/mash/login/login.cc
@@ -93,9 +93,10 @@ Login::Login() {} Login::~Login() {} -void Login::Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) { - tracing_.Initialize(connector, url); +void Login::Initialize(mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) { + tracing_.Initialize(connector, identity.name()); aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); views::WindowManagerConnection::Create(connector); @@ -118,7 +119,7 @@ } bool Login::AcceptConnection(mojo::Connection* connection) { - if (connection->GetRemoteApplicationName() == "mojo:mash_init") { + if (connection->GetRemoteIdentity().name() == "mojo:mash_init") { connection->GetInterface(&login_); return true; }
diff --git a/mash/login/login.h b/mash/login/login.h index 53fcbf6..88216b3 100644 --- a/mash/login/login.h +++ b/mash/login/login.h
@@ -29,8 +29,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; mojo::TracingImpl tracing_;
diff --git a/mash/quick_launch/quick_launch_application.cc b/mash/quick_launch/quick_launch_application.cc index d00baf3..c4887a49 100644 --- a/mash/quick_launch/quick_launch_application.cc +++ b/mash/quick_launch/quick_launch_application.cc
@@ -89,10 +89,9 @@ QuickLaunchApplication::~QuickLaunchApplication() {} void QuickLaunchApplication::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); views::WindowManagerConnection::Create(connector);
diff --git a/mash/quick_launch/quick_launch_application.h b/mash/quick_launch/quick_launch_application.h index 8fbd6508..130a1dd 100644 --- a/mash/quick_launch/quick_launch_application.h +++ b/mash/quick_launch/quick_launch_application.h
@@ -25,8 +25,7 @@ private: // mojo::ShellClient: void Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override;
diff --git a/mash/screenlock/screenlock.cc b/mash/screenlock/screenlock.cc index 42f2b04..60f6f1e 100644 --- a/mash/screenlock/screenlock.cc +++ b/mash/screenlock/screenlock.cc
@@ -75,9 +75,10 @@ Screenlock::Screenlock() {} Screenlock::~Screenlock() {} -void Screenlock::Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) { - tracing_.Initialize(connector, url); +void Screenlock::Initialize(mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) { + tracing_.Initialize(connector, identity.name()); mash::shell::mojom::ShellPtr mash_shell; connector->ConnectToInterface("mojo:mash_shell", &mash_shell);
diff --git a/mash/screenlock/screenlock.h b/mash/screenlock/screenlock.h index e6c0611..f1d2755 100644 --- a/mash/screenlock/screenlock.h +++ b/mash/screenlock/screenlock.h
@@ -29,8 +29,9 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) override; // mash::shell::mojom::ScreenlockStateListener: void ScreenlockStateChanged(bool locked) override;
diff --git a/mash/shell/shell_application_delegate.cc b/mash/shell/shell_application_delegate.cc index ff472e79..8c217bc 100644 --- a/mash/shell/shell_application_delegate.cc +++ b/mash/shell/shell_application_delegate.cc
@@ -18,8 +18,7 @@ ShellApplicationDelegate::~ShellApplicationDelegate() {} void ShellApplicationDelegate::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { connector_ = connector; StartBrowserDriver();
diff --git a/mash/shell/shell_application_delegate.h b/mash/shell/shell_application_delegate.h index 99b24eda..ba692e87 100644 --- a/mash/shell/shell_application_delegate.h +++ b/mash/shell/shell_application_delegate.h
@@ -33,8 +33,9 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // mash::shell::mojom::Shell:
diff --git a/mash/task_viewer/task_viewer.cc b/mash/task_viewer/task_viewer.cc index e3af3da..4a26c4f 100644 --- a/mash/task_viewer/task_viewer.cc +++ b/mash/task_viewer/task_viewer.cc
@@ -142,8 +142,9 @@ DCHECK(instances_.empty()); mojo::Array<mojo::String> names; for (size_t i = 0; i < instances.size(); ++i) { - InsertInstance(instances[i]->id, instances[i]->name, instances[i]->pid); - names.push_back(instances[i]->name); + InsertInstance(instances[i]->id, instances[i]->identity->name, + instances[i]->pid); + names.push_back(instances[i]->identity->name); } catalog_->GetEntries(std::move(names), base::Bind(&TaskViewerContents::OnGotCatalogEntries, @@ -151,10 +152,10 @@ } void InstanceCreated(InstanceInfoPtr instance) override { DCHECK(!ContainsId(instance->id)); - InsertInstance(instance->id, instance->name, instance->pid); + InsertInstance(instance->id, instance->identity->name, instance->pid); observer_->OnItemsAdded(static_cast<int>(instances_.size()), 1); mojo::Array<mojo::String> names; - names.push_back(instance->name); + names.push_back(instance->identity->name); catalog_->GetEntries(std::move(names), base::Bind(&TaskViewerContents::OnGotCatalogEntries, weak_ptr_factory_.GetWeakPtr())); @@ -259,10 +260,9 @@ TaskViewer::~TaskViewer() {} void TaskViewer::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak")); views::WindowManagerConnection::Create(connector);
diff --git a/mash/task_viewer/task_viewer.h b/mash/task_viewer/task_viewer.h index 0a696cd..e5eeae09 100644 --- a/mash/task_viewer/task_viewer.h +++ b/mash/task_viewer/task_viewer.h
@@ -27,8 +27,9 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, + const mojo::Identity& identity, + uint32_t id) override; mojo::TracingImpl tracing_; scoped_ptr<views::AuraInit> aura_init_;
diff --git a/mash/wm/window_manager_application.cc b/mash/wm/window_manager_application.cc index 6511c94..91fb08e 100644 --- a/mash/wm/window_manager_application.cc +++ b/mash/wm/window_manager_application.cc
@@ -104,11 +104,10 @@ } void WindowManagerApplication::Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) { connector_ = connector; - tracing_.Initialize(connector, url); + tracing_.Initialize(connector, identity.name()); mus::mojom::WindowManagerFactoryServicePtr wm_factory_service; connector_->ConnectToInterface("mojo:mus", &wm_factory_service); @@ -121,7 +120,7 @@ bool WindowManagerApplication::AcceptConnection(mojo::Connection* connection) { connection->AddInterface<mash::wm::mojom::UserWindowController>(this); connection->AddInterface<mus::mojom::AcceleratorRegistrar>(this); - if (connection->GetRemoteApplicationName() == "mojo:mash_shell") + if (connection->GetRemoteIdentity().name() == "mojo:mash_shell") connection->GetInterface(&mash_shell_); return true; }
diff --git a/mash/wm/window_manager_application.h b/mash/wm/window_manager_application.h index 0eedaab..bb517dcd 100644 --- a/mash/wm/window_manager_application.h +++ b/mash/wm/window_manager_application.h
@@ -83,8 +83,8 @@ void OnAcceleratorRegistrarDestroyed(AcceleratorRegistrarImpl* registrar); // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override; bool AcceptConnection(mojo::Connection* connection) override; // InterfaceFactory<mash::wm::mojom::UserWindowController>:
diff --git a/media/BUILD.gn b/media/BUILD.gn index 01d09d1..100df8b 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -417,8 +417,6 @@ "formats/mp4/box_definitions.h", "formats/mp4/box_reader.cc", "formats/mp4/box_reader.h", - "formats/mp4/cenc.cc", - "formats/mp4/cenc.h", "formats/mp4/es_descriptor.cc", "formats/mp4/es_descriptor.h", "formats/mp4/mp4_stream_parser.cc",
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc index 1aa4ae4..9e9df76 100644 --- a/media/audio/mac/audio_low_latency_input_mac.cc +++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -32,15 +32,6 @@ // if input callbacks have started, and false otherwise. const int kInputCallbackStartTimeoutInSeconds = 5; -// Replaces AudioManagerMac::kStartDelayInSecsForPowerEvents to allow for a -// longer delay when calling Start() in conjunction to a power resume event. -// If it is detected that Start() should be deferred, we wait this amount of -// time before trying Start() again. The default value in AudioManagerMac is -// 2 seconds. -// TODO(henrika): investigate if an increase results in a lower frequency of -// detecting no input callbacks at startup. -const int kStartDelayInSecsForPowerEvents = 4; - // Returns true if the format flags in |format_flags| has the "non-interleaved" // flag (kAudioFormatFlagIsNonInterleaved) cleared (set to 0). static bool FormatIsInterleaved(UInt32 format_flags) { @@ -485,7 +476,8 @@ &AUAudioInputStream::Start, base::Unretained(this), callback)); manager_->GetTaskRunner()->PostDelayedTask( FROM_HERE, deferred_start_cb_.callback(), - base::TimeDelta::FromSeconds(kStartDelayInSecsForPowerEvents)); + base::TimeDelta::FromSeconds( + AudioManagerMac::kStartDelayInSecsForPowerEvents)); return; }
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h index b82aa60..2112a883 100644 --- a/media/audio/mac/audio_manager_mac.h +++ b/media/audio/mac/audio_manager_mac.h
@@ -71,7 +71,9 @@ // Streams should consult ShouldDeferStreamStart() and if true check the value // again after |kStartDelayInSecsForPowerEvents| has elapsed. If false, the // stream may be started immediately. - enum { kStartDelayInSecsForPowerEvents = 2 }; + // TOOD(henrika): track UMA statistics related to defer start to come up with + // a suitable delay value. + enum { kStartDelayInSecsForPowerEvents = 5 }; bool ShouldDeferStreamStart() const; // True if the device is on battery power.
diff --git a/media/base/bitstream_buffer.cc b/media/base/bitstream_buffer.cc index 3378170..5a1907db 100644 --- a/media/base/bitstream_buffer.cc +++ b/media/base/bitstream_buffer.cc
@@ -7,23 +7,17 @@ namespace media { BitstreamBuffer::BitstreamBuffer() - : id_(-1), size_(0), presentation_timestamp_(kNoTimestamp()) {} - -BitstreamBuffer::BitstreamBuffer(int32_t id, - base::SharedMemoryHandle handle, - size_t size) - : id_(id), - handle_(handle), - size_(size), - presentation_timestamp_(kNoTimestamp()) {} + : BitstreamBuffer(-1, base::SharedMemoryHandle(), 0) {} BitstreamBuffer::BitstreamBuffer(int32_t id, base::SharedMemoryHandle handle, size_t size, + off_t offset, base::TimeDelta presentation_timestamp) : id_(id), handle_(handle), size_(size), + offset_(offset), presentation_timestamp_(presentation_timestamp) {} BitstreamBuffer::BitstreamBuffer(const BitstreamBuffer& other) = default;
diff --git a/media/base/bitstream_buffer.h b/media/base/bitstream_buffer.h index 42451cc..c8983f2 100644 --- a/media/base/bitstream_buffer.h +++ b/media/base/bitstream_buffer.h
@@ -24,12 +24,17 @@ public: BitstreamBuffer(); - BitstreamBuffer(int32_t id, base::SharedMemoryHandle handle, size_t size); - + // Constructs a new BitstreamBuffer. The content of the bitstream is located + // at |offset| bytes away from the start of the shared memory and the payload + // is |size| bytes. When not provided, the default value for |offset| is 0. + // |presentation_timestamp| is when the decoded frame should be displayed. + // When not provided, |presentation_timestamp| will be + // |media::kNoTimestamp()|. BitstreamBuffer(int32_t id, base::SharedMemoryHandle handle, size_t size, - base::TimeDelta presentation_timestamp); + off_t offset = 0, + base::TimeDelta presentation_timestamp = kNoTimestamp()); BitstreamBuffer(const BitstreamBuffer& other); @@ -39,15 +44,21 @@ int32_t id() const { return id_; } base::SharedMemoryHandle handle() const { return handle_; } + + // The number of bytes of the actual bitstream data. It is the size of the + // content instead of the whole shared memory. size_t size() const { return size_; } - void set_handle(const base::SharedMemoryHandle& handle) { handle_ = handle; } + // The offset to the start of actual bitstream data in the shared memory. + off_t offset() const { return offset_; } // The timestamp is only valid if it's not equal to |media::kNoTimestamp()|. base::TimeDelta presentation_timestamp() const { return presentation_timestamp_; } + void set_handle(const base::SharedMemoryHandle& handle) { handle_ = handle; } + // The following methods come from DecryptConfig. const std::string& key_id() const { return key_id_; } @@ -58,6 +69,7 @@ int32_t id_; base::SharedMemoryHandle handle_; size_t size_; + off_t offset_; // This is only set when necessary. For example, AndroidVideoDecodeAccelerator // needs the timestamp because the underlying decoder may require it to
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 3d466526..07e2aad 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -717,14 +717,14 @@ return stats.video_frames_dropped; } -unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { +size_t WebMediaPlayerImpl::audioDecodedByteCount() const { DCHECK(main_task_runner_->BelongsToCurrentThread()); PipelineStatistics stats = pipeline_.GetStatistics(); return stats.audio_bytes_decoded; } -unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { +size_t WebMediaPlayerImpl::videoDecodedByteCount() const { DCHECK(main_task_runner_->BelongsToCurrentThread()); PipelineStatistics stats = pipeline_.GetStatistics();
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 5ae347c..9cba070 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -147,8 +147,8 @@ unsigned decodedFrameCount() const override; unsigned droppedFrameCount() const override; - unsigned audioDecodedByteCount() const override; - unsigned videoDecodedByteCount() const override; + size_t audioDecodedByteCount() const override; + size_t videoDecodedByteCount() const override; bool copyVideoTextureToPlatformTexture( blink::WebGraphicsContext3D* web_graphics_context,
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index 260bfaab..aa052dd 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc
@@ -334,7 +334,7 @@ // AndroidVideoDecodeAccelerator needs the timestamp to output frames in // presentation order. BitstreamBuffer bitstream_buffer(next_bitstream_buffer_id_, - shm_buffer->shm->handle(), size, + shm_buffer->shm->handle(), size, 0, buffer->timestamp()); if (buffer->decrypt_config())
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc index a792c90..705232f4e 100644 --- a/media/formats/mp4/box_definitions.cc +++ b/media/formats/mp4/box_definitions.cc
@@ -138,6 +138,65 @@ return true; } +SampleEncryptionEntry::SampleEncryptionEntry() {} +SampleEncryptionEntry::~SampleEncryptionEntry() {} + +bool SampleEncryptionEntry::Parse(BufferReader* reader, + uint8_t iv_size, + bool has_subsamples) { + // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either + // 64-bit (8-byte) or 128-bit (16-byte). + RCHECK(iv_size == 8 || iv_size == 16); + + memset(initialization_vector, 0, sizeof(initialization_vector)); + for (uint8_t i = 0; i < iv_size; i++) + RCHECK(reader->Read1(initialization_vector + i)); + + if (!has_subsamples) { + subsamples.clear(); + return true; + } + + uint16_t subsample_count; + RCHECK(reader->Read2(&subsample_count)); + RCHECK(subsample_count > 0); + subsamples.resize(subsample_count); + for (SubsampleEntry& subsample : subsamples) { + uint16_t clear_bytes; + uint32_t cypher_bytes; + RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes)); + subsample.clear_bytes = clear_bytes; + subsample.cypher_bytes = cypher_bytes; + } + return true; +} + +bool SampleEncryptionEntry::GetTotalSizeOfSubsamples(size_t* total_size) const { + size_t size = 0; + for (const SubsampleEntry& subsample : subsamples) { + size += subsample.clear_bytes; + RCHECK(size >= subsample.clear_bytes); // overflow + size += subsample.cypher_bytes; + RCHECK(size >= subsample.cypher_bytes); // overflow + } + *total_size = size; + return true; +} + +SampleEncryption::SampleEncryption() : use_subsample_encryption(false) {} +SampleEncryption::~SampleEncryption() {} +FourCC SampleEncryption::BoxType() const { + return FOURCC_SENC; +} + +bool SampleEncryption::Parse(BoxReader* reader) { + RCHECK(reader->ReadFullBoxHeader()); + use_subsample_encryption = (reader->flags() & kUseSubsampleEncryption) != 0; + sample_encryption_data.assign(reader->data() + reader->pos(), + reader->data() + reader->size()); + return true; +} + OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {} OriginalFormat::~OriginalFormat() {} FourCC OriginalFormat::BoxType() const { return FOURCC_FRMA; }
diff --git a/media/formats/mp4/box_definitions.h b/media/formats/mp4/box_definitions.h index e6a62bba..542f4de 100644 --- a/media/formats/mp4/box_definitions.h +++ b/media/formats/mp4/box_definitions.h
@@ -12,6 +12,7 @@ #include <vector> #include "base/compiler_specific.h" +#include "media/base/decrypt_config.h" #include "media/base/media_export.h" #include "media/base/media_log.h" #include "media/base/video_codecs.h" @@ -78,6 +79,39 @@ std::vector<uint8_t> sample_info_sizes; }; +// Represent an entry in SampleEncryption box or CENC auxiliary info. +struct MEDIA_EXPORT SampleEncryptionEntry { + SampleEncryptionEntry(); + ~SampleEncryptionEntry(); + + // Parse SampleEncryptionEntry from |reader|. + // |iv_size| specifies the size of initialization vector. |has_subsamples| + // indicates whether this sample encryption entry constains subsamples. + // Returns false if parsing fails. + bool Parse(BufferReader* reader, uint8_t iv_size, bool has_subsamples); + + // Get accumulated size of subsamples. Returns false if there is an overflow + // anywhere. + bool GetTotalSizeOfSubsamples(size_t* total_size) const; + + uint8_t initialization_vector[16]; + std::vector<SubsampleEntry> subsamples; +}; + +// ISO/IEC 23001-7:2015 8.1.1. +struct MEDIA_EXPORT SampleEncryption : Box { + enum SampleEncryptionFlags { + kUseSubsampleEncryption = 2, + }; + + DECLARE_BOX_METHODS(SampleEncryption); + + bool use_subsample_encryption; + // We may not know |iv_size| before reading this box, so we store the box + // data for parsing later when |iv_size| is known. + std::vector<uint8_t> sample_encryption_data; +}; + struct MEDIA_EXPORT OriginalFormat : Box { DECLARE_BOX_METHODS(OriginalFormat); @@ -425,6 +459,7 @@ IndependentAndDisposableSamples sdtp; SampleGroupDescription sample_group_description; SampleToGroup sample_to_group; + SampleEncryption sample_encryption; }; struct MEDIA_EXPORT MovieFragment : Box {
diff --git a/media/formats/mp4/cenc.cc b/media/formats/mp4/cenc.cc deleted file mode 100644 index 3a7b592..0000000 --- a/media/formats/mp4/cenc.cc +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/formats/mp4/cenc.h" - -#include <cstring> - -#include "media/formats/mp4/box_reader.h" -#include "media/formats/mp4/rcheck.h" - -namespace media { -namespace mp4 { - -FrameCENCInfo::FrameCENCInfo() {} -FrameCENCInfo::~FrameCENCInfo() {} - -bool FrameCENCInfo::Parse(int iv_size, BufferReader* reader) { - const int kEntrySize = 6; - // Mandated by CENC spec - RCHECK(iv_size == 8 || iv_size == 16); - - memset(iv, 0, sizeof(iv)); - for (int i = 0; i < iv_size; i++) - RCHECK(reader->Read1(&iv[i])); - - if (!reader->HasBytes(1)) return true; - - uint16_t subsample_count; - RCHECK(reader->Read2(&subsample_count) && - reader->HasBytes(subsample_count * kEntrySize)); - - subsamples.resize(subsample_count); - for (int i = 0; i < subsample_count; i++) { - uint16_t clear_bytes; - uint32_t cypher_bytes; - RCHECK(reader->Read2(&clear_bytes) && - reader->Read4(&cypher_bytes)); - subsamples[i].clear_bytes = clear_bytes; - subsamples[i].cypher_bytes = cypher_bytes; - } - return true; -} - -bool FrameCENCInfo::GetTotalSizeOfSubsamples(size_t* total_size) const { - size_t size = 0; - for (size_t i = 0; i < subsamples.size(); i++) { - size += subsamples[i].clear_bytes; - RCHECK(size >= subsamples[i].clear_bytes); // overflow - size += subsamples[i].cypher_bytes; - RCHECK(size >= subsamples[i].cypher_bytes); // overflow - } - *total_size = size; - return true; -} - -} // namespace mp4 -} // namespace media
diff --git a/media/formats/mp4/cenc.h b/media/formats/mp4/cenc.h deleted file mode 100644 index 6e3b3805..0000000 --- a/media/formats/mp4/cenc.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_FORMATS_MP4_CENC_H_ -#define MEDIA_FORMATS_MP4_CENC_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <vector> - -#include "media/base/decrypt_config.h" - -namespace media { -namespace mp4 { - -class BufferReader; - -struct FrameCENCInfo { - uint8_t iv[16]; - std::vector<SubsampleEntry> subsamples; - - FrameCENCInfo(); - ~FrameCENCInfo(); - bool Parse(int iv_size, BufferReader* r) WARN_UNUSED_RESULT; - bool GetTotalSizeOfSubsamples(size_t* total_size) const WARN_UNUSED_RESULT; -}; - - -} // namespace mp4 -} // namespace media - -#endif // MEDIA_FORMATS_MP4_CENC_H_
diff --git a/media/formats/mp4/fourccs.h b/media/formats/mp4/fourccs.h index ad5f4a3..ac39bd4 100644 --- a/media/formats/mp4/fourccs.h +++ b/media/formats/mp4/fourccs.h
@@ -69,6 +69,7 @@ FOURCC_SCHM = 0x7363686d, FOURCC_SDTP = 0x73647470, FOURCC_SEIG = 0x73656967, + FOURCC_SENC = 0x73656e63, FOURCC_SGPD = 0x73677064, FOURCC_SIDX = 0x73696478, FOURCC_SINF = 0x73696e66,
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc index 1fd2b75..c7d41fe 100644 --- a/media/formats/mp4/mp4_stream_parser_unittest.cc +++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -45,8 +45,8 @@ return CONTAINS_STRING(arg, "Audio codec: " + std::string(codec_string)); } -MATCHER(AuxInfoUnavailableLog, "") { - return CONTAINS_STRING(arg, "Aux Info is not available."); +MATCHER(SampleEncryptionInfoUnavailableLog, "") { + return CONTAINS_STRING(arg, "Sample encryption info is not available."); } MATCHER_P(ErrorLog, error_string, "") { @@ -284,9 +284,10 @@ } // Test an invalid file where there are encrypted samples, but -// SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. +// SampleEncryptionBox (senc) and SampleAuxiliaryInformation{Sizes|Offsets}Box +// (saiz|saio) are missing. // The parser should fail instead of crash. See http://crbug.com/361347 -TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { +TEST_F(MP4StreamParserTest, MissingSampleEncryptionInfo) { InSequence s; // Encrypted test mp4 files have non-zero duration and are treated as @@ -296,7 +297,7 @@ scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); - EXPECT_MEDIA_LOG(AuxInfoUnavailableLog()); + EXPECT_MEDIA_LOG(SampleEncryptionInfoUnavailableLog()); EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); } @@ -321,7 +322,9 @@ AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); } -TEST_F(MP4StreamParserTest, CENC) { +// Sample encryption information is stored as CencSampleAuxiliaryDataFormat +// (ISO/IEC 23001-7:2015 8) inside 'mdat' box. No SampleEncryption ('senc') box. +TEST_F(MP4StreamParserTest, CencWithEncryptionInfoStoredAsAuxDataInMdat) { // Encrypted test mp4 files have non-zero duration and are treated as // recorded streams. InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); @@ -332,6 +335,17 @@ EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); } +TEST_F(MP4StreamParserTest, CencWithSampleEncryptionBox) { + // Encrypted test mp4 files have non-zero duration and are treated as + // recorded streams. + InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); + + scoped_refptr<DecoderBuffer> buffer = + ReadTestDataFile("bear-640x360-v_frag-cenc-senc.mp4"); + EXPECT_MEDIA_LOG(VideoCodecLog("avc1.64001E")); + EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); +} + TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED);
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc index c47b8a3a..7dae938 100644 --- a/media/formats/mp4/track_run_iterator.cc +++ b/media/formats/mp4/track_run_iterator.cc
@@ -35,6 +35,12 @@ const VideoSampleEntry* video_description; const SampleGroupDescription* track_sample_encryption_group; + // Stores sample encryption entries, which is populated from 'senc' box if it + // is available, otherwise will try to load from cenc auxiliary information. + std::vector<SampleEncryptionEntry> sample_encryption_entries; + + // These variables are useful to load |sample_encryption_entries| from cenc + // auxiliary information when 'senc' box is not available. int64_t aux_info_start_offset; // Only valid if aux_info_total_size > 0. int aux_info_default_size; std::vector<uint8_t> aux_info_sizes; // Populated if default_size == 0. @@ -272,6 +278,16 @@ RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file desc_idx -= 1; + const std::vector<uint8_t>& sample_encryption_data = + traf.sample_encryption.sample_encryption_data; + scoped_ptr<BufferReader> sample_encryption_reader; + uint32_t sample_encrytion_entries_count = 0; + if (!sample_encryption_data.empty()) { + sample_encryption_reader.reset(new BufferReader( + sample_encryption_data.data(), sample_encryption_data.size())); + RCHECK(sample_encryption_reader->Read4(&sample_encrytion_entries_count)); + } + // Process edit list to remove CTS offset introduced in the presence of // B-frames (those that contain a single edit with a nonnegative media // time). Other uses of edit lists are not supported, as they are @@ -306,23 +322,30 @@ tri.fragment_sample_encryption_info = traf.sample_group_description.entries; + uint8_t default_iv_size = 0; tri.is_audio = (stsd.type == kAudio); if (tri.is_audio) { RCHECK(!stsd.audio_entries.empty()); if (desc_idx > stsd.audio_entries.size()) desc_idx = 0; tri.audio_description = &stsd.audio_entries[desc_idx]; + default_iv_size = + tri.audio_description->sinf.info.track_encryption.default_iv_size; } else { RCHECK(!stsd.video_entries.empty()); if (desc_idx > stsd.video_entries.size()) desc_idx = 0; tri.video_description = &stsd.video_entries[desc_idx]; + default_iv_size = + tri.video_description->sinf.info.track_encryption.default_iv_size; } - // Collect information from the auxiliary_offset entry with the same index - // in the 'saiz' container as the current run's index in the 'trun' - // container, if it is present. - if (traf.auxiliary_offset.offsets.size() > j) { + // Initialize aux_info variables only if no sample encryption entries. + if (sample_encrytion_entries_count == 0 && + traf.auxiliary_offset.offsets.size() > j) { + // Collect information from the auxiliary_offset entry with the same + // index in the 'saiz' container as the current run's index in the + // 'trun' container, if it is present. // There should be an auxiliary info entry corresponding to each sample // in the auxiliary offset entry's corresponding track run. RCHECK(traf.auxiliary_size.sample_count >= @@ -333,8 +356,8 @@ if (tri.aux_info_default_size == 0) { const std::vector<uint8_t>& sizes = traf.auxiliary_size.sample_info_sizes; - tri.aux_info_sizes.insert(tri.aux_info_sizes.begin(), - sizes.begin() + sample_count_sum, + tri.aux_info_sizes.insert( + tri.aux_info_sizes.begin(), sizes.begin() + sample_count_sum, sizes.begin() + sample_count_sum + trun.sample_count); } @@ -378,6 +401,20 @@ RCHECK(GetSampleEncryptionInfoEntry(tri, index)); is_sample_to_group_valid = sample_to_group_itr.Advance(); } + if (sample_encrytion_entries_count > 0) { + RCHECK(sample_encrytion_entries_count >= + sample_count_sum + trun.sample_count); + tri.sample_encryption_entries.resize(trun.sample_count); + for (size_t k = 0; k < trun.sample_count; k++) { + uint32_t index = tri.samples[k].cenc_group_description_index; + const uint8_t iv_size = + index == 0 ? default_iv_size + : GetSampleEncryptionInfoEntry(tri, index)->iv_size; + RCHECK(tri.sample_encryption_entries[k].Parse( + sample_encryption_reader.get(), iv_size, + traf.sample_encryption.use_subsample_encryption)); + } + } runs_.push_back(tri); sample_count_sum += trun.sample_count; } @@ -402,7 +439,6 @@ sample_dts_ = run_itr_->start_dts; sample_offset_ = run_itr_->sample_start_offset; sample_itr_ = run_itr_->samples.begin(); - cenc_info_.clear(); } void TrackRunIterator::AdvanceSample() { @@ -416,14 +452,17 @@ // info is available in the stream. bool TrackRunIterator::AuxInfoNeedsToBeCached() { DCHECK(IsRunValid()); - return aux_info_size() > 0 && cenc_info_.size() == 0; + return is_encrypted() && aux_info_size() > 0 && + run_itr_->sample_encryption_entries.size() == 0; } // This implementation currently only caches CENC auxiliary info. bool TrackRunIterator::CacheAuxInfo(const uint8_t* buf, int buf_size) { RCHECK(AuxInfoNeedsToBeCached() && buf_size >= aux_info_size()); - cenc_info_.resize(run_itr_->samples.size()); + std::vector<SampleEncryptionEntry>& sample_encryption_entries = + runs_[run_itr_ - runs_.begin()].sample_encryption_entries; + sample_encryption_entries.resize(run_itr_->samples.size()); int64_t pos = 0; for (size_t i = 0; i < run_itr_->samples.size(); i++) { int info_size = run_itr_->aux_info_default_size; @@ -432,7 +471,10 @@ if (IsSampleEncrypted(i)) { BufferReader reader(buf + pos, info_size); - RCHECK(cenc_info_[i].Parse(GetIvSize(i), &reader)); + const uint8_t iv_size = GetIvSize(i); + const bool has_subsamples = info_size > iv_size; + RCHECK( + sample_encryption_entries[i].Parse(&reader, iv_size, has_subsamples)); } pos += info_size; } @@ -550,19 +592,20 @@ scoped_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() { DCHECK(is_encrypted()); - if (cenc_info_.empty()) { + if (run_itr_->sample_encryption_entries.empty()) { DCHECK_EQ(0, aux_info_size()); - MEDIA_LOG(ERROR, media_log_) << "Aux Info is not available."; + MEDIA_LOG(ERROR, media_log_) << "Sample encryption info is not available."; return scoped_ptr<DecryptConfig>(); } size_t sample_idx = sample_itr_ - run_itr_->samples.begin(); - DCHECK_LT(sample_idx, cenc_info_.size()); - const FrameCENCInfo& cenc_info = cenc_info_[sample_idx]; + DCHECK_LT(sample_idx, run_itr_->sample_encryption_entries.size()); + const SampleEncryptionEntry& sample_encryption_entry = + run_itr_->sample_encryption_entries[sample_idx]; size_t total_size = 0; - if (!cenc_info.subsamples.empty() && - (!cenc_info.GetTotalSizeOfSubsamples(&total_size) || + if (!sample_encryption_entry.subsamples.empty() && + (!sample_encryption_entry.GetTotalSizeOfSubsamples(&total_size) || total_size != static_cast<size_t>(sample_size()))) { MEDIA_LOG(ERROR, media_log_) << "Incorrect CENC subsample size."; return scoped_ptr<DecryptConfig>(); @@ -571,9 +614,10 @@ const std::vector<uint8_t>& kid = GetKeyId(sample_idx); return scoped_ptr<DecryptConfig>(new DecryptConfig( std::string(reinterpret_cast<const char*>(&kid[0]), kid.size()), - std::string(reinterpret_cast<const char*>(cenc_info.iv), - arraysize(cenc_info.iv)), - cenc_info.subsamples)); + std::string(reinterpret_cast<const char*>( + sample_encryption_entry.initialization_vector), + arraysize(sample_encryption_entry.initialization_vector)), + sample_encryption_entry.subsamples)); } uint32_t TrackRunIterator::GetGroupDescriptionIndex(
diff --git a/media/formats/mp4/track_run_iterator.h b/media/formats/mp4/track_run_iterator.h index bab090e6..4903f76 100644 --- a/media/formats/mp4/track_run_iterator.h +++ b/media/formats/mp4/track_run_iterator.h
@@ -17,7 +17,6 @@ #include "media/base/media_log.h" #include "media/base/stream_parser_buffer.h" #include "media/formats/mp4/box_definitions.h" -#include "media/formats/mp4/cenc.h" namespace media { @@ -108,8 +107,6 @@ std::vector<TrackRunInfo>::const_iterator run_itr_; std::vector<SampleInfo>::const_iterator sample_itr_; - std::vector<FrameCENCInfo> cenc_info_; - int64_t sample_dts_; int64_t sample_offset_;
diff --git a/media/formats/mp4/track_run_iterator_unittest.cc b/media/formats/mp4/track_run_iterator_unittest.cc index 3ac4a41..20023b4 100644 --- a/media/formats/mp4/track_run_iterator_unittest.cc +++ b/media/formats/mp4/track_run_iterator_unittest.cc
@@ -18,34 +18,84 @@ using ::testing::StrictMock; +namespace { + // The sum of the elements in a vector initialized with SumAscending, // less the value of the last element. -static const int kSumAscending1 = 45; +const int kSumAscending1 = 45; -static const int kAudioScale = 48000; -static const int kVideoScale = 25; +const int kAudioScale = 48000; +const int kVideoScale = 25; -static const uint8_t kAuxInfo[] = { +const uint8_t kAuxInfo[] = { 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04}; - -static const char kIv1[] = { - 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, }; -static const uint8_t kKeyId[] = {0x41, 0x47, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x54, 0x65, 0x73, 0x74, 0x4b, - 0x65, 0x79, 0x49, 0x44}; +// Sample encryption data for two samples, one with 8 byte IV, one with 16 byte +// IV. This data is generated for testing. It should be very unlikely to see +// IV of mixed size in actual media files, though it is permitted by spec. +const uint8_t kSampleEncryptionDataWithSubsamples[] = { + // Sample count. + 0x00, 0x00, 0x00, 0x02, + // Sample 1: IV (8 Bytes). + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, + // Sample 1: Subsample count. + 0x00, 0x01, + // Sample 1: Subsample 1. + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + // Sample 2: IV (16 bytes). + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, + // Sample 2: Subsample count. + 0x00, 0x02, + // Sample 2: Subsample 1. + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + // Sample 2: Subsample 2. + 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, +}; -static const uint8_t kTrackCencSampleGroupKeyId[] = { +const uint8_t kSampleEncryptionDataWithoutSubsamples[] = { + // Sample count. + 0x00, 0x00, 0x00, 0x02, + // Sample 1: IV. + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, + // Sample 2: IV. + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, +}; + +// Size of these two IVs are 8 bytes. They are padded with 0 to 16 bytes. +const char kIv1[] = { + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +const char kIv2[] = { + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +// Size of this IV is 16 bytes. +const char kIv3[] = { + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, +}; + +const uint8_t kKeyId[] = { + 0x41, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x54, + 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x44, +}; + +const uint8_t kTrackCencSampleGroupKeyId[] = { 0x46, 0x72, 0x61, 0x67, 0x53, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b}; + 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, +}; -static const uint8_t kFragmentCencSampleGroupKeyId[] = { +const uint8_t kFragmentCencSampleGroupKeyId[] = { 0x6b, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x43, 0x65, 0x6e, 0x63, 0x53, 0x61, 0x6d}; + 0x74, 0x43, 0x65, 0x6e, 0x63, 0x53, 0x61, 0x6d, +}; + +} // namespace namespace media { namespace mp4 { @@ -241,7 +291,7 @@ kTrackCencSampleGroupKeyId + arraysize(kTrackCencSampleGroupKeyId)); frag->sample_group_description.grouping_type = FOURCC_SEIG; - frag->sample_group_description.entries.resize(2); + frag->sample_group_description.entries.resize(3); frag->sample_group_description.entries[0].is_encrypted = false; frag->sample_group_description.entries[0].iv_size = 0; frag->sample_group_description.entries[1].is_encrypted = true; @@ -250,6 +300,10 @@ kFragmentCencSampleGroupKeyId, kFragmentCencSampleGroupKeyId + arraysize(kFragmentCencSampleGroupKeyId)); + frag->sample_group_description.entries[2].is_encrypted = true; + frag->sample_group_description.entries[2].iv_size = 16; + frag->sample_group_description.entries[2].key_id.assign( + kKeyId, kKeyId + arraysize(kKeyId)); frag->sample_to_group.grouping_type = FOURCC_SEIG; frag->sample_to_group.entries.assign(sample_to_group_entries, @@ -267,6 +321,37 @@ frag->runs[0].sample_sizes[1] = 10; } + void AddSampleEncryption(uint8_t use_subsample_flag, TrackFragment* frag) { + frag->sample_encryption.use_subsample_encryption = use_subsample_flag; + if (use_subsample_flag) { + frag->sample_encryption.sample_encryption_data.assign( + kSampleEncryptionDataWithSubsamples, + kSampleEncryptionDataWithSubsamples + + arraysize(kSampleEncryptionDataWithSubsamples)); + } else { + frag->sample_encryption.sample_encryption_data.assign( + kSampleEncryptionDataWithoutSubsamples, + kSampleEncryptionDataWithoutSubsamples + + arraysize(kSampleEncryptionDataWithoutSubsamples)); + } + + // Update sample sizes and aux info header. + frag->runs.resize(1); + frag->runs[0].sample_count = 2; + frag->auxiliary_offset.offsets.push_back(0); + frag->auxiliary_size.sample_count = 2; + if (use_subsample_flag) { + // Update sample sizes to match with subsample entries above. + frag->runs[0].sample_sizes[0] = 3; + frag->runs[0].sample_sizes[1] = 10; + // Set aux info header. + frag->auxiliary_size.sample_info_sizes.push_back(16); + frag->auxiliary_size.sample_info_sizes.push_back(30); + } else { + frag->auxiliary_size.default_sample_info_size = 8; + } + } + bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) { // Add aux info header (equal sized aux info for every sample). for (uint32_t i = 0; i < moof->tracks.size(); ++i) { @@ -470,7 +555,89 @@ EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached()); } -TEST_F(TrackRunIteratorTest, DecryptConfigTest) { +TEST_F(TrackRunIteratorTest, + DecryptConfigTestWithSampleEncryptionAndNoSubsample) { + AddEncryption(&moov_.tracks[1]); + iter_.reset(new TrackRunIterator(&moov_, media_log_)); + + MovieFragment moof = CreateFragment(); + AddSampleEncryption(!SampleEncryption::kUseSubsampleEncryption, + &moof.tracks[1]); + + ASSERT_TRUE(iter_->Init(moof)); + // The run for track 2 will be the second, which is parsed according to + // data_offset. + iter_->AdvanceRun(); + EXPECT_EQ(iter_->track_id(), 2u); + + EXPECT_TRUE(iter_->is_encrypted()); + // No need to cache aux info as it is already available in SampleEncryption. + EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached()); + EXPECT_EQ(iter_->aux_info_size(), 0); + EXPECT_EQ(iter_->sample_offset(), 200); + EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[1].runs[0].data_offset); + scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig(); + EXPECT_EQ( + std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)), + config->key_id()); + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv1), arraysize(kIv1)), + config->iv()); + EXPECT_EQ(config->subsamples().size(), 0u); + iter_->AdvanceSample(); + config = iter_->GetDecryptConfig(); + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv2), arraysize(kIv2)), + config->iv()); + EXPECT_EQ(config->subsamples().size(), 0u); +} + +TEST_F(TrackRunIteratorTest, + DecryptConfigTestWithSampleEncryptionAndSubsample) { + AddEncryption(&moov_.tracks[1]); + iter_.reset(new TrackRunIterator(&moov_, media_log_)); + + MovieFragment moof = CreateFragment(); + AddSampleEncryption(SampleEncryption::kUseSubsampleEncryption, + &moof.tracks[1]); + const SampleToGroupEntry kSampleToGroupTable[] = { + // Associated with the second entry in SampleGroupDescription Box. + // With Iv size 8 bytes. + {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2}, + // Associated with the third entry in SampleGroupDescription Box. + // With Iv size 16 bytes. + {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 3}}; + AddCencSampleGroup(&moov_.tracks[1], &moof.tracks[1], kSampleToGroupTable, + arraysize(kSampleToGroupTable)); + + ASSERT_TRUE(iter_->Init(moof)); + // The run for track 2 will be the second, which is parsed according to + // data_offset. + iter_->AdvanceRun(); + EXPECT_EQ(iter_->track_id(), 2u); + + EXPECT_TRUE(iter_->is_encrypted()); + // No need to cache aux info as it is already available in SampleEncryption. + EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached()); + EXPECT_EQ(iter_->aux_info_size(), 0); + EXPECT_EQ(iter_->sample_offset(), 200); + EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[1].runs[0].data_offset); + scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig(); + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv1), arraysize(kIv1)), + config->iv()); + EXPECT_EQ(config->subsamples().size(), 1u); + EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u); + EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u); + iter_->AdvanceSample(); + config = iter_->GetDecryptConfig(); + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv3), arraysize(kIv3)), + config->iv()); + EXPECT_EQ(config->subsamples().size(), 2u); + EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u); + EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u); + EXPECT_EQ(config->subsamples()[1].clear_bytes, 3u); + EXPECT_EQ(config->subsamples()[1].cypher_bytes, 4u); +} + +TEST_F(TrackRunIteratorTest, DecryptConfigTestWithAuxInfo) { AddEncryption(&moov_.tracks[1]); iter_.reset(new TrackRunIterator(&moov_, media_log_)); @@ -483,7 +650,7 @@ // element in the file. EXPECT_EQ(iter_->track_id(), 2u); EXPECT_TRUE(iter_->is_encrypted()); - EXPECT_TRUE(iter_->AuxInfoNeedsToBeCached()); + ASSERT_TRUE(iter_->AuxInfoNeedsToBeCached()); EXPECT_EQ(static_cast<uint32_t>(iter_->aux_info_size()), arraysize(kAuxInfo)); EXPECT_EQ(iter_->aux_info_offset(), 50); EXPECT_EQ(iter_->GetMaxClearOffset(), 50); @@ -495,11 +662,11 @@ EXPECT_EQ(iter_->sample_offset(), 200); EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[0].runs[0].data_offset); scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig(); - ASSERT_EQ(arraysize(kKeyId), config->key_id().size()); - EXPECT_TRUE(!memcmp(kKeyId, config->key_id().data(), - config->key_id().size())); - ASSERT_EQ(arraysize(kIv1), config->iv().size()); - EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size())); + EXPECT_EQ( + std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)), + config->key_id()); + EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv1), arraysize(kIv1)), + config->iv()); EXPECT_TRUE(config->subsamples().empty()); iter_->AdvanceSample(); config = iter_->GetDecryptConfig();
diff --git a/media/media.gyp b/media/media.gyp index bdc7d5c..071444aa 100644 --- a/media/media.gyp +++ b/media/media.gyp
@@ -1023,8 +1023,6 @@ 'formats/mp4/box_definitions.h', 'formats/mp4/box_reader.cc', 'formats/mp4/box_reader.h', - 'formats/mp4/cenc.cc', - 'formats/mp4/cenc.h', 'formats/mp4/es_descriptor.cc', 'formats/mp4/es_descriptor.h', 'formats/mp4/mp4_stream_parser.cc',
diff --git a/media/mojo/services/mojo_media_application.cc b/media/mojo/services/mojo_media_application.cc index 380d95f0..8925e99 100644 --- a/media/mojo/services/mojo_media_application.cc +++ b/media/mojo/services/mojo_media_application.cc
@@ -26,8 +26,7 @@ MojoMediaApplication::~MojoMediaApplication() {} void MojoMediaApplication::Initialize(mojo::Connector* connector, - const std::string& /* url */, - const std::string& user_id, + const mojo::Identity& identity, uint32_t /* id */) { connector_ = connector; mojo_media_client_->Initialize();
diff --git a/media/mojo/services/mojo_media_application.h b/media/mojo/services/mojo_media_application.h index 9844ab13..c004e83 100644 --- a/media/mojo/services/mojo_media_application.h +++ b/media/mojo/services/mojo_media_application.h
@@ -28,8 +28,7 @@ private: // mojo::ShellClient implementation. void Initialize(mojo::Connector* connector, - const std::string& url, - const std::string& user_id, + const mojo::Identity& identity, uint32_t id) final; bool AcceptConnection(mojo::Connection* connection) final;
diff --git a/media/test/data/README b/media/test/data/README index 4b85fe39..6f27250 100644 --- a/media/test/data/README +++ b/media/test/data/README
@@ -68,7 +68,8 @@ bear-320x240-opus-av_enc-v.webm - bear-vp9-opus.webm with video track encrypted using key ID [1] and key[2]. bear-640x360-a_frag-cenc.mp4 - A fragmented MP4 version of the audio track of bear-640x360.mp4 encrypted (ISO CENC) using key ID [1] and key [2]. bear-640x360-a_frag-cenc-key_rotation.mp4 - A fragmented MP4 version of the audio track of bear-640x360.mp4 encrypted (ISO CENC) using key ID [1] and key [2] with key rotation [3]. -bear-640x360-v_frag-cenc.mp4 - A fragmented MP4 version of the video track of bear-640x360.mp4 encrypted (ISO CENC) using key ID [1] and key [2]. +bear-640x360-v_frag-cenc.mp4 - A fragmented MP4 version of the video track of bear-640x360.mp4 encrypted (ISO CENC) using key ID [1] and key [2] and with sample encryption auxiliary information in the beginning of mdat box. +bear-640x360-v_frag-cenc-senc.mp4 - Same as above, but with sample encryption information stored in SampleEncryption ('senc') box. bear-640x360-v_frag-cenc-key_rotation.mp4 - A fragmented MP4 version of the video track of bear-640x360.mp4 encrypted (ISO CENC) using key ID [1] and key [2] with key rotation [3]. bear-a_enc-a.webm - bear-320x240-audio-only.webm encrypted using key ID [1] and key [2]. frame_size_change-av_enc-v.webm - third_party/WebKit/LayoutTests/media/resources/frame_size_change.webm encrypted using key ID [1] and key [2].
diff --git a/media/test/data/bear-640x360-v_frag-cenc-senc.mp4 b/media/test/data/bear-640x360-v_frag-cenc-senc.mp4 new file mode 100644 index 0000000..05761982 --- /dev/null +++ b/media/test/data/bear-640x360-v_frag-cenc-senc.mp4 Binary files differ
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index 9f4deaf..1f0c3a8 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -1708,6 +1708,23 @@ } TEST_F(PipelineIntegrationTest, + MAYBE_EME(EncryptedPlayback_MP4_CENC_SENC_Video)) { + MockMediaSource source("bear-640x360-v_frag-cenc-senc.mp4", kMP4Video, + kAppendWholeFile); + FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); + StartPipelineWithEncryptedMedia(&source, &encrypted_media); + + source.EndOfStream(); + ASSERT_EQ(PIPELINE_OK, pipeline_status_); + + Play(); + + ASSERT_TRUE(WaitUntilOnEnded()); + source.Shutdown(); + Stop(); +} + +TEST_F(PipelineIntegrationTest, MAYBE_EME(EncryptedPlayback_MP4_CENC_KeyRotation_Video)) { MockMediaSource source("bear-1280x720-v_frag-cenc-key_rotation.mp4", kMP4Video, kAppendWholeFile);
diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.cc b/mojo/edk/system/data_pipe_consumer_dispatcher.cc index 2dfddbc..10a8069 100644 --- a/mojo/edk/system/data_pipe_consumer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
@@ -29,14 +29,24 @@ namespace { -struct MOJO_ALIGNAS(8) SerializedState { +const uint8_t kFlagPeerClosed = 0x01; + +#pragma pack(push, 1) + +struct SerializedState { MojoCreateDataPipeOptions options; uint64_t pipe_id; - bool peer_closed; uint32_t read_offset; uint32_t bytes_available; + uint8_t flags; + char padding[7]; }; +static_assert(sizeof(SerializedState) % 8 == 0, + "Invalid SerializedState size."); + +#pragma pack(pop) + } // namespace // A PortObserver which forwards to a DataPipeConsumerDispatcher. This owns a @@ -324,13 +334,14 @@ PlatformHandle* platform_handles) { SerializedState* state = static_cast<SerializedState*>(destination); memcpy(&state->options, &options_, sizeof(MojoCreateDataPipeOptions)); + memset(state->padding, 0, sizeof(state->padding)); base::AutoLock lock(lock_); DCHECK(in_transit_); state->pipe_id = pipe_id_; - state->peer_closed = peer_closed_; state->read_offset = read_offset_; state->bytes_available = bytes_available_; + state->flags = peer_closed_ ? kFlagPeerClosed : 0; ports[0] = control_port_.name(); @@ -405,9 +416,9 @@ { base::AutoLock lock(dispatcher->lock_); - dispatcher->peer_closed_ = state->peer_closed; dispatcher->read_offset_ = state->read_offset; dispatcher->bytes_available_ = state->bytes_available; + dispatcher->peer_closed_ = state->flags & kFlagPeerClosed; dispatcher->InitializeNoLock(); }
diff --git a/mojo/edk/system/data_pipe_producer_dispatcher.cc b/mojo/edk/system/data_pipe_producer_dispatcher.cc index 0aa8f7e..9f6a72e1 100644 --- a/mojo/edk/system/data_pipe_producer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_producer_dispatcher.cc
@@ -28,14 +28,24 @@ namespace { +const uint8_t kFlagPeerClosed = 0x01; + +#pragma pack(push, 1) + struct SerializedState { MojoCreateDataPipeOptions options; uint64_t pipe_id; - bool peer_closed; uint32_t write_offset; uint32_t available_capacity; + uint8_t flags; + char padding[7]; }; +static_assert(sizeof(SerializedState) % 8 == 0, + "Invalid SerializedState size."); + +#pragma pack(pop) + } // namespace // A PortObserver which forwards to a DataPipeProducerDispatcher. This owns a @@ -306,13 +316,14 @@ PlatformHandle* platform_handles) { SerializedState* state = static_cast<SerializedState*>(destination); memcpy(&state->options, &options_, sizeof(MojoCreateDataPipeOptions)); + memset(state->padding, 0, sizeof(state->padding)); base::AutoLock lock(lock_); DCHECK(in_transit_); state->pipe_id = pipe_id_; - state->peer_closed = peer_closed_; state->write_offset = write_offset_; state->available_capacity = available_capacity_; + state->flags = peer_closed_ ? kFlagPeerClosed : 0; ports[0] = control_port_.name(); @@ -387,9 +398,9 @@ { base::AutoLock lock(dispatcher->lock_); - dispatcher->peer_closed_ = state->peer_closed; dispatcher->write_offset_ = state->write_offset; dispatcher->available_capacity_ = state->available_capacity; + dispatcher->peer_closed_ = state->flags & kFlagPeerClosed; dispatcher->InitializeNoLock(); }
diff --git a/mojo/edk/system/message_pipe_dispatcher.cc b/mojo/edk/system/message_pipe_dispatcher.cc index ce35f64..c630b8b 100644 --- a/mojo/edk/system/message_pipe_dispatcher.cc +++ b/mojo/edk/system/message_pipe_dispatcher.cc
@@ -14,15 +14,16 @@ #include "mojo/edk/system/node_controller.h" #include "mojo/edk/system/ports_message.h" #include "mojo/edk/system/request_context.h" -#include "mojo/public/c/system/macros.h" namespace mojo { namespace edk { namespace { +#pragma pack(push, 1) + // Header attached to every message sent over a message pipe. -struct MOJO_ALIGNAS(8) MessageHeader { +struct MessageHeader { // The number of serialized dispatchers included in this header. uint32_t num_dispatchers; @@ -30,8 +31,10 @@ uint32_t header_size; }; +static_assert(sizeof(MessageHeader) % 8 == 0, "Invalid MessageHeader size."); + // Header for each dispatcher, immediately following the message header. -struct MOJO_ALIGNAS(8) DispatcherHeader { +struct DispatcherHeader { // The type of the dispatcher, correpsonding to the Dispatcher::Type enum. int32_t type; @@ -45,11 +48,20 @@ uint32_t num_platform_handles; }; -struct MOJO_ALIGNAS(8) SerializedState { +static_assert(sizeof(DispatcherHeader) % 8 == 0, + "Invalid DispatcherHeader size."); + +struct SerializedState { uint64_t pipe_id; int8_t endpoint; + char padding[7]; }; +static_assert(sizeof(SerializedState) % 8 == 0, + "Invalid SerializedState size."); + +#pragma pack(pop) + } // namespace // A PortObserver which forwards to a MessagePipeDispatcher. This owns a @@ -503,6 +515,7 @@ SerializedState* state = static_cast<SerializedState*>(destination); state->pipe_id = pipe_id_; state->endpoint = static_cast<int8_t>(endpoint_); + memset(state->padding, 0, sizeof(state->padding)); ports[0] = port_.name(); return true; }
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc index 02ec902..4c548e0c 100644 --- a/mojo/edk/system/shared_buffer_dispatcher.cc +++ b/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -16,17 +16,23 @@ #include "mojo/edk/system/configuration.h" #include "mojo/edk/system/node_controller.h" #include "mojo/edk/system/options_validation.h" -#include "mojo/public/c/system/macros.h" namespace mojo { namespace edk { namespace { -struct MOJO_ALIGNAS(8) SerializedSharedBufferDispatcher { - size_t num_bytes; +#pragma pack(push, 1) + +struct SerializedState { + uint64_t num_bytes; }; +#pragma pack(pop) + +static_assert(sizeof(SerializedState) % 8 == 0, + "Invalid SerializedState size."); + } // namespace // static @@ -108,13 +114,13 @@ size_t num_ports, PlatformHandle* platform_handles, size_t num_platform_handles) { - if (num_bytes != sizeof(SerializedSharedBufferDispatcher)) { + if (num_bytes != sizeof(SerializedState)) { LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)"; return nullptr; } - const SerializedSharedBufferDispatcher* serialization = - static_cast<const SerializedSharedBufferDispatcher*>(bytes); + const SerializedState* serialization = + static_cast<const SerializedState*>(bytes); if (!serialization->num_bytes) { LOG(ERROR) << "Invalid serialized shared buffer dispatcher (invalid num_bytes)"; @@ -137,7 +143,8 @@ // closed even if creation fails. scoped_refptr<PlatformSharedBuffer> shared_buffer( PlatformSharedBuffer::CreateFromPlatformHandle( - serialization->num_bytes, ScopedPlatformHandle(platform_handle))); + static_cast<size_t>(serialization->num_bytes), + ScopedPlatformHandle(platform_handle))); if (!shared_buffer) { LOG(ERROR) << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)"; @@ -217,7 +224,7 @@ void SharedBufferDispatcher::StartSerialize(uint32_t* num_bytes, uint32_t* num_ports, uint32_t* num_platform_handles) { - *num_bytes = sizeof(SerializedSharedBufferDispatcher); + *num_bytes = sizeof(SerializedState); *num_ports = 0; *num_platform_handles = 1; } @@ -225,10 +232,11 @@ bool SharedBufferDispatcher::EndSerialize(void* destination, ports::PortName* ports, PlatformHandle* handles) { - SerializedSharedBufferDispatcher* serialization = - static_cast<SerializedSharedBufferDispatcher*>(destination); + SerializedState* serialization = + static_cast<SerializedState*>(destination); base::AutoLock lock(lock_); - serialization->num_bytes = shared_buffer_->GetNumBytes(); + serialization->num_bytes = + static_cast<uint64_t>(shared_buffer_->GetNumBytes()); handle_for_transit_ = shared_buffer_->DuplicatePlatformHandle(); if (!handle_for_transit_.is_valid()) {
diff --git a/mojo/edk/test/mojo_test_base.h b/mojo/edk/test/mojo_test_base.h index 71c9276..1dcadf1 100644 --- a/mojo/edk/test/mojo_test_base.h +++ b/mojo/edk/test/mojo_test_base.h
@@ -188,14 +188,13 @@ }; \ MULTIPROCESS_TEST_MAIN_WITH_SETUP( \ client_name##TestChildMain, \ - test::MultiprocessTestHelper::ChildSetup) { \ - client_name##_MainFixture test; \ - return test::MultiprocessTestHelper::RunClientMain( \ - base::Bind(&client_name##_MainFixture::Main, \ - base::Unretained(&test))); \ - } \ - int client_name##_MainFixture::Main(MojoHandle pipe_name) - + ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \ + client_name##_MainFixture test; \ + return ::mojo::edk::test::MultiprocessTestHelper::RunClientMain( \ + base::Bind(&client_name##_MainFixture::Main, \ + base::Unretained(&test))); \ + } \ + int client_name##_MainFixture::Main(MojoHandle pipe_name) // This is a version of DEFINE_TEST_CLIENT_WITH_PIPE which can be used with // gtest ASSERT/EXPECT macros. @@ -207,13 +206,13 @@ }; \ MULTIPROCESS_TEST_MAIN_WITH_SETUP( \ client_name##TestChildMain, \ - test::MultiprocessTestHelper::ChildSetup) { \ - client_name##_MainFixture test; \ - return test::MultiprocessTestHelper::RunClientTestMain( \ - base::Bind(&client_name##_MainFixture::Main, \ - base::Unretained(&test))); \ - } \ - void client_name##_MainFixture::Main(MojoHandle pipe_name) + ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \ + client_name##_MainFixture test; \ + return ::mojo::edk::test::MultiprocessTestHelper::RunClientTestMain( \ + base::Bind(&client_name##_MainFixture::Main, \ + base::Unretained(&test))); \ + } \ + void client_name##_MainFixture::Main(MojoHandle pipe_name) #else // !defined(OS_IOS) #define DEFINE_TEST_CLIENT_WITH_PIPE(client_name, test_base, pipe_name) #define DEFINE_TEST_CLIENT_TEST_WITH_PIPE(client_name, test_base, pipe_name)
diff --git a/mojo/edk/test/scoped_ipc_support.cc b/mojo/edk/test/scoped_ipc_support.cc index d7ff28b..7dc7c99b 100644 --- a/mojo/edk/test/scoped_ipc_support.cc +++ b/mojo/edk/test/scoped_ipc_support.cc
@@ -13,6 +13,14 @@ namespace edk { namespace test { +namespace { +base::TaskRunner* g_io_task_runner = nullptr; +} + +base::TaskRunner* GetIoTaskRunner() { + return g_io_task_runner; +} + namespace internal { ScopedIPCSupportHelper::ScopedIPCSupportHelper() { @@ -38,6 +46,7 @@ ScopedIPCSupport::ScopedIPCSupport( scoped_refptr<base::TaskRunner> io_thread_task_runner) { + g_io_task_runner = io_thread_task_runner.get(); helper_.Init(this, std::move(io_thread_task_runner)); }
diff --git a/mojo/edk/test/scoped_ipc_support.h b/mojo/edk/test/scoped_ipc_support.h index bb1f458..ff2f558 100644 --- a/mojo/edk/test/scoped_ipc_support.h +++ b/mojo/edk/test/scoped_ipc_support.h
@@ -17,6 +17,8 @@ namespace edk { namespace test { +base::TaskRunner* GetIoTaskRunner(); + namespace internal { class ScopedIPCSupportHelper {
diff --git a/mojo/mojo_base.gyp b/mojo/mojo_base.gyp index 532d44a..36c38cca 100644 --- a/mojo/mojo_base.gyp +++ b/mojo/mojo_base.gyp
@@ -200,6 +200,7 @@ 'shell/public/cpp/connect.h', 'shell/public/cpp/connection.h', 'shell/public/cpp/connector.h', + 'shell/public/cpp/identity.h', 'shell/public/cpp/initialize_base_and_icu.cc', 'shell/public/cpp/initialize_base_and_icu.h', 'shell/public/cpp/interface_binder.h', @@ -211,6 +212,7 @@ 'shell/public/cpp/lib/connection_impl.h', 'shell/public/cpp/lib/connector_impl.cc', 'shell/public/cpp/lib/connector_impl.h', + 'shell/public/cpp/lib/identity.cc', 'shell/public/cpp/lib/interface_factory_binder.h', 'shell/public/cpp/lib/interface_registry.cc', 'shell/public/cpp/lib/message_loop_ref.cc',
diff --git a/mojo/mojo_edk_tests.gyp b/mojo/mojo_edk_tests.gyp index 0ace217..e2f92129 100644 --- a/mojo/mojo_edk_tests.gyp +++ b/mojo/mojo_edk_tests.gyp
@@ -108,6 +108,7 @@ 'target_name': 'mojo_public_bindings_perftests', 'type': 'executable', 'dependencies': [ + '../base/base.gyp:test_support_base', '../testing/gtest.gyp:gtest', 'mojo_base.gyp:mojo_common_lib', 'mojo_edk.gyp:mojo_run_all_perftests', @@ -121,6 +122,7 @@ ], 'sources': [ 'public/cpp/bindings/tests/bindings_perftest.cc', + 'public/cpp/bindings/tests/e2e_perftest.cc', ], }, {
diff --git a/mojo/mojo_shell.gyp b/mojo/mojo_shell.gyp index 7080eaa9..192c8ac5 100644 --- a/mojo/mojo_shell.gyp +++ b/mojo/mojo_shell.gyp
@@ -16,8 +16,6 @@ 'shell/connect_params.h', 'shell/connect_util.cc', 'shell/connect_util.h', - 'shell/identity.cc', - 'shell/identity.h', 'shell/native_runner.h', 'shell/native_runner_delegate.h', 'shell/shell.cc',
diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h index cb611c6..575ba77 100644 --- a/mojo/public/cpp/bindings/array.h +++ b/mojo/public/cpp/bindings/array.h
@@ -88,6 +88,9 @@ // Indicates whether the array is null (which is distinct from empty). bool is_null() const { return is_null_; } + // Indicates whether the array is empty (which is distinct from null). + bool empty() const { return vec_.empty() && !is_null_; } + // Returns a reference to the first element of the array. Calling this on a // null or empty array causes undefined behavior. ConstRefType front() const { return vec_.front(); }
diff --git a/mojo/public/cpp/bindings/map.h b/mojo/public/cpp/bindings/map.h index 4c64d48..6d0d57d 100644 --- a/mojo/public/cpp/bindings/map.h +++ b/mojo/public/cpp/bindings/map.h
@@ -87,9 +87,14 @@ return TypeConverter<U, Map>::Convert(*this); } + // Indicates whether the map is null (which is distinct from empty). bool is_null() const { return is_null_; } - // Indicates the number of keys in the map. + // Indicates whether the map is empty (which is distinct from null). + bool empty() const { return map_.empty() && !is_null_; } + + // Indicates the number of keys in the map, which will be zero if the map is + // null. size_t size() const { return map_.size(); } // Inserts a key-value pair into the map. Like std::map, this does not insert
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn index 78853674..5c661b4 100644 --- a/mojo/public/cpp/bindings/tests/BUILD.gn +++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -74,9 +74,12 @@ sources = [ "bindings_perftest.cc", + "e2e_perftest.cc", ] deps = [ + "//base/test:test_support", + "//mojo/edk/test:test_support", "//mojo/message_pump", "//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings:callback",
diff --git a/mojo/public/cpp/bindings/tests/array_unittest.cc b/mojo/public/cpp/bindings/tests/array_unittest.cc index c5a227e..f4dad7c 100644 --- a/mojo/public/cpp/bindings/tests/array_unittest.cc +++ b/mojo/public/cpp/bindings/tests/array_unittest.cc
@@ -26,6 +26,23 @@ using ArrayTest = testing::Test; +// Tests null and empty arrays. +TEST_F(ArrayTest, NullAndEmpty) { + Array<char> array0; + EXPECT_TRUE(array0.empty()); + EXPECT_FALSE(array0.is_null()); + array0 = nullptr; + EXPECT_TRUE(array0.is_null()); + EXPECT_FALSE(array0.empty()); + + Array<char> array1(nullptr); + EXPECT_TRUE(array1.is_null()); + EXPECT_FALSE(array1.empty()); + array1.SetToEmpty(); + EXPECT_TRUE(array1.empty()); + EXPECT_FALSE(array1.is_null()); +} + // Tests that basic Array operations work. TEST_F(ArrayTest, Basic) { Array<char> array(8);
diff --git a/mojo/public/cpp/bindings/tests/e2e_perftest.cc b/mojo/public/cpp/bindings/tests/e2e_perftest.cc new file mode 100644 index 0000000..cfa507b --- /dev/null +++ b/mojo/public/cpp/bindings/tests/e2e_perftest.cc
@@ -0,0 +1,196 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/test/perf_time_logger.h" +#include "base/thread_task_runner_handle.h" +#include "mojo/edk/test/mojo_test_base.h" +#include "mojo/edk/test/scoped_ipc_support.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace { + +class EchoServiceImpl : public test::EchoService { + public: + EchoServiceImpl(InterfaceRequest<EchoService> request, + const base::Closure& quit_closure); + ~EchoServiceImpl() override; + + // |EchoService| methods: + void Echo(const mojo::String& test_data, + const EchoCallback& callback) override; + + private: + const StrongBinding<EchoService> binding_; + const base::Closure quit_closure_; +}; + +EchoServiceImpl::EchoServiceImpl(InterfaceRequest<EchoService> request, + const base::Closure& quit_closure) + : binding_(this, std::move(request)), quit_closure_(quit_closure) {} + +EchoServiceImpl::~EchoServiceImpl() { + quit_closure_.Run(); +} + +void EchoServiceImpl::Echo(const mojo::String& test_data, + const EchoCallback& callback) { + callback.Run(test_data); +} + +class PingPongTest { + public: + explicit PingPongTest(test::EchoServicePtr service); + + void RunTest(int iterations, int batch_size, int message_size); + + private: + void DoPing(); + void OnPingDone(const mojo::String& reply); + + test::EchoServicePtr service_; + const base::Callback<void(const mojo::String&)> ping_done_callback_; + + int iterations_; + int batch_size_; + std::string message_; + + int current_iterations_; + int calls_outstanding_; + + base::Closure quit_closure_; +}; + +PingPongTest::PingPongTest(test::EchoServicePtr service) + : service_(std::move(service)), + ping_done_callback_( + base::Bind(&PingPongTest::OnPingDone, base::Unretained(this))) {} + +void PingPongTest::RunTest(int iterations, int batch_size, int message_size) { + iterations_ = iterations; + batch_size_ = batch_size; + message_ = std::string(message_size, 'a'); + current_iterations_ = 0; + calls_outstanding_ = 0; + + base::MessageLoop::current()->SetNestableTasksAllowed(true); + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&PingPongTest::DoPing, base::Unretained(this))); + run_loop.Run(); +} + +void PingPongTest::DoPing() { + DCHECK_EQ(0, calls_outstanding_); + current_iterations_++; + if (current_iterations_ > iterations_) { + quit_closure_.Run(); + return; + } + + calls_outstanding_ = batch_size_; + for (int i = 0; i < batch_size_; i++) { + service_->Echo(message_, ping_done_callback_); + } +} + +void PingPongTest::OnPingDone(const mojo::String& reply) { + DCHECK_GT(calls_outstanding_, 0); + calls_outstanding_--; + + if (!calls_outstanding_) + DoPing(); +} + +class MojoE2EPerftest : public edk::test::MojoTestBase { + public: + void RunTestOnTaskRunner(base::TaskRunner* runner, + MojoHandle client_mp, + const std::string& test_name) { + if (runner == base::ThreadTaskRunnerHandle::Get().get()) { + RunTests(client_mp, test_name); + } else { + base::RunLoop run_loop; + runner->PostTaskAndReply( + FROM_HERE, base::Bind(&MojoE2EPerftest::RunTests, + base::Unretained(this), client_mp, test_name), + run_loop.QuitClosure()); + run_loop.Run(); + } + } + + protected: + base::MessageLoop message_loop_; + + private: + void RunTests(MojoHandle client_mp, const std::string& test_name) { + const int kMessages = 10000; + const int kBatchSizes[] = {1, 10, 100}; + const int kMessageSizes[] = {8, 64, 512, 4096, 65536}; + + test::EchoServicePtr service; + service.Bind(InterfacePtrInfo<test::EchoService>( + ScopedMessagePipeHandle(MessagePipeHandle(client_mp)), + service.version())); + PingPongTest test(std::move(service)); + + for (int batch_size : kBatchSizes) { + for (int message_size : kMessageSizes) { + int num_messages = kMessages; + if (message_size == 65536) + num_messages /= 10; + std::string sub_test_name = base::StringPrintf( + "%s/%dx%d/%dbytes", test_name.c_str(), num_messages / batch_size, + batch_size, message_size); + base::PerfTimeLogger timer(sub_test_name.c_str()); + test.RunTest(num_messages / batch_size, batch_size, message_size); + } + } + } +}; + +DEFINE_TEST_CLIENT_TEST_WITH_PIPE(PingService, MojoE2EPerftest, mp) { + MojoHandle service_mp; + EXPECT_EQ("hello", ReadMessageWithHandles(mp, &service_mp, 1)); + + InterfaceRequest<test::EchoService> request; + request.Bind(ScopedMessagePipeHandle(MessagePipeHandle(service_mp))); + base::RunLoop run_loop; + new EchoServiceImpl(std::move(request), run_loop.QuitClosure()); + run_loop.Run(); +} + +TEST_F(MojoE2EPerftest, MultiProcessEchoMainThread) { + RUN_CHILD_ON_PIPE(PingService, mp) + MojoHandle client_mp, service_mp; + CreateMessagePipe(&client_mp, &service_mp); + WriteMessageWithHandles(mp, "hello", &service_mp, 1); + RunTestOnTaskRunner(message_loop_.task_runner().get(), client_mp, + "MultiProcessEchoMainThread"); + END_CHILD() +} + +TEST_F(MojoE2EPerftest, MultiProcessEchoIoThread) { + RUN_CHILD_ON_PIPE(PingService, mp) + MojoHandle client_mp, service_mp; + CreateMessagePipe(&client_mp, &service_mp); + WriteMessageWithHandles(mp, "hello", &service_mp, 1); + RunTestOnTaskRunner(edk::test::GetIoTaskRunner(), client_mp, + "MultiProcessEchoIoThread"); + END_CHILD() +} + +} // namespace +} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc index 4ccd8c0e..e4d2bee 100644 --- a/mojo/public/cpp/bindings/tests/map_unittest.cc +++ b/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -42,6 +42,23 @@ using MapTest = testing::Test; +// Tests null and empty maps. +TEST_F(MapTest, NullAndEmpty) { + Map<char, char> map0; + EXPECT_TRUE(map0.empty()); + EXPECT_FALSE(map0.is_null()); + map0 = nullptr; + EXPECT_TRUE(map0.is_null()); + EXPECT_FALSE(map0.empty()); + + Map<char, char> map1(nullptr); + EXPECT_TRUE(map1.is_null()); + EXPECT_FALSE(map1.empty()); + map1.SetToEmpty(); + EXPECT_TRUE(map1.empty()); + EXPECT_FALSE(map1.is_null()); +} + // Tests that basic Map operations work. TEST_F(MapTest, InsertWorks) { Map<String, int> map;
diff --git a/mojo/public/interfaces/bindings/tests/ping_service.mojom b/mojo/public/interfaces/bindings/tests/ping_service.mojom index 3e1f1c4..ba6ad3d 100644 --- a/mojo/public/interfaces/bindings/tests/ping_service.mojom +++ b/mojo/public/interfaces/bindings/tests/ping_service.mojom
@@ -8,3 +8,7 @@ interface PingService { Ping() => (); }; + +interface EchoService { + Echo(string test_data) => (string echo_data); +};
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index 22e089c..c2d3a1c3 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -105,6 +105,9 @@ return hasattr(kind, "name") and \ GetFullMojomNameForKind(kind) in _current_typemap +def IsCloneableKind(kind): + return mojom.IsCloneableKind(kind, IsTypemappedKind) + def IsNativeOnlyKind(kind): return mojom.IsStructKind(kind) and kind.native_only @@ -477,7 +480,7 @@ "should_inline": ShouldInlineStruct, "should_inline_union": ShouldInlineUnion, "is_array_kind": mojom.IsArrayKind, - "is_cloneable_kind": mojom.IsCloneableKind, + "is_cloneable_kind": IsCloneableKind, "is_enum_kind": mojom.IsEnumKind, "is_integral_kind": mojom.IsIntegralKind, "is_move_only_kind": mojom.IsMoveOnlyKind,
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py index 6a86f167..a673d8e 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -607,7 +607,7 @@ IsAnyHandleKind(kind) or IsInterfaceKind(kind) or IsAssociatedKind(kind) -def IsCloneableKind(kind): +def IsCloneableKind(kind, filter): def _IsCloneable(kind, visited_kinds): if kind in visited_kinds: # No need to examine the kind again. @@ -618,7 +618,7 @@ if IsArrayKind(kind): return _IsCloneable(kind.kind, visited_kinds) if IsStructKind(kind) or IsUnionKind(kind): - if IsStructKind(kind) and kind.native_only: + if IsStructKind(kind) and (kind.native_only or filter(kind)): return False for field in kind.fields: if not _IsCloneable(field.kind, visited_kinds):
diff --git a/mojo/services/network/network_service_delegate.cc b/mojo/services/network/network_service_delegate.cc index aadc5cac..b257331 100644 --- a/mojo/services/network/network_service_delegate.cc +++ b/mojo/services/network/network_service_delegate.cc
@@ -48,8 +48,7 @@ } void NetworkServiceDelegate::Initialize(Connector* connector, - const std::string& name, - const std::string& user_id, + const Identity& identity, uint32_t id) { // TODO(erg): Find everything else that writes to the filesystem and // transition it to proxying mojo:filesystem. We shouldn't have any path @@ -67,7 +66,7 @@ } context_.reset(new NetworkContext(base_path, this)); - tracing_.Initialize(connector, name); + tracing_.Initialize(connector, identity.name()); } bool NetworkServiceDelegate::AcceptConnection(Connection* connection) {
diff --git a/mojo/services/network/network_service_delegate.h b/mojo/services/network/network_service_delegate.h index 07e93b5..70989395 100644 --- a/mojo/services/network/network_service_delegate.h +++ b/mojo/services/network/network_service_delegate.h
@@ -35,8 +35,8 @@ private: // mojo::ShellClient implementation. - void Initialize(Connector* connector, const std::string& url, - const std::string& user_id, uint32_t id) override; + void Initialize(Connector* connector, const Identity& identity, + uint32_t id) override; bool AcceptConnection(Connection* connection) override; // InterfaceFactory<NetworkService> implementation.
diff --git a/mojo/services/package_manager/package_manager.cc b/mojo/services/package_manager/package_manager.cc index 00d59c01..858cf9d 100644 --- a/mojo/services/package_manager/package_manager.cc +++ b/mojo/services/package_manager/package_manager.cc
@@ -119,7 +119,7 @@ bool PackageManager::AcceptConnection(mojo::Connection* connection) { connection->AddInterface<mojom::Catalog>(this); connection->AddInterface<mojom::Resolver>(this); - if (connection->GetRemoteApplicationName() == "mojo:shell") + if (connection->GetRemoteIdentity().name() == "mojo:shell") connection->AddInterface<mojom::ShellResolver>(this); return true; }
diff --git a/mojo/shell/BUILD.gn b/mojo/shell/BUILD.gn index 51c6c215..504372acb 100644 --- a/mojo/shell/BUILD.gn +++ b/mojo/shell/BUILD.gn
@@ -24,8 +24,6 @@ "connect_params.h", "connect_util.cc", "connect_util.h", - "identity.cc", - "identity.h", "loader.h", "native_runner.h", "native_runner_delegate.h",
diff --git a/mojo/shell/background/background_shell.cc b/mojo/shell/background/background_shell.cc index 1d31de7..24ec075 100644 --- a/mojo/shell/background/background_shell.cc +++ b/mojo/shell/background/background_shell.cc
@@ -178,7 +178,8 @@ mojom::ShellClientRequest BackgroundShell::CreateShellClientRequest( const std::string& name) { scoped_ptr<ConnectParams> params(new ConnectParams); - params->set_target(Identity(name, std::string(), mojom::kRootUserID)); + params->set_source(CreateShellIdentity()); + params->set_target(Identity(name, mojom::kRootUserID)); mojom::ShellClientRequest request; base::WaitableEvent signal(true, false); thread_->message_loop()->task_runner()->PostTask(
diff --git a/mojo/shell/connect_params.h b/mojo/shell/connect_params.h index b90ac32..3b28a50 100644 --- a/mojo/shell/connect_params.h +++ b/mojo/shell/connect_params.h
@@ -11,7 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "mojo/public/cpp/bindings/interface_request.h" -#include "mojo/shell/identity.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/interfaces/connector.mojom.h" #include "mojo/shell/public/interfaces/interface_provider.mojom.h" @@ -22,8 +22,8 @@ // application. class ConnectParams { public: - ConnectParams(); - ~ConnectParams(); + ConnectParams(); + ~ConnectParams(); void set_source(const Identity& source) { source_ = source; } const Identity& source() const { return source_; }
diff --git a/mojo/shell/connect_util.h b/mojo/shell/connect_util.h index 87df3d81..d7f629c 100644 --- a/mojo/shell/connect_util.h +++ b/mojo/shell/connect_util.h
@@ -7,7 +7,7 @@ #include "mojo/public/cpp/bindings/interface_ptr.h" #include "mojo/public/cpp/system/handle.h" -#include "mojo/shell/identity.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/interfaces/connector.mojom.h" namespace mojo { @@ -39,7 +39,7 @@ const std::string& name, InterfacePtr<Interface>* ptr) { ScopedMessagePipeHandle service_handle = ConnectToInterfaceByName( - shell, source, Identity(name, std::string(), mojom::kInheritUserID), + shell, source, Identity(name, mojom::kInheritUserID), Interface::Name_); ptr->Bind(InterfacePtrInfo<Interface>(std::move(service_handle), 0u)); }
diff --git a/mojo/shell/identity.cc b/mojo/shell/identity.cc deleted file mode 100644 index 243565a..0000000 --- a/mojo/shell/identity.cc +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/shell/identity.h" - -#include "mojo/shell/public/cpp/names.h" -#include "mojo/shell/public/interfaces/connector.mojom.h" - -namespace mojo { -namespace shell { - -Identity::Identity() {} - -Identity::Identity(const std::string& name) - : Identity(name, GetNamePath(name), mojom::kRootUserID) {} - -Identity::Identity(const std::string& name, const std::string& qualifier, - const std::string& user_id) - : name_(name), - qualifier_(qualifier.empty() ? GetNamePath(name_) : qualifier), - user_id_(user_id) {} - -Identity::Identity(const Identity& other) = default; - -Identity::~Identity() {} - -bool Identity::operator<(const Identity& other) const { - // We specifically don't include filter in the equivalence check because we - // don't quite know how this should work yet. - // TODO(beng): figure out how it should work. - if (name_ != other.name_) - return name_ < other.name_; - if (qualifier_ != other.qualifier_) - return qualifier_ < other.qualifier_; - return user_id_ < other.user_id_; -} - -bool Identity::operator==(const Identity& other) const { - // We specifically don't include filter in the equivalence check because we - // don't quite know how this should work yet. - // TODO(beng): figure out how it should work. - return other.name_ == name_ && other.qualifier_ == qualifier_ && - other.user_id_ == user_id_; -} - -Identity CreateShellIdentity() { - Identity id = Identity("mojo:shell", "", mojom::kRootUserID); - id.set_filter(GetPermissiveCapabilityFilter()); - return id; -} - -CapabilityFilter GetPermissiveCapabilityFilter() { - CapabilityFilter filter; - AllowedInterfaces interfaces; - interfaces.insert("*"); - filter["*"] = interfaces; - return filter; -} - -AllowedInterfaces GetAllowedInterfaces(const CapabilityFilter& filter, - const Identity& identity) { - // Start by looking for interfaces specific to the supplied identity. - auto it = filter.find(identity.name()); - if (it != filter.end()) - return it->second; - - // Fall back to looking for a wildcard rule. - it = filter.find("*"); - if (filter.size() == 1 && it != filter.end()) - return it->second; - - // Finally, nothing is allowed. - return AllowedInterfaces(); -} - -} // namespace shell -} // namespace mojo
diff --git a/mojo/shell/identity.h b/mojo/shell/identity.h deleted file mode 100644 index 7d33295d..0000000 --- a/mojo/shell/identity.h +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_SHELL_IDENTITY_H_ -#define MOJO_SHELL_IDENTITY_H_ - -#include <stdint.h> - -#include <map> -#include <set> -#include <string> - -namespace mojo { -namespace shell { - -// A set of names of interfaces that may be exposed to an application. -using AllowedInterfaces = std::set<std::string>; -// A map of allowed applications to allowed interface sets. See shell.mojom for -// more details. -using CapabilityFilter = std::map<std::string, AllowedInterfaces>; - -// Represents the identity of an application. -// |name| is the structured name of the application. -// |qualifier| is a string that allows to tie a specific instance of an -// application to another. A typical use case of qualifier is to control process -// grouping for a given application name. For example, the core services are -// grouped into "Core"/"Files"/"Network"/etc. using qualifier; content handler's -// qualifier is derived from the origin of the content. -class Identity { - public: - Identity(); - // Assumes user = mojom::kRootUserID. - // Used in tests or for shell-initiated connections. - explicit Identity(const std::string& in_name); - Identity(const std::string& in_name, - const std::string& in_qualifier, - const std::string& user_id); - Identity(const Identity& other); - ~Identity(); - - bool operator<(const Identity& other) const; - bool is_null() const { return name_.empty(); } - bool operator==(const Identity& other) const; - - const std::string& name() const { return name_; } - const std::string& user_id() const { return user_id_; } - void set_user_id(const std::string& user_id) { user_id_ = user_id; } - const std::string& qualifier() const { return qualifier_; } - void set_filter(const CapabilityFilter& filter) { filter_ = filter; } - const CapabilityFilter& filter() const { return filter_; } - - private: - std::string name_; - std::string qualifier_; - - std::string user_id_; - - // TODO(beng): CapabilityFilter is not currently included in equivalence - // checks for Identity since we're not currently clear on the - // policy for instance disambiguation. Need to figure this out. - // This field is supplied because it is logically part of the - // instance identity of an application. - CapabilityFilter filter_; -}; - -// Creates an identity for the Shell, used when the Shell connects to -// applications. -Identity CreateShellIdentity(); - -// Returns a capability filter that allows an application to connect to any -// other application and any service exposed by other applications. -CapabilityFilter GetPermissiveCapabilityFilter(); - -// Returns the set of interfaces that an application instance with |filter| is -// allowed to see from an instance with |identity|. -AllowedInterfaces GetAllowedInterfaces(const CapabilityFilter& filter, - const Identity& identity); - -} // namespace shell -} // namespace mojo - -#endif // MOJO_SHELL_IDENTITY_H_
diff --git a/mojo/shell/native_runner.h b/mojo/shell/native_runner.h index ce14f11..92c1adc 100644 --- a/mojo/shell/native_runner.h +++ b/mojo/shell/native_runner.h
@@ -17,9 +17,9 @@ } namespace mojo { +class Identity; namespace shell { -class Identity; // Shell requires implementations of NativeRunner and NativeRunnerFactory to run // native applications.
diff --git a/mojo/shell/native_runner_delegate.h b/mojo/shell/native_runner_delegate.h index d2fe826..b732ec60 100644 --- a/mojo/shell/native_runner_delegate.h +++ b/mojo/shell/native_runner_delegate.h
@@ -10,9 +10,8 @@ } namespace mojo { -namespace shell { - class Identity; +namespace shell { class NativeRunnerDelegate { public:
diff --git a/mojo/shell/public/cpp/BUILD.gn b/mojo/shell/public/cpp/BUILD.gn index 576704c..e2cfbc8e 100644 --- a/mojo/shell/public/cpp/BUILD.gn +++ b/mojo/shell/public/cpp/BUILD.gn
@@ -24,6 +24,7 @@ "connect.h", "connection.h", "connector.h", + "identity.h", "initialize_base_and_icu.cc", "interface_binder.h", "interface_factory.h", @@ -34,6 +35,7 @@ "lib/connection_impl.h", "lib/connector_impl.cc", "lib/connector_impl.h", + "lib/identity.cc", "lib/interface_factory_binder.h", "lib/interface_registry.cc", "lib/message_loop_ref.cc",
diff --git a/mojo/shell/public/cpp/connection.h b/mojo/shell/public/cpp/connection.h index ce1401c8..d3b3b8a 100644 --- a/mojo/shell/public/cpp/connection.h +++ b/mojo/shell/public/cpp/connection.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "mojo/shell/public/cpp/connect.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/cpp/interface_registry.h" #include "mojo/shell/public/interfaces/connector.mojom.h" #include "mojo/shell/public/interfaces/interface_provider.mojom.h" @@ -88,14 +89,12 @@ // same as the value returned by GetRemoveApplicationName(). virtual const std::string& GetConnectionName() = 0; - // Returns the name identifying the remote application on this connection. - virtual const std::string& GetRemoteApplicationName() = 0; - - // Returns the User ID for the remote application. Prior to the Connect() - // callback being fired, this will return the value passed via Connect(). - // After the Connect() callback (call AddRemoteIDCallback to register one) - // this will return the actual user id the shell ran the target as. - virtual const std::string& GetRemoteUserID() const = 0; + // Returns the remote identity. While the connection is in the pending state, + // the user_id() field will be the value passed via Connect(). After the + // connection is completed, it will change to the value assigned by the shell. + // Call AddConnectionCompletedClosure() to schedule a closure to be run when + // the resolved user id is available. + virtual const Identity& GetRemoteIdentity() const = 0; // Register a handler to receive an error notification on the pipe to the // remote application's InterfaceProvider.
diff --git a/mojo/shell/public/cpp/connector.h b/mojo/shell/public/cpp/connector.h index 94fdc9a..be6ba43 100644 --- a/mojo/shell/public/cpp/connector.h +++ b/mojo/shell/public/cpp/connector.h
@@ -6,6 +6,7 @@ #define MOJO_SHELL_PUBLIC_CPP_CONNECTOR_H_ #include "mojo/shell/public/cpp/connection.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/interfaces/connector.mojom.h" namespace mojo { @@ -30,16 +31,15 @@ class ConnectParams { public: + explicit ConnectParams(const Identity& target); explicit ConnectParams(const std::string& name); ~ConnectParams(); - const std::string& name() { return name_; } - void set_user_id(const std::string& user_id) { user_id_ = user_id; } - const std::string& user_id() const { return user_id_; } + const Identity& target() { return target_; } + void set_target(const Identity& target) { target_ = target; } private: - std::string name_; - std::string user_id_; + Identity target_; DISALLOW_COPY_AND_ASSIGN(ConnectParams); };
diff --git a/mojo/shell/public/cpp/identity.h b/mojo/shell/public/cpp/identity.h new file mode 100644 index 0000000..90f4608 --- /dev/null +++ b/mojo/shell/public/cpp/identity.h
@@ -0,0 +1,55 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_SHELL_PUBLIC_CPP_IDENTITY_H_ +#define MOJO_SHELL_PUBLIC_CPP_IDENTITY_H_ + +#include <string> + +#include "mojo/shell/public/interfaces/connector.mojom.h" + +namespace mojo { + +// Represents the identity of an application. +// |name| is the structured name of the application. +// |instance| is a string that allows to tie a specific instance to another. A +// typical use case of instance is to control process grouping for a given name. +class Identity { + public: + Identity(); + Identity(const std::string& name, + const std::string& user_id); + Identity(const std::string& name, + const std::string& user_id, + const std::string& instance); + Identity(const Identity& other); + ~Identity(); + + bool operator<(const Identity& other) const; + bool is_null() const { return name_.empty(); } + bool operator==(const Identity& other) const; + + const std::string& name() const { return name_; } + const std::string& user_id() const { return user_id_; } + void set_user_id(const std::string& user_id) { user_id_ = user_id; } + const std::string& instance() const { return instance_; } + + private: + std::string name_; + std::string user_id_; + std::string instance_; +}; + +template <> +struct TypeConverter<shell::mojom::IdentityPtr, Identity> { + static shell::mojom::IdentityPtr Convert(const Identity& input); +}; +template <> +struct TypeConverter<Identity, shell::mojom::IdentityPtr> { + static Identity Convert(const shell::mojom::IdentityPtr& input); +}; + +} // namespace mojo + +#endif // MOJO_SHELL_PUBLIC_CPP_IDENTITY_H_
diff --git a/mojo/shell/public/cpp/lib/application_test_base.cc b/mojo/shell/public/cpp/lib/application_test_base.cc index 7f8f684..e2e5826 100644 --- a/mojo/shell/public/cpp/lib/application_test_base.cc +++ b/mojo/shell/public/cpp/lib/application_test_base.cc
@@ -19,9 +19,8 @@ namespace { // Share the application name with multiple application tests. -String g_name; +shell::mojom::IdentityPtr g_identity; uint32_t g_id = shell::mojom::kInvalidInstanceID; -String g_user_id = shell::mojom::kRootUserID; // ShellClient request handle passed from the shell in MojoMain, stored in // between SetUp()/TearDown() so we can (re-)intialize new ShellConnections. @@ -45,20 +44,17 @@ private: // shell::mojom::ShellClient implementation. void Initialize(shell::mojom::ConnectorPtr connector, - const String& name, - const String& user_id, + shell::mojom::IdentityPtr identity, uint32_t id) override { - g_name = name; + g_identity = std::move(identity); g_id = id; - g_user_id = user_id; g_shell_client_request = binding_.Unbind(); g_connector = std::move(connector); } void AcceptConnection( - const String& requestor_name, - const String& requestor_user_id, - uint32_t requestor_id, + shell::mojom::IdentityPtr source, + uint32_t source_id, shell::mojom::InterfaceProviderRequest local_interfaces, shell::mojom::InterfaceProviderPtr remote_interfaces, Array<String> allowed_interfaces, @@ -118,12 +114,12 @@ : shell_connection_(new ShellConnection( client == nullptr ? &default_shell_client_ : client, std::move(g_shell_client_request))), - name_(g_name), - userid_(g_user_id), + name_(g_identity->name), + userid_(g_identity->user_id), instance_id_(g_id) { // Fake ShellClient initialization. shell::mojom::ShellClient* shell_client = shell_connection_.get(); - shell_client->Initialize(std::move(g_connector), g_name, g_user_id, g_id); + shell_client->Initialize(std::move(g_connector), std::move(g_identity), g_id); } TestHelper::~TestHelper() {
diff --git a/mojo/shell/public/cpp/lib/connection_impl.cc b/mojo/shell/public/cpp/lib/connection_impl.cc index 3541f55..d3585e7 100644 --- a/mojo/shell/public/cpp/lib/connection_impl.cc +++ b/mojo/shell/public/cpp/lib/connection_impl.cc
@@ -21,18 +21,16 @@ ConnectionImpl::ConnectionImpl( const std::string& connection_name, - const std::string& remote_name, + const Identity& remote, uint32_t remote_id, - const std::string& remote_user_id, shell::mojom::InterfaceProviderPtr remote_interfaces, shell::mojom::InterfaceProviderRequest local_interfaces, const std::set<std::string>& allowed_interfaces, State initial_state) : connection_name_(connection_name), - remote_name_(remote_name), - state_(initial_state), + remote_(remote), remote_id_(remote_id), - remote_user_id_(remote_user_id), + state_(initial_state), local_registry_(std::move(local_interfaces), this), remote_interfaces_(std::move(remote_interfaces)), allowed_interfaces_(allowed_interfaces), @@ -59,12 +57,8 @@ return connection_name_; } -const std::string& ConnectionImpl::GetRemoteApplicationName() { - return remote_name_; -} - -const std::string& ConnectionImpl::GetRemoteUserID() const { - return remote_user_id_; +const Identity& ConnectionImpl::GetRemoteIdentity() const { + return remote_; } void ConnectionImpl::SetConnectionLostClosure(const Closure& handler) { @@ -118,7 +112,7 @@ state_ = result_ == shell::mojom::ConnectResult::SUCCEEDED ? State::CONNECTED : State::DISCONNECTED; remote_id_ = target_application_id; - remote_user_id_= target_user_id; + remote_.set_user_id(target_user_id); std::vector<Closure> callbacks; callbacks.swap(connection_completed_callbacks_); for (auto callback : callbacks)
diff --git a/mojo/shell/public/cpp/lib/connection_impl.h b/mojo/shell/public/cpp/lib/connection_impl.h index e0a03d4d..3247a5a 100644 --- a/mojo/shell/public/cpp/lib/connection_impl.h +++ b/mojo/shell/public/cpp/lib/connection_impl.h
@@ -12,6 +12,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "mojo/shell/public/cpp/connection.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/interfaces/connector.mojom.h" #include "mojo/shell/public/interfaces/interface_provider.mojom.h" @@ -28,9 +29,8 @@ // an application to expose to another application. If this set contains only // the string value "*" all interfaces may be exposed. ConnectionImpl(const std::string& connection_name, - const std::string& remote_name, + const Identity& remote, uint32_t remote_id, - const std::string& remote_user_id, shell::mojom::InterfaceProviderPtr remote_interfaces, shell::mojom::InterfaceProviderRequest local_interfaces, const std::set<std::string>& allowed_interfaces, @@ -42,8 +42,7 @@ private: // Connection: const std::string& GetConnectionName() override; - const std::string& GetRemoteApplicationName() override; - const std::string& GetRemoteUserID() const override; + const Identity& GetRemoteIdentity() const override; void SetConnectionLostClosure(const Closure& handler) override; shell::mojom::ConnectResult GetResult() const override; bool IsPending() const override; @@ -59,13 +58,12 @@ uint32_t target_application_id); const std::string connection_name_; - const std::string remote_name_; + Identity remote_; + uint32_t remote_id_ = shell::mojom::kInvalidInstanceID; State state_; shell::mojom::ConnectResult result_ = shell::mojom::ConnectResult::SUCCEEDED; - uint32_t remote_id_ = shell::mojom::kInvalidInstanceID; std::vector<Closure> connection_completed_callbacks_; - std::string remote_user_id_ = shell::mojom::kInheritUserID; InterfaceRegistry local_registry_; shell::mojom::InterfaceProviderPtr remote_interfaces_;
diff --git a/mojo/shell/public/cpp/lib/connector_impl.cc b/mojo/shell/public/cpp/lib/connector_impl.cc index 9adeebd..cc12dbb0 100644 --- a/mojo/shell/public/cpp/lib/connector_impl.cc +++ b/mojo/shell/public/cpp/lib/connector_impl.cc
@@ -4,14 +4,15 @@ #include "mojo/shell/public/cpp/lib/connector_impl.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/cpp/lib/connection_impl.h" namespace mojo { +Connector::ConnectParams::ConnectParams(const Identity& target) + : target_(target) {} Connector::ConnectParams::ConnectParams(const std::string& name) - : name_(name), - user_id_(shell::mojom::kInheritUserID) { -} + : target_(name, shell::mojom::kInheritUserID) {} Connector::ConnectParams::~ConnectParams() {} ConnectorImpl::ConnectorImpl(shell::mojom::ConnectorPtrInfo unbound_state) @@ -43,7 +44,6 @@ DCHECK(thread_checker_->CalledOnValidThread()); DCHECK(params); - std::string application_name = params->name(); // We allow all interfaces on outgoing connections since we are presumably in // a position to know who we're talking to. // TODO(beng): We should filter outgoing interfaces also. The shell must pass @@ -58,14 +58,13 @@ shell::mojom::InterfaceProviderRequest remote_request = GetProxy(&remote_interfaces); scoped_ptr<internal::ConnectionImpl> registry(new internal::ConnectionImpl( - application_name, application_name, shell::mojom::kInvalidInstanceID, - params->user_id(), std::move(remote_interfaces), std::move(local_request), - allowed, Connection::State::PENDING)); - connector_->Connect(application_name, - params->user_id(), - std::move(remote_request), - std::move(local_interfaces), - registry->GetConnectCallback()); + params->target().name(), params->target(), + shell::mojom::kInvalidInstanceID, std::move(remote_interfaces), + std::move(local_request), allowed, Connection::State::PENDING)); + connector_->Connect( + shell::mojom::Identity::From(params->target()), + std::move(remote_request), std::move(local_interfaces), + registry->GetConnectCallback()); return std::move(registry); }
diff --git a/mojo/shell/public/cpp/lib/identity.cc b/mojo/shell/public/cpp/lib/identity.cc new file mode 100644 index 0000000..85860a0 --- /dev/null +++ b/mojo/shell/public/cpp/lib/identity.cc
@@ -0,0 +1,60 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/shell/public/cpp/identity.h" + +#include "base/guid.h" +#include "mojo/shell/public/cpp/names.h" + +namespace mojo { + +Identity::Identity() {} + +Identity::Identity(const std::string& name, const std::string& user_id) + : Identity(name, user_id, "") {} + +Identity::Identity(const std::string& name, const std::string& user_id, + const std::string& instance) + : name_(name), + user_id_(user_id), + instance_(instance.empty() ? GetNamePath(name_) : instance) { + CHECK(!user_id.empty()); + CHECK(base::IsValidGUID(user_id)); +} + +Identity::Identity(const Identity& other) = default; + +Identity::~Identity() {} + +bool Identity::operator<(const Identity& other) const { + if (name_ != other.name_) + return name_ < other.name_; + if (instance_ != other.instance_) + return instance_ < other.instance_; + return user_id_ < other.user_id_; +} + +bool Identity::operator==(const Identity& other) const { + return other.name_ == name_ && other.instance_ == instance_ && + other.user_id_ == user_id_; +} + +// static +shell::mojom::IdentityPtr + TypeConverter<shell::mojom::IdentityPtr, Identity>::Convert( + const Identity& input) { + shell::mojom::IdentityPtr identity(shell::mojom::Identity::New()); + identity->name = input.name(); + identity->user_id = input.user_id(); + identity->instance = input.instance(); + return identity; +} + +// static +Identity TypeConverter<Identity, shell::mojom::IdentityPtr>::Convert( + const shell::mojom::IdentityPtr& input) { + return Identity(input->name, input->user_id, input->instance); +} + +} // namespace mojo
diff --git a/mojo/shell/public/cpp/lib/interface_registry.cc b/mojo/shell/public/cpp/lib/interface_registry.cc index 9333207..c8f9703b 100644 --- a/mojo/shell/public/cpp/lib/interface_registry.cc +++ b/mojo/shell/public/cpp/lib/interface_registry.cc
@@ -53,7 +53,7 @@ LOG(WARNING) << "Connection CapabilityFilter prevented binding to interface: " << interface_name << " connection_name:" << connection_->GetConnectionName() << " remote_name:" - << connection_->GetRemoteApplicationName(); + << connection_->GetRemoteIdentity().name(); return false; }
diff --git a/mojo/shell/public/cpp/lib/shell_client.cc b/mojo/shell/public/cpp/lib/shell_client.cc index f5441ce1..c41999b 100644 --- a/mojo/shell/public/cpp/lib/shell_client.cc +++ b/mojo/shell/public/cpp/lib/shell_client.cc
@@ -9,8 +9,8 @@ ShellClient::ShellClient() {} ShellClient::~ShellClient() {} -void ShellClient::Initialize(Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) { +void ShellClient::Initialize(Connector* connector, const Identity& identity, + uint32_t id) { } bool ShellClient::AcceptConnection(Connection* connection) {
diff --git a/mojo/shell/public/cpp/lib/shell_connection.cc b/mojo/shell/public/cpp/lib/shell_connection.cc index 0abac7e..8ee729d0 100644 --- a/mojo/shell/public/cpp/lib/shell_connection.cc +++ b/mojo/shell/public/cpp/lib/shell_connection.cc
@@ -35,27 +35,25 @@ // ShellConnection, shell::mojom::ShellClient implementation: void ShellConnection::Initialize(shell::mojom::ConnectorPtr connector, - const String& name, - const String& user_id, + shell::mojom::IdentityPtr identity, uint32_t id) { connector_.reset(new ConnectorImpl(std::move(connector))); binding_.set_connection_error_handler( base::Bind(&ShellConnection::OnConnectionError, weak_factory_.GetWeakPtr())); - client_->Initialize(connector_.get(), name, user_id, id); + client_->Initialize(connector_.get(), identity.To<Identity>(), id); } void ShellConnection::AcceptConnection( - const String& requestor_name, - const String& requestor_user_id, - uint32_t requestor_id, + shell::mojom::IdentityPtr source, + uint32_t source_id, shell::mojom::InterfaceProviderRequest local_interfaces, shell::mojom::InterfaceProviderPtr remote_interfaces, Array<String> allowed_interfaces, const String& name) { scoped_ptr<Connection> registry(new internal::ConnectionImpl( - name, requestor_name, requestor_id, requestor_user_id, - std::move(remote_interfaces), std::move(local_interfaces), + name, source.To<Identity>(), source_id, std::move(remote_interfaces), + std::move(local_interfaces), allowed_interfaces.To<std::set<std::string>>(), Connection::State::CONNECTED)); if (!client_->AcceptConnection(registry.get()))
diff --git a/mojo/shell/public/cpp/lib/shell_test.cc b/mojo/shell/public/cpp/lib/shell_test.cc index 7f981fe8..624fdc5 100644 --- a/mojo/shell/public/cpp/lib/shell_test.cc +++ b/mojo/shell/public/cpp/lib/shell_test.cc
@@ -14,9 +14,9 @@ ShellTestClient::ShellTestClient(ShellTest* test) : test_(test) {} ShellTestClient::~ShellTestClient() {} -void ShellTestClient::Initialize(Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) { - test_->InitializeCalled(connector, name, user_id, id); +void ShellTestClient::Initialize(Connector* connector, const Identity& identity, + uint32_t id) { + test_->InitializeCalled(connector, identity.name(), identity.user_id(), id); } ShellTest::ShellTest() {}
diff --git a/mojo/shell/public/cpp/shell_client.h b/mojo/shell/public/cpp/shell_client.h index 12c444a..5f60316 100644 --- a/mojo/shell/public/cpp/shell_client.h +++ b/mojo/shell/public/cpp/shell_client.h
@@ -10,6 +10,7 @@ #include "mojo/public/cpp/system/macros.h" #include "mojo/shell/public/cpp/connection.h" +#include "mojo/shell/public/cpp/identity.h" namespace mojo { @@ -26,14 +27,12 @@ virtual ~ShellClient(); // Called once a bidirectional connection with the shell has been established. - // |name| is the name used to start the application. + // |identity| is the identity of the instance. // |id| is a unique identifier the shell uses to identify this specific // instance of the application. - // |user_id| identifies the user this instance is run as. // Called exactly once before any other method. virtual void Initialize(Connector* connector, - const std::string& name, - const std::string& user_id, + const Identity& identity, uint32_t id); // Called when a connection to this client is brokered by the shell. Override
diff --git a/mojo/shell/public/cpp/shell_connection.h b/mojo/shell/public/cpp/shell_connection.h index 8e2f980..7ec245b 100644 --- a/mojo/shell/public/cpp/shell_connection.h +++ b/mojo/shell/public/cpp/shell_connection.h
@@ -59,13 +59,11 @@ private: // shell::mojom::ShellClient: void Initialize(shell::mojom::ConnectorPtr connector, - const String& name, - const String& user_id, + shell::mojom::IdentityPtr identity, uint32_t id) override; void AcceptConnection( - const String& requestor_name, - const String& requestor_user_id, - uint32_t requestor_id, + shell::mojom::IdentityPtr source, + uint32_t source_id, shell::mojom::InterfaceProviderRequest remote_interfaces, shell::mojom::InterfaceProviderPtr local_interfaces, Array<String> allowed_interfaces,
diff --git a/mojo/shell/public/cpp/shell_test.h b/mojo/shell/public/cpp/shell_test.h index aec85a9..c3ed59a 100644 --- a/mojo/shell/public/cpp/shell_test.h +++ b/mojo/shell/public/cpp/shell_test.h
@@ -35,8 +35,7 @@ protected: void Initialize(Connector* connector, - const std::string& name, - const std::string& user_id, + const Identity& identity, uint32_t id) override; private:
diff --git a/mojo/shell/public/interfaces/connector.mojom b/mojo/shell/public/interfaces/connector.mojom index 524047c..94acb69 100644 --- a/mojo/shell/public/interfaces/connector.mojom +++ b/mojo/shell/public/interfaces/connector.mojom
@@ -26,6 +26,37 @@ ACCESS_DENIED }; +// A collection of metadata that disambiguates instances in the shell. +struct Identity { + // A mojo: or exe: name identifying an application. + string name; + + // The user id of the target application instance to connect to. If no such + // instance exists, the shell may start one. This user id will be passed to + // the new instance via Initialize(). + // When connecting to other applications, applications must generally pass + // kInheritUserID for this value, and the shell will either connect to an + // existing instance matching the caller's user id, create a new instance + // matching the caller's user id, or connect to an existing instance running + // as kRootUserID. By default, applications do not have the ability to set + // arbitrary values to this field, and doing so will result in a connection + // error on the remote service provider. An application with the ability to + // launch applications with arbitrary user ids (e.g. a login app) may set this + // value to something meaningful to it. The user id string is a valid guid of + // the form "%08X-%04X-%04X-%04X-%012llX", and (aside from the root user whose + // guid is defined above) intended to be not-guessable. + // When an application is initialized or receives a connection from another + // application, this value is always the resolved user id, never + // kInheritUserID. + string user_id; + + // An application may spawn multiple instances with the same name,user_id + // pair, provided they are started with unique values of this field. + // TODO(beng): enforce the emptiness of this parameter unless the client bears + // the appropriate capability. + string instance; +}; + // Encapsulates establishing connections with other Mojo applications. interface Connector { // Requests a connection with another application. The application originating @@ -43,24 +74,8 @@ // // Parameters: // - // name - // A mojo: or exe: name identifying the target application. - // - // user_id - // The user id of the target application instance to connect to. If no such - // instance exists, the shell may start one. This user id will be passed - // to the new instance via Initialize(). Applications must generally pass - // kInheritUserID for this value, and the shell will either connect to an - // existing instance matching the caller's user id, create a new instance - // matching the caller's user id, or connect to an existing instance - // running as kRootUserID. By default, applications do not have the ability - // to pass arbitrary values to this method, and doing so will result in a - // connection error on the remote service provider. An application with - // the ability to launch applications with arbitrary user ids (e.g. a login - // app) may set this value to something meaningful to it. The user id - // string is a valid guid of the form "%08X-%04X-%04X-%04X-%012llX", and - // (aside from the root user whose guid is defined above) intended to be - // not-guessable. + // target + // Identifies the target application instance to connect to. // // remote_interfaces // Allows the source application access to interface implementations @@ -87,8 +102,7 @@ // application_id // A unique identifier for the instance that was connected to. // - Connect(string name, - string user_id, + Connect(Identity target, InterfaceProvider&? remote_interfaces, InterfaceProvider? local_interfaces) => (ConnectResult result, string user_id,
diff --git a/mojo/shell/public/interfaces/shell.mojom b/mojo/shell/public/interfaces/shell.mojom index f20b87ce..1076127 100644 --- a/mojo/shell/public/interfaces/shell.mojom +++ b/mojo/shell/public/interfaces/shell.mojom
@@ -9,8 +9,7 @@ struct InstanceInfo { uint32 id; - string name; - string qualifier; + Identity identity; uint32 pid; }; @@ -67,8 +66,7 @@ // code, see connector.mojom for definitions) the status of the instance // creation. CreateInstance(ShellClientFactory factory, - string name, - string user_id, + Identity target, CapabilityFilter filter, PIDReceiver& pid_receiver) => (ConnectResult result);
diff --git a/mojo/shell/public/interfaces/shell_client.mojom b/mojo/shell/public/interfaces/shell_client.mojom index 2af9a1f..d6a223e 100644 --- a/mojo/shell/public/interfaces/shell_client.mojom +++ b/mojo/shell/public/interfaces/shell_client.mojom
@@ -20,20 +20,18 @@ // An interface back to the shell by which new connections may be // established. // - // name - // The resolved name used in the connection request that resulted in this - // application being initialized. - // - // user_id - // Identifies the user this instance is run as in the shell. This may - // differ from the user the application that caused this application to be - // instantiated is run as. This will always be a valid user id, never - // Shell::kUserInherit. + // identity + // The identity of this instance in the shell. Includes: + // * The resolved name used in the connection request that resulted in this + // instance being initialized. + // * The user associated with this instance in the shell. This will never + // be kInheritUserID. + // * The instance group this instance belongs to. // // id // A unique identifier used by the shell to identify this instance. // - Initialize(Connector connector, string name, string user_id, uint32 id); + Initialize(Connector connector, Identity identity, uint32 id); // Called when another application attempts to open a connection to this // application. An application implements this method to complete the exchange @@ -44,18 +42,11 @@ // // Parameters: // - // requestor_name - // The name of the source application. + // source + // The identity of the instance originating the connection. // - // requestor_id - // A unique identifier used by the shell to identify the source - // application's instance. - // - // requestor_user_id - // An identifier for the user the source application is run as. This may - // differ from the application the target is run as (i.e. the one received - // via Initialize() above). This will always be a valid user id, never - // kInheritUserID. + // source_id + // A unique identifier used by the shell to identify the source instance. // // local_interfaces // A request for an InterfaceProvider by which the source application may @@ -74,9 +65,8 @@ // resolved_name // The resolved name used to complete this connection. // - AcceptConnection(string requestor_name, - string requestor_user_id, - uint32 requestor_id, + AcceptConnection(Identity source, + uint32 source_id, InterfaceProvider&? local_interfaces, InterfaceProvider? remote_interfaces, array<string> allowed_interfaces,
diff --git a/mojo/shell/runner/host/BUILD.gn b/mojo/shell/runner/host/BUILD.gn index 59f2cc7d..f7b45383 100644 --- a/mojo/shell/runner/host/BUILD.gn +++ b/mojo/shell/runner/host/BUILD.gn
@@ -76,6 +76,7 @@ "//mojo/message_pump", "//mojo/platform_handle:platform_handle_impl", "//mojo/shell", + "//mojo/shell/public/cpp:sources", "//mojo/shell/public/interfaces", "//mojo/shell/runner:init", "//mojo/shell/runner/common",
diff --git a/mojo/shell/runner/host/child_process_host.h b/mojo/shell/runner/host/child_process_host.h index 25b59dc3..6c6411d 100644 --- a/mojo/shell/runner/host/child_process_host.h +++ b/mojo/shell/runner/host/child_process_host.h
@@ -19,7 +19,7 @@ #include "base/synchronization/waitable_event.h" #include "mojo/edk/embedder/platform_channel_pair.h" #include "mojo/public/cpp/system/message_pipe.h" -#include "mojo/shell/identity.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/interfaces/shell_client_factory.mojom.h" #include "mojo/shell/runner/host/child_process_host.h" @@ -28,9 +28,9 @@ } namespace mojo { +class Identity; namespace shell { -class Identity; class NativeRunnerDelegate; // This class represents a "child process host". Handles launching and
diff --git a/mojo/shell/shell.cc b/mojo/shell/shell.cc index 17e912b6..4955c97 100644 --- a/mojo/shell/shell.cc +++ b/mojo/shell/shell.cc
@@ -37,12 +37,40 @@ const char kPackageManagerName[] = "mojo:package_manager"; void EmptyResolverCallback(const String& resolved_name, - const String& resolved_qualifier, + const String& resolved_instance, mojom::CapabilityFilterPtr base_filter, const String& file_url) {} } +Identity CreateShellIdentity() { + return Identity("mojo:shell", mojom::kRootUserID); +} + +CapabilityFilter GetPermissiveCapabilityFilter() { + CapabilityFilter filter; + AllowedInterfaces interfaces; + interfaces.insert("*"); + filter["*"] = interfaces; + return filter; +} + +AllowedInterfaces GetAllowedInterfaces(const CapabilityFilter& filter, + const Identity& identity) { + // Start by looking for interfaces specific to the supplied identity. + auto it = filter.find(identity.name()); + if (it != filter.end()) + return it->second; + + // Fall back to looking for a wildcard rule. + it = filter.find("*"); + if (filter.size() == 1 && it != filter.end()) + return it->second; + + // Finally, nothing is allowed. + return AllowedInterfaces(); +} + // Encapsulates a connection to an instance of an application, tracked by the // shell's Shell. class Shell::Instance : public mojom::Connector, @@ -53,12 +81,13 @@ public: Instance(mojom::ShellClientPtr shell_client, mojo::shell::Shell* shell, - const Identity& identity) + const Identity& identity, + const CapabilityFilter& filter) : shell_(shell), id_(GenerateUniqueID()), identity_(identity), - allow_any_application_(identity.filter().size() == 1 && - identity.filter().count("*") == 1), + filter_(filter), + allow_any_application_(filter.size() == 1 && filter.count("*") == 1), shell_client_(std::move(shell_client)), pid_receiver_binding_(this), weak_factory_(this) { @@ -73,7 +102,7 @@ void InitializeClient() { shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), - identity_.name(), identity_.user_id(), id_); + mojom::Identity::From(identity_), id_); connectors_.set_connection_error_handler( base::Bind(&mojo::shell::Shell::OnInstanceError, base::Unretained(shell_), base::Unretained(this))); @@ -82,15 +111,16 @@ void ConnectToClient(scoped_ptr<ConnectParams> params) { params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, identity_.user_id(), id_); + uint32_t source_id = mojom::kInvalidInstanceID; AllowedInterfaces interfaces; interfaces.insert("*"); - if (!params->source().is_null()) - interfaces = GetAllowedInterfaces(params->source().filter(), identity_); - Instance* source = shell_->GetExistingInstance(params->source()); - uint32_t source_id = source ? source->id() : mojom::kInvalidInstanceID; + if (source) { + interfaces = GetAllowedInterfaces(source->filter_, identity_); + source_id = source->id(); + } shell_client_->AcceptConnection( - params->source().name(), params->source().user_id(), source_id, + mojom::Identity::From(params->source()), source_id, params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), Array<String>::From(interfaces), params->target().name()); } @@ -114,8 +144,7 @@ mojom::InstanceInfoPtr CreateInstanceInfo() const { mojom::InstanceInfoPtr info(mojom::InstanceInfo::New()); info->id = id_; - info->name = identity_.name(); - info->qualifier = identity_.qualifier(); + info->identity = mojom::Identity::From(identity_); info->pid = pid_; return info; } @@ -131,37 +160,37 @@ private: // mojom::Connector implementation: - void Connect(const String& app_name, - const String& user_id, - shell::mojom::InterfaceProviderRequest remote_interfaces, - shell::mojom::InterfaceProviderPtr local_interfaces, + void Connect(mojom::IdentityPtr target, + mojom::InterfaceProviderRequest remote_interfaces, + mojom::InterfaceProviderPtr local_interfaces, const ConnectCallback& callback) override { - if (!IsValidName(app_name)) { - LOG(ERROR) << "Error: invalid Name: " << app_name; + if (!IsValidName(target->name)) { + LOG(ERROR) << "Error: invalid Name: " << target->name; callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, mojom::kInheritUserID, mojom::kInvalidInstanceID); return; } - if (!base::IsValidGUID(user_id)) { - LOG(ERROR) << "Error: invalid user_id: " << user_id; + if (!base::IsValidGUID(target->user_id)) { + LOG(ERROR) << "Error: invalid user_id: " << target->user_id; callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, mojom::kInheritUserID, mojom::kInvalidInstanceID); return; } // TODO(beng): perform checking on policy of whether this instance is // allowed to pass different user_ids. - if (allow_any_application_ || - identity_.filter().find(app_name) != identity_.filter().end()) { + // TODO(beng): perform checking on policy of whether this instance is + // allowed to pass non-empty instance identifiers. + if (allow_any_application_ || filter_.find(target->name) != filter_.end()) { scoped_ptr<ConnectParams> params(new ConnectParams); params->set_source(identity_); - params->set_target(Identity(app_name, std::string(), user_id)); + params->set_target(target.To<Identity>()); params->set_remote_interfaces(std::move(remote_interfaces)); params->set_local_interfaces(std::move(local_interfaces)); params->set_connect_callback(callback); shell_->Connect(std::move(params)); } else { LOG(WARNING) << "CapabilityFilter prevented connection from: " << - identity_.name() << " to: " << app_name; + identity_.name() << " to: " << target->name; callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID, mojom::kInvalidInstanceID); } @@ -183,31 +212,31 @@ // mojom::Shell implementation: void CreateInstance(mojom::ShellClientFactoryPtr factory, - const String& name, - const String& user_id, + mojom::IdentityPtr target, mojom::CapabilityFilterPtr filter, mojom::PIDReceiverRequest pid_receiver, const CreateInstanceCallback& callback) override { - if (!base::IsValidGUID(user_id)) + if (!base::IsValidGUID(target->user_id)) callback.Run(mojom::ConnectResult::INVALID_ARGUMENT); + + Identity target_id = target.To<Identity>(); + // TODO(beng): perform checking on policy of whether this instance is // allowed to pass different user_ids. - std::string user_id_string = user_id; - if (user_id_string == mojom::kInheritUserID) - user_id_string = identity_.user_id(); + if (target_id.user_id() == mojom::kInheritUserID) + target_id.set_user_id(identity_.user_id()); + mojom::ShellClientRequest request; + Instance* instance = shell_->CreateInstance( + target_id, filter->filter.To<CapabilityFilter>(), &request); + instance->pid_receiver_binding_.Bind(std::move(pid_receiver)); + instance->factory_ = std::move(factory); + instance->factory_->CreateShellClient(std::move(request), target->name); + callback.Run(mojom::ConnectResult::SUCCEEDED); // We don't call ConnectToClient() here since the instance was created // manually by other code, not in response to a Connect() request. The newly // created instance is identified by |name| and may be subsequently reached // by client code using this identity. - Identity target_id(name, std::string(), user_id_string); - target_id.set_filter(filter->filter.To<CapabilityFilter>()); - mojom::ShellClientRequest request; - Instance* instance = shell_->CreateInstance(target_id, &request); - instance->pid_receiver_binding_.Bind(std::move(pid_receiver)); - instance->factory_ = std::move(factory); - instance->factory_->CreateShellClient(std::move(request), name); - callback.Run(mojom::ConnectResult::SUCCEEDED); } void AddInstanceListener(mojom::InstanceListenerPtr listener) override { // TODO(beng): this should only track the instances matching this user, and @@ -233,6 +262,7 @@ // process is launched. const uint32_t id_; const Identity identity_; + const CapabilityFilter filter_; const bool allow_any_application_; mojom::ShellClientPtr shell_client_; Binding<mojom::PIDReceiver> pid_receiver_binding_; @@ -251,8 +281,11 @@ Shell::TestAPI::~TestAPI() {} bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { - return shell_->identity_to_instance_.find(Identity(name)) != - shell_->identity_to_instance_.end(); + for (const auto& entry : shell_->identity_to_instance_) { + if (entry.first.name() == name) + return true; + } + return false; } //////////////////////////////////////////////////////////////////////////////// @@ -265,7 +298,8 @@ native_runner_factory_(std::move(native_runner_factory)), weak_ptr_factory_(this) { mojom::ShellClientRequest request; - CreateInstance(CreateShellIdentity(), &request); + CreateInstance(CreateShellIdentity(), GetPermissiveCapabilityFilter(), + &request); shell_connection_.reset(new ShellConnection(this, std::move(request))); InitPackageManager(std::move(app_catalog)); @@ -298,6 +332,8 @@ params->set_target(target); } + CHECK(params->target().user_id() != mojom::kInheritUserID); + // Connect to an existing matching instance, if possible. if (ConnectToExistingInstance(¶ms)) return; @@ -313,12 +349,12 @@ const std::string& name) { DCHECK(!embedder_instance_); - mojo::shell::Identity target(name, std::string(), mojom::kRootUserID); - target.set_filter(GetPermissiveCapabilityFilter()); + Identity target(name, mojom::kRootUserID); DCHECK(!GetExistingInstance(target)); mojom::ShellClientRequest request; - embedder_instance_ = CreateInstance(target, &request); + embedder_instance_ = CreateInstance( + target, GetPermissiveCapabilityFilter(), &request); DCHECK(embedder_instance_); return request; @@ -363,7 +399,10 @@ SetLoaderForName(std::move(loader), name); mojom::ShellClientRequest request; - CreateInstance(Identity(name), &request); + // TODO(beng): Does the package manager actually have to be run with a + // permissive filter? + Identity identity(name, mojom::kRootUserID); + CreateInstance(identity, GetPermissiveCapabilityFilter(), &request); loader_raw->Load(name, std::move(request)); ConnectToInterface(this, CreateShellIdentity(), name, &shell_resolver_); @@ -419,10 +458,13 @@ } Shell::Instance* Shell::CreateInstance(const Identity& target_id, + const CapabilityFilter& filter, mojom::ShellClientRequest* request) { + CHECK(target_id.user_id() != mojom::kInheritUserID); mojom::ShellClientPtr shell_client; *request = GetProxy(&shell_client); - Instance* instance = new Instance(std::move(shell_client), this, target_id); + Instance* instance = + new Instance(std::move(shell_client), this, target_id, filter); DCHECK(identity_to_instance_.find(target_id) == identity_to_instance_.end()); identity_to_instance_[target_id] = instance; @@ -483,14 +525,14 @@ void Shell::OnGotResolvedName(scoped_ptr<ConnectParams> params, const String& resolved_name, - const String& resolved_qualifier, + const String& resolved_instance, mojom::CapabilityFilterPtr base_filter, const String& file_url) { - std::string qualifier = params->target().qualifier(); - if (qualifier == GetNamePath(params->target().name())) - qualifier = resolved_qualifier; - Identity target(params->target().name(), qualifier, - params->target().user_id()); + std::string instance_name = params->target().instance(); + if (instance_name == GetNamePath(params->target().name())) + instance_name = resolved_instance; + Identity target(params->target().name(), params->target().user_id(), + instance_name); params->set_target(target); // It's possible that when this manifest request was issued, another one was @@ -505,10 +547,9 @@ CapabilityFilter filter = GetPermissiveCapabilityFilter(); if (!base_filter.is_null()) filter = base_filter->filter.To<CapabilityFilter>(); - target.set_filter(filter); mojom::ShellClientRequest request; - Instance* instance = CreateInstance(target, &request); + Instance* instance = CreateInstance(target, filter, &request); instance->ConnectToClient(std::move(params)); if (LoadWithLoader(target, &request)) @@ -517,11 +558,11 @@ CHECK(!file_url.is_null() && !base_filter.is_null()); if (target.name() != resolved_name) { - // In cases where a package alias is resolved, we have to use the qualifier + // In cases where a package alias is resolved, we have to use the instance // from the original request rather than for the package itself, which will // always be the same. CreateShellClient( - source, Identity(resolved_name, resolved_qualifier, target.user_id()), + source, Identity(resolved_name, target.user_id(), resolved_instance), target.name(), std::move(request)); } else { bool start_sandboxed = false;
diff --git a/mojo/shell/shell.h b/mojo/shell/shell.h index 4a5dcb2..407f75d 100644 --- a/mojo/shell/shell.h +++ b/mojo/shell/shell.h
@@ -16,9 +16,9 @@ #include "mojo/services/package_manager/package_manager.h" #include "mojo/services/package_manager/public/interfaces/shell_resolver.mojom.h" #include "mojo/shell/connect_params.h" -#include "mojo/shell/identity.h" #include "mojo/shell/loader.h" #include "mojo/shell/native_runner.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/cpp/interface_factory.h" #include "mojo/shell/public/cpp/shell_client.h" #include "mojo/shell/public/interfaces/connector.mojom.h" @@ -36,6 +36,25 @@ class ShellConnection; namespace shell { +// A set of names of interfaces that may be exposed to an application. +using AllowedInterfaces = std::set<std::string>; +// A map of allowed applications to allowed interface sets. See shell.mojom for +// more details. +using CapabilityFilter = std::map<std::string, AllowedInterfaces>; + +// Creates an identity for the Shell, used when the Shell connects to +// applications. +Identity CreateShellIdentity(); + +// Returns a capability filter that allows an application to connect to any +// other application and any service exposed by other applications. +CapabilityFilter GetPermissiveCapabilityFilter(); + +// Returns the set of interfaces that an application instance with |filter| is +// allowed to see from an instance with |identity|. +AllowedInterfaces GetAllowedInterfaces(const CapabilityFilter& filter, + const Identity& identity); + class Shell : public ShellClient { public: // API for testing. @@ -119,6 +138,7 @@ bool ConnectToExistingInstance(scoped_ptr<ConnectParams>* params); Instance* CreateInstance(const Identity& target_id, + const CapabilityFilter& filter, mojom::ShellClientRequest* request); // Called from the instance implementing mojom::Shell. |user_id| must be @@ -152,7 +172,7 @@ // run with, from its manifest. void OnGotResolvedName(scoped_ptr<ConnectParams> params, const String& resolved_name, - const String& resolved_qualifier, + const String& resolved_instance, mojom::CapabilityFilterPtr base_filter, const String& file_url);
diff --git a/mojo/shell/standalone/context.cc b/mojo/shell/standalone/context.cc index 6cd1ac4..a6fcbed 100644 --- a/mojo/shell/standalone/context.cc +++ b/mojo/shell/standalone/context.cc
@@ -164,8 +164,7 @@ scoped_ptr<ConnectParams> params(new ConnectParams); params->set_source(CreateShellIdentity()); - params->set_target( - Identity("mojo:tracing", std::string(), mojom::kInheritUserID)); + params->set_target(Identity("mojo:tracing", mojom::kInheritUserID)); params->set_remote_interfaces(GetProxy(&tracing_remote_interfaces)); params->set_local_interfaces(std::move(tracing_local_interfaces)); shell_->Connect(std::move(params)); @@ -238,7 +237,7 @@ scoped_ptr<ConnectParams> params(new ConnectParams); params->set_source(CreateShellIdentity()); - params->set_target(Identity(name, std::string(), mojom::kRootUserID)); + params->set_target(Identity(name, mojom::kRootUserID)); params->set_remote_interfaces(GetProxy(&remote_interfaces)); params->set_local_interfaces(std::move(local_interfaces)); shell_->Connect(std::move(params));
diff --git a/mojo/shell/tests/connect/connect_test.mojom b/mojo/shell/tests/connect/connect_test.mojom index 356061e..3eeaa12 100644 --- a/mojo/shell/tests/connect/connect_test.mojom +++ b/mojo/shell/tests/connect/connect_test.mojom
@@ -14,6 +14,8 @@ // the standalone app's CapabilityFilter, but whose enclosing package is not. // The connection should be blocked and title should be "uninitialized". ConnectToAllowedAppInBlockedPackage() => (string title); + + GetInstance() => (string instance); }; struct ConnectionState {
diff --git a/mojo/shell/tests/connect/connect_test_app.cc b/mojo/shell/tests/connect/connect_test_app.cc index b469d165..205ddcf 100644 --- a/mojo/shell/tests/connect/connect_test_app.cc +++ b/mojo/shell/tests/connect/connect_test_app.cc
@@ -33,12 +33,11 @@ private: // mojo::ShellClient: - void Initialize(Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) override { + void Initialize(Connector* connector, const Identity& identity, + uint32_t id) override { connector_ = connector; - name_ = name; + identity_ = identity; id_ = id; - userid_ = user_id; bindings_.set_connection_error_handler( base::Bind(&ConnectTestApp::OnConnectionError, base::Unretained(this))); @@ -54,12 +53,12 @@ uint32_t remote_id = connection->GetRemoteInstanceID(); test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); state->connection_local_name = connection->GetConnectionName(); - state->connection_remote_name = connection->GetRemoteApplicationName(); - state->connection_remote_userid = connection->GetRemoteUserID(); + state->connection_remote_name = connection->GetRemoteIdentity().name(); + state->connection_remote_userid = connection->GetRemoteIdentity().user_id(); state->connection_remote_id = remote_id; - state->initialize_local_name = name_; + state->initialize_local_name = identity_.name(); state->initialize_id = id_; - state->initialize_userid = userid_; + state->initialize_userid = identity_.user_id(); connection->GetInterface(&caller_); caller_->ConnectionAccepted(std::move(state)); @@ -117,6 +116,9 @@ run_loop.Run(); } } + void GetInstance(const GetInstanceCallback& callback) override { + callback.Run(identity_.instance()); + } // test::mojom::BlockedInterface: void GetTitleBlocked(const GetTitleBlockedCallback& callback) override { @@ -144,9 +146,8 @@ } Connector* connector_ = nullptr; - std::string name_; + Identity identity_; uint32_t id_ = shell::mojom::kInvalidInstanceID; - std::string userid_ = mojom::kRootUserID; BindingSet<test::mojom::ConnectTestService> bindings_; BindingSet<test::mojom::StandaloneApp> standalone_bindings_; BindingSet<test::mojom::BlockedInterface> blocked_bindings_;
diff --git a/mojo/shell/tests/connect/connect_test_package.cc b/mojo/shell/tests/connect/connect_test_package.cc index e927335..7956425 100644 --- a/mojo/shell/tests/connect/connect_test_package.cc +++ b/mojo/shell/tests/connect/connect_test_package.cc
@@ -50,11 +50,11 @@ private: // mojo::ShellClient: - void Initialize(Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) override { - name_ = name; + void Initialize(Connector* connector, const Identity& identity, + uint32_t id) override { + name_ = identity.name(); + userid_ = identity.user_id(); id_ = id; - userid_ = user_id; bindings_.set_connection_error_handler( base::Bind(&ProvidedShellClient::OnConnectionError, base::Unretained(this))); @@ -66,8 +66,8 @@ uint32_t remote_id = connection->GetRemoteInstanceID(); test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); state->connection_local_name = connection->GetConnectionName(); - state->connection_remote_name = connection->GetRemoteApplicationName(); - state->connection_remote_userid = connection->GetRemoteUserID(); + state->connection_remote_name = connection->GetRemoteIdentity().name(); + state->connection_remote_userid = connection->GetRemoteIdentity().user_id(); state->connection_remote_id = remote_id; state->initialize_local_name = name_; state->initialize_id = id_; @@ -136,8 +136,8 @@ private: // mojo::ShellClient: - void Initialize(Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) override { + void Initialize(Connector* connector, const Identity& identity, + uint32_t id) override { bindings_.set_connection_error_handler( base::Bind(&ConnectTestShellClient::OnConnectionError, base::Unretained(this)));
diff --git a/mojo/shell/tests/connect/connect_unittest.cc b/mojo/shell/tests/connect/connect_unittest.cc index bf04e14..e28a635 100644 --- a/mojo/shell/tests/connect/connect_unittest.cc +++ b/mojo/shell/tests/connect/connect_unittest.cc
@@ -49,6 +49,14 @@ ~ConnectTest() override {} protected: + scoped_ptr<Connection> ConnectTo(Connector::ConnectParams* params) { + scoped_ptr<Connection> connection = connector()->Connect(params); + base::RunLoop loop; + connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); + loop.Run(); + return connection; + } + void set_ping_callback(const base::Closure& callback) { ping_callback_ = callback; } @@ -119,7 +127,47 @@ EXPECT_EQ("APP", title); EXPECT_FALSE(connection->IsPending()); EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); - EXPECT_EQ(connection->GetRemoteApplicationName(), kTestAppName); + EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppName); +} + +TEST_F(ConnectTest, Instances) { + Connector::ConnectParams params_a( + Identity(kTestAppName, mojom::kInheritUserID, "A")); + scoped_ptr<Connection> connection_a1 = ConnectTo(¶ms_a); + scoped_ptr<Connection> connection_a2 = ConnectTo(¶ms_a); + std::string instance_a1, instance_a2; + test::mojom::StandaloneAppPtr standalone_app_a1; + { + connection_a1->GetInterface(&standalone_app_a1); + base::RunLoop loop; + standalone_app_a1->GetInstance( + base::Bind(&ReceiveTitle, &instance_a1, &loop)); + loop.Run(); + } + test::mojom::StandaloneAppPtr standalone_app_a2; + { + connection_a2->GetInterface(&standalone_app_a2); + base::RunLoop loop; + standalone_app_a2->GetInstance( + base::Bind(&ReceiveTitle, &instance_a2, &loop)); + loop.Run(); + } + EXPECT_EQ(instance_a1, instance_a2); + + Connector::ConnectParams params_b( + Identity(kTestAppName, mojom::kInheritUserID, "B")); + scoped_ptr<Connection> connection_b = ConnectTo(¶ms_b); + std::string instance_b; + test::mojom::StandaloneAppPtr standalone_app_b; + { + connection_b->GetInterface(&standalone_app_b); + base::RunLoop loop; + standalone_app_b->GetInstance( + base::Bind(&ReceiveTitle, &instance_b, &loop)); + loop.Run(); + } + + EXPECT_NE(instance_a1, instance_b); } // BlockedInterface should not be exposed to this application because it is not @@ -148,7 +196,7 @@ EXPECT_EQ("A", a_name); EXPECT_FALSE(connection->IsPending()); EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); - EXPECT_EQ(connection->GetRemoteApplicationName(), kTestAppAName); + EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppAName); } // Ask the target application to attempt to connect to a third application @@ -222,7 +270,7 @@ run_loop.Run(); CompareConnectionState( kTestAppName, test_name(), test_userid(), test_instance_id(), - kTestAppName, connection->GetRemoteUserID(), remote_id); + kTestAppName, connection->GetRemoteIdentity().user_id(), remote_id); } } @@ -252,7 +300,7 @@ run_loop.Run(); CompareConnectionState( kTestAppAName, test_name(), test_userid(), test_instance_id(), - kTestAppAName, connection->GetRemoteUserID(), remote_id); + kTestAppAName, connection->GetRemoteIdentity().user_id(), remote_id); } }
diff --git a/mojo/shell/tests/lifecycle/lifecycle_unittest.cc b/mojo/shell/tests/lifecycle/lifecycle_unittest.cc index 012dffc..e85d08b 100644 --- a/mojo/shell/tests/lifecycle/lifecycle_unittest.cc +++ b/mojo/shell/tests/lifecycle/lifecycle_unittest.cc
@@ -13,6 +13,7 @@ #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/platform_channel_pair.h" #include "mojo/edk/embedder/scoped_platform_handle.h" +#include "mojo/shell/public/cpp/identity.h" #include "mojo/shell/public/cpp/shell_test.h" #include "mojo/shell/public/interfaces/shell.mojom.h" #include "mojo/shell/runner/common/switches.h" @@ -40,12 +41,10 @@ struct Instance { Instance() : id(shell::mojom::kInvalidInstanceID), pid(0) {} - Instance(const std::string& name, const std::string& qualifier, uint32_t id, - uint32_t pid) - : name(name), qualifier(qualifier), id(id), pid(pid) {} + Instance(const Identity& identity, uint32_t id, uint32_t pid) + : identity(identity), id(id), pid(pid) {} - std::string name; - std::string qualifier; + Identity identity; uint32_t id; uint32_t pid; }; @@ -74,17 +73,17 @@ // mojom::InstanceListener: void SetExistingInstances(Array<mojom::InstanceInfoPtr> instances) override { for (const auto& instance : instances) { - Instance i(instance->name, instance->qualifier, instance->id, + Instance i(instance->identity.To<Identity>(), instance->id, instance->pid); - initial_instances_[i.name] = i; - instances_[i.name] = i; + initial_instances_[i.identity.name()] = i; + instances_[i.identity.name()] = i; } loop_->Quit(); } void InstanceCreated(mojom::InstanceInfoPtr instance) override { - instances_[instance->name] = - Instance(instance->name, instance->qualifier, instance->id, - instance->pid); + instances_[instance->identity->name] = + Instance(instance->identity.To<Identity>(), instance->id, + instance->pid); } void InstanceDestroyed(uint32_t id) override { for (auto it = instances_.begin(); it != instances_.end(); ++it) { @@ -217,9 +216,12 @@ factory.Bind(mojo::InterfacePtrInfo<mojo::shell::mojom::ShellClientFactory>( std::move(pipe), 0u)); base::RunLoop loop; - shell->CreateInstance(std::move(factory), kTestExeName, - mojom::kInheritUserID, std::move(filter), - std::move(request), + mojo::shell::mojom::IdentityPtr target(mojo::shell::mojom::Identity::New()); + target->name = kTestExeName; + target->user_id = mojom::kInheritUserID; + target->instance = ""; + shell->CreateInstance(std::move(factory), std::move(target), + std::move(filter), std::move(request), base::Bind(&LifecycleTest::OnConnectionCompleted, base::Unretained(this), &loop)); loop.Run();
diff --git a/mojo/shell/tests/loader_unittest.cc b/mojo/shell/tests/loader_unittest.cc index 45156be..56ffd6fb 100644 --- a/mojo/shell/tests/loader_unittest.cc +++ b/mojo/shell/tests/loader_unittest.cc
@@ -123,7 +123,7 @@ // mojo::ShellClient implementation. bool AcceptConnection(Connection* connection) override { connection->AddInterface<TestService>(this); - last_requestor_name_ = connection->GetRemoteApplicationName(); + last_requestor_name_ = connection->GetRemoteIdentity().name(); return true; } @@ -353,14 +353,14 @@ bool AcceptConnection(Connection* connection) override { if (!requestor_name_.empty() && - requestor_name_ != connection->GetRemoteApplicationName()) { + requestor_name_ != connection->GetRemoteIdentity().name()) { context_->set_tester_called_quit(); context_->QuitSoon(); base::MessageLoop::current()->QuitWhenIdle(); return false; } // If we're coming from A, then add B, otherwise A. - if (connection->GetRemoteApplicationName() == kTestAURLString) + if (connection->GetRemoteIdentity().name() == kTestAURLString) connection->AddInterface<TestB>(this); else connection->AddInterface<TestA>(this); @@ -433,7 +433,7 @@ mojom::InterfaceProviderPtr remote_interfaces; scoped_ptr<ConnectParams> params(new ConnectParams); params->set_source(CreateShellIdentity()); - params->set_target(Identity(name)); + params->set_target(Identity(name, mojom::kRootUserID)); params->set_remote_interfaces(GetProxy(&remote_interfaces)); params->set_connect_callback( base::Bind(&OnConnect, base::Unretained(&loop))); @@ -523,7 +523,7 @@ bool called = false; scoped_ptr<ConnectParams> params(new ConnectParams); params->set_source(CreateShellIdentity()); - params->set_target(Identity("test:test", "", mojom::kRootUserID)); + params->set_target(Identity("test:test", mojom::kRootUserID)); shell_->SetInstanceQuitCallback( base::Bind(&QuitClosure, params->target(), &called)); shell_->Connect(std::move(params));
diff --git a/mojo/shell/tests/shell/driver.cc b/mojo/shell/tests/shell/driver.cc index 62c57bfc..68254f8 100644 --- a/mojo/shell/tests/shell/driver.cc +++ b/mojo/shell/tests/shell/driver.cc
@@ -44,8 +44,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) override { + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override { base::FilePath target_path; CHECK(base::PathService::Get(base::DIR_EXE, &target_path)); #if defined(OS_WIN) @@ -98,9 +98,12 @@ mojo::shell::mojom::ShellPtr shell; connector->ConnectToInterface("mojo:shell", &shell); - shell->CreateInstance(std::move(factory), "exe:shell_unittest_target", - mojo::shell::mojom::kInheritUserID, std::move(filter), - std::move(request), + mojo::shell::mojom::IdentityPtr target(mojo::shell::mojom::Identity::New()); + target->name = "exe:shell_unittest_target"; + target->user_id = mojo::shell::mojom::kInheritUserID; + target->instance = ""; + shell->CreateInstance(std::move(factory), std::move(target), + std::move(filter), std::move(request), base::Bind(&Driver::OnConnectionCompleted, base::Unretained(this)));
diff --git a/mojo/shell/tests/shell/shell_unittest.cc b/mojo/shell/tests/shell/shell_unittest.cc index db752bba..4a0debf 100644 --- a/mojo/shell/tests/shell/shell_unittest.cc +++ b/mojo/shell/tests/shell/shell_unittest.cc
@@ -127,11 +127,11 @@ void SetExistingInstances(Array<mojom::InstanceInfoPtr> instances) override { for (size_t i = 0; i < instances.size(); ++i) { initial_instances_.push_back(InstanceInfo(instances[i]->id, - instances[i]->name)); + instances[i]->identity->name)); } } void InstanceCreated(mojom::InstanceInfoPtr instance) override { - instances_.push_back(InstanceInfo(instance->id, instance->name)); + instances_.push_back(InstanceInfo(instance->id, instance->identity->name)); } void InstanceDestroyed(uint32_t id) override { for (auto it = instances_.begin(); it != instances_.end(); ++it) {
diff --git a/mojo/shell/tests/shell/target.cc b/mojo/shell/tests/shell/target.cc index 3f75dc9..e05a9dc 100644 --- a/mojo/shell/tests/shell/target.cc +++ b/mojo/shell/tests/shell/target.cc
@@ -23,8 +23,8 @@ private: // mojo::ShellClient: - void Initialize(mojo::Connector* connector, const std::string& name, - const std::string& user_id, uint32_t id) override { + void Initialize(mojo::Connector* connector, const mojo::Identity& identity, + uint32_t id) override { CreateInstanceTestPtr service; connector->ConnectToInterface("mojo:shell_unittest", &service); service->SetTargetID(id);
diff --git a/net/socket/ssl_server_socket.h b/net/socket/ssl_server_socket.h index bfbe7de..479bbc7 100644 --- a/net/socket/ssl_server_socket.h +++ b/net/socket/ssl_server_socket.h
@@ -31,6 +31,20 @@ virtual int Handshake(const CompletionCallback& callback) = 0; }; +class SSLServerContext { + public: + virtual ~SSLServerContext(){}; + + // Creates an SSL server socket over an already-connected transport socket. + // The caller must ensure the returned socket does not outlive the server + // context. + // + // The caller starts the SSL server handshake by calling Handshake on the + // returned socket. + virtual scoped_ptr<SSLServerSocket> CreateSSLServerSocket( + scoped_ptr<StreamSocket> socket) = 0; +}; + // Configures the underlying SSL library for the use of SSL server sockets. // // Due to the requirements of the underlying libraries, this should be called @@ -41,18 +55,14 @@ // omitted. NET_EXPORT void EnableSSLServerSockets(); -// Creates an SSL server socket over an already-connected transport socket. -// The caller must provide the server certificate and private key to use. +// Creates an SSL server socket context where all sockets spawned using this +// context will share the same session cache. // -// The returned SSLServerSocket takes ownership of |socket|. Stubbed versions -// of CreateSSLServerSocket will delete |socket| and return NULL. +// The caller must provide the server certificate and private key to use. // It takes a reference to |certificate|. // The |key| and |ssl_config| parameters are copied. // -// The caller starts the SSL server handshake by calling Handshake on the -// returned socket. -NET_EXPORT scoped_ptr<SSLServerSocket> CreateSSLServerSocket( - scoped_ptr<StreamSocket> socket, +NET_EXPORT scoped_ptr<SSLServerContext> CreateSSLServerContext( X509Certificate* certificate, const crypto::RSAPrivateKey& key, const SSLServerConfig& ssl_config);
diff --git a/net/socket/ssl_server_socket_nss.cc b/net/socket/ssl_server_socket_nss.cc index 6258c87c..9d29a46 100644 --- a/net/socket/ssl_server_socket_nss.cc +++ b/net/socket/ssl_server_socket_nss.cc
@@ -75,27 +75,140 @@ static base::LazyInstance<NSSSSLServerInitSingleton>::Leaky g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; -} // namespace +class SSLServerSocketNSS : public SSLServerSocket { + public: + // See comments on CreateSSLServerSocket for details of how these + // parameters are used. + SSLServerSocketNSS(scoped_ptr<StreamSocket> socket, + X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config); + ~SSLServerSocketNSS() override; -void EnableSSLServerSockets() { - g_nss_ssl_server_init_singleton.Get(); -} + // SSLServerSocket interface. + int Handshake(const CompletionCallback& callback) override; -scoped_ptr<SSLServerSocket> CreateSSLServerSocket( - scoped_ptr<StreamSocket> socket, - X509Certificate* certificate, - const crypto::RSAPrivateKey& key, - const SSLServerConfig& ssl_server_config) { - DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" - << " called yet!"; + // SSLSocket interface. + int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, + const base::StringPiece& context, + unsigned char* out, + unsigned int outlen) override; + int GetTLSUniqueChannelBinding(std::string* out) override; - return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( - std::move(socket), certificate, key, ssl_server_config)); -} + // Socket interface (via StreamSocket). + int Read(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) override; + int Write(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) override; + int SetReceiveBufferSize(int32_t size) override; + int SetSendBufferSize(int32_t size) override; + + // StreamSocket implementation. + int Connect(const CompletionCallback& callback) override; + void Disconnect() override; + bool IsConnected() const override; + bool IsConnectedAndIdle() const override; + int GetPeerAddress(IPEndPoint* address) const override; + int GetLocalAddress(IPEndPoint* address) const override; + const BoundNetLog& NetLog() const override; + void SetSubresourceSpeculation() override; + void SetOmniboxSpeculation() override; + bool WasEverUsed() const override; + bool UsingTCPFastOpen() const override; + bool WasNpnNegotiated() const override; + NextProto GetNegotiatedProtocol() const override; + bool GetSSLInfo(SSLInfo* ssl_info) override; + void GetConnectionAttempts(ConnectionAttempts* out) const override; + void ClearConnectionAttempts() override {} + void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} + int64_t GetTotalReceivedBytes() const override; + + private: + enum State { + STATE_NONE, + STATE_HANDSHAKE, + }; + + int InitializeSSLOptions(); + + void OnSendComplete(int result); + void OnRecvComplete(int result); + void OnHandshakeIOComplete(int result); + + int BufferSend(); + void BufferSendComplete(int result); + int BufferRecv(); + void BufferRecvComplete(int result); + bool DoTransportIO(); + int DoPayloadRead(); + int DoPayloadWrite(); + + int DoHandshakeLoop(int last_io_result); + int DoReadLoop(int result); + int DoWriteLoop(int result); + int DoHandshake(); + void DoHandshakeCallback(int result); + void DoReadCallback(int result); + void DoWriteCallback(int result); + + static SECStatus OwnAuthCertHandler(void* arg, + PRFileDesc* socket, + PRBool checksig, + PRBool is_server); + static void HandshakeCallback(PRFileDesc* socket, void* arg); + + int Init(); + + // Members used to send and receive buffer. + bool transport_send_busy_; + bool transport_recv_busy_; + + scoped_refptr<IOBuffer> recv_buffer_; + + BoundNetLog net_log_; + + CompletionCallback user_handshake_callback_; + CompletionCallback user_read_callback_; + CompletionCallback user_write_callback_; + + // Used by Read function. + scoped_refptr<IOBuffer> user_read_buf_; + int user_read_buf_len_; + + // Used by Write function. + scoped_refptr<IOBuffer> user_write_buf_; + int user_write_buf_len_; + + // The NSS SSL state machine + PRFileDesc* nss_fd_; + + // Buffers for the network end of the SSL state machine + memio_Private* nss_bufs_; + + // StreamSocket for sending and receiving data. + scoped_ptr<StreamSocket> transport_socket_; + + // Options for the SSL socket. + SSLServerConfig ssl_server_config_; + + // Certificate for the server. + scoped_refptr<X509Certificate> cert_; + + // Private key used by the server. + scoped_ptr<crypto::RSAPrivateKey> key_; + + State next_handshake_state_; + bool completed_handshake_; + + DISALLOW_COPY_AND_ASSIGN(SSLServerSocketNSS); +}; SSLServerSocketNSS::SSLServerSocketNSS( scoped_ptr<StreamSocket> transport_socket, - scoped_refptr<X509Certificate> cert, + X509Certificate* cert, const crypto::RSAPrivateKey& key, const SSLServerConfig& ssl_server_config) : transport_send_busy_(false), @@ -193,7 +306,8 @@ return ERR_NOT_IMPLEMENTED; } -int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, +int SSLServerSocketNSS::Read(IOBuffer* buf, + int buf_len, const CompletionCallback& callback) { DCHECK(user_read_callback_.is_null()); DCHECK(user_handshake_callback_.is_null()); @@ -217,7 +331,8 @@ return rv; } -int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, +int SSLServerSocketNSS::Write(IOBuffer* buf, + int buf_len, const CompletionCallback& callback) { DCHECK(user_write_callback_.is_null()); DCHECK(!user_write_buf_); @@ -582,8 +697,7 @@ memcpy(send_buffer->data(), buf1, len1); memcpy(send_buffer->data() + len1, buf2, len2); rv = transport_socket_->Write( - send_buffer.get(), - len, + send_buffer.get(), len, base::Bind(&SSLServerSocketNSS::BufferSendComplete, base::Unretained(this))); if (rv == ERR_IO_PENDING) { @@ -614,8 +728,7 @@ } else { recv_buffer_ = new IOBuffer(nb); rv = transport_socket_->Read( - recv_buffer_.get(), - nb, + recv_buffer_.get(), nb, base::Bind(&SSLServerSocketNSS::BufferRecvComplete, base::Unretained(this))); if (rv == ERR_IO_PENDING) { @@ -838,8 +951,7 @@ // static // NSS calls this when handshake is completed. // After the SSL handshake is finished we need to verify the certificate. -void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, - void* arg) { +void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, void* arg) { // TODO(hclam): Implement. } @@ -854,4 +966,39 @@ return OK; } +} // namespace + +scoped_ptr<SSLServerContext> CreateSSLServerContext( + X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config) { + return scoped_ptr<SSLServerContext>( + new SSLServerContextNSS(certificate, key, ssl_server_config)); +} + +SSLServerContextNSS::SSLServerContextNSS( + X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config) + : ssl_server_config_(ssl_server_config), + cert_(certificate), + key_(key.Copy()) { + CHECK(key_); +} + +SSLServerContextNSS::~SSLServerContextNSS() {} + +scoped_ptr<SSLServerSocket> SSLServerContextNSS::CreateSSLServerSocket( + scoped_ptr<StreamSocket> socket) { + DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" + << " called yet!"; + + return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( + std::move(socket), cert_.get(), *key_, ssl_server_config_)); +} + +void EnableSSLServerSockets() { + g_nss_ssl_server_init_singleton.Get(); +} + } // namespace net
diff --git a/net/socket/ssl_server_socket_nss.h b/net/socket/ssl_server_socket_nss.h index 788e452..497d461 100644 --- a/net/socket/ssl_server_socket_nss.h +++ b/net/socket/ssl_server_socket_nss.h
@@ -22,122 +22,17 @@ namespace net { -class SSLServerSocketNSS : public SSLServerSocket { +class SSLServerContextNSS : public SSLServerContext { public: - // See comments on CreateSSLServerSocket for details of how these - // parameters are used. - SSLServerSocketNSS(scoped_ptr<StreamSocket> socket, - scoped_refptr<X509Certificate> certificate, - const crypto::RSAPrivateKey& key, - const SSLServerConfig& ssl_server_config); - ~SSLServerSocketNSS() override; + SSLServerContextNSS(X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config); + ~SSLServerContextNSS() override; - // SSLServerSocket interface. - int Handshake(const CompletionCallback& callback) override; - - // SSLSocket interface. - int ExportKeyingMaterial(const base::StringPiece& label, - bool has_context, - const base::StringPiece& context, - unsigned char* out, - unsigned int outlen) override; - int GetTLSUniqueChannelBinding(std::string* out) override; - - // Socket interface (via StreamSocket). - int Read(IOBuffer* buf, - int buf_len, - const CompletionCallback& callback) override; - int Write(IOBuffer* buf, - int buf_len, - const CompletionCallback& callback) override; - int SetReceiveBufferSize(int32_t size) override; - int SetSendBufferSize(int32_t size) override; - - // StreamSocket implementation. - int Connect(const CompletionCallback& callback) override; - void Disconnect() override; - bool IsConnected() const override; - bool IsConnectedAndIdle() const override; - int GetPeerAddress(IPEndPoint* address) const override; - int GetLocalAddress(IPEndPoint* address) const override; - const BoundNetLog& NetLog() const override; - void SetSubresourceSpeculation() override; - void SetOmniboxSpeculation() override; - bool WasEverUsed() const override; - bool UsingTCPFastOpen() const override; - bool WasNpnNegotiated() const override; - NextProto GetNegotiatedProtocol() const override; - bool GetSSLInfo(SSLInfo* ssl_info) override; - void GetConnectionAttempts(ConnectionAttempts* out) const override; - void ClearConnectionAttempts() override {} - void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} - int64_t GetTotalReceivedBytes() const override; + scoped_ptr<SSLServerSocket> CreateSSLServerSocket( + scoped_ptr<StreamSocket> socket) override; private: - enum State { - STATE_NONE, - STATE_HANDSHAKE, - }; - - int InitializeSSLOptions(); - - void OnSendComplete(int result); - void OnRecvComplete(int result); - void OnHandshakeIOComplete(int result); - - int BufferSend(); - void BufferSendComplete(int result); - int BufferRecv(); - void BufferRecvComplete(int result); - bool DoTransportIO(); - int DoPayloadRead(); - int DoPayloadWrite(); - - int DoHandshakeLoop(int last_io_result); - int DoReadLoop(int result); - int DoWriteLoop(int result); - int DoHandshake(); - void DoHandshakeCallback(int result); - void DoReadCallback(int result); - void DoWriteCallback(int result); - - static SECStatus OwnAuthCertHandler(void* arg, - PRFileDesc* socket, - PRBool checksig, - PRBool is_server); - static void HandshakeCallback(PRFileDesc* socket, void* arg); - - int Init(); - - // Members used to send and receive buffer. - bool transport_send_busy_; - bool transport_recv_busy_; - - scoped_refptr<IOBuffer> recv_buffer_; - - BoundNetLog net_log_; - - CompletionCallback user_handshake_callback_; - CompletionCallback user_read_callback_; - CompletionCallback user_write_callback_; - - // Used by Read function. - scoped_refptr<IOBuffer> user_read_buf_; - int user_read_buf_len_; - - // Used by Write function. - scoped_refptr<IOBuffer> user_write_buf_; - int user_write_buf_len_; - - // The NSS SSL state machine - PRFileDesc* nss_fd_; - - // Buffers for the network end of the SSL state machine - memio_Private* nss_bufs_; - - // StreamSocket for sending and receiving data. - scoped_ptr<StreamSocket> transport_socket_; - // Options for the SSL socket. SSLServerConfig ssl_server_config_; @@ -146,11 +41,6 @@ // Private key used by the server. scoped_ptr<crypto::RSAPrivateKey> key_; - - State next_handshake_state_; - bool completed_handshake_; - - DISALLOW_COPY_AND_ASSIGN(SSLServerSocketNSS); }; } // namespace net
diff --git a/net/socket/ssl_server_socket_openssl.cc b/net/socket/ssl_server_socket_openssl.cc index adde711..75a76da 100644 --- a/net/socket/ssl_server_socket_openssl.cc +++ b/net/socket/ssl_server_socket_openssl.cc
@@ -19,7 +19,6 @@ #include "net/cert/client_cert_verifier.h" #include "net/cert/x509_util_openssl.h" #include "net/ssl/openssl_ssl_util.h" -#include "net/ssl/scoped_openssl_types.h" #include "net/ssl/ssl_connection_status_flags.h" #include "net/ssl/ssl_info.h" @@ -52,43 +51,142 @@ return X509Certificate::CreateFromDERCertChain(der_chain); } -} // namespace +class SSLServerSocketOpenSSL : public SSLServerSocket { + public: + // See comments on CreateSSLServerSocket for details of how these + // parameters are used. + SSLServerSocketOpenSSL(scoped_ptr<StreamSocket> socket, SSL* ssl); + ~SSLServerSocketOpenSSL() override; -void EnableSSLServerSockets() { - // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit(). -} + // SSLServerSocket interface. + int Handshake(const CompletionCallback& callback) override; -scoped_ptr<SSLServerSocket> CreateSSLServerSocket( - scoped_ptr<StreamSocket> socket, - X509Certificate* certificate, - const crypto::RSAPrivateKey& key, - const SSLServerConfig& ssl_server_config) { - crypto::EnsureOpenSSLInit(); - return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL( - std::move(socket), certificate, key, ssl_server_config)); -} + // SSLSocket interface. + int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, + const base::StringPiece& context, + unsigned char* out, + unsigned int outlen) override; + int GetTLSUniqueChannelBinding(std::string* out) override; + + // Socket interface (via StreamSocket). + int Read(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) override; + int Write(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) override; + int SetReceiveBufferSize(int32_t size) override; + int SetSendBufferSize(int32_t size) override; + + // StreamSocket implementation. + int Connect(const CompletionCallback& callback) override; + void Disconnect() override; + bool IsConnected() const override; + bool IsConnectedAndIdle() const override; + int GetPeerAddress(IPEndPoint* address) const override; + int GetLocalAddress(IPEndPoint* address) const override; + const BoundNetLog& NetLog() const override; + void SetSubresourceSpeculation() override; + void SetOmniboxSpeculation() override; + bool WasEverUsed() const override; + bool UsingTCPFastOpen() const override; + bool WasNpnNegotiated() const override; + NextProto GetNegotiatedProtocol() const override; + bool GetSSLInfo(SSLInfo* ssl_info) override; + void GetConnectionAttempts(ConnectionAttempts* out) const override; + void ClearConnectionAttempts() override {} + void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} + int64_t GetTotalReceivedBytes() const override; + static int CertVerifyCallback(X509_STORE_CTX* store_ctx, void* arg); + + private: + enum State { + STATE_NONE, + STATE_HANDSHAKE, + }; + + void OnSendComplete(int result); + void OnRecvComplete(int result); + void OnHandshakeIOComplete(int result); + + int BufferSend(); + void BufferSendComplete(int result); + void TransportWriteComplete(int result); + int BufferRecv(); + void BufferRecvComplete(int result); + int TransportReadComplete(int result); + bool DoTransportIO(); + int DoPayloadRead(); + int DoPayloadWrite(); + + int DoHandshakeLoop(int last_io_result); + int DoReadLoop(int result); + int DoWriteLoop(int result); + int DoHandshake(); + void DoHandshakeCallback(int result); + void DoReadCallback(int result); + void DoWriteCallback(int result); + + int Init(); + void ExtractClientCert(); + + // Members used to send and receive buffer. + bool transport_send_busy_; + bool transport_recv_busy_; + bool transport_recv_eof_; + + scoped_refptr<DrainableIOBuffer> send_buffer_; + scoped_refptr<IOBuffer> recv_buffer_; + + BoundNetLog net_log_; + + CompletionCallback user_handshake_callback_; + CompletionCallback user_read_callback_; + CompletionCallback user_write_callback_; + + // Used by Read function. + scoped_refptr<IOBuffer> user_read_buf_; + int user_read_buf_len_; + + // Used by Write function. + scoped_refptr<IOBuffer> user_write_buf_; + int user_write_buf_len_; + + // Used by TransportWriteComplete() and TransportReadComplete() to signify an + // error writing to the transport socket. A value of OK indicates no error. + int transport_write_error_; + + // OpenSSL stuff + SSL* ssl_; + BIO* transport_bio_; + + // StreamSocket for sending and receiving data. + scoped_ptr<StreamSocket> transport_socket_; + + // Certificate for the client. + scoped_refptr<X509Certificate> client_cert_; + + State next_handshake_state_; + bool completed_handshake_; + + DISALLOW_COPY_AND_ASSIGN(SSLServerSocketOpenSSL); +}; SSLServerSocketOpenSSL::SSLServerSocketOpenSSL( scoped_ptr<StreamSocket> transport_socket, - scoped_refptr<X509Certificate> certificate, - const crypto::RSAPrivateKey& key, - const SSLServerConfig& ssl_server_config) + SSL* ssl) : transport_send_busy_(false), transport_recv_busy_(false), transport_recv_eof_(false), user_read_buf_len_(0), user_write_buf_len_(0), transport_write_error_(OK), - ssl_(NULL), + ssl_(ssl), transport_bio_(NULL), transport_socket_(std::move(transport_socket)), - ssl_server_config_(ssl_server_config), - cert_(certificate), - key_(key.Copy()), next_handshake_state_(STATE_NONE), - completed_handshake_(false) { - CHECK(key_); -} + completed_handshake_(false) {} SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() { if (ssl_) { @@ -160,7 +258,8 @@ return ERR_NOT_IMPLEMENTED; } -int SSLServerSocketOpenSSL::Read(IOBuffer* buf, int buf_len, +int SSLServerSocketOpenSSL::Read(IOBuffer* buf, + int buf_len, const CompletionCallback& callback) { DCHECK(user_read_callback_.is_null()); DCHECK(user_handshake_callback_.is_null()); @@ -184,7 +283,8 @@ return rv; } -int SSLServerSocketOpenSSL::Write(IOBuffer* buf, int buf_len, +int SSLServerSocketOpenSSL::Write(IOBuffer* buf, + int buf_len, const CompletionCallback& callback) { DCHECK(user_write_callback_.is_null()); DCHECK(!user_write_buf_); @@ -377,8 +477,7 @@ } int rv = transport_socket_->Write( - send_buffer_.get(), - send_buffer_->BytesRemaining(), + send_buffer_.get(), send_buffer_->BytesRemaining(), base::Bind(&SSLServerSocketOpenSSL::BufferSendComplete, base::Unretained(this))); if (rv == ERR_IO_PENDING) { @@ -450,8 +549,7 @@ recv_buffer_ = new IOBuffer(max_write); int rv = transport_socket_->Read( - recv_buffer_.get(), - max_write, + recv_buffer_.get(), max_write, base::Bind(&SSLServerSocketOpenSSL::BufferRecvComplete, base::Unretained(this))); if (rv == ERR_IO_PENDING) { @@ -681,27 +779,10 @@ } int SSLServerSocketOpenSSL::Init() { - DCHECK(!ssl_); DCHECK(!transport_bio_); crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedSSL_CTX ssl_ctx(SSL_CTX_new(TLS_method())); - int verify_mode = 0; - switch (ssl_server_config_.client_cert_type) { - case SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT: - verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - // Fall-through - case SSLServerConfig::ClientCertType::OPTIONAL_CLIENT_CERT: - verify_mode |= SSL_VERIFY_PEER; - SSL_CTX_set_verify(ssl_ctx.get(), verify_mode, nullptr); - SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), CertVerifyCallback, - ssl_server_config_.client_cert_verifier); - break; - case SSLServerConfig::ClientCertType::NO_CLIENT_CERT: - break; - } - ssl_ = SSL_new(ssl_ctx.get()); if (!ssl_) return ERR_UNEXPECTED; @@ -714,100 +795,6 @@ SSL_set_bio(ssl_, ssl_bio, ssl_bio); - // Set certificate and private key. - DCHECK(cert_->os_cert_handle()); -#if defined(USE_OPENSSL_CERTS) - if (SSL_use_certificate(ssl_, cert_->os_cert_handle()) != 1) { - LOG(ERROR) << "Cannot set certificate."; - return ERR_UNEXPECTED; - } -#else - // Convert OSCertHandle to X509 structure. - std::string der_string; - if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string)) - return ERR_UNEXPECTED; - - const unsigned char* der_string_array = - reinterpret_cast<const unsigned char*>(der_string.data()); - - ScopedX509 x509(d2i_X509(NULL, &der_string_array, der_string.length())); - if (!x509) - return ERR_UNEXPECTED; - - // On success, SSL_use_certificate acquires a reference to |x509|. - if (SSL_use_certificate(ssl_, x509.get()) != 1) { - LOG(ERROR) << "Cannot set certificate."; - return ERR_UNEXPECTED; - } -#endif // USE_OPENSSL_CERTS - - DCHECK(key_->key()); - if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) { - LOG(ERROR) << "Cannot set private key."; - return ERR_UNEXPECTED; - } - - DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_min); - DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_max); - SSL_set_min_version(ssl_, ssl_server_config_.version_min); - SSL_set_max_version(ssl_, ssl_server_config_.version_max); - - // OpenSSL defaults some options to on, others to off. To avoid ambiguity, - // set everything we care about to an absolute value. - SslSetClearMask options; - options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); - - SSL_set_options(ssl_, options.set_mask); - SSL_clear_options(ssl_, options.clear_mask); - - // Same as above, this time for the SSL mode. - SslSetClearMask mode; - - mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); - - SSL_set_mode(ssl_, mode.set_mask); - SSL_clear_mode(ssl_, mode.clear_mask); - - // See SSLServerConfig::disabled_cipher_suites for description of the suites - // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 - // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 - // as the handshake hash. - std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); - - if (ssl_server_config_.require_ecdhe) - command.append(":!kRSA:!kDHE"); - - // Remove any disabled ciphers. - for (uint16_t id : ssl_server_config_.disabled_cipher_suites) { - const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id); - if (cipher) { - command.append(":!"); - command.append(SSL_CIPHER_get_name(cipher)); - } - } - - int rv = SSL_set_cipher_list(ssl_, command.c_str()); - // If this fails (rv = 0) it means there are no ciphers enabled on this SSL. - // This will almost certainly result in the socket failing to complete the - // handshake at which point the appropriate error is bubbled up to the client. - LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command - << "') returned " << rv; - - if (ssl_server_config_.client_cert_type != - SSLServerConfig::ClientCertType::NO_CLIENT_CERT && - !ssl_server_config_.cert_authorities_.empty()) { - ScopedX509NameStack stack(sk_X509_NAME_new_null()); - for (const auto& authority : ssl_server_config_.cert_authorities_) { - const uint8_t* name = reinterpret_cast<const uint8_t*>(authority.c_str()); - const uint8_t* name_start = name; - ScopedX509_NAME subj(d2i_X509_NAME(nullptr, &name, authority.length())); - if (!subj || name != name_start + authority.length()) - return ERR_UNEXPECTED; - sk_X509_NAME_push(stack.get(), subj.release()); - } - SSL_set_client_CA_list(ssl_, stack.release()); - } - return OK; } @@ -841,4 +828,141 @@ return 1; } +} // namespace + +scoped_ptr<SSLServerContext> CreateSSLServerContext( + X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config) { + return scoped_ptr<SSLServerContext>( + new SSLServerContextOpenSSL(certificate, key, ssl_server_config)); +} + +SSLServerContextOpenSSL::SSLServerContextOpenSSL( + X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config) + : ssl_server_config_(ssl_server_config), + cert_(certificate), + key_(key.Copy()) { + CHECK(key_); + crypto::EnsureOpenSSLInit(); + ssl_ctx_.reset(SSL_CTX_new(TLS_method())); + SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_SERVER); + uint8_t session_ctx_id = 0; + SSL_CTX_set_session_id_context(ssl_ctx_.get(), &session_ctx_id, + sizeof(session_ctx_id)); + + int verify_mode = 0; + switch (ssl_server_config_.client_cert_type) { + case SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT: + verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + // Fall-through + case SSLServerConfig::ClientCertType::OPTIONAL_CLIENT_CERT: + verify_mode |= SSL_VERIFY_PEER; + SSL_CTX_set_verify(ssl_ctx_.get(), verify_mode, nullptr); + SSL_CTX_set_cert_verify_callback( + ssl_ctx_.get(), SSLServerSocketOpenSSL::CertVerifyCallback, + ssl_server_config_.client_cert_verifier); + break; + case SSLServerConfig::ClientCertType::NO_CLIENT_CERT: + break; + } + + // Set certificate and private key. + DCHECK(cert_->os_cert_handle()); +#if defined(USE_OPENSSL_CERTS) + CHECK(SSL_CTX_use_certificate(ssl_ctx_.get(), cert_->os_cert_handle())); +#else + // Convert OSCertHandle to X509 structure. + std::string der_string; + CHECK(X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string)); + + const unsigned char* der_string_array = + reinterpret_cast<const unsigned char*>(der_string.data()); + + ScopedX509 x509(d2i_X509(NULL, &der_string_array, der_string.length())); + CHECK(x509); + + // On success, SSL_CTX_use_certificate acquires a reference to |x509|. + CHECK(SSL_CTX_use_certificate(ssl_ctx_.get(), x509.get())); +#endif // USE_OPENSSL_CERTS + + DCHECK(key_->key()); + CHECK(SSL_CTX_use_PrivateKey(ssl_ctx_.get(), key_->key())); + + DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_min); + DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_max); + SSL_CTX_set_min_version(ssl_ctx_.get(), ssl_server_config_.version_min); + SSL_CTX_set_max_version(ssl_ctx_.get(), ssl_server_config_.version_max); + + // OpenSSL defaults some options to on, others to off. To avoid ambiguity, + // set everything we care about to an absolute value. + SslSetClearMask options; + options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); + + SSL_CTX_set_options(ssl_ctx_.get(), options.set_mask); + SSL_CTX_clear_options(ssl_ctx_.get(), options.clear_mask); + + // Same as above, this time for the SSL mode. + SslSetClearMask mode; + + mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); + + SSL_CTX_set_mode(ssl_ctx_.get(), mode.set_mask); + SSL_CTX_clear_mode(ssl_ctx_.get(), mode.clear_mask); + + // See SSLServerConfig::disabled_cipher_suites for description of the suites + // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 + // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 + // as the handshake hash. + std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); + + if (ssl_server_config_.require_ecdhe) + command.append(":!kRSA:!kDHE"); + + // Remove any disabled ciphers. + for (uint16_t id : ssl_server_config_.disabled_cipher_suites) { + const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id); + if (cipher) { + command.append(":!"); + command.append(SSL_CIPHER_get_name(cipher)); + } + } + + int rv = SSL_CTX_set_cipher_list(ssl_ctx_.get(), command.c_str()); + // If this fails (rv = 0) it means there are no ciphers enabled on this SSL. + // This will almost certainly result in the socket failing to complete the + // handshake at which point the appropriate error is bubbled up to the client. + LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command + << "') returned " << rv; + + if (ssl_server_config_.client_cert_type != + SSLServerConfig::ClientCertType::NO_CLIENT_CERT && + !ssl_server_config_.cert_authorities_.empty()) { + ScopedX509NameStack stack(sk_X509_NAME_new_null()); + for (const auto& authority : ssl_server_config_.cert_authorities_) { + const uint8_t* name = reinterpret_cast<const uint8_t*>(authority.c_str()); + const uint8_t* name_start = name; + ScopedX509_NAME subj(d2i_X509_NAME(nullptr, &name, authority.length())); + CHECK(subj && name == name_start + authority.length()); + sk_X509_NAME_push(stack.get(), subj.release()); + } + SSL_CTX_set_client_CA_list(ssl_ctx_.get(), stack.release()); + } +} + +SSLServerContextOpenSSL::~SSLServerContextOpenSSL() {} + +scoped_ptr<SSLServerSocket> SSLServerContextOpenSSL::CreateSSLServerSocket( + scoped_ptr<StreamSocket> socket) { + SSL* ssl = SSL_new(ssl_ctx_.get()); + return scoped_ptr<SSLServerSocket>( + new SSLServerSocketOpenSSL(std::move(socket), ssl)); +} + +void EnableSSLServerSockets() { + // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit(). +} + } // namespace net
diff --git a/net/socket/ssl_server_socket_openssl.h b/net/socket/ssl_server_socket_openssl.h index 52f8241b..3a9d9c85 100644 --- a/net/socket/ssl_server_socket_openssl.h +++ b/net/socket/ssl_server_socket_openssl.h
@@ -13,6 +13,7 @@ #include "net/base/io_buffer.h" #include "net/log/net_log.h" #include "net/socket/ssl_server_socket.h" +#include "net/ssl/scoped_openssl_types.h" #include "net/ssl/ssl_server_config.h" // Avoid including misc OpenSSL headers, i.e.: @@ -26,120 +27,18 @@ class SSLInfo; -class SSLServerSocketOpenSSL : public SSLServerSocket { +class SSLServerContextOpenSSL : public SSLServerContext { public: - // See comments on CreateSSLServerSocket for details of how these - // parameters are used. - SSLServerSocketOpenSSL(scoped_ptr<StreamSocket> socket, - scoped_refptr<X509Certificate> certificate, - const crypto::RSAPrivateKey& key, - const SSLServerConfig& ssl_server_config); - ~SSLServerSocketOpenSSL() override; + SSLServerContextOpenSSL(X509Certificate* certificate, + const crypto::RSAPrivateKey& key, + const SSLServerConfig& ssl_server_config); + ~SSLServerContextOpenSSL() override; - // SSLServerSocket interface. - int Handshake(const CompletionCallback& callback) override; - - // SSLSocket interface. - int ExportKeyingMaterial(const base::StringPiece& label, - bool has_context, - const base::StringPiece& context, - unsigned char* out, - unsigned int outlen) override; - int GetTLSUniqueChannelBinding(std::string* out) override; - - // Socket interface (via StreamSocket). - int Read(IOBuffer* buf, - int buf_len, - const CompletionCallback& callback) override; - int Write(IOBuffer* buf, - int buf_len, - const CompletionCallback& callback) override; - int SetReceiveBufferSize(int32_t size) override; - int SetSendBufferSize(int32_t size) override; - - // StreamSocket implementation. - int Connect(const CompletionCallback& callback) override; - void Disconnect() override; - bool IsConnected() const override; - bool IsConnectedAndIdle() const override; - int GetPeerAddress(IPEndPoint* address) const override; - int GetLocalAddress(IPEndPoint* address) const override; - const BoundNetLog& NetLog() const override; - void SetSubresourceSpeculation() override; - void SetOmniboxSpeculation() override; - bool WasEverUsed() const override; - bool UsingTCPFastOpen() const override; - bool WasNpnNegotiated() const override; - NextProto GetNegotiatedProtocol() const override; - bool GetSSLInfo(SSLInfo* ssl_info) override; - void GetConnectionAttempts(ConnectionAttempts* out) const override; - void ClearConnectionAttempts() override {} - void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} - int64_t GetTotalReceivedBytes() const override; + scoped_ptr<SSLServerSocket> CreateSSLServerSocket( + scoped_ptr<StreamSocket> socket) override; private: - enum State { - STATE_NONE, - STATE_HANDSHAKE, - }; - - void OnSendComplete(int result); - void OnRecvComplete(int result); - void OnHandshakeIOComplete(int result); - - int BufferSend(); - void BufferSendComplete(int result); - void TransportWriteComplete(int result); - int BufferRecv(); - void BufferRecvComplete(int result); - int TransportReadComplete(int result); - bool DoTransportIO(); - int DoPayloadRead(); - int DoPayloadWrite(); - - int DoHandshakeLoop(int last_io_result); - int DoReadLoop(int result); - int DoWriteLoop(int result); - int DoHandshake(); - void DoHandshakeCallback(int result); - void DoReadCallback(int result); - void DoWriteCallback(int result); - - int Init(); - static int CertVerifyCallback(X509_STORE_CTX* store_ctx, void* arg); - - // Members used to send and receive buffer. - bool transport_send_busy_; - bool transport_recv_busy_; - bool transport_recv_eof_; - - scoped_refptr<DrainableIOBuffer> send_buffer_; - scoped_refptr<IOBuffer> recv_buffer_; - - BoundNetLog net_log_; - - CompletionCallback user_handshake_callback_; - CompletionCallback user_read_callback_; - CompletionCallback user_write_callback_; - - // Used by Read function. - scoped_refptr<IOBuffer> user_read_buf_; - int user_read_buf_len_; - - // Used by Write function. - scoped_refptr<IOBuffer> user_write_buf_; - int user_write_buf_len_; - - // Used by TransportWriteComplete() and TransportReadComplete() to signify an - // error writing to the transport socket. A value of OK indicates no error. - int transport_write_error_; - - // OpenSSL stuff - SSL* ssl_; - BIO* transport_bio_; - - // StreamSocket for sending and receiving data. - scoped_ptr<StreamSocket> transport_socket_; + ScopedSSL_CTX ssl_ctx_; // Options for the SSL socket. SSLServerConfig ssl_server_config_; @@ -149,14 +48,6 @@ // Private key used by the server. scoped_ptr<crypto::RSAPrivateKey> key_; - - // Certificate for the client. - scoped_refptr<X509Certificate> client_cert_; - - State next_handshake_state_; - bool completed_handshake_; - - DISALLOW_COPY_AND_ASSIGN(SSLServerSocketOpenSSL); }; } // namespace net
diff --git a/net/socket/ssl_server_socket_unittest.cc b/net/socket/ssl_server_socket_unittest.cc index 9a2dd9c..52ae7d8 100644 --- a/net/socket/ssl_server_socket_unittest.cc +++ b/net/socket/ssl_server_socket_unittest.cc
@@ -204,9 +204,7 @@ public: FakeSocket(FakeDataChannel* incoming_channel, FakeDataChannel* outgoing_channel) - : incoming_(incoming_channel), - outgoing_(outgoing_channel) { - } + : incoming_(incoming_channel), outgoing_(outgoing_channel) {} ~FakeSocket() override {} @@ -340,20 +338,10 @@ transport_security_state_(new TransportSecurityState) { cert_verifier_->set_default_result(ERR_CERT_AUTHORITY_INVALID); client_cert_verifier_->set_default_result(ERR_CERT_AUTHORITY_INVALID); - } - protected: - void Initialize() { - scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle); - client_connection->SetSocket( - scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_))); - scoped_ptr<StreamSocket> server_socket( - new FakeSocket(&channel_2_, &channel_1_)); - - scoped_refptr<X509Certificate> server_cert( - ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der")); - scoped_ptr<crypto::RSAPrivateKey> server_private_key( - ReadTestKey("unittest.key.bin")); + server_cert_ = + ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); + server_private_key_ = ReadTestKey("unittest.key.bin"); client_ssl_config_.false_start_enabled = false; client_ssl_config_.channel_id_enabled = false; @@ -362,22 +350,44 @@ SSLConfig::CertAndStatus cert_and_status; cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID; std::string server_cert_der; - CHECK(X509Certificate::GetDEREncoded(server_cert->os_cert_handle(), + CHECK(X509Certificate::GetDEREncoded(server_cert_->os_cert_handle(), &server_cert_der)); cert_and_status.der_cert = server_cert_der; client_ssl_config_.allowed_bad_certs.push_back(cert_and_status); + } + + protected: + void CreateContext() { + client_socket_.reset(); + server_socket_.reset(); + channel_1_.reset(); + channel_2_.reset(); + server_context_.reset(); + server_context_ = CreateSSLServerContext( + server_cert_.get(), *server_private_key_, server_ssl_config_); + } + + void CreateSockets() { + client_socket_.reset(); + server_socket_.reset(); + channel_1_.reset(new FakeDataChannel()); + channel_2_.reset(new FakeDataChannel()); + scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle); + client_connection->SetSocket(scoped_ptr<StreamSocket>( + new FakeSocket(channel_1_.get(), channel_2_.get()))); + scoped_ptr<StreamSocket> server_socket( + new FakeSocket(channel_2_.get(), channel_1_.get())); HostPortPair host_and_pair("unittest", 0); SSLClientSocketContext context; context.cert_verifier = cert_verifier_.get(); context.transport_security_state = transport_security_state_.get(); - socket_factory_->ClearSSLSessionCache(); client_socket_ = socket_factory_->CreateSSLClientSocket( std::move(client_connection), host_and_pair, client_ssl_config_, context); + server_socket_ = - CreateSSLServerSocket(std::move(server_socket), server_cert.get(), - *server_private_key, server_ssl_config_); + server_context_->CreateSSLServerSocket(std::move(server_socket)); } #if defined(USE_OPENSSL) @@ -434,8 +444,8 @@ } #endif - FakeDataChannel channel_1_; - FakeDataChannel channel_2_; + scoped_ptr<FakeDataChannel> channel_1_; + scoped_ptr<FakeDataChannel> channel_2_; SSLConfig client_ssl_config_; SSLServerConfig server_ssl_config_; scoped_ptr<SSLClientSocket> client_socket_; @@ -444,20 +454,25 @@ scoped_ptr<MockCertVerifier> cert_verifier_; scoped_ptr<MockClientCertVerifier> client_cert_verifier_; scoped_ptr<TransportSecurityState> transport_security_state_; + scoped_ptr<SSLServerContext> server_context_; + scoped_ptr<crypto::RSAPrivateKey> server_private_key_; + scoped_refptr<X509Certificate> server_cert_; }; // This test only executes creation of client and server sockets. This is to // test that creation of sockets doesn't crash and have minimal code to run // under valgrind in order to help debugging memory problems. TEST_F(SSLServerSocketTest, Initialize) { - Initialize(); + CreateContext(); + CreateSockets(); } // This test executes Connect() on SSLClientSocket and Handshake() on // SSLServerSocket to make sure handshaking between the two sockets is // completed successfully. TEST_F(SSLServerSocketTest, Handshake) { - Initialize(); + CreateContext(); + CreateSockets(); TestCompletionCallback handshake_callback; int server_ret = server_socket_->Handshake(handshake_callback.callback()); @@ -489,9 +504,107 @@ EXPECT_TRUE(is_aead); } -// NSS ports don't support client certificates. +// NSS ports don't support client certificates and have a global session cache. #if defined(USE_OPENSSL) +// This test makes sure the session cache is working. +TEST_F(SSLServerSocketTest, HandshakeCached) { + CreateContext(); + CreateSockets(); + + TestCompletionCallback handshake_callback; + int server_ret = server_socket_->Handshake(handshake_callback.callback()); + + TestCompletionCallback connect_callback; + int client_ret = client_socket_->Connect(connect_callback.callback()); + + client_ret = connect_callback.GetResult(client_ret); + server_ret = handshake_callback.GetResult(server_ret); + + ASSERT_EQ(OK, client_ret); + ASSERT_EQ(OK, server_ret); + + // Make sure the cert status is expected. + SSLInfo ssl_info; + ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info)); + EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + SSLInfo ssl_server_info; + ASSERT_TRUE(server_socket_->GetSSLInfo(&ssl_server_info)); + EXPECT_EQ(ssl_server_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + + // Make sure the second connection is cached. + CreateSockets(); + TestCompletionCallback handshake_callback2; + int server_ret2 = server_socket_->Handshake(handshake_callback2.callback()); + + TestCompletionCallback connect_callback2; + int client_ret2 = client_socket_->Connect(connect_callback2.callback()); + + client_ret2 = connect_callback2.GetResult(client_ret2); + server_ret2 = handshake_callback2.GetResult(server_ret2); + + ASSERT_EQ(OK, client_ret2); + ASSERT_EQ(OK, server_ret2); + + // Make sure the cert status is expected. + SSLInfo ssl_info2; + ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info2)); + EXPECT_EQ(ssl_info2.handshake_type, SSLInfo::HANDSHAKE_RESUME); + SSLInfo ssl_server_info2; + ASSERT_TRUE(server_socket_->GetSSLInfo(&ssl_server_info2)); + EXPECT_EQ(ssl_server_info2.handshake_type, SSLInfo::HANDSHAKE_RESUME); +} + +// This test makes sure the session cache separates out by server context. +TEST_F(SSLServerSocketTest, HandshakeCachedContextSwitch) { + CreateContext(); + CreateSockets(); + + TestCompletionCallback handshake_callback; + int server_ret = server_socket_->Handshake(handshake_callback.callback()); + + TestCompletionCallback connect_callback; + int client_ret = client_socket_->Connect(connect_callback.callback()); + + client_ret = connect_callback.GetResult(client_ret); + server_ret = handshake_callback.GetResult(server_ret); + + ASSERT_EQ(OK, client_ret); + ASSERT_EQ(OK, server_ret); + + // Make sure the cert status is expected. + SSLInfo ssl_info; + ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info)); + EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + SSLInfo ssl_server_info; + ASSERT_TRUE(server_socket_->GetSSLInfo(&ssl_server_info)); + EXPECT_EQ(ssl_server_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + + // Make sure the second connection is NOT cached when using a new context. + CreateContext(); + CreateSockets(); + + TestCompletionCallback handshake_callback2; + int server_ret2 = server_socket_->Handshake(handshake_callback2.callback()); + + TestCompletionCallback connect_callback2; + int client_ret2 = client_socket_->Connect(connect_callback2.callback()); + + client_ret2 = connect_callback2.GetResult(client_ret2); + server_ret2 = handshake_callback2.GetResult(server_ret2); + + ASSERT_EQ(OK, client_ret2); + ASSERT_EQ(OK, server_ret2); + + // Make sure the cert status is expected. + SSLInfo ssl_info2; + ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info2)); + EXPECT_EQ(ssl_info2.handshake_type, SSLInfo::HANDSHAKE_FULL); + SSLInfo ssl_server_info2; + ASSERT_TRUE(server_socket_->GetSSLInfo(&ssl_server_info2)); + EXPECT_EQ(ssl_server_info2.handshake_type, SSLInfo::HANDSHAKE_FULL); +} + // This test executes Connect() on SSLClientSocket and Handshake() on // SSLServerSocket to make sure handshaking between the two sockets is // completed successfully, using client certificate. @@ -500,7 +613,8 @@ ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); ConfigureClientCertsForClient(kClientCertFileName, kClientPrivateKeyFileName); ConfigureClientCertsForServer(); - Initialize(); + CreateContext(); + CreateSockets(); TestCompletionCallback handshake_callback; int server_ret = server_socket_->Handshake(handshake_callback.callback()); @@ -523,9 +637,71 @@ EXPECT_TRUE(client_cert->Equals(ssl_info.cert.get())); } +// This test executes Connect() on SSLClientSocket and Handshake() twice on +// SSLServerSocket to make sure handshaking between the two sockets is +// completed successfully, using client certificate. The second connection is +// expected to succeed through the session cache. +TEST_F(SSLServerSocketTest, HandshakeWithClientCertCached) { + scoped_refptr<X509Certificate> client_cert = + ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); + ConfigureClientCertsForClient(kClientCertFileName, kClientPrivateKeyFileName); + ConfigureClientCertsForServer(); + CreateContext(); + CreateSockets(); + + TestCompletionCallback handshake_callback; + int server_ret = server_socket_->Handshake(handshake_callback.callback()); + + TestCompletionCallback connect_callback; + int client_ret = client_socket_->Connect(connect_callback.callback()); + + client_ret = connect_callback.GetResult(client_ret); + server_ret = handshake_callback.GetResult(server_ret); + + ASSERT_EQ(OK, client_ret); + ASSERT_EQ(OK, server_ret); + + // Make sure the cert status is expected. + SSLInfo ssl_info; + ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info)); + EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + SSLInfo ssl_server_info; + ASSERT_TRUE(server_socket_->GetSSLInfo(&ssl_server_info)); + ASSERT_TRUE(ssl_server_info.cert.get()); + EXPECT_TRUE(client_cert->Equals(ssl_server_info.cert.get())); + EXPECT_EQ(ssl_server_info.handshake_type, SSLInfo::HANDSHAKE_FULL); + server_socket_->Disconnect(); + client_socket_->Disconnect(); + + // Create the connection again. + CreateSockets(); + TestCompletionCallback handshake_callback2; + int server_ret2 = server_socket_->Handshake(handshake_callback2.callback()); + + TestCompletionCallback connect_callback2; + int client_ret2 = client_socket_->Connect(connect_callback2.callback()); + + client_ret2 = connect_callback2.GetResult(client_ret2); + server_ret2 = handshake_callback2.GetResult(server_ret2); + + ASSERT_EQ(OK, client_ret2); + ASSERT_EQ(OK, server_ret2); + + // Make sure the cert status is expected. + SSLInfo ssl_info2; + ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info2)); + EXPECT_EQ(ssl_info2.handshake_type, SSLInfo::HANDSHAKE_RESUME); + SSLInfo ssl_server_info2; + ASSERT_TRUE(server_socket_->GetSSLInfo(&ssl_server_info2)); + ASSERT_TRUE(ssl_server_info2.cert.get()); + EXPECT_TRUE(client_cert->Equals(ssl_server_info2.cert.get())); + EXPECT_EQ(ssl_server_info2.handshake_type, SSLInfo::HANDSHAKE_RESUME); +} + TEST_F(SSLServerSocketTest, HandshakeWithClientCertRequiredNotSupplied) { ConfigureClientCertsForServer(); - Initialize(); + CreateContext(); + CreateSockets(); // Use the default setting for the client socket, which is to not send // a client certificate. This will cause the client to receive an // ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, and allow for inspecting the @@ -554,13 +730,68 @@ EXPECT_EQ(ERR_FAILED, handshake_callback.GetResult(server_ret)); } +TEST_F(SSLServerSocketTest, HandshakeWithClientCertRequiredNotSuppliedCached) { + ConfigureClientCertsForServer(); + CreateContext(); + CreateSockets(); + // Use the default setting for the client socket, which is to not send + // a client certificate. This will cause the client to receive an + // ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, and allow for inspecting the + // requested cert_authorities from the CertificateRequest sent by the + // server. + + TestCompletionCallback handshake_callback; + int server_ret = server_socket_->Handshake(handshake_callback.callback()); + + TestCompletionCallback connect_callback; + EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, + connect_callback.GetResult( + client_socket_->Connect(connect_callback.callback()))); + + scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo(); + client_socket_->GetSSLCertRequestInfo(request_info.get()); + + // Check that the authority name that arrived in the CertificateRequest + // handshake message is as expected. + scoped_refptr<X509Certificate> client_cert = + ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); + EXPECT_TRUE(client_cert->IsIssuedByEncoded(request_info->cert_authorities)); + + client_socket_->Disconnect(); + + EXPECT_EQ(ERR_FAILED, handshake_callback.GetResult(server_ret)); + server_socket_->Disconnect(); + + // Below, check that the cache didn't store the result of a failed handshake. + CreateSockets(); + TestCompletionCallback handshake_callback2; + int server_ret2 = server_socket_->Handshake(handshake_callback2.callback()); + + TestCompletionCallback connect_callback2; + EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, + connect_callback2.GetResult( + client_socket_->Connect(connect_callback2.callback()))); + + scoped_refptr<SSLCertRequestInfo> request_info2 = new SSLCertRequestInfo(); + client_socket_->GetSSLCertRequestInfo(request_info2.get()); + + // Check that the authority name that arrived in the CertificateRequest + // handshake message is as expected. + EXPECT_TRUE(client_cert->IsIssuedByEncoded(request_info2->cert_authorities)); + + client_socket_->Disconnect(); + + EXPECT_EQ(ERR_FAILED, handshake_callback2.GetResult(server_ret2)); +} + TEST_F(SSLServerSocketTest, HandshakeWithWrongClientCertSupplied) { scoped_refptr<X509Certificate> client_cert = ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); ConfigureClientCertsForClient(kWrongClientCertFileName, kWrongClientPrivateKeyFileName); ConfigureClientCertsForServer(); - Initialize(); + CreateContext(); + CreateSockets(); TestCompletionCallback handshake_callback; int server_ret = server_socket_->Handshake(handshake_callback.callback()); @@ -573,10 +804,48 @@ EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, handshake_callback.GetResult(server_ret)); } + +TEST_F(SSLServerSocketTest, HandshakeWithWrongClientCertSuppliedCached) { + scoped_refptr<X509Certificate> client_cert = + ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName); + ConfigureClientCertsForClient(kWrongClientCertFileName, + kWrongClientPrivateKeyFileName); + ConfigureClientCertsForServer(); + CreateContext(); + CreateSockets(); + + TestCompletionCallback handshake_callback; + int server_ret = server_socket_->Handshake(handshake_callback.callback()); + + TestCompletionCallback connect_callback; + int client_ret = client_socket_->Connect(connect_callback.callback()); + + EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, + connect_callback.GetResult(client_ret)); + EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, + handshake_callback.GetResult(server_ret)); + + client_socket_->Disconnect(); + server_socket_->Disconnect(); + + // Below, check that the cache didn't store the result of a failed handshake. + CreateSockets(); + TestCompletionCallback handshake_callback2; + int server_ret2 = server_socket_->Handshake(handshake_callback2.callback()); + + TestCompletionCallback connect_callback2; + int client_ret2 = client_socket_->Connect(connect_callback2.callback()); + + EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, + connect_callback2.GetResult(client_ret2)); + EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, + handshake_callback2.GetResult(server_ret2)); +} #endif // defined(USE_OPENSSL) TEST_F(SSLServerSocketTest, DataTransfer) { - Initialize(); + CreateContext(); + CreateSockets(); // Establish connection. TestCompletionCallback connect_callback; @@ -601,8 +870,8 @@ // Write then read. TestCompletionCallback write_callback; TestCompletionCallback read_callback; - server_ret = server_socket_->Write( - write_buf.get(), write_buf->size(), write_callback.callback()); + server_ret = server_socket_->Write(write_buf.get(), write_buf->size(), + write_callback.callback()); EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING); client_ret = client_socket_->Read( read_buf.get(), read_buf->BytesRemaining(), read_callback.callback()); @@ -631,8 +900,8 @@ server_ret = server_socket_->Read( read_buf.get(), read_buf->BytesRemaining(), read_callback.callback()); EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING); - client_ret = client_socket_->Write( - write_buf.get(), write_buf->size(), write_callback.callback()); + client_ret = client_socket_->Write(write_buf.get(), write_buf->size(), + write_callback.callback()); EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING); server_ret = read_callback.GetResult(server_ret); @@ -659,8 +928,8 @@ // the client's Write() call should not cause an infinite loop. // NOTE: this is a test for SSLClientSocket rather than SSLServerSocket. TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) { - Initialize(); - + CreateContext(); + CreateSockets(); // Establish connection. TestCompletionCallback connect_callback; @@ -683,8 +952,8 @@ // socket won't return ERR_IO_PENDING. This ensures that the client // will call Read() on the transport socket again. TestCompletionCallback write_callback; - server_ret = server_socket_->Write( - write_buf.get(), write_buf->size(), write_callback.callback()); + server_ret = server_socket_->Write(write_buf.get(), write_buf->size(), + write_callback.callback()); EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING); server_ret = write_callback.GetResult(server_ret); @@ -693,8 +962,8 @@ server_socket_->Disconnect(); // The client writes some data. This should not cause an infinite loop. - client_ret = client_socket_->Write( - write_buf.get(), write_buf->size(), write_callback.callback()); + client_ret = client_socket_->Write(write_buf.get(), write_buf->size(), + write_callback.callback()); EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING); client_ret = write_callback.GetResult(client_ret); @@ -710,7 +979,8 @@ // after connecting them, and verifies that the results match. // This test will fail if False Start is enabled (see crbug.com/90208). TEST_F(SSLServerSocketTest, ExportKeyingMaterial) { - Initialize(); + CreateContext(); + CreateSockets(); TestCompletionCallback connect_callback; int client_ret = client_socket_->Connect(connect_callback.callback()); @@ -731,23 +1001,20 @@ const char kKeyingLabel[] = "EXPERIMENTAL-server-socket-test"; const char kKeyingContext[] = ""; unsigned char server_out[kKeyingMaterialSize]; - int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel, - false, kKeyingContext, - server_out, sizeof(server_out)); + int rv = server_socket_->ExportKeyingMaterial( + kKeyingLabel, false, kKeyingContext, server_out, sizeof(server_out)); ASSERT_EQ(OK, rv); unsigned char client_out[kKeyingMaterialSize]; - rv = client_socket_->ExportKeyingMaterial(kKeyingLabel, - false, kKeyingContext, + rv = client_socket_->ExportKeyingMaterial(kKeyingLabel, false, kKeyingContext, client_out, sizeof(client_out)); ASSERT_EQ(OK, rv); EXPECT_EQ(0, memcmp(server_out, client_out, sizeof(server_out))); const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad"; unsigned char client_bad[kKeyingMaterialSize]; - rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, - false, kKeyingContext, - client_bad, sizeof(client_bad)); + rv = client_socket_->ExportKeyingMaterial( + kKeyingLabelBad, false, kKeyingContext, client_bad, sizeof(client_bad)); ASSERT_EQ(rv, OK); EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out))); } @@ -773,7 +1040,8 @@ // Require ECDHE on the server. server_ssl_config_.require_ecdhe = true; - Initialize(); + CreateContext(); + CreateSockets(); TestCompletionCallback connect_callback; int client_ret = client_socket_->Connect(connect_callback.callback());
diff --git a/net/ssl/ssl_server_config.h b/net/ssl/ssl_server_config.h index 7a1861b..21ec128 100644 --- a/net/ssl/ssl_server_config.h +++ b/net/ssl/ssl_server_config.h
@@ -73,7 +73,7 @@ // Provides the ClientCertVerifier that is to be used to verify // client certificates during the handshake. // The |client_cert_verifier| continues to be owned by the caller, - // and must outlive any sockets using this SSLServerConfig. + // and must outlive any sockets spawned from this SSLServerContext. // This field is meaningful only if client certificates are requested. // If a verifier is not provided then all certificates are accepted. ClientCertVerifier* client_cert_verifier;
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 8f10e1ca..eb09b96 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -111,9 +111,32 @@ port_ = local_endpoint_.port(); listen_socket_->DetachFromThread(); + + if (is_using_ssl_) + InitializeSSLServerContext(); return true; } +void EmbeddedTestServer::InitializeSSLServerContext() { + base::FilePath certs_dir(GetTestCertsDirectory()); + std::string cert_name = GetCertificateName(); + + base::FilePath key_path = certs_dir.AppendASCII(cert_name); + std::string key_string; + CHECK(base::ReadFileToString(key_path, &key_string)); + std::vector<std::string> headers; + headers.push_back("PRIVATE KEY"); + PEMTokenizer pem_tokenizer(key_string, headers); + pem_tokenizer.GetNext(); + std::vector<uint8_t> key_vector; + key_vector.assign(pem_tokenizer.data().begin(), pem_tokenizer.data().end()); + + scoped_ptr<crypto::RSAPrivateKey> server_key( + crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); + context_ = + CreateSSLServerContext(GetCertificate().get(), *server_key, ssl_config_); +} + void EmbeddedTestServer::StartAcceptingConnections() { DCHECK(!io_thread_.get()); base::Thread::Options thread_options; @@ -276,24 +299,7 @@ scoped_ptr<StreamSocket> connection) { DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); - base::FilePath certs_dir(GetTestCertsDirectory()); - std::string cert_name = GetCertificateName(); - - base::FilePath key_path = certs_dir.AppendASCII(cert_name); - std::string key_string; - CHECK(base::ReadFileToString(key_path, &key_string)); - std::vector<std::string> headers; - headers.push_back("PRIVATE KEY"); - PEMTokenizer pem_tokenizer(key_string, headers); - pem_tokenizer.GetNext(); - std::vector<uint8_t> key_vector; - key_vector.assign(pem_tokenizer.data().begin(), pem_tokenizer.data().end()); - - scoped_ptr<crypto::RSAPrivateKey> server_key( - crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); - - return CreateSSLServerSocket(std::move(connection), GetCertificate().get(), - *server_key, ssl_config_); + return context_->CreateSSLServerSocket(std::move(connection)); } void EmbeddedTestServer::DoAcceptLoop() {
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h index f226286..00952f9 100644 --- a/net/test/embedded_test_server/embedded_test_server.h +++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -25,6 +25,7 @@ #include "net/base/host_port_pair.h" #include "net/base/ip_endpoint.h" #include "net/cert/x509_certificate.h" +#include "net/socket/ssl_server_socket.h" #include "net/socket/stream_socket.h" #include "net/socket/tcp_server_socket.h" #include "net/ssl/ssl_server_config.h" @@ -243,6 +244,10 @@ void HandleRequest(HttpConnection* connection, scoped_ptr<HttpRequest> request); + // Initializes the SSLServerContext so that SSLServerSocket connections may + // share the same cache + void InitializeSSLServerContext(); + HttpConnection* FindConnection(StreamSocket* socket); // Posts a task to the |io_thread_| and waits for a reply. @@ -272,6 +277,7 @@ net::SSLServerConfig ssl_config_; ServerCertificate cert_; + scoped_ptr<SSLServerContext> context_; base::WeakPtrFactory<EmbeddedTestServer> weak_factory_;
diff --git a/remoting/protocol/ssl_hmac_channel_authenticator.cc b/remoting/protocol/ssl_hmac_channel_authenticator.cc index 808bd1b..fb91655 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator.cc +++ b/remoting/protocol/ssl_hmac_channel_authenticator.cc
@@ -151,8 +151,10 @@ // Implements P2PStreamSocket interface on top of net::StreamSocket. class P2PStreamSocketAdapter : public P2PStreamSocket { public: - P2PStreamSocketAdapter(scoped_ptr<net::StreamSocket> socket) - : socket_(std::move(socket)) {} + P2PStreamSocketAdapter(scoped_ptr<net::StreamSocket> socket, + scoped_ptr<net::SSLServerContext> server_context) + : server_context_(std::move(server_context)), + socket_(std::move(socket)) {} ~P2PStreamSocketAdapter() override {} int Read(const scoped_refptr<net::IOBuffer>& buf, int buf_len, @@ -165,6 +167,9 @@ } private: + // The server_context_ will be a nullptr for client sockets. + // The server_context_ must outlive any sockets it spawns. + scoped_ptr<net::SSLServerContext> server_context_; scoped_ptr<net::StreamSocket> socket_; }; @@ -217,8 +222,8 @@ result = net::ERR_FAILED; #else scoped_refptr<net::X509Certificate> cert = - net::X509Certificate::CreateFromBytes( - local_cert_.data(), local_cert_.length()); + net::X509Certificate::CreateFromBytes(local_cert_.data(), + local_cert_.length()); if (!cert.get()) { LOG(ERROR) << "Failed to parse X509Certificate"; NotifyError(net::ERR_FAILED); @@ -228,9 +233,12 @@ net::SSLServerConfig ssl_config; ssl_config.require_ecdhe = true; - scoped_ptr<net::SSLServerSocket> server_socket = net::CreateSSLServerSocket( - make_scoped_ptr(new NetStreamSocketAdapter(std::move(socket))), + server_context_ = net::CreateSSLServerContext( cert.get(), *local_key_pair_->private_key(), ssl_config); + + scoped_ptr<net::SSLServerSocket> server_socket = + server_context_->CreateSSLServerSocket( + make_scoped_ptr(new NetStreamSocketAdapter(std::move(socket)))); net::SSLServerSocket* raw_server_socket = server_socket.get(); socket_ = std::move(server_socket); result = raw_server_socket->Handshake( @@ -430,8 +438,8 @@ *callback_called = true; base::ResetAndReturn(&done_callback_) - .Run(net::OK, - make_scoped_ptr(new P2PStreamSocketAdapter(std::move(socket_)))); + .Run(net::OK, make_scoped_ptr(new P2PStreamSocketAdapter( + std::move(socket_), std::move(server_context_)))); } }
diff --git a/remoting/protocol/ssl_hmac_channel_authenticator.h b/remoting/protocol/ssl_hmac_channel_authenticator.h index e1da9ca..313f4bb 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator.h +++ b/remoting/protocol/ssl_hmac_channel_authenticator.h
@@ -18,6 +18,7 @@ class CertVerifier; class DrainableIOBuffer; class GrowableIOBuffer; +class SSLServerContext; class SSLSocket; class TransportSecurityState; } // namespace net @@ -86,6 +87,7 @@ // Used in the SERVER mode only. std::string local_cert_; scoped_refptr<RsaKeyPair> local_key_pair_; + scoped_ptr<net::SSLServerContext> server_context_; // Used in the CLIENT mode only. std::string remote_cert_;
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations index fb6a1581..1ba76df 100644 --- a/third_party/WebKit/LayoutTests/LeakExpectations +++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -48,13 +48,10 @@ # Untriaged but known leaks which may be false positives. # ----------------------------------------------------------------- -crbug.com/364411 fast/frames/location-observe-callback-crash.html [ Leak ] - crbug.com/364417 editing/selection/selection-in-iframe-removed-crash.html [ Leak ] crbug.com/364417 editing/selection/user-select-js-property.html [ Leak ] crbug.com/364417 fast/events/touch/gesture/context-menu-on-long-tap.html [ Leak ] crbug.com/364417 fast/repaint/japanese-rl-selection-clear.html [ Leak ] -crbug.com/364417 virtual/spv2/fast/repaint/japanese-rl-selection-clear.html [ Leak ] crbug.com/364417 fast/text/international/hebrew-selection.html [ Leak ] crbug.com/455369 fast/html/marquee-destroyed-without-removed-from-crash.html [ Leak Pass ] @@ -94,8 +91,6 @@ crbug.com/564571 virtual/threaded/animations/svg-length-unittype-crash.html [ Leak ] crbug.com/571534 virtual/threaded/animations/svg-element-css-animation-crash.html [ Leak ] -crbug.com/588598 web-animations-api/player-cancel-event.html [ Leak ] - # ----------------------------------------------------------------- # Untriaged but known leaks of ActiveDOMObject (fast). # ----------------------------------------------------------------- @@ -117,7 +112,6 @@ # Untriaged but known leaks of ActiveDOMObject (http). # ----------------------------------------------------------------- crbug.com/506754 http/tests/cachestorage/window/cache-put.html [ Leak ] -crbug.com/506754 http/tests/inspector/filesystem/request-file-content.html [ Leak ] crbug.com/506754 http/tests/inspector/network/network-xhr-replay.html [ Leak ] crbug.com/506754 http/tests/inspector/service-workers/service-worker-agents.html [ Crash Leak ] crbug.com/506754 http/tests/security/cross-origin-indexeddb-allowed.html [ Leak ]
diff --git a/third_party/WebKit/LayoutTests/animations/additive-transform-animations-expected.html b/third_party/WebKit/LayoutTests/animations/additive-transform-animations-expected.html index 1b5d690..b64dd6b 100644 --- a/third_party/WebKit/LayoutTests/animations/additive-transform-animations-expected.html +++ b/third_party/WebKit/LayoutTests/animations/additive-transform-animations-expected.html
@@ -1,24 +1,13 @@ <!DOCTYPE html> -<html> -<head> - <style type="text/css"> - .box { - height: 100px; - width: 100px; - background-color: blue; - } - - #box { - transform: rotate(90deg) translate(100px, 0); - } - </style> -</head> -<body> +<style> +.box { + height: 100px; + width: 100px; + background-color: blue; +} +#box { + transform: rotate(90deg) translate(100px, 0); +} +</style> <div class="box" id="box"></div> -<div id="result"> -PASS - "webkitTransform" property for "box" element at 1s saw something close to: 0,1,-1,0,0,100 -</div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/animations/additive-transform-animations.html b/third_party/WebKit/LayoutTests/animations/additive-transform-animations.html index 00e326e..2c94473 100644 --- a/third_party/WebKit/LayoutTests/animations/additive-transform-animations.html +++ b/third_party/WebKit/LayoutTests/animations/additive-transform-animations.html
@@ -1,39 +1,22 @@ <!DOCTYPE html> +<style> +.box { + height: 100px; + width: 100px; + background-color: blue; +} -<html> -<head> - <style type="text/css"> - .box { - height: 100px; - width: 100px; - background-color: blue; - } - - #box { - -webkit-animation: anim 2s linear both; - } - - @-webkit-keyframes anim { - from { transform: rotate(0deg) translate(-100px, 0); } - to { transform: rotate(180deg) translate(300px, 0); } - } - </style> - <script src="resources/animation-test-helpers.js" type="text/javascript"></script> - <script type="text/javascript"> - const expectedValues = [ - // [time, element-id, property, expected-value, tolerance] - [1, "box", "webkitTransform", [0, 1, -1, 0, 0, 100], 0.002], - ]; - - const doPixelTest = true; - const disablePauseAnimationAPI = false; - runAnimationTest(expectedValues, null, null, disablePauseAnimationAPI, doPixelTest); - </script> -</head> -<body> +#box { + animation-name: anim; + animation-duration: 1s; + animation-delay: -0.5s; + animation-play-state: paused; + animation-timing-function: linear; +} +@-webkit-keyframes anim { + from { transform: rotate(0deg) translate(-100px, 0); } + to { transform: rotate(180deg) translate(300px, 0); } +} +</style> <div class="box" id="box"></div> -<div id="result"></div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/animations/change-keyframes-expected.txt b/third_party/WebKit/LayoutTests/animations/change-keyframes-expected.txt deleted file mode 100644 index d833812..0000000 --- a/third_party/WebKit/LayoutTests/animations/change-keyframes-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -Warning this test is running in real-time and may be flaky. -PASS - "left" property for "box" element at 0.5s saw something close to: 200 -PASS - "top" property for "box" element at 1s saw something close to: 100 -
diff --git a/third_party/WebKit/LayoutTests/animations/change-keyframes.html b/third_party/WebKit/LayoutTests/animations/change-keyframes.html index a7358b8..97fda5a4 100644 --- a/third_party/WebKit/LayoutTests/animations/change-keyframes.html +++ b/third_party/WebKit/LayoutTests/animations/change-keyframes.html
@@ -1,81 +1,60 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<style> + #box { + position: relative; + height: 100px; + width: 100px; + background-color: blue; + animation-name: anim; + animation-duration: 1s; + animation-delay: -0.5s; + animation-play-state: paused; + animation-timing-function: linear; + } -<html lang="en"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title>Test Changing Keyframes Using CSSOM</title> - <style type="text/css" media="screen"> - #box { - position: relative; - left: 0; - top: 0; - height: 100px; - width: 100px; - background-color: blue; - -webkit-animation-duration: 1s; - -webkit-animation-timing-function: linear; - -webkit-animation-name: anim; - } - @-webkit-keyframes anim { - from { left: 100px; } - 10% { left: 200px; } - 90% { left: 200px; } - to { left: 300px; } - } - </style> - <script src="resources/animation-test-helpers.js" type="text/javascript" charset="utf-8"></script> - <script type="text/javascript" charset="utf-8"> - - function findKeyframesRule(rule) - { - var ss = document.styleSheets; - for (var i = 0; i < ss.length; ++i) { - for (var j = 0; j < ss[i].cssRules.length; ++j) { - if (ss[i].cssRules[j].type == window.CSSRule.WEBKIT_KEYFRAMES_RULE && ss[i].cssRules[j].name == rule) - return ss[i].cssRules[j]; - } + @keyframes anim { + from { left: 100px; } + to { left: 200px; } + } +</style> +<div id="box"></div> +<script> + function findKeyframesRule(rule) { + var ss = document.styleSheets; + for (var i = 0; i < ss.length; ++i) { + for (var j = 0; j < ss[i].cssRules.length; ++j) { + if (ss[i].cssRules[j].type == CSSRule.KEYFRAMES_RULE && + ss[i].cssRules[j].name == rule) { + return ss[i].cssRules[j]; } - - return null; - } - - const expectedValues = [ - // [time, element-id, property, expected-value, tolerance] - [0.5, "box", "left", 200, 10], - [1, "box", "top", 100, 10], - ]; - - const callbacks = { - 0.6: function() { - document.getElementById('box').style.webkitAnimationName = "none"; - // a forced style-recalc aborts the previous animation - document.getElementById('box').offsetTop; - // change keyframes - var keyframes = findKeyframesRule("anim"); - keyframes.deleteRule("0%"); - keyframes.deleteRule("40%"); - keyframes.deleteRule("60%"); - keyframes.deleteRule("100%"); - keyframes.appendRule("0% { top: 50px; }"); - keyframes.appendRule("10% { top: 100px; }"); - keyframes.appendRule("90% { top: 100px; }"); - keyframes.appendRule("100% { top: 150px; }"); - document.getElementById('box').style.webkitAnimationName = "anim"; } } - // FIXME: Consider whether we can support this kind of test (staggered start) under the pause API - runAnimationTest(expectedValues, callbacks, null, 'do-not-use-pause-api'); - </script> -</head> -<body> -This test performs an animation of the left property and makes sure it is animating. Then it stops -the animation, changes the keyframes to an animation of the top property, restarts the animation -and makes sure top is animating. -<div id="box"> -</div> -<div id="result"> -</div> -</body> -</html> + return null; + } + + test(function() { + var box = document.getElementById('box'); + + // The left property should be animating initially. + assert_equals(getComputedStyle(box).left, '150px', 'left'); + + // A forced style-recalc aborts the previous animation. + box.style.animationName = "none"; + assert_equals(getComputedStyle(box).left, 'auto', 'left'); + + // Change keyframes. + var keyframes = findKeyframesRule("anim"); + keyframes.deleteRule("0%"); + keyframes.deleteRule("100%"); + keyframes.appendRule("0% { top: 50px; }"); + keyframes.appendRule("100% { top: 150px; }"); + box.style.webkitAnimationName = "anim"; + + // The left property should reset to auto and top should be animating. + assert_equals(getComputedStyle(box).left, 'auto', 'left'); + assert_equals(getComputedStyle(box).top, '100px', 'top'); + }, "Check that changes to keyframe rules take effect"); +</script>
diff --git a/third_party/WebKit/LayoutTests/css3/images/cross-fade-svg-size-expected.html b/third_party/WebKit/LayoutTests/css3/images/cross-fade-svg-size-expected.html new file mode 100644 index 0000000..17996c3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/images/cross-fade-svg-size-expected.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<title>Test SVG in -webkit-cross-fade image</title> +<p>There should be four green circles below. +<div> +<img width=100 src="data:image/svg+xml,<svg width='100' height='100' xmlns='http://www.w3.org/2000/svg'><circle cx='50' cy='50' r='25' fill='green'/></svg>"> +<img width=100 src="data:image/svg+xml,<svg width='100' height='100' xmlns='http://www.w3.org/2000/svg'><circle cx='50' cy='50' r='25' fill='green'/></svg>"> +<img width=100 src="data:image/svg+xml,<svg width='100' height='100' xmlns='http://www.w3.org/2000/svg'><circle cx='50' cy='50' r='25' fill='green'/></svg>"> +<img width=100 src="data:image/svg+xml,<svg width='100' height='100' xmlns='http://www.w3.org/2000/svg'><circle cx='50' cy='50' r='25' fill='green'/></svg>">
diff --git a/third_party/WebKit/LayoutTests/css3/images/cross-fade-svg-size.html b/third_party/WebKit/LayoutTests/css3/images/cross-fade-svg-size.html new file mode 100644 index 0000000..c1ea969 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/images/cross-fade-svg-size.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<title>Test SVG in -webkit-cross-fade image</title> +<style> +div { + display: inline-block; + width: 100px; + height: 100px; +} +#tst1 { + background-image: -webkit-cross-fade( + url("data:image/svg+xml,<svg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'><circle cx='5' cy='5' r='2.5' fill='green'/></svg>"), + url("data:image/svg+xml,<svg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'><circle cx='5' cy='5' r='2.5' fill='red'/></svg>"), + 0); +} +#tst2 { + background-image: -webkit-cross-fade( + url("data:image/svg+xml,<svg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'><circle cx='5' cy='5' r='2.5' fill='red'/></svg>"), + url("data:image/svg+xml,<svg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'><circle cx='5' cy='5' r='2.5' fill='green'/></svg>"), + 1.0); +} +#tst3 { + background-image: -webkit-cross-fade( + url("resources/green-10.png"), + url("data:image/svg+xml,<svg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'><circle cx='5' cy='5' r='2.5' fill='green'/></svg>"), + 1.0); +} +#tst4 { + background-image: -webkit-cross-fade( + url("data:image/svg+xml,<svg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'><circle cx='5' cy='5' r='2.5' fill='green'/></svg>"), + url("resources/green-10.png"), + 0.0); +} +</style> +<p>There should be four green circles below. +<div id=tst1></div> +<div id=tst2></div> +<div id=tst3></div> +<div id=tst4></div>
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-clip-per-layer-expected.txt b/third_party/WebKit/LayoutTests/fast/backgrounds/background-clip-per-layer-expected.txt new file mode 100644 index 0000000..afe7065 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-clip-per-layer-expected.txt
@@ -0,0 +1,11 @@ +Tests that background shorthand property parsing will deal correctly with clip values in multiple layers. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS e.style.backgroundOrigin is "content-box, border-box" +PASS e.style.backgroundClip is "padding-box, border-box" +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-clip-per-layer.html b/third_party/WebKit/LayoutTests/fast/backgrounds/background-clip-per-layer.html new file mode 100644 index 0000000..8f5284f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-clip-per-layer.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<script src="../../resources/js-test.js"></script> +<div id="test"> </div> +<script> +description("Tests that background shorthand property parsing will deal correctly with clip values in multiple layers."); + +var e = document.getElementById('test'); + +e.style.background = "url('a') content-box padding-box, url('b') border-box"; +shouldBeEqualToString("e.style.backgroundOrigin", 'content-box, border-box'); +shouldBeEqualToString("e.style.backgroundClip", 'padding-box, border-box'); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2-expected.txt b/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2-expected.txt index f666e88..bb5334e 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2-expected.txt
@@ -200,30 +200,30 @@ background-position inside the background shorthand PASS style.background is 'left 30% top 10% / 10em round fixed border-box border-box gray' PASS computedStyle.background is 'rgb(128, 128, 128) none round fixed left 30% top 10% / 160px border-box border-box' -PASS style.background is 'right 0% top 15px / 10em round fixed border-box border-box gray' -PASS computedStyle.background is 'rgb(128, 128, 128) none round fixed right 0% top 15px / 160px border-box border-box' -PASS style.background is 'left 10px top 50% / 10em round fixed border-box border-box gray' -PASS computedStyle.background is 'rgb(128, 128, 128) none round fixed left 10px top 50% / 160px border-box border-box' -PASS style.background is 'left 10px top 50% round fixed border-box border-box' -PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 10px top 50% / auto border-box border-box' -PASS style.background is 'left 50% top 20px round fixed border-box border-box' -PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 50% top 20px / auto border-box border-box' -PASS style.background is 'left 50% top 20px round fixed border-box border-box' -PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 50% top 20px / auto border-box border-box' -PASS style.background is '50% 0% round fixed border-box border-box' +PASS style.background is 'right top 15px / 10em round fixed border-box border-box gray' +PASS computedStyle.background is 'rgb(128, 128, 128) none round fixed 100% top 15px / 160px border-box border-box' +PASS style.background is 'left 10px center / 10em round fixed border-box border-box gray' +PASS computedStyle.background is 'rgb(128, 128, 128) none round fixed left 10px 50% / 160px border-box border-box' +PASS style.background is 'left 10px center round fixed border-box border-box' +PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 10px 50% / auto border-box border-box' +PASS style.background is 'center top 20px round fixed border-box border-box' +PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed 50% top 20px / auto border-box border-box' +PASS style.background is 'center top 20px round fixed border-box border-box' +PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed 50% top 20px / auto border-box border-box' +PASS style.background is 'center top round fixed border-box border-box' PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed 50% 0% / auto border-box border-box' PASS style.background is '50px 60px / 50px round fixed border-box border-box' PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed 50px 60px / 50px border-box border-box' -PASS style.background is '50px 50% / 50px round fixed border-box border-box' +PASS style.background is '50px center / 50px round fixed border-box border-box' PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed 50px 50% / 50px border-box border-box' -PASS style.background is 'left 0% top 60px / 50px round fixed border-box border-box' -PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 0% top 60px / 50px border-box border-box' +PASS style.background is 'left top 60px / 50px round fixed border-box border-box' +PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed 0% top 60px / 50px border-box border-box' PASS style.background is 'left -20px top 60px / 50px round fixed border-box border-box' PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left -20px top 60px / 50px border-box border-box' -PASS style.background is 'left 20px top 0% / 50px round fixed border-box border-box' -PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 20px top 0% / 50px border-box border-box' -PASS style.background is 'left 20px top 0% / 50px round fixed border-box border-box' -PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 20px top 0% / 50px border-box border-box' +PASS style.background is 'left 20px top / 50px round fixed border-box border-box' +PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 20px 0% / 50px border-box border-box' +PASS style.background is 'left 20px top / 50px round fixed border-box border-box' +PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 20px 0% / 50px border-box border-box' PASS style.background is 'left 20px top 40px / 50px round fixed border-box border-box' PASS computedStyle.background is 'rgba(0, 0, 0, 0) none round fixed left 20px top 40px / 50px border-box border-box' PASS style.background is 'left 20px top 40px round fixed border-box border-box'
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2.html b/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2.html index db23060..b3cd721 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2.html +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-position-parsing-2.html
@@ -412,27 +412,27 @@ shouldBe("computedStyle.background", "'rgb(128, 128, 128) none round fixed left 30% top 10% / 160px border-box border-box'"); style.background = "right top 15px / 10em gray round fixed border-box"; -shouldBe("style.background", "'right 0% top 15px / 10em round fixed border-box border-box gray'"); -shouldBe("computedStyle.background", "'rgb(128, 128, 128) none round fixed right 0% top 15px / 160px border-box border-box'"); +shouldBe("style.background", "'right top 15px / 10em round fixed border-box border-box gray'"); +shouldBe("computedStyle.background", "'rgb(128, 128, 128) none round fixed 100% top 15px / 160px border-box border-box'"); style.background = "left 10px center / 10em gray round fixed border-box"; -shouldBe("style.background", "'left 10px top 50% / 10em round fixed border-box border-box gray'"); -shouldBe("computedStyle.background", "'rgb(128, 128, 128) none round fixed left 10px top 50% / 160px border-box border-box'"); +shouldBe("style.background", "'left 10px center / 10em round fixed border-box border-box gray'"); +shouldBe("computedStyle.background", "'rgb(128, 128, 128) none round fixed left 10px 50% / 160px border-box border-box'"); style.background = "left 10px center round fixed border-box"; -shouldBe("style.background", "'left 10px top 50% round fixed border-box border-box'"); -shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 10px top 50% / auto border-box border-box'"); +shouldBe("style.background", "'left 10px center round fixed border-box border-box'"); +shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 10px 50% / auto border-box border-box'"); style.background = "center top 20px round fixed border-box"; -shouldBe("style.background", "'left 50% top 20px round fixed border-box border-box'"); -shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 50% top 20px / auto border-box border-box'"); +shouldBe("style.background", "'center top 20px round fixed border-box border-box'"); +shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed 50% top 20px / auto border-box border-box'"); style.background = "top 20px center round fixed border-box"; -shouldBe("style.background", "'left 50% top 20px round fixed border-box border-box'"); -shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 50% top 20px / auto border-box border-box'"); +shouldBe("style.background", "'center top 20px round fixed border-box border-box'"); +shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed 50% top 20px / auto border-box border-box'"); style.background = "top center round fixed border-box"; -shouldBe("style.background", "'50% 0% round fixed border-box border-box'"); +shouldBe("style.background", "'center top round fixed border-box border-box'"); shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed 50% 0% / auto border-box border-box'"); style.background = "50px 60px / 50px round fixed border-box"; @@ -440,24 +440,24 @@ shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed 50px 60px / 50px border-box border-box'"); style.background = "50px / 50px round fixed border-box"; -shouldBe("style.background", "'50px 50% / 50px round fixed border-box border-box'"); +shouldBe("style.background", "'50px center / 50px round fixed border-box border-box'"); shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed 50px 50% / 50px border-box border-box'"); style.background = "left top 60px / 50px round fixed border-box"; -shouldBe("style.background", "'left 0% top 60px / 50px round fixed border-box border-box'"); -shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 0% top 60px / 50px border-box border-box'"); +shouldBe("style.background", "'left top 60px / 50px round fixed border-box border-box'"); +shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed 0% top 60px / 50px border-box border-box'"); style.background = "left -20px top 60px / 50px round fixed border-box"; shouldBe("style.background", "'left -20px top 60px / 50px round fixed border-box border-box'"); shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left -20px top 60px / 50px border-box border-box'"); style.background = "border-box left 20px top / 50px round fixed"; -shouldBe("style.background", "'left 20px top 0% / 50px round fixed border-box border-box'"); -shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 20px top 0% / 50px border-box border-box'"); +shouldBe("style.background", "'left 20px top / 50px round fixed border-box border-box'"); +shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 20px 0% / 50px border-box border-box'"); style.background = "border-box round fixed left 20px top / 50px"; -shouldBe("style.background", "'left 20px top 0% / 50px round fixed border-box border-box'"); -shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 20px top 0% / 50px border-box border-box'"); +shouldBe("style.background", "'left 20px top / 50px round fixed border-box border-box'"); +shouldBe("computedStyle.background", "'rgba(0, 0, 0, 0) none round fixed left 20px 0% / 50px border-box border-box'"); style.background = "border-box round fixed left 20px top 40px / 50px"; shouldBe("style.background", "'left 20px top 40px / 50px round fixed border-box border-box'");
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize-expected.txt b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize-expected.txt index a2b24540..bf8adea 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize-expected.txt
@@ -3,7 +3,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS e.style.background is "url(\"dummy://test.png\") 50% 50% / cover no-repeat border-box border-box red" +PASS e.style.background is "url(\"dummy://test.png\") center center / cover no-repeat border-box border-box red" PASS e.style.backgroundSize is "cover" PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize.html b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize.html index 0f5e82a6..f04969e 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize.html +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-after-set-backgroundSize.html
@@ -12,7 +12,7 @@ e.style.backgroundSize = "cover"; e.style.background = "center red url(dummy://test.png) no-repeat border-box"; - shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 50% 50% / cover no-repeat border-box border-box red') + shouldBeEqualToString("e.style.background", 'url("dummy://test.png") center center / cover no-repeat border-box border-box red') shouldBeEqualToString("e.style.backgroundSize", 'cover'); debug("")
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style-expected.txt b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style-expected.txt index 311620f..850ea68 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style-expected.txt
@@ -3,14 +3,14 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS e.style.background is "url(\"dummy://test.png\") 50% 50% / cover no-repeat border-box border-box red" +PASS e.style.background is "url(\"dummy://test.png\") center center / cover no-repeat border-box border-box red" PASS e.style.backgroundSize is "cover" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgb(255, 0, 0) url(\"dummy://test.png\") no-repeat scroll 50% 50% / cover border-box border-box" PASS computedStyle.getPropertyValue("background-size") is "cover" PASS checkComputedStyleValue() is true -PASS e.style.background is "url(\"dummy://test.png\") 20px 50% / contain no-repeat padding-box padding-box red" +PASS e.style.background is "url(\"dummy://test.png\") 20px center / contain no-repeat padding-box padding-box red" PASS e.style.backgroundSize is "contain" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgb(255, 0, 0) url(\"dummy://test.png\") no-repeat scroll 20px 50% / contain padding-box padding-box" @@ -24,14 +24,14 @@ PASS computedStyle.getPropertyValue("background-size") is "50% 75%" PASS checkComputedStyleValue() is true -PASS e.style.background is "url(\"dummy://test.png\") 0% 0% / 100px 200px repeat border-box content-box red" +PASS e.style.background is "url(\"dummy://test.png\") left top / 100px 200px repeat border-box content-box red" PASS e.style.backgroundSize is "100px 200px" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgb(255, 0, 0) url(\"dummy://test.png\") repeat scroll 0% 0% / 100px 200px border-box content-box" PASS computedStyle.getPropertyValue("background-size") is "100px 200px" PASS checkComputedStyleValue() is true -PASS e.style.background is "url(\"dummy://test.png\") 50% 50% / auto repeat content-box padding-box red" +PASS e.style.background is "url(\"dummy://test.png\") 50% center / auto repeat content-box padding-box red" PASS e.style.backgroundSize is "auto" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgb(255, 0, 0) url(\"dummy://test.png\") repeat scroll 50% 50% / auto content-box padding-box" @@ -45,21 +45,21 @@ PASS computedStyle.getPropertyValue("background-size") is "50%" PASS checkComputedStyleValue() is true -PASS e.style.background is "url(\"dummy://test.png\") 0% 0% / 100px repeat scroll padding-box border-box red" +PASS e.style.background is "url(\"dummy://test.png\") left top / 100px repeat scroll padding-box border-box red" PASS e.style.backgroundSize is "100px" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgb(255, 0, 0) url(\"dummy://test.png\") repeat scroll 0% 0% / 100px padding-box border-box" PASS computedStyle.getPropertyValue("background-size") is "100px" PASS checkComputedStyleValue() is true -PASS e.style.background is "url(\"dummy://test.png\") 50% 50% / auto repeat fixed content-box content-box red" +PASS e.style.background is "url(\"dummy://test.png\") 50% center / auto repeat fixed content-box content-box red" PASS e.style.backgroundSize is "auto" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgb(255, 0, 0) url(\"dummy://test.png\") repeat fixed 50% 50% / auto content-box content-box" PASS computedStyle.getPropertyValue("background-size") is "auto" PASS checkComputedStyleValue() is true -PASS e.style.background is "0% 0% / 50%" +PASS e.style.background is "left top / 50%" PASS e.style.backgroundSize is "50%" PASS checkStyle() is true PASS computedStyle.getPropertyValue("background") is "rgba(0, 0, 0, 0) none repeat scroll 0% 0% / 50% padding-box border-box"
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style.html b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style.html index 25adc59..8bd7570 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style.html +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style.html
@@ -23,7 +23,7 @@ } e.style.background = 'center / cover red url("dummy://test.png") no-repeat border-box'; -shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 50% 50% / cover no-repeat border-box border-box red'); +shouldBeEqualToString("e.style.background", 'url("dummy://test.png") center center / cover no-repeat border-box border-box red'); shouldBeEqualToString("e.style.backgroundSize", 'cover'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgb(255, 0, 0) url("dummy://test.png") no-repeat scroll 50% 50% / cover border-box border-box'); @@ -32,7 +32,7 @@ debug("") e.style.background = 'red 20px / contain url("dummy://test.png") no-repeat padding-box'; -shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 20px 50% / contain no-repeat padding-box padding-box red'); +shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 20px center / contain no-repeat padding-box padding-box red'); shouldBeEqualToString("e.style.backgroundSize", 'contain'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgb(255, 0, 0) url("dummy://test.png") no-repeat scroll 20px 50% / contain padding-box padding-box'); @@ -50,7 +50,7 @@ debug("") e.style.background = 'red url("dummy://test.png") repeat top left / 100px 200px border-box content-box'; -shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 0% 0% / 100px 200px repeat border-box content-box red'); +shouldBeEqualToString("e.style.background", 'url("dummy://test.png") left top / 100px 200px repeat border-box content-box red'); shouldBeEqualToString("e.style.backgroundSize", '100px 200px'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgb(255, 0, 0) url("dummy://test.png") repeat scroll 0% 0% / 100px 200px border-box content-box'); @@ -59,7 +59,7 @@ debug("") e.style.background = 'red url("dummy://test.png") repeat 50% / auto auto content-box padding-box'; -shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 50% 50% / auto repeat content-box padding-box red'); +shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 50% center / auto repeat content-box padding-box red'); shouldBeEqualToString("e.style.backgroundSize", 'auto'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgb(255, 0, 0) url("dummy://test.png") repeat scroll 50% 50% / auto content-box padding-box'); @@ -77,7 +77,7 @@ debug("") e.style.background = 'red repeat scroll padding-box border-box top left / 100px url("dummy://test.png")'; -shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 0% 0% / 100px repeat scroll padding-box border-box red'); +shouldBeEqualToString("e.style.background", 'url("dummy://test.png") left top / 100px repeat scroll padding-box border-box red'); shouldBeEqualToString("e.style.backgroundSize", '100px'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgb(255, 0, 0) url("dummy://test.png") repeat scroll 0% 0% / 100px padding-box border-box'); @@ -86,7 +86,7 @@ debug("") e.style.background = '50% / auto fixed url("dummy://test.png") repeat content-box red'; -shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 50% 50% / auto repeat fixed content-box content-box red'); +shouldBeEqualToString("e.style.background", 'url("dummy://test.png") 50% center / auto repeat fixed content-box content-box red'); shouldBeEqualToString("e.style.backgroundSize", 'auto'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgb(255, 0, 0) url("dummy://test.png") repeat fixed 50% 50% / auto content-box content-box'); @@ -95,7 +95,7 @@ debug("") e.style.background = "top left / 50%"; -shouldBeEqualToString("e.style.background", '0% 0% / 50%'); +shouldBeEqualToString("e.style.background", 'left top / 50%'); shouldBeEqualToString("e.style.backgroundSize", '50%'); shouldBe("checkStyle()", "true"); shouldBeEqualToString('computedStyle.getPropertyValue("background")', 'rgba(0, 0, 0, 0) none repeat scroll 0% 0% / 50% padding-box border-box');
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-constructor-expected.txt deleted file mode 100644 index bd3a4f8..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-constructor-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -Tests that the constructor of the OffscreenCanvas can be called on the main thread - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS aCanvas.width is 50 -PASS aCanvas.height is 50 -PASS aCanvas.width is 100 -PASS aCanvas.height is 100 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-constructor.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-constructor.html deleted file mode 100644 index 0b61a34..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-constructor.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/js-test.js"></script> -<script> -description("Tests that the constructor of the OffscreenCanvas can be called on the main thread"); - -var aCanvas = new OffscreenCanvas(50, 50); -shouldBe("aCanvas.width", "50"); -shouldBe("aCanvas.height", "50"); - -aCanvas.width = 100; -aCanvas.height = 100; -shouldBe("aCanvas.width", "100"); -shouldBe("aCanvas.height", "100"); -</script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-expected.txt new file mode 100644 index 0000000..6894f5c0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-expected.txt
@@ -0,0 +1,20 @@ +Tests basic functionalities of offscreenCanvas.getContext on the main thread + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS aCanvas.width is 40 +PASS aCanvas.height is 60 +PASS aCanvas.width is 110 +PASS aCanvas.height is 90 +PASS aCanvas.width is 0 +PASS ctx = aCanvas.getContext('2d') did not throw exception. +PASS ctx is an instance of OffscreenCanvasRenderingContext2D +PASS ctx2 is null +PASS ctx3 is non-null. +PASS ctx3 == ctx is true +PASS bogusCtx is null +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker-expected.txt new file mode 100644 index 0000000..2682efa --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker-expected.txt
@@ -0,0 +1,10 @@ +Tests that the 2D context of OffscreenCanvas can be constructed on a worker thread. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS getContext('2d') correctly returns [object OffscreenCanvasRenderingContext2D]. +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker.html new file mode 100644 index 0000000..e555fa9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<script src="../../resources/js-test.js"></script> +<body> +<script id="myWorker" type="text/worker"> +self.onmessage = function(e) { + var aCanvas = new OffscreenCanvas(50, 50); + try { + var ctx = aCanvas.getContext('2d'); + if (toString.call(ctx) != '[object OffscreenCanvasRenderingContext2D]') { + self.postMessage("aCanvas.getContext('2d') does not return [object OffscreenCanvasRenderingContext2D]"); + } else { + self.postMessage("success"); + } + } catch (e) { + self.postMessage(e); + } +}; +</script> + +<script> +jsTestIsAsync = true; +description("Tests that the 2D context of OffscreenCanvas can be constructed on a worker thread."); + +function makeWorker(script) { + var blob = new Blob([script]); + return new Worker(URL.createObjectURL(blob)); +} + +function handleMessageFromWorker(msg) +{ + if (msg.data == "success") { + testPassed("getContext('2d') correctly returns [object OffscreenCanvasRenderingContext2D]."); + } else { + testFailed(msg.data); + } + finishJSTest(); +} + +var worker = makeWorker(document.getElementById('myWorker').textContent); +worker.addEventListener('message', handleMessageFromWorker); +worker.postMessage(""); +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D.html new file mode 100644 index 0000000..be7fad2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<script src="../../resources/js-test.js"></script> +<script> +description("Tests basic functionalities of offscreenCanvas.getContext on the main thread"); + +// Tests onstructor of OffscreenCanvas and length/width change +var aCanvas = new OffscreenCanvas(40, 60); +shouldBe("aCanvas.width", "40"); +shouldBe("aCanvas.height", "60"); + +aCanvas.width = 110; +aCanvas.height = 90; +shouldBe("aCanvas.width", "110"); +shouldBe("aCanvas.height", "90"); + +aCanvas.width = 0; // Zero dimension is allowed +shouldBe("aCanvas.width", "0"); + +// Tests object type of getContext('2d') +var ctx; +shouldNotThrow("ctx = aCanvas.getContext('2d')"); +shouldBeType("ctx", "OffscreenCanvasRenderingContext2D"); + +// Calling getContext on a different context type will return null +var ctx2 = aCanvas.getContext("webgl"); +shouldBeNull("ctx2"); + +// Calling getContext on the same context type will return the original context type +var ctx3 = aCanvas.getContext("2d"); +shouldBeNonNull("ctx3"); +shouldBeTrue("ctx3 == ctx"); + +// TODO: change the below part of the test when webgl is supported. +// Calling getContext on an unimplemented context type will return null +var bogusCanvas = new OffscreenCanvas(20, 20); +var bogusCtx = bogusCanvas.getContext("webgl"); +shouldBeNull("bogusCtx"); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-nesting.html b/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-nesting.html index e0a472f7..00df0c6 100644 --- a/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-nesting.html +++ b/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-nesting.html
@@ -11,7 +11,7 @@ --red: { background-color: red; }; --foo: { background-color: green; - var(--apply1) var(--apply2); + var(--apply1, ) var(--apply2, ); }; @apply --foo; } @@ -21,7 +21,8 @@ <script> test(function(){ assert_equals(getComputedStyle(e).backgroundColor, "rgb(0, 128, 0)"); - assert_equals(getComputedStyle(e).getPropertyValue("--foo"), " { background-color: green; @apply --red; }"); + assert_equals(getComputedStyle(e).getPropertyValue("--apply1"), ""); + assert_equals(getComputedStyle(e).getPropertyValue("--foo"), " { background-color: green; --red; }"); }, "@apply inside custom properties don't get expanded if the @apply rule was " + "constructed from variable references"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-syntax.html b/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-syntax.html index 1cbf1e4..a578ce4 100644 --- a/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-syntax.html +++ b/third_party/WebKit/LayoutTests/fast/css/atapply/at-apply-invalid-syntax.html
@@ -24,6 +24,12 @@ --red2: { background-color: red; } bla ; @apply --red2; + --var1: @apply; + --var2: @apply foo; + --var3: @apply --red :/ ; + --var4: @apply --red @apply --red; + --var5: @apply --red {; + width: 100px; height: 100px; @@ -43,5 +49,10 @@ <script> test(function(){ assert_equals(getComputedStyle(e).backgroundColor, "rgb(0, 128, 0)"); + assert_equals(getComputedStyle(e).getPropertyValue("--var1"), ""); + assert_equals(getComputedStyle(e).getPropertyValue("--var2"), ""); + assert_equals(getComputedStyle(e).getPropertyValue("--var3"), ""); + assert_equals(getComputedStyle(e).getPropertyValue("--var4"), ""); + assert_equals(getComputedStyle(e).getPropertyValue("--var5"), ""); }, "Tests various invalid @apply rules get rejected"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/parsing-unitless-length-quirk.html b/third_party/WebKit/LayoutTests/fast/css/parsing-unitless-length-quirk.html index 1313ae6..2a2142b 100644 --- a/third_party/WebKit/LayoutTests/fast/css/parsing-unitless-length-quirk.html +++ b/third_party/WebKit/LayoutTests/fast/css/parsing-unitless-length-quirk.html
@@ -195,7 +195,7 @@ assert_equals(sheet.cssRules[44].style.background, ""); }, "No unitless length quirk for background property"); test(function(){ - assert_equals(sheet.cssRules[45].style.background, "10px 50% rgb(255, 0, 0)"); + assert_equals(sheet.cssRules[45].style.background, "10px center rgb(255, 0, 0)"); }, "No unitless length quirk for background property"); test(function(){ assert_equals(sheet.cssRules[46].style.background, "");
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order-expected.txt b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order-expected.txt new file mode 100644 index 0000000..be77474 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order-expected.txt
@@ -0,0 +1,12 @@ +Preferred stylesheet where insertion order is reversed tree order + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS getComputedStyle(t1).color is "rgb(0, 128, 0)" +PASS document.preferredStylesheetSet is "preferred" +PASS document.selectedStylesheetSet is "preferred" +PASS successfullyParsed is true + +TEST COMPLETE +This text should be green
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order.html b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order.html new file mode 100644 index 0000000..b28225e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<script src="../../resources/js-test.js"></script> +<div id="t1">This text should be green</div> +<script> +description("Preferred stylesheet where insertion order is reversed tree order"); + +function createStyleElement(text, title) { + var elm = document.createElement("style"); + elm.setAttribute("title", title); + elm.appendChild(document.createTextNode(text)); + return elm; +} + +document.head.appendChild(createStyleElement("#t1 {color:green}", "preferred")); +document.head.appendChild(createStyleElement("#t1 {color:red}", "notpreferred")); + +shouldBeEqualToString("getComputedStyle(t1).color", "rgb(0, 128, 0)"); +shouldBeEqualToString("document.preferredStylesheetSet", "preferred"); +shouldBeEqualToString("document.selectedStylesheetSet", "preferred"); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order-expected.txt b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order-expected.txt new file mode 100644 index 0000000..b78f3a9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order-expected.txt
@@ -0,0 +1,12 @@ +Preferred stylesheet where insertion order is tree order + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS getComputedStyle(t1).color is "rgb(0, 128, 0)" +PASS document.preferredStylesheetSet is "preferred" +PASS document.selectedStylesheetSet is "preferred" +PASS successfullyParsed is true + +TEST COMPLETE +This text should be green
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order.html b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order.html new file mode 100644 index 0000000..f3278801 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<script src="../../resources/js-test.js"></script> +<div id="t1">This text should be green</div> +<script> +description("Preferred stylesheet where insertion order is tree order"); + +function createStyleElement(text, title) { + var elm = document.createElement("style"); + elm.setAttribute("title", title); + elm.appendChild(document.createTextNode(text)); + return elm; +} + +document.head.insertBefore(createStyleElement("#t1 {color:green}", "preferred"), document.head.firstChild); +document.head.insertBefore(createStyleElement("#t1 {color:red}", "notpreferred"), document.head.firstChild); + +shouldBeEqualToString("getComputedStyle(t1).color", "rgb(0, 128, 0)"); +shouldBeEqualToString("document.preferredStylesheetSet", "preferred"); +shouldBeEqualToString("document.selectedStylesheetSet", "preferred"); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/pseudo-default-dynamic.html b/third_party/WebKit/LayoutTests/fast/css/pseudo-default-dynamic.html index 73a2893..202af00e 100644 --- a/third_party/WebKit/LayoutTests/fast/css/pseudo-default-dynamic.html +++ b/third_party/WebKit/LayoutTests/fast/css/pseudo-default-dynamic.html
@@ -4,8 +4,8 @@ <div id="log"></div> <div id="container"></div> <style> -button, input { background: red; } -button:default, input:default { background: green; } +button, input, option { background: red; } +button:default, input:default, option:default { background: green; } </style> <script> // TODO(tkent): This should be merged to web-platform-tests/html/semantics/selectors/pseudo-classes/default.html. @@ -86,4 +86,83 @@ assert_equals(background('second'), NOT_DEFAULT); }, 'Adding a button by form content attribute should update the default button.'); +test(function() { + container.innerHTML = '<form><input type=checkbox checked id=c1><input type=text checked id=t1></form>'; + assert_equals(background('c1'), DEFAULT); + assert_equals(background('t1'), NOT_DEFAULT); + document.querySelector('#c1').type = 'text'; + document.querySelector('#t1').type = 'checkbox'; + assert_equals(background('c1'), NOT_DEFAULT); + assert_equals(background('t1'), DEFAULT); +}, 'Updating type attribute of :default checkbox should update default status'); + +test(function() { + container.innerHTML = '<form><input type=radio checked id=r1><input type=text checked id=t1></form>'; + assert_equals(background('r1'), DEFAULT); + assert_equals(background('t1'), NOT_DEFAULT); + document.querySelector('#r1').type = 'text'; + document.querySelector('#t1').type = 'radio'; + assert_equals(background('r1'), NOT_DEFAULT); + assert_equals(background('t1'), DEFAULT); +}, 'Updating type attribute of :default radio should update default status'); + +test(function() { + container.innerHTML = '<form><input type=checkbox checked id=c1><input type=radio checked id=r1></form>'; + assert_equals(background('c1'), DEFAULT); + assert_equals(background('r1'), DEFAULT); + document.querySelector('#c1').defaultChecked = false; + document.querySelector('#r1').defaultChecked = false; + assert_equals(background('c1'), NOT_DEFAULT); + assert_equals(background('r1'), NOT_DEFAULT); +}, 'Updating the checked attribute of :default checkbox or radio should update default status'); + +test(function() { + container.innerHTML = '<form><input type=checkbox id=c1><input type=radio id=r1></form>'; + assert_equals(background('c1'), NOT_DEFAULT); + assert_equals(background('r1'), NOT_DEFAULT); + if (window.eventSender){ + var checkbox = document.querySelector('#c1'); + checkbox.focus(); + eventSender.keyDown(' '); + assert_equals(checkbox.checked, true); + assert_equals(background('c1'), NOT_DEFAULT); + + var radio = document.querySelector('#r1'); + radio.focus(); + eventSender.keyDown(' '); + assert_equals(radio.checked, true); + assert_equals(background('r1'), NOT_DEFAULT); + } + document.querySelector('#c1').setAttribute('checked', 'checked'); + document.querySelector('#r1').setAttribute('checked', 'checked'); + assert_equals(background('c1'), DEFAULT); + assert_equals(background('r1'), DEFAULT); + + document.querySelector('#c1').removeAttribute('checked'); + document.querySelector('#r1').removeAttribute('checked'); + assert_equals(background('c1'), NOT_DEFAULT); + assert_equals(background('r1'), NOT_DEFAULT); +}, 'Dynamically updating checked status or setting checked attribute should reflect correct default status'); + +test(function() { + container.innerHTML = '<form><select><option selected id=o1>1</option><option id=o2>2</option></select></form>'; + assert_equals(background('o1'), DEFAULT); + assert_equals(background('o2'), NOT_DEFAULT); + document.querySelector('#o1').defaultSelected = false; + document.querySelector('#o2').defaultSelected = true; + assert_equals(background('o1'), NOT_DEFAULT); + assert_equals(background('o2'), DEFAULT); +}, 'Updating the selected attribute of :default option element should update default status'); + +test(function() { + container.innerHTML = '<form><select><option id=o1></option><option id=o2></option</select></form>'; + assert_equals(background('o1'), NOT_DEFAULT); + document.querySelector('#o1').selected = true; + assert_equals(background('o1'), NOT_DEFAULT); + document.querySelector('#o1').setAttribute('selected', 'selected'); + assert_equals(background('o1'), DEFAULT); + document.querySelector('#o1').removeAttribute('selected'); + assert_equals(background('o1'), NOT_DEFAULT); +}, 'Dynamically updating selected status or setting selected attribute should reflect correct default status'); + </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/serialize-style-with-all-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/css/serialize-style-with-all-crash-expected.txt new file mode 100644 index 0000000..43699ea --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/serialize-style-with-all-crash-expected.txt
@@ -0,0 +1,9 @@ +crbug.com/590412: this test checks that style is correctly serialized without any crashes when applying property-all after setting identity-box-chrome-color. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS successfullyParsed is true + +TEST COMPLETE +PASS
diff --git a/third_party/WebKit/LayoutTests/fast/css/serialize-style-with-all-crash.html b/third_party/WebKit/LayoutTests/fast/css/serialize-style-with-all-crash.html new file mode 100644 index 0000000..7ff0b84 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/serialize-style-with-all-crash.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<script src="../../resources/js-test.js"></script> +<div id="target">PASS</div> +<script> +description("crbug.com/590412: this test checks that style is correctly serialized without any crashes when applying property-all after setting identity-box-chrome-color."); + +var target=document.getElementById("target") +target.style.setProperty('--identity-box-chrome-color','important'); +target.style['all']='initial'; +// cloneNode serializes target's style internally. +target.cloneNode(); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height-svg-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height-svg-expected.txt index ae3d2ea5..b1acd09 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height-svg-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height-svg-expected.txt
@@ -4,7 +4,7 @@ FAIL naturalWidth/Height of SVG in <img>, width in pixels; height unspecified assert_equals: expected "500x0" but got "500x150" FAIL naturalWidth/Height of SVG in <img>, width in pixels; percentage height assert_equals: expected "500x0" but got "500x150" PASS naturalWidth/Height of SVG in <img>, width/height in pixels; viewBox -FAIL naturalWidth/Height of SVG in <img>, width/height unspecified; viewBox assert_equals: expected "0x0" but got "800x600" +FAIL naturalWidth/Height of SVG in <img>, width/height unspecified; viewBox assert_equals: expected "0x0" but got "200x150" FAIL naturalWidth/Height of SVG in <img>, width in pixels; height unspecified; viewBox assert_equals: expected "400x0" but got "400x300" Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/resources/shadow-dom.js b/third_party/WebKit/LayoutTests/fast/dom/shadow/resources/shadow-dom.js index 54800d4..80a1c00 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/resources/shadow-dom.js +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/resources/shadow-dom.js
@@ -1,3 +1,37 @@ +// TODO(yuzus): These two functions below need cleaning up. They are currently +// from js-test.js. +function getOrCreateTestElement(id, tagName) +{ + var element = document.getElementById(id); + if (element) + return element; + + element = document.createElement(tagName); + element.id = id; + var refNode; + var parent = document.body || document.documentElement; + if (id == "description") + refNode = getOrCreateTestElement("console", "div"); + else + refNode = parent.firstChild; + + parent.insertBefore(element, refNode); + return element; +} + +function debug(msg) +{ + if (self._lazyTestResults) { + self._lazyTestResults.push(msg); + } else { + var span = document.createElement("span"); + // insert it first so XHTML knows the namespace; + getOrCreateTestElement("console", "div").appendChild(span); + span.innerHTML = msg + '<br />'; + }; +} + + function createShadowRoot() { var children = Array.prototype.slice.call(arguments); @@ -227,6 +261,7 @@ debug('PASS'); else debug('FAIL'); + return isInnermostActiveElement(to); } function navigateFocusForward()
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/tabindex-slot.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/tabindex-slot.html index d5f73ce..6810bec 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/tabindex-slot.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/tabindex-slot.html
@@ -39,23 +39,6 @@ <script> -function shouldCustomNavigateFocus(from, to, direction) -{ - var fromElement = getNodeInComposedTree(from); - if (!fromElement) { - return; - } - fromElement.focus(); - if (!isInnermostActiveElement(from)) { - return; - } - if (direction == 'forward') - navigateFocusForward(); - else - navigateFocusBackward(); - return isInnermostActiveElement(to); -} - test(function() { var xfoo = document.getElementById('x-foo'); convertTemplatesToShadowRootsWithin(xfoo); @@ -80,10 +63,10 @@ ]; for (var i = 0; i + 1 < elements.length; ++i) - assert_true(shouldCustomNavigateFocus(elements[i], elements[i + 1], 'forward'), elements[i]+" to "+ elements[i+1]); + assert_true(shouldNavigateFocus(elements[i], elements[i + 1], 'forward'), elements[i]+" to "+ elements[i+1]); elements.reverse(); for (var i = 0; i + 1 < elements.length; ++i) - assert_true(shouldCustomNavigateFocus(elements[i], elements[i + 1], 'backward'), elements[i]+" to "+ elements[i+1]); + assert_true(shouldNavigateFocus(elements[i], elements[i + 1], 'backward'), elements[i]+" to "+ elements[i+1]); }, 'Focus controller should treat slots as a focus scope.'); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol-expected.txt new file mode 100644 index 0000000..924a7fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL TEXTAREA with white-space:nowrap should not increase the number of EOLs assert_equals: expected "a\n\n b\n" but got "a\n\n\n\n\n b\n" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html new file mode 100644 index 0000000..0bca8f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<body> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id="log"></div> +<textarea style="white-space:nowrap"></textarea> +<script> +test(function() { + var textarea = document.querySelector('textarea'); + textarea.focus(); + textarea.addEventListener('copy', function(event) { + event.clipboardData.setData('text', 'a\r\n\r\n b\r\n'); + event.preventDefault(); + }); + document.execCommand('copy'); + document.execCommand('paste'); + // TODO(tkent): The following assertion fails now. crbug.com/2007 and + // crbug.com/528491. + assert_equals(textarea.value, 'a\n\n b\n'); +}, 'TEXTAREA with white-space:nowrap should not increase the number of EOLs'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol-expected.txt new file mode 100644 index 0000000..dac87d7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL TEXTAREA with white-space:pre-line should not produce nbsp by Enter key assert_equals: expected "P1\n\nP2\n\n\n\nP3\n" but got "P1\n\nP2\n\n \nP3\n" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html new file mode 100644 index 0000000..781d49a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<body> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id="log"></div> +<textarea style="white-space:pre-line">P1 + +P2 + +P3 +</textarea> +<script> +test(function() { + var textarea = document.querySelector('textarea'); + textarea.focus(); + textarea.setSelectionRange(7, 7); // Empty line between P2 and P3. + eventSender.keyDown('\n'); + eventSender.keyDown('upArrow'); + eventSender.keyDown('\n'); + // TODO(tkent): The following assertion fails now. crbug.com/410417 + assert_equals(textarea.value, 'P1\n\nP2\n\n\n\nP3\n'); +}, 'TEXTAREA with white-space:pre-line should not produce nbsp by Enter key'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol-expected.txt new file mode 100644 index 0000000..f715bfd --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL TEXTAREA should not remove the last EOL on paste. assert_equals: expected "WH\n" but got "WH" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html new file mode 100644 index 0000000..1664f53 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<body> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id="log"></div> +<textarea></textarea> +<script> +test(function() { + var textarea = document.querySelector('textarea'); + textarea.focus(); + eventSender.keyDown('H'); + eventSender.keyDown('\n'); + eventSender.keyDown('W'); + assert_equals(textarea.value, 'H\nW'); + textarea.setSelectionRange(2, 3); // "W" + document.execCommand('cut'); + textarea.setSelectionRange(0, 0); + document.execCommand('paste'); + // TODO(tkent): The following assertion fails now. crbug.com/522144. + assert_equals(textarea.value, 'WH\n'); +}, 'TEXTAREA should not remove the last EOL on paste.'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-list-style-image-expected.html b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-list-style-image-expected.html new file mode 100644 index 0000000..52c59b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-list-style-image-expected.html
@@ -0,0 +1,2 @@ +<script src="resources/srcset-helper.js"></script> +<img width=30 src="resources/deleteButton-2x.png">
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-list-style-image.html b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-list-style-image.html new file mode 100644 index 0000000..b23af9b5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-list-style-image.html
@@ -0,0 +1,9 @@ +<script src="resources/srcset-helper.js"></script> +<style> +ul { + list-style-image: -webkit-image-set(url('resources/deleteButton.png') 1x, url('resources/deleteButton-2x.png') 2x); + list-style-position: inside; + padding: 0; +} +</style> +<ul><li></ul>
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-shape-outside-expected.html b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-shape-outside-expected.html new file mode 100644 index 0000000..8f38854 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-shape-outside-expected.html
@@ -0,0 +1,9 @@ +<style> +.left { + float: left; + width: 30px; + height: 1em; +} +</style> +<div class="left"></div> +<img width=30 src="resources/deleteButton.png">
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/image-set-shape-outside.html b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-shape-outside.html new file mode 100644 index 0000000..ad1a5da36 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/hidpi/image-set-shape-outside.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<style> +.left { + -webkit-shape-outside: -webkit-image-set(url('resources/deleteButton.png') 1x, url('resources/deleteButton-2x.png') 2x); + float: left; + width: 60px; + height: 1em; +} +</style> +<div class="left"></div> +<img width=30 src="resources/deleteButton.png">
diff --git a/third_party/WebKit/LayoutTests/fast/inspector-support/style-expected.txt b/third_party/WebKit/LayoutTests/fast/inspector-support/style-expected.txt index 64ee892..a1f21b0 100644 --- a/third_party/WebKit/LayoutTests/fast/inspector-support/style-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/inspector-support/style-expected.txt
@@ -2,15 +2,15 @@ Note that background is buggy right now! Test background-image: initial +background-position-x: initial +background-position-y: initial +background-size: initial background-repeat-x: initial background-repeat-y: initial background-attachment: initial -background-position-x: initial -background-position-y: initial background-origin: initial background-clip: initial background-color: purple -background-size: initial margin-top: 1em margin-right: 1em margin-bottom: 1em
diff --git a/third_party/WebKit/LayoutTests/fast/masking/parsing-mask-expected.txt b/third_party/WebKit/LayoutTests/fast/masking/parsing-mask-expected.txt index c00c5ee..f372473 100644 --- a/third_party/WebKit/LayoutTests/fast/masking/parsing-mask-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/masking/parsing-mask-expected.txt
@@ -8,30 +8,30 @@ PASS innerStyle("-webkit-mask", "none, none, none") is "none, none, none" PASS innerStyle("-webkit-mask", "url(file:///image.png), none") is "url(\"file:///image.png\"), none" PASS innerStyle("-webkit-mask", "none, url(file:///image.png)") is "none, url(\"file:///image.png\")" -PASS innerStyle("-webkit-mask", "top left") is "0% 0%" -PASS innerStyle("-webkit-mask", "bottom right") is "100% 100%" -PASS innerStyle("-webkit-mask", "left bottom") is "0% 100%" -PASS innerStyle("-webkit-mask", "right top") is "100% 0%" -PASS innerStyle("-webkit-mask", "center") is "50% 50%" -PASS innerStyle("-webkit-mask", "none top") is "none 50% 0%" -PASS innerStyle("-webkit-mask", "none bottom") is "none 50% 100%" -PASS innerStyle("-webkit-mask", "none right") is "none 100% 50%" -PASS innerStyle("-webkit-mask", "none top right") is "none 100% 0%" -PASS innerStyle("-webkit-mask", "none bottom left") is "none 0% 100%" -PASS innerStyle("-webkit-mask", "none right") is "none 100% 50%" -PASS innerStyle("-webkit-mask", "none left") is "none 0% 50%" -PASS innerStyle("-webkit-mask", "center 50%") is "50% 50%" +PASS innerStyle("-webkit-mask", "top left") is "left top" +PASS innerStyle("-webkit-mask", "bottom right") is "right bottom" +PASS innerStyle("-webkit-mask", "left bottom") is "left bottom" +PASS innerStyle("-webkit-mask", "right top") is "right top" +PASS innerStyle("-webkit-mask", "center") is "center center" +PASS innerStyle("-webkit-mask", "none top") is "none center top" +PASS innerStyle("-webkit-mask", "none bottom") is "none center bottom" +PASS innerStyle("-webkit-mask", "none right") is "none right center" +PASS innerStyle("-webkit-mask", "none top right") is "none right top" +PASS innerStyle("-webkit-mask", "none bottom left") is "none left bottom" +PASS innerStyle("-webkit-mask", "none right") is "none right center" +PASS innerStyle("-webkit-mask", "none left") is "none left center" +PASS innerStyle("-webkit-mask", "center 50%") is "center 50%" PASS innerStyle("-webkit-mask", "50px 50%") is "50px 50%" -PASS innerStyle("-webkit-mask", "center left") is "0% 50%" -PASS innerStyle("-webkit-mask", "top center") is "50% 0%" +PASS innerStyle("-webkit-mask", "center left") is "left center" +PASS innerStyle("-webkit-mask", "top center") is "center top" PASS innerStyle("-webkit-mask", "left 10px top 15px") is "left 10px top 15px" PASS innerStyle("-webkit-mask", "left 10% top 30%") is "left 10% top 30%" -PASS innerStyle("-webkit-mask", "right top 15px") is "right 0% top 15px" -PASS innerStyle("-webkit-mask", "left 10px center") is "left 10px top 50%" -PASS innerStyle("-webkit-mask", "center top 20px") is "left 50% top 20px" -PASS innerStyle("-webkit-mask", "center left 30px") is "left 30px top 50%" -PASS innerStyle("-webkit-mask", "left 20% top") is "left 20% top 0%" -PASS innerStyle("-webkit-mask", "center center") is "50% 50%" +PASS innerStyle("-webkit-mask", "right top 15px") is "right top 15px" +PASS innerStyle("-webkit-mask", "left 10px center") is "left 10px center" +PASS innerStyle("-webkit-mask", "center top 20px") is "center top 20px" +PASS innerStyle("-webkit-mask", "center left 30px") is "left 30px center" +PASS innerStyle("-webkit-mask", "left 20% top") is "left 20% top" +PASS innerStyle("-webkit-mask", "center center") is "center center" PASS innerStyle("-webkit-mask-position", "left 10px top 15px") is "left 10px top 15px" PASS innerStyle("-webkit-mask-position", "left 10% top 30%") is "left 10% top 30%" PASS innerStyle("-webkit-mask-position", "right top 15px") is "right top 15px" @@ -67,25 +67,25 @@ PASS innerStyle("-webkit-mask", "padding-box border-box") is "padding-box border-box" PASS innerStyle("-webkit-mask", "padding-box border-box none") is "none padding-box border-box" PASS innerStyle("-webkit-mask", "none padding-box border-box") is "none padding-box border-box" -PASS innerStyle("-webkit-mask", "none left top / auto") is "none 0% 0% / auto" -PASS innerStyle("-webkit-mask", "none left top / auto auto") is "none 0% 0% / auto" -PASS innerStyle("-webkit-mask", "none left top / 100%") is "none 0% 0% / 100%" -PASS innerStyle("-webkit-mask", "none left top / 100% 100%") is "none 0% 0% / 100% 100%" -PASS innerStyle("-webkit-mask", "none left top / 0%") is "none 0% 0% / 0%" -PASS innerStyle("-webkit-mask", "none left top / auto 0%") is "none 0% 0% / auto 0%" -PASS innerStyle("-webkit-mask", "none left top / cover") is "none 0% 0% / cover" -PASS innerStyle("-webkit-mask", "none left top / contain") is "none 0% 0% / contain" +PASS innerStyle("-webkit-mask", "none left top / auto") is "none left top / auto" +PASS innerStyle("-webkit-mask", "none left top / auto auto") is "none left top / auto" +PASS innerStyle("-webkit-mask", "none left top / 100%") is "none left top / 100%" +PASS innerStyle("-webkit-mask", "none left top / 100% 100%") is "none left top / 100% 100%" +PASS innerStyle("-webkit-mask", "none left top / 0%") is "none left top / 0%" +PASS innerStyle("-webkit-mask", "none left top / auto 0%") is "none left top / auto 0%" +PASS innerStyle("-webkit-mask", "none left top / cover") is "none left top / cover" +PASS innerStyle("-webkit-mask", "none left top / contain") is "none left top / contain" PASS innerStyle("-webkit-mask", "none left 20px top 10px / contain") is "none left 20px top 10px / contain" -PASS innerStyle("-webkit-mask", "none left 20px top / contain") is "none left 20px top 0% / contain" +PASS innerStyle("-webkit-mask", "none left 20px top / contain") is "none left 20px top / contain" PASS innerStyle("-webkit-mask", "none padding-box content-box") is "none padding-box content-box" PASS innerStyle("-webkit-mask", "none padding-box") is "none padding-box padding-box" -PASS innerStyle("-webkit-mask", "none top") is "none 50% 0%" -PASS innerStyle("-webkit-mask", "none center right 20px") is "none right 20px top 50%" -PASS innerStyle("-webkit-mask", "none border-box left top") is "none 0% 0% border-box border-box" -PASS innerStyle("-webkit-mask", "none border-box left top 20px") is "none left 0% top 20px border-box border-box" -PASS innerStyle("-webkit-mask", "none border-box content-box left top repeat-x") is "none 0% 0% repeat-x border-box content-box" -PASS innerStyle("-webkit-mask", "none border-box content-box left top / auto repeat-x") is "none 0% 0% / auto repeat-x border-box content-box" -PASS innerStyle("-webkit-mask", "none border-box content-box right 0px center / auto repeat-x") is "none right 0px top 50% / auto repeat-x border-box content-box" +PASS innerStyle("-webkit-mask", "none top") is "none center top" +PASS innerStyle("-webkit-mask", "none center right 20px") is "none right 20px center" +PASS innerStyle("-webkit-mask", "none border-box left top") is "none left top border-box border-box" +PASS innerStyle("-webkit-mask", "none border-box left top 20px") is "none left top 20px border-box border-box" +PASS innerStyle("-webkit-mask", "none border-box content-box left top repeat-x") is "none left top repeat-x border-box content-box" +PASS innerStyle("-webkit-mask", "none border-box content-box left top / auto repeat-x") is "none left top / auto repeat-x border-box content-box" +PASS innerStyle("-webkit-mask", "none border-box content-box right 0px center / auto repeat-x") is "none right 0px center / auto repeat-x border-box content-box" PASS innerStyle("-webkit-mask", "top none left") is "" PASS innerStyle("-webkit-mask", "right none bottom") is "" PASS innerStyle("-webkit-mask", "right right") is ""
diff --git a/third_party/WebKit/LayoutTests/fast/masking/parsing-mask.html b/third_party/WebKit/LayoutTests/fast/masking/parsing-mask.html index 32f846ca..4511888c 100644 --- a/third_party/WebKit/LayoutTests/fast/masking/parsing-mask.html +++ b/third_party/WebKit/LayoutTests/fast/masking/parsing-mask.html
@@ -50,30 +50,30 @@ // test mask-position -testInner("-webkit-mask", "top left", "0% 0%"); -testInner("-webkit-mask", "bottom right", "100% 100%"); -testInner("-webkit-mask", "left bottom", "0% 100%"); -testInner("-webkit-mask", "right top", "100% 0%"); -testInner("-webkit-mask", "center", "50% 50%"); -testInner("-webkit-mask", "none top", "none 50% 0%"); -testInner("-webkit-mask", "none bottom", "none 50% 100%"); -testInner("-webkit-mask", "none right", "none 100% 50%"); -testInner("-webkit-mask", "none top right", "none 100% 0%"); -testInner("-webkit-mask", "none bottom left", "none 0% 100%"); -testInner("-webkit-mask", "none right", "none 100% 50%"); -testInner("-webkit-mask", "none left", "none 0% 50%"); -testInner("-webkit-mask", "center 50%", "50% 50%"); +testInner("-webkit-mask", "top left", "left top"); +testInner("-webkit-mask", "bottom right", "right bottom"); +testInner("-webkit-mask", "left bottom", "left bottom"); +testInner("-webkit-mask", "right top", "right top"); +testInner("-webkit-mask", "center", "center center"); +testInner("-webkit-mask", "none top", "none center top"); +testInner("-webkit-mask", "none bottom", "none center bottom"); +testInner("-webkit-mask", "none right", "none right center"); +testInner("-webkit-mask", "none top right", "none right top"); +testInner("-webkit-mask", "none bottom left", "none left bottom"); +testInner("-webkit-mask", "none right", "none right center"); +testInner("-webkit-mask", "none left", "none left center"); +testInner("-webkit-mask", "center 50%", "center 50%"); testInner("-webkit-mask", "50px 50%", "50px 50%"); -testInner("-webkit-mask", "center left", "0% 50%"); -testInner("-webkit-mask", "top center", "50% 0%"); +testInner("-webkit-mask", "center left", "left center"); +testInner("-webkit-mask", "top center", "center top"); testInner("-webkit-mask", "left 10px top 15px", "left 10px top 15px"); testInner("-webkit-mask", "left 10% top 30%", "left 10% top 30%"); -testInner("-webkit-mask", "right top 15px", "right 0% top 15px"); -testInner("-webkit-mask", "left 10px center", "left 10px top 50%"); -testInner("-webkit-mask", "center top 20px", "left 50% top 20px"); -testInner("-webkit-mask", "center left 30px", "left 30px top 50%"); -testInner("-webkit-mask", "left 20% top", "left 20% top 0%"); -testInner("-webkit-mask", "center center", "50% 50%"); +testInner("-webkit-mask", "right top 15px", "right top 15px"); +testInner("-webkit-mask", "left 10px center", "left 10px center"); +testInner("-webkit-mask", "center top 20px", "center top 20px"); +testInner("-webkit-mask", "center left 30px", "left 30px center"); +testInner("-webkit-mask", "left 20% top", "left 20% top"); +testInner("-webkit-mask", "center center", "center center"); testInner("-webkit-mask-position", "left 10px top 15px", "left 10px top 15px"); testInner("-webkit-mask-position", "left 10% top 30%", "left 10% top 30%"); @@ -118,27 +118,27 @@ testInner("-webkit-mask", "none padding-box border-box", "none padding-box border-box"); // test mask-size -testInner("-webkit-mask", "none left top / auto", "none 0% 0% / auto"); -testInner("-webkit-mask", "none left top / auto auto", "none 0% 0% / auto"); -testInner("-webkit-mask", "none left top / 100%", "none 0% 0% / 100%"); -testInner("-webkit-mask", "none left top / 100% 100%", "none 0% 0% / 100% 100%"); -testInner("-webkit-mask", "none left top / 0%", "none 0% 0% / 0%"); -testInner("-webkit-mask", "none left top / auto 0%", "none 0% 0% / auto 0%"); -testInner("-webkit-mask", "none left top / cover", "none 0% 0% / cover"); -testInner("-webkit-mask", "none left top / contain", "none 0% 0% / contain"); +testInner("-webkit-mask", "none left top / auto", "none left top / auto"); +testInner("-webkit-mask", "none left top / auto auto", "none left top / auto"); +testInner("-webkit-mask", "none left top / 100%", "none left top / 100%"); +testInner("-webkit-mask", "none left top / 100% 100%", "none left top / 100% 100%"); +testInner("-webkit-mask", "none left top / 0%", "none left top / 0%"); +testInner("-webkit-mask", "none left top / auto 0%", "none left top / auto 0%"); +testInner("-webkit-mask", "none left top / cover", "none left top / cover"); +testInner("-webkit-mask", "none left top / contain", "none left top / contain"); testInner("-webkit-mask", "none left 20px top 10px / contain", "none left 20px top 10px / contain"); -testInner("-webkit-mask", "none left 20px top / contain", "none left 20px top 0% / contain"); +testInner("-webkit-mask", "none left 20px top / contain", "none left 20px top / contain"); // combinations testInner("-webkit-mask", "none padding-box content-box", "none padding-box content-box"); testInner("-webkit-mask", "none padding-box", "none padding-box padding-box"); -testInner("-webkit-mask", "none top", "none 50% 0%"); -testInner("-webkit-mask", "none center right 20px", "none right 20px top 50%"); -testInner("-webkit-mask", "none border-box left top", "none 0% 0% border-box border-box"); -testInner("-webkit-mask", "none border-box left top 20px", "none left 0% top 20px border-box border-box"); -testInner("-webkit-mask", "none border-box content-box left top repeat-x", "none 0% 0% repeat-x border-box content-box"); -testInner("-webkit-mask", "none border-box content-box left top / auto repeat-x", "none 0% 0% / auto repeat-x border-box content-box"); -testInner("-webkit-mask", "none border-box content-box right 0px center / auto repeat-x", "none right 0px top 50% / auto repeat-x border-box content-box"); +testInner("-webkit-mask", "none top", "none center top"); +testInner("-webkit-mask", "none center right 20px", "none right 20px center"); +testInner("-webkit-mask", "none border-box left top", "none left top border-box border-box"); +testInner("-webkit-mask", "none border-box left top 20px", "none left top 20px border-box border-box"); +testInner("-webkit-mask", "none border-box content-box left top repeat-x", "none left top repeat-x border-box content-box"); +testInner("-webkit-mask", "none border-box content-box left top / auto repeat-x", "none left top / auto repeat-x border-box content-box"); +testInner("-webkit-mask", "none border-box content-box right 0px center / auto repeat-x", "none right 0px center / auto repeat-x border-box content-box"); // FIXME: Computed style not yet implemented. // testComputed("-webkit-mask", "", "");
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash-expected.txt index 9e16c0b2..0e74c24 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash-expected.txt
@@ -1,3 +1,4 @@ CONSOLE ERROR: The shape-outside image is too large. CONSOLE ERROR: The shape-outside image is too large. +CONSOLE ERROR: The shape-outside image is too large. This test passes if it doesn't crash.
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash2-expected.txt b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash2-expected.txt index 9e16c0b2..0e74c24 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash2-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-line-height-crash2-expected.txt
@@ -1,3 +1,4 @@ CONSOLE ERROR: The shape-outside image is too large. CONSOLE ERROR: The shape-outside image is too large. +CONSOLE ERROR: The shape-outside image is too large. This test passes if it doesn't crash.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/addressspace-document-appcache.html b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/addressspace-document-appcache.html new file mode 100644 index 0000000..c2ac4f9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/addressspace-document-appcache.html
@@ -0,0 +1,27 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/addressspace-test.js"></script> +<script> + window.onload = function () { + addressSpaceTest("http://localhost:8000", "document+appcache", "local", + // If we request the same resources again, we should load them from the + // memory cache with the same properties. + function () { + addressSpaceTest("http://localhost:8000", "document+appcache", "local"); + }); + addressSpaceTest("http://127.0.0.1:8000", "document", "local", + // If we request the same resources again, we should load them from the + // memory cache with the same properties. + function () { + addressSpaceTest("http://127.0.0.1:8000", "document+appcache", "local"); + }); + + addressSpaceTest("http://example.test:8000", "document+appcache", "private", + // If we request the same resources again, we should load them from the + // memory cache with the same properties. + function () { + addressSpaceTest("http://example.test:8000", "document+appcache", "private"); + }); + }; +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.html b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.html new file mode 100644 index 0000000..b77a776 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.html
@@ -0,0 +1,27 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/addressspace-test.js"></script> +<script> + window.onload = function () { + addressSpaceTest("http://localhost:8000", "document+appcache+csp", "public", + // If we request the same resources again, we should load them from the + // memory cache with the same properties. + function () { + addressSpaceTest("http://localhost:8000", "document+appcache+csp", "public"); + }); + addressSpaceTest("http://127.0.0.1:8000", "document+appcache+csp", "public", + // If we request the same resources again, we should load them from the + // memory cache with the same properties. + function () { + addressSpaceTest("http://127.0.0.1:8000", "document+appcache+csp", "public"); + }); + + addressSpaceTest("http://example.test:8000", "document+appcache+csp", "public", + // If we request the same resources again, we should load them from the + // memory cache with the same properties. + function () { + addressSpaceTest("http://example.test:8000", "document+appcache+csp", "public"); + }); + }; +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/addressspace-test.js b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/addressspace-test.js index 8e019a5..c7738bbf 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/addressspace-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/addressspace-test.js
@@ -4,6 +4,10 @@ file = "post-addressspace-to-parent.html"; } else if (type == "document+csp") { file = "post-addressspace-to-parent.html?csp"; + } else if (type == "document+appcache") { + file = "post-addressspace-to-parent-with-appcache.html"; + } else if (type == "document+appcache+csp") { + file = "post-addressspace-to-parent-with-appcache.html?csp"; } else if (type == "worker") { file = "post-addressspace-from-worker.html"; } else if (type == "sharedworker") { @@ -15,13 +19,15 @@ return i; } -function addressSpaceTest(origin, type, expected) { +function addressSpaceTest(origin, type, expected, callback) { async_test(function (t) { var i = createIFrame(origin, type); window.addEventListener("message", t.step_func(function (e) { if (e.source == i.contentWindow) { assert_equals(e.data.origin, origin); assert_equals(e.data.addressSpace, expected); + if (callback) + callback(); t.done(); } }));
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/appcache.php b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/appcache.php new file mode 100644 index 0000000..7265cb2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/appcache.php
@@ -0,0 +1,5 @@ +<?php +header("Content-Type: text/cache-manifest"); +print("CACHE MANIFEST\n\n"); +print("post-addressspace-to-parent-with-appcache.html"); +?>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/post-addressspace-to-parent-with-appcache.html b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/post-addressspace-to-parent-with-appcache.html new file mode 100644 index 0000000..cf75676 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/cors-rfc1918/resources/post-addressspace-to-parent-with-appcache.html
@@ -0,0 +1,16 @@ +<html manifest="/security/cors-rfc1918/resources/appcache.php"> +<script> + if (window.location.search == "?csp") { + var m = document.createElement("meta"); + m.setAttribute("http-equiv", "Content-Security-Policy"); + m.setAttribute("content", "treat-as-public-address"); + document.head.appendChild(m); + } + + window.applicationCache.oncached = window.applicationCache.onnoupdate = function (e) { + window.parent.postMessage({ + "origin": window.location.origin, + "addressSpace": document.addressSpace + }, "*"); + } +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index ddf65c1..7890480f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -476,8 +476,21 @@ getter height getter width method constructor + method getContext setter height setter width +interface OffscreenCanvasRenderingContext2D + getter offscreenCanvas + method arc + method arcTo + method bezierCurveTo + method closePath + method constructor + method ellipse + method lineTo + method moveTo + method quadraticCurveTo + method rect interface PerformanceObserverEntryList method constructor method getEntries
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/tabular-data/the-tbody-element/deleteRow-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/tabular-data/the-tbody-element/deleteRow-expected.txt deleted file mode 100644 index 89e17977..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/tabular-data/the-tbody-element/deleteRow-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS HTMLTableSectionElement deleteRow(0) -PASS HTMLTableSectionElement deleteRow(-1) -PASS HTMLTableSectionElement deleteRow(rows.length) -PASS HTMLTableSectionElement deleteRow(-2) -FAIL HTMLTableSectionElement deleteRow(-1) with no rows Failed to execute 'deleteRow' on 'HTMLTableSectionElement': The provided index (-1 is outside the range [-1, 0]. -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-new-API-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-new-API-expected.txt index 806e8ef..c2b28cb 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-new-API-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-new-API-expected.txt
@@ -40,15 +40,15 @@ body.main2: [regular, 23:0-23:10] { ['background':'green /* value !important comment */ !important /* no semicolon, very !important */' is-important] @[23:11-23:106] ['background-image':'initial' is-important] @[undefined-undefined] + ['background-position-x':'initial' is-important] @[undefined-undefined] + ['background-position-y':'initial' is-important] @[undefined-undefined] + ['background-size':'initial' is-important] @[undefined-undefined] ['background-repeat-x':'initial' is-important] @[undefined-undefined] ['background-repeat-y':'initial' is-important] @[undefined-undefined] ['background-attachment':'initial' is-important] @[undefined-undefined] - ['background-position-x':'initial' is-important] @[undefined-undefined] - ['background-position-y':'initial' is-important] @[undefined-undefined] ['background-origin':'initial' is-important] @[undefined-undefined] ['background-clip':'initial' is-important] @[undefined-undefined] ['background-color':'green' is-important] @[undefined-undefined] - ['background-size':'initial' is-important] @[undefined-undefined] } body.mainpage: [regular, 3:0-3:13] { ['text-decoration':'none'] @[4:4-4:26] @@ -116,15 +116,15 @@ body.main2: [regular, 23:0-23:10] { ['background':'green /* value !important comment */ !important /* no semicolon, very !important */' is-important] @[23:11-23:106] ['background-image':'initial' is-important] @[undefined-undefined] + ['background-position-x':'initial' is-important] @[undefined-undefined] + ['background-position-y':'initial' is-important] @[undefined-undefined] + ['background-size':'initial' is-important] @[undefined-undefined] ['background-repeat-x':'initial' is-important] @[undefined-undefined] ['background-repeat-y':'initial' is-important] @[undefined-undefined] ['background-attachment':'initial' is-important] @[undefined-undefined] - ['background-position-x':'initial' is-important] @[undefined-undefined] - ['background-position-y':'initial' is-important] @[undefined-undefined] ['background-origin':'initial' is-important] @[undefined-undefined] ['background-clip':'initial' is-important] @[undefined-undefined] ['background-color':'green' is-important] @[undefined-undefined] - ['background-size':'initial' is-important] @[undefined-undefined] } body.mainpage: [regular, 3:0-3:13] { ['text-decoration':'none'] @[4:4-4:26] @@ -194,15 +194,15 @@ body.main2: [regular, 23:0-23:10] { ['background':'green /* value !important comment */ !important /* no semicolon, very !important */' is-important] @[23:11-23:106] ['background-image':'initial' is-important] @[undefined-undefined] + ['background-position-x':'initial' is-important] @[undefined-undefined] + ['background-position-y':'initial' is-important] @[undefined-undefined] + ['background-size':'initial' is-important] @[undefined-undefined] ['background-repeat-x':'initial' is-important] @[undefined-undefined] ['background-repeat-y':'initial' is-important] @[undefined-undefined] ['background-attachment':'initial' is-important] @[undefined-undefined] - ['background-position-x':'initial' is-important] @[undefined-undefined] - ['background-position-y':'initial' is-important] @[undefined-undefined] ['background-origin':'initial' is-important] @[undefined-undefined] ['background-clip':'initial' is-important] @[undefined-undefined] ['background-color':'green' is-important] @[undefined-undefined] - ['background-size':'initial' is-important] @[undefined-undefined] } body.mainpage: [regular, 3:0-3:13] { ['text-decoration':'none'] @[4:4-4:26]
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt index 828795e..290e3de 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-2-expected.txt
@@ -1,4 +1,3 @@ -CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently do. Setting 'border-style' will be required in M51, around May 2016. See https://www.chromestatus.com/features/5542503914668032 for more details. layer at (0,0) size 800x600 LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 @@ -9,17 +8,17 @@ LayoutText {#text} at (0,0) size 195x28 text run at (0,0) width 195: "SVG border-image" LayoutBlockFlow (anonymous) at (1,68.81) size 368x368 - LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,166) size 4x18 text run at (180,166) width 4: " " - LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (364,166) size 4x18 text run at (364,166) width 4: " " LayoutBR {BR} at (0,0) size 0x0 - LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,350) size 4x18 text run at (180,350) width 4: " " - LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (370,418) size 4x18 text run at (370,418) width 4: " " @@ -28,16 +27,16 @@ LayoutText {#text} at (0,0) size 196x28 text run at (0,0) width 196: "PNG border-image" LayoutBlockFlow (anonymous) at (1,68.81) size 368x368 - LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,166) size 4x18 text run at (180,166) width 4: " " - LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (364,166) size 4x18 text run at (364,166) width 4: " " LayoutBR {BR} at (0,0) size 0x0 - LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,350) size 4x18 text run at (180,350) width 4: " " - LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt index 828795e..290e3de 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/as-border-image/svg-as-border-image-expected.txt
@@ -1,4 +1,3 @@ -CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently do. Setting 'border-style' will be required in M51, around May 2016. See https://www.chromestatus.com/features/5542503914668032 for more details. layer at (0,0) size 800x600 LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 @@ -9,17 +8,17 @@ LayoutText {#text} at (0,0) size 195x28 text run at (0,0) width 195: "SVG border-image" LayoutBlockFlow (anonymous) at (1,68.81) size 368x368 - LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,166) size 4x18 text run at (180,166) width 4: " " - LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (364,166) size 4x18 text run at (364,166) width 4: " " LayoutBR {BR} at (0,0) size 0x0 - LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,350) size 4x18 text run at (180,350) width 4: " " - LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (370,418) size 4x18 text run at (370,418) width 4: " " @@ -28,16 +27,16 @@ LayoutText {#text} at (0,0) size 196x28 text run at (0,0) width 196: "PNG border-image" LayoutBlockFlow (anonymous) at (1,68.81) size 368x368 - LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,166) size 4x18 text run at (180,166) width 4: " " - LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,10) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (364,166) size 4x18 text run at (364,166) width 4: " " LayoutBR {BR} at (0,0) size 0x0 - LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (10,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (180,350) size 4x18 text run at (180,350) width 4: " " - LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px none #000000)] + LayoutBlockFlow {DIV} at (194,194) size 160x160 [border: (30px solid #000000)] LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html b/third_party/WebKit/LayoutTests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html index 7e9f7f5..67c687a 100644 --- a/third_party/WebKit/LayoutTests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html +++ b/third_party/WebKit/LayoutTests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html
@@ -1,24 +1,29 @@ <!DOCTYPE html> -<title>Zoomed SVG in list-style-image</title> +<title>Zoomed SVG and raster image in list-style-image</title> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <style> ul { font-family: Ahem; } ul li { - list-style-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'><rect width='1' height='1' fill='green'/></svg>"); - font-size: 30px; + font-size: 250px; color: green; list-style-position: inside; line-height: 1em; } + ul li.svg { + list-style-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'><rect width='1' height='1' fill='green'/></svg>"); + } + ul li.png { + list-style-image: url("../filters/resources/green.png"); + } </style> -<ul><li></ul> +<ul><li class="svg"><li class="png"></ul> <script> var ul = document.querySelector('ul'); - [ 2, 3, 4, 5, 1].forEach(function(zoom) { + [ 2, 3, 4, 5, 0.5, 0.2, 1].forEach(function(zoom) { test(function() { document.body.style.zoom = zoom; - assert_approx_equals(ul.getBoundingClientRect().height, 30, 0.5); + assert_approx_equals(ul.getBoundingClientRect().height, 500, 0.5); }, 'Zoom to ' + zoom + " and list height should be equal to line-height"); }); </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/animations/inline-block-transform.html b/third_party/WebKit/LayoutTests/virtual/threaded/animations/inline-block-transform.html new file mode 100644 index 0000000..cb7efc3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/threaded/animations/inline-block-transform.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id=target style="display:inline-block"></div> +<script> +var test = async_test('inline-block should run compositor animations'); +var anim = target.animate({transform: ['rotate(0deg)', 'rotate(180deg)']}, 100000); +anim.ready.then(() => { + test.step(() => assert_true(internals.isCompositedAnimation(anim))); + test.done(); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index ff3cd52d..1c761a13 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -451,8 +451,21 @@ [Worker] getter height [Worker] getter width [Worker] method constructor +[Worker] method getContext [Worker] setter height [Worker] setter width +[Worker] interface OffscreenCanvasRenderingContext2D +[Worker] getter offscreenCanvas +[Worker] method arc +[Worker] method arcTo +[Worker] method bezierCurveTo +[Worker] method closePath +[Worker] method constructor +[Worker] method ellipse +[Worker] method lineTo +[Worker] method moveTo +[Worker] method quadraticCurveTo +[Worker] method rect [Worker] interface PerformanceObserverEntryList [Worker] method constructor [Worker] method getEntries
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index db02c2af..204bbd11 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3696,8 +3696,21 @@ getter height getter width method constructor + method getContext setter height setter width +interface OffscreenCanvasRenderingContext2D + getter offscreenCanvas + method arc + method arcTo + method bezierCurveTo + method closePath + method constructor + method ellipse + method lineTo + method moveTo + method quadraticCurveTo + method rect interface Option method constructor interface OscillatorNode : AudioSourceNode
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 389dc39..2893e6f 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -439,8 +439,21 @@ [Worker] getter height [Worker] getter width [Worker] method constructor +[Worker] method getContext [Worker] setter height [Worker] setter width +[Worker] interface OffscreenCanvasRenderingContext2D +[Worker] getter offscreenCanvas +[Worker] method arc +[Worker] method arcTo +[Worker] method bezierCurveTo +[Worker] method closePath +[Worker] method constructor +[Worker] method ellipse +[Worker] method lineTo +[Worker] method moveTo +[Worker] method quadraticCurveTo +[Worker] method rect [Worker] interface PerformanceObserverEntryList [Worker] method constructor [Worker] method getEntries
diff --git a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp index 49ddfe5..a76e6d0 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
@@ -12,7 +12,6 @@ #include "bindings/core/v8/V8BindingForTesting.h" #include "bindings/core/v8/V8BindingMacros.h" #include "bindings/core/v8/V8IteratorResultValue.h" -#include "bindings/core/v8/V8RecursionScope.h" #include "bindings/core/v8/V8ThrowException.h" #include "core/dom/Document.h" #include "core/streams/ReadableStreamController.h" @@ -139,7 +138,7 @@ ~ReadableStreamOperationsTest() override { // Execute all pending microtasks - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(m_block.HasCaught()); } @@ -150,7 +149,6 @@ { v8::Local<v8::String> source; v8::Local<v8::Script> script; - V8RecursionScope::MicrotaskSuppression microtasks(isolate()); if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) { ADD_FAILURE(); return ScriptValue(); @@ -255,12 +253,12 @@ Function::createFunction(scriptState(), it2), NotReached::createFunction(scriptState())); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(it1->isSet()); EXPECT_FALSE(it2->isSet()); ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(it1->isSet()); EXPECT_TRUE(it1->isValid()); EXPECT_FALSE(it1->isDone()); @@ -268,7 +266,7 @@ EXPECT_FALSE(it2->isSet()); ASSERT_FALSE(evalWithPrintingError("controller.close()").isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(it1->isSet()); EXPECT_TRUE(it1->isValid()); EXPECT_FALSE(it1->isDone()); @@ -311,7 +309,7 @@ ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it2), NotReached::createFunction(scriptState())); ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it3), NotReached::createFunction(scriptState())); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(10, underlyingSource->desiredSize()); @@ -328,7 +326,7 @@ EXPECT_FALSE(it3->isSet()); underlyingSource->close(); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(it3->isSet()); EXPECT_TRUE(it3->isValid());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp index f6601dd3..34f2d7ca 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
@@ -281,7 +281,7 @@ property()->resolve(value); EXPECT_EQ(Property::Resolved, property()->getState()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nResolveCalls); EXPECT_EQ(1u, nOtherResolveCalls); EXPECT_EQ(wrap(mainWorld(), value), actual); @@ -307,7 +307,7 @@ property()->resolve(value); EXPECT_EQ(Property::Resolved, property()->getState()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nResolveCalls); EXPECT_EQ(0u, nOtherResolveCalls); @@ -316,7 +316,7 @@ otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState())); } - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nResolveCalls); EXPECT_EQ(1u, nOtherResolveCalls); EXPECT_EQ(wrap(mainWorld(), value), actual); @@ -343,7 +343,7 @@ property()->promise(otherWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), otherActual, nOtherRejectCalls)); } - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nRejectCalls); EXPECT_EQ(wrap(mainWorld(), reason), actual); EXPECT_EQ(1u, nOtherRejectCalls); @@ -374,7 +374,7 @@ property()->resolve(new GarbageCollectedScriptWrappable("value")); EXPECT_EQ(Property::Pending, property()->getState()); - v8::MicrotasksScope::PerformCheckpoint(v8::Isolate::GetCurrent()); + v8::Isolate::GetCurrent()->RunMicrotasks(); } TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset) @@ -405,7 +405,7 @@ EXPECT_EQ(0u, nOldResolveCalls); EXPECT_EQ(0u, nNewRejectCalls); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nOldResolveCalls); EXPECT_EQ(1u, nNewRejectCalls); EXPECT_NE(oldPromise, newPromise); @@ -445,7 +445,7 @@ property()->resolve(value.get()); EXPECT_EQ(Property::Resolved, property()->getState()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nResolveCalls); EXPECT_EQ(wrap(mainWorld(), value), actual); } @@ -464,7 +464,7 @@ property()->reject(reason); EXPECT_EQ(Property::Rejected, property()->getState()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(1u, nRejectCalls); EXPECT_EQ(wrap(mainWorld(), reason), actual); } @@ -514,7 +514,7 @@ property->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actualValue, nResolveCalls), notReached(currentScriptState())); } property->resolve(value); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); { ScriptState::Scope scope(mainScriptState()); actual = toCoreString(actualValue.v8Value()->ToString(mainScriptState()->context()).ToLocalChecked());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp index 1c946d9..b6cf586 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
@@ -60,7 +60,7 @@ createClosure(callback, v8::Undefined(isolate()), isolate()); // Execute all pending microtasks - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); } OwnPtr<DummyPageHolder> m_pageHolder; @@ -96,7 +96,7 @@ EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); @@ -111,14 +111,14 @@ EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("hello", onFulfilled); EXPECT_EQ(String(), onRejected); resolver->resolve("bye"); resolver->reject("bye"); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("hello", onFulfilled); EXPECT_EQ(String(), onRejected); @@ -144,7 +144,7 @@ EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); @@ -159,14 +159,14 @@ EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ("hello", onRejected); resolver->resolve("bye"); resolver->reject("bye"); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ("hello", onRejected); @@ -196,7 +196,7 @@ } resolver->resolve("hello"); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); @@ -321,7 +321,7 @@ } resolver->resolve(); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onFulfilled); EXPECT_EQ(String(), onRejected); @@ -345,7 +345,7 @@ } resolver->reject(); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ("undefined", onRejected);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp index 01d144e..5c3fec7 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
@@ -83,7 +83,7 @@ createClosure(callback, v8::Undefined(m_scope.isolate()), m_scope.isolate()); // Execute all pending microtasks - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); } String toString(const ScriptValue& value) @@ -124,13 +124,13 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); resolver.resolve(v8String(isolate(), "hello")); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("hello", toString(onFulfilled)); EXPECT_TRUE(onRejected.isEmpty()); @@ -148,7 +148,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("hello", toString(onFulfilled)); EXPECT_TRUE(onRejected.isEmpty()); @@ -165,13 +165,13 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); resolver.reject(v8String(isolate(), "hello")); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_EQ("hello", toString(onRejected)); @@ -189,7 +189,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_EQ("hello", toString(onRejected)); @@ -226,7 +226,7 @@ EXPECT_TRUE(onRejected1.isEmpty()); EXPECT_TRUE(onRejected2.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("hello", toString(onFulfilled1)); EXPECT_EQ("hello", toString(onFulfilled2)); @@ -248,7 +248,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_EQ("hello", toString(onRejected)); @@ -264,7 +264,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_EQ("SyntaxError: some syntax error", toString(onRejected)); @@ -282,7 +282,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(onFulfilled.isEmpty()); EXPECT_TRUE(toStringArray(onFulfilled).isEmpty()); @@ -304,7 +304,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(onFulfilled.isEmpty()); Vector<String> values = toStringArray(onFulfilled); @@ -329,7 +329,7 @@ EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_TRUE(onRejected.isEmpty()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isEmpty()); EXPECT_FALSE(onRejected.isEmpty());
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp index f0a8dfd..bafc93d7 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -321,7 +321,7 @@ v8::Debug::SetLiveEditEnabled(isolate, false); - isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped); + isolate->SetAutorunMicrotasks(false); } namespace { @@ -351,15 +351,10 @@ } // namespace -void V8Initializer::initializeMainThreadIfNeeded() +void V8Initializer::initializeMainThread() { ASSERT(isMainThread()); - static bool initialized = false; - if (initialized) - return; - initialized = true; - DEFINE_STATIC_LOCAL(ArrayBufferAllocator, arrayBufferAllocator, ()); auto v8ExtrasMode = RuntimeEnabledFeatures::experimentalV8ExtrasEnabled() ? gin::IsolateHolder::kStableAndExperimentalV8Extras : gin::IsolateHolder::kStableV8Extras; gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, v8ExtrasMode, &arrayBufferAllocator); @@ -384,6 +379,14 @@ profiler->SetWrapperClassInfoProvider(WrapperTypeInfo::NodeClassId, &RetainedDOMInfo::createRetainedDOMInfo); } +void V8Initializer::shutdownMainThread() +{ + ASSERT(isMainThread()); + v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); + V8PerIsolateData::willBeDestroyed(isolate); + V8PerIsolateData::destroy(isolate); +} + static void reportFatalErrorInWorker(const char* location, const char* message) { // FIXME: We temporarily deal with V8 internal error situations such as out-of-memory by crashing the worker.
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.h b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.h index c17256d..7fe4bbf 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.h
@@ -35,7 +35,8 @@ class CORE_EXPORT V8Initializer { STATIC_ONLY(V8Initializer); public: - static void initializeMainThreadIfNeeded(); + static void initializeMainThread(); + static void shutdownMainThread(); static void initializeWorker(v8::Isolate*); static void reportRejectedPromisesOnMainThread();
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp index 65c02bc..0a2cfcb9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -30,6 +30,7 @@ #include "bindings/core/v8/V8Binding.h" #include "bindings/core/v8/V8HiddenValue.h" #include "bindings/core/v8/V8ObjectConstructor.h" +#include "bindings/core/v8/V8RecursionScope.h" #include "bindings/core/v8/V8ScriptRunner.h" #include "core/frame/Deprecation.h" #include "core/inspector/MainThreadDebugger.h" @@ -52,6 +53,18 @@ V8PerIsolateData::from(isolate)->runEndOfScopeTasks(); } +#if ENABLE(ASSERT) +static void assertV8RecursionScope(v8::Isolate* isolate) +{ + ASSERT(V8RecursionScope::properlyUsed(isolate)); +} + +static bool runningUnitTest() +{ + return Platform::current()->unitTestSupport(); +} +#endif + static void useCounterCallback(v8::Isolate* isolate, v8::Isolate::UseCounterFeature feature) { UseCounter::Feature blinkFeature; @@ -130,15 +143,25 @@ } V8PerIsolateData::V8PerIsolateData() - : m_isolateHolder(adoptPtr(new gin::IsolateHolder())) + : m_destructionPending(false) + , m_isolateHolder(adoptPtr(new gin::IsolateHolder())) , m_stringCache(adoptPtr(new StringCache(isolate()))) , m_hiddenValue(V8HiddenValue::create()) , m_constructorMode(ConstructorMode::CreateNewObject) + , m_recursionLevel(0) , m_isHandlingRecursionLevelError(false) , m_isReportingException(false) +#if ENABLE(ASSERT) + , m_internalScriptRecursionLevel(0) +#endif + , m_performingMicrotaskCheckpoint(false) { // FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone. isolate()->Enter(); +#if ENABLE(ASSERT) + if (!runningUnitTest()) + isolate()->AddCallCompletedCallback(&assertV8RecursionScope); +#endif isolate()->AddBeforeCallEnteredCallback(&beforeCallEnteredCallback); isolate()->AddMicrotasksCompletedCallback(µtasksCompletedCallback); if (isMainThread()) @@ -183,6 +206,9 @@ { V8PerIsolateData* data = from(isolate); + ASSERT(!data->m_destructionPending); + data->m_destructionPending = true; + data->m_threadDebugger.clear(); // Clear any data that may have handles into the heap, // prior to calling ThreadState::detach(). @@ -193,6 +219,10 @@ // gets called but before the Isolate exits. void V8PerIsolateData::destroy(v8::Isolate* isolate) { +#if ENABLE(ASSERT) + if (!runningUnitTest()) + isolate->RemoveCallCompletedCallback(&assertV8RecursionScope); +#endif isolate->RemoveBeforeCallEnteredCallback(&beforeCallEnteredCallback); isolate->RemoveMicrotasksCompletedCallback(µtasksCompletedCallback); V8PerIsolateData* data = from(isolate);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h index 33ed8dc8..5d709e736 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
@@ -74,18 +74,31 @@ static void enableIdleTasks(v8::Isolate*, PassOwnPtr<gin::V8IdleTaskRunner>); + bool destructionPending() const { return m_destructionPending; } v8::Isolate* isolate() { return m_isolateHolder->isolate(); } StringCache* stringCache() { return m_stringCache.get(); } v8::Persistent<v8::Value>& ensureLiveRoot(); + int recursionLevel() const { return m_recursionLevel; } + int incrementRecursionLevel() { return ++m_recursionLevel; } + int decrementRecursionLevel() { return --m_recursionLevel; } bool isHandlingRecursionLevelError() const { return m_isHandlingRecursionLevelError; } void setIsHandlingRecursionLevelError(bool value) { m_isHandlingRecursionLevelError = value; } bool isReportingException() const { return m_isReportingException; } void setReportingException(bool value) { m_isReportingException = value; } + bool performingMicrotaskCheckpoint() const { return m_performingMicrotaskCheckpoint; } + void setPerformingMicrotaskCheckpoint(bool performingMicrotaskCheckpoint) { m_performingMicrotaskCheckpoint = performingMicrotaskCheckpoint; } + +#if ENABLE(ASSERT) + int internalScriptRecursionLevel() const { return m_internalScriptRecursionLevel; } + int incrementInternalScriptRecursionLevel() { return ++m_internalScriptRecursionLevel; } + int decrementInternalScriptRecursionLevel() { return --m_internalScriptRecursionLevel; } +#endif + V8HiddenValue* hiddenValue() { return m_hiddenValue.get(); } v8::Local<v8::FunctionTemplate> domTemplate(const void* domTemplateKey, v8::FunctionCallback = 0, v8::Local<v8::Value> data = v8::Local<v8::Value>(), v8::Local<v8::Signature> = v8::Local<v8::Signature>(), int length = 0); @@ -118,6 +131,7 @@ bool hasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value>, DOMTemplateMap&); v8::Local<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Local<v8::Value>, DOMTemplateMap&); + bool m_destructionPending; OwnPtr<gin::IsolateHolder> m_isolateHolder; DOMTemplateMap m_domTemplateMapForMainWorld; DOMTemplateMap m_domTemplateMapForNonMainWorld; @@ -129,9 +143,15 @@ bool m_constructorMode; friend class ConstructorMode; + int m_recursionLevel; bool m_isHandlingRecursionLevelError; bool m_isReportingException; +#if ENABLE(ASSERT) + int m_internalScriptRecursionLevel; +#endif + bool m_performingMicrotaskCheckpoint; + Vector<OwnPtr<EndOfScopeTask>> m_endOfScopeTasks; OwnPtr<ThreadDebugger> m_threadDebugger; };
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp index b4c3acf7..ed10e86 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
@@ -30,6 +30,13 @@ #include "bindings/core/v8/V8RecursionScope.h" +#include "core/dom/Microtask.h" + namespace blink { +void V8RecursionScope::didLeaveScriptContext() +{ + Microtask::performCheckpoint(m_isolate); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h index 8bbd26c..dd9a51f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
@@ -59,39 +59,63 @@ STACK_ALLOCATED(); public: explicit V8RecursionScope(v8::Isolate* isolate) - : m_scope(isolate, v8::MicrotasksScope::kRunMicrotasks) + : m_isolate(isolate) { - ASSERT(isolate->GetMicrotasksPolicy() == v8::MicrotasksPolicy::kScoped); + V8PerIsolateData::from(m_isolate)->incrementRecursionLevel(); + // If you want V8 to autorun microtasks, this class needs to have a + // v8::Isolate::SuppressMicrotaskExecutionScope member. + ASSERT(!isolate->WillAutorunMicrotasks()); } ~V8RecursionScope() { + if (!V8PerIsolateData::from(m_isolate)->decrementRecursionLevel()) + didLeaveScriptContext(); } static int recursionLevel(v8::Isolate* isolate) { - return v8::MicrotasksScope::GetCurrentDepth(isolate); + return V8PerIsolateData::from(isolate)->recursionLevel(); } +#if ENABLE(ASSERT) + static bool properlyUsed(v8::Isolate* isolate) + { + return recursionLevel(isolate) > 0 || V8PerIsolateData::from(isolate)->internalScriptRecursionLevel() > 0; + } +#endif + class MicrotaskSuppression { USING_FAST_MALLOC(MicrotaskSuppression); WTF_MAKE_NONCOPYABLE(MicrotaskSuppression); public: - explicit MicrotaskSuppression(v8::Isolate* isolate) - : m_scope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks) + MicrotaskSuppression(v8::Isolate* isolate) +#if ENABLE(ASSERT) + : m_isolate(isolate) +#endif { +#if ENABLE(ASSERT) + V8PerIsolateData::from(m_isolate)->incrementInternalScriptRecursionLevel(); +#endif } ~MicrotaskSuppression() { +#if ENABLE(ASSERT) + V8PerIsolateData::from(m_isolate)->decrementInternalScriptRecursionLevel(); +#endif } private: - v8::MicrotasksScope m_scope; +#if ENABLE(ASSERT) + v8::Isolate* m_isolate; +#endif }; private: - v8::MicrotasksScope m_scope; + void didLeaveScriptContext(); + + v8::Isolate* m_isolate; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp index 221fe6bc..ba39698 100644 --- a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp +++ b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
@@ -254,7 +254,7 @@ return false; if (isTransformRelatedCSSProperty(property)) { - if (targetElement.layoutObject() && targetElement.layoutObject()->isInline()) { + if (targetElement.layoutObject() && targetElement.layoutObject()->isInline() && !targetElement.layoutObject()->isInlineBlockOrInlineTable()) { return false; } transformPropertyCount++;
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index ebc628c8..ce975660 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -242,7 +242,6 @@ 'html/TimeRanges.idl', 'html/ValidityState.idl', 'html/VoidCallback.idl', - 'html/canvas/OffscreenCanvas.idl', 'html/track/AudioTrack.idl', 'html/track/AudioTrackList.idl', 'html/track/TextTrack.idl', @@ -806,6 +805,7 @@ 'style/StyleBoxData.cpp', 'style/StyleContentAlignmentData.h', 'style/StyleDeprecatedFlexibleBoxData.cpp', + 'style/StyleImage.cpp', 'style/StyleFetchedImage.cpp', 'style/StyleFetchedImageSet.cpp', 'style/StyleFilterData.cpp', @@ -1528,8 +1528,6 @@ 'editing/commands/SplitTextNodeCommand.h', 'editing/commands/SplitTextNodeContainingElementCommand.cpp', 'editing/commands/SplitTextNodeContainingElementCommand.h', - 'editing/commands/TextInsertionBaseCommand.cpp', - 'editing/commands/TextInsertionBaseCommand.h', 'editing/commands/TypingCommand.cpp', 'editing/commands/TypingCommand.h', 'editing/commands/UndoStack.cpp', @@ -2986,8 +2984,6 @@ 'html/canvas/CanvasRenderingContext.cpp', 'html/canvas/CanvasRenderingContext.h', 'html/canvas/CanvasRenderingContextFactory.h', - 'html/canvas/OffscreenCanvas.cpp', - 'html/canvas/OffscreenCanvas.h', 'html/forms/BaseButtonInputType.cpp', 'html/forms/BaseButtonInputType.h', 'html/forms/BaseCheckableInputType.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp index 426c6b5..c657f2b 100644 --- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
@@ -159,7 +159,7 @@ return CSSCrossfadeValue::create(fromValue.release(), toValue.release(), m_percentageValue); } -IntSize CSSCrossfadeValue::fixedSize(const LayoutObject* layoutObject) +IntSize CSSCrossfadeValue::fixedSize(const LayoutObject* layoutObject, const FloatSize& defaultObjectSize) { Image* fromImage = renderableImageForCSSValue(m_fromValue.get(), layoutObject); Image* toImage = renderableImageForCSSValue(m_toValue.get(), layoutObject); @@ -170,6 +170,12 @@ IntSize fromImageSize = fromImage->size(); IntSize toImageSize = toImage->size(); + if (fromImage->isSVGImage()) + fromImageSize = roundedIntSize(toSVGImage(fromImage)->concreteObjectSize(defaultObjectSize)); + + if (toImage->isSVGImage()) + toImageSize = roundedIntSize(toSVGImage(toImage)->concreteObjectSize(defaultObjectSize)); + // Rounding issues can cause transitions between images of equal size to return // a different fixed size; avoid performing the interpolation if the images are the same size. if (fromImageSize == toImageSize) @@ -237,7 +243,7 @@ if (toImage->isSVGImage()) toImageRef = SVGImageForContainer::create(toSVGImage(toImage), size, 1, urlForCSSValue(m_toValue.get())); - m_generatedImage = CrossfadeGeneratedImage::create(fromImageRef, toImageRef, m_percentageValue->getFloatValue(), fixedSize(layoutObject), size); + m_generatedImage = CrossfadeGeneratedImage::create(fromImageRef, toImageRef, m_percentageValue->getFloatValue(), fixedSize(layoutObject, FloatSize(size)), size); return m_generatedImage.release(); }
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h index 0a3a9d6..4ecacbe 100644 --- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h +++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
@@ -54,7 +54,7 @@ PassRefPtr<Image> image(const LayoutObject*, const IntSize&); bool isFixedSize() const { return true; } - IntSize fixedSize(const LayoutObject*); + IntSize fixedSize(const LayoutObject*, const FloatSize&); bool isPending() const; bool knownToBeOpaque(const LayoutObject*) const;
diff --git a/third_party/WebKit/Source/core/css/CSSFontSelector.cpp b/third_party/WebKit/Source/core/css/CSSFontSelector.cpp index 7c432eb..65b0d4d 100644 --- a/third_party/WebKit/Source/core/css/CSSFontSelector.cpp +++ b/third_party/WebKit/Source/core/css/CSSFontSelector.cpp
@@ -176,8 +176,7 @@ if (!document.settings()) return; m_genericFontFamilySettings = document.settings()->genericFontFamilySettings(); - // Need to increment FontFaceCache version to update ComputedStyles. - m_fontFaceCache.incrementVersion(); + fontCacheInvalidated(); } DEFINE_TRACE(CSSFontSelector)
diff --git a/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp b/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp index df434dd..e1bf097 100644 --- a/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
@@ -155,11 +155,11 @@ return false; } -IntSize CSSImageGeneratorValue::fixedSize(const LayoutObject* layoutObject) +IntSize CSSImageGeneratorValue::fixedSize(const LayoutObject* layoutObject, const FloatSize& defaultObjectSize) { switch (getClassType()) { case CrossfadeClass: - return toCSSCrossfadeValue(this)->fixedSize(layoutObject); + return toCSSCrossfadeValue(this)->fixedSize(layoutObject, defaultObjectSize); case LinearGradientClass: return toCSSLinearGradientValue(this)->fixedSize(layoutObject); case RadialGradientClass:
diff --git a/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h b/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h index f286127..0291834 100644 --- a/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h +++ b/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h
@@ -37,6 +37,7 @@ class Document; class Image; class LayoutObject; +class FloatSize; struct SizeAndCount { DISALLOW_NEW(); @@ -61,7 +62,7 @@ PassRefPtr<Image> image(const LayoutObject*, const IntSize&); bool isFixedSize() const; - IntSize fixedSize(const LayoutObject*); + IntSize fixedSize(const LayoutObject*, const FloatSize& defaultObjectSize); bool isPending() const; bool knownToBeOpaque(const LayoutObject*) const;
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp index 7596bafd..8f8cf72 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp +++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -60,6 +60,8 @@ continue; m_needToExpandAll = true; } + if (property.id() < firstCSSProperty || property.id() > lastCSSProperty) + continue; m_longhandPropertyUsed.set(property.id() - firstCSSProperty); } } @@ -105,6 +107,8 @@ StylePropertySet::PropertyReference property = m_propertySet->propertyAt(index); if (property.id() == CSSPropertyAll || !CSSProperty::isAffectedByAllProperty(property.id())) return true; + if (property.id() < firstCSSProperty || property.id() > lastCSSProperty) + return false; return m_longhandPropertyUsed.get(property.id() - firstCSSProperty); }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index c1c015f..6e57c22 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -4560,6 +4560,93 @@ return true; } +// Note: consumeBackgroundShorthand assumes y properties (for example background-position-y) follow +// the x properties in the shorthand array. +bool CSSPropertyParser::consumeBackgroundShorthand(const StylePropertyShorthand& shorthand, bool important) +{ + const unsigned longhandCount = shorthand.length(); + RefPtrWillBeRawPtr<CSSValue> longhands[10]; + ASSERT(longhandCount <= 10); +#if ENABLE(OILPAN) + // Zero initialize the array of raw pointers. + memset(&longhands, 0, sizeof(longhands)); +#endif + bool implicit = false; + do { + bool parsedLonghand[10] = { false }; + RefPtrWillBeRawPtr<CSSValue> originValue = nullptr; + do { + bool foundProperty = false; + for (size_t i = 0; i < longhandCount; ++i) { + if (parsedLonghand[i]) + continue; + + RefPtrWillBeRawPtr<CSSValue> value = nullptr; + RefPtrWillBeRawPtr<CSSValue> valueY = nullptr; + CSSPropertyID property = shorthand.properties()[i]; + if (property == CSSPropertyBackgroundRepeatX || property == CSSPropertyWebkitMaskRepeatX) { + consumeRepeatStyleComponent(m_range, value, valueY, implicit); + } else if (property == CSSPropertyBackgroundPositionX || property == CSSPropertyWebkitMaskPositionX) { + CSSParserTokenRange rangeCopy = m_range; + if (!consumePosition(rangeCopy, m_context.mode(), UnitlessQuirk::Forbid, value, valueY)) + continue; + m_range = rangeCopy; + } else if (property == CSSPropertyBackgroundSize || property == CSSPropertyWebkitMaskSize) { + if (!consumeSlashIncludingWhitespace(m_range)) + continue; + value = consumeBackgroundSize(property, m_range, m_context.mode()); + if (!value || !parsedLonghand[i - 1]) // Position must have been parsed in the current layer. + return false; + } else if (property == CSSPropertyBackgroundPositionY || property == CSSPropertyBackgroundRepeatY + || property == CSSPropertyWebkitMaskPositionY || property == CSSPropertyWebkitMaskRepeatY) { + continue; + } else { + value = consumeBackgroundComponent(property, m_range, m_context); + } + if (value) { + if (property == CSSPropertyBackgroundOrigin || property == CSSPropertyWebkitMaskOrigin) + originValue = value; + parsedLonghand[i] = true; + foundProperty = true; + addBackgroundValue(longhands[i], value.release()); + if (valueY) { + parsedLonghand[i + 1] = true; + addBackgroundValue(longhands[i + 1], valueY.release()); + } + } + } + if (!foundProperty) + return false; + } while (!m_range.atEnd() && m_range.peek().type() != CommaToken); + + // TODO(timloh): This will make invalid longhands, see crbug.com/386459 + for (size_t i = 0; i < longhandCount; ++i) { + CSSPropertyID property = shorthand.properties()[i]; + if (property == CSSPropertyBackgroundColor && !m_range.atEnd()) { + if (parsedLonghand[i]) + return false; // Colors are only allowed in the last layer. + continue; + } + if ((property == CSSPropertyBackgroundClip || property == CSSPropertyWebkitMaskClip) && !parsedLonghand[i] && originValue) { + addBackgroundValue(longhands[i], originValue.release()); + continue; + } + if (!parsedLonghand[i]) + addBackgroundValue(longhands[i], cssValuePool().createImplicitInitialValue()); + } + } while (consumeCommaIncludingWhitespace(m_range)); + if (!m_range.atEnd()) + return false; + + for (size_t i = 0; i < longhandCount; ++i) { + CSSPropertyID property = shorthand.properties()[i]; + if (property == CSSPropertyBackgroundSize && longhands[i] && m_context.useLegacyBackgroundSizeShorthandBehavior()) + continue; + addProperty(property, longhands[i].release(), important, implicit); + } + return true; +} + bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important) { CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); @@ -4722,6 +4809,10 @@ addProperty(property == CSSPropertyBackgroundRepeat ? CSSPropertyBackgroundRepeatY : CSSPropertyWebkitMaskRepeatY, resultY.release(), important, implicit); return true; } + case CSSPropertyBackground: + return consumeBackgroundShorthand(backgroundShorthand(), important); + case CSSPropertyWebkitMask: + return consumeBackgroundShorthand(webkitMaskShorthand(), important); default: m_currentShorthand = oldShorthand; CSSParserValueList valueList(m_range);
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h index 63148814..82c214f 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -154,6 +154,7 @@ // Legacy parsing allows <string>s for animation-name bool consumeAnimationShorthand(const StylePropertyShorthand&, bool useLegacyParsing, bool important); + bool consumeBackgroundShorthand(const StylePropertyShorthand&, bool important); bool consumeColumns(bool important);
diff --git a/third_party/WebKit/Source/core/css/parser/CSSVariableParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSVariableParser.cpp index a54302e..f75d27d 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSVariableParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSVariableParser.cpp
@@ -48,10 +48,14 @@ const CSSParserToken& token = range.consume(); switch (token.type()) { case AtKeywordToken: { - // This might have false positives if the @apply doesn't actually match - // the syntax, but that just means we do extra computation work. - if (token.valueEqualsIgnoringASCIICase("apply")) + if (token.valueEqualsIgnoringASCIICase("apply")) { + range.consumeWhitespace(); + const CSSParserToken& variableName = range.consumeIncludingWhitespace(); + if (!CSSVariableParser::isValidVariableName(variableName) + || !(range.atEnd() || range.peek().type() == SemicolonToken || range.peek().type() == RightBraceToken)) + return false; hasReferences = true; + } break; } case DelimiterToken: {
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp index bc966ffb..2535a38 100644 --- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -362,20 +362,6 @@ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); return parseGridShorthand(important); - case CSSPropertyBackground: { - // Position must come before color in this array because a plain old "0" is a legal color - // in quirks mode but it's usually the X coordinate of a position. - const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, - CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin, - CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize }; - return parseFillShorthand(propertyID, properties, WTF_ARRAY_LENGTH(properties), important); - } - case CSSPropertyWebkitMask: { - const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, - CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize }; - return parseFillShorthand(propertyID, properties, WTF_ARRAY_LENGTH(properties), important); - } - // The remaining shorthands are handled in CSSPropertyParser.cpp default: return false;
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp index 135aa41..936cb2d 100644 --- a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp +++ b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
@@ -15,7 +15,6 @@ #include "core/css/parser/CSSParserTokenRange.h" #include "core/css/parser/CSSParserValues.h" #include "core/css/parser/CSSPropertyParser.h" -#include "core/css/parser/CSSVariableParser.h" #include "core/css/resolver/StyleBuilder.h" #include "core/css/resolver/StyleResolverState.h" #include "core/style/StyleVariableData.h" @@ -92,16 +91,9 @@ Vector<CSSParserToken>& result) { ASSERT(range.peek().type() == AtKeywordToken && range.peek().valueEqualsIgnoringASCIICase("apply")); - CSSParserTokenRange originalRange = range; - range.consumeIncludingWhitespace(); const CSSParserToken& variableName = range.consumeIncludingWhitespace(); - if (!CSSVariableParser::isValidVariableName(variableName) - || !(range.atEnd() || range.peek().type() == SemicolonToken || range.peek().type() == RightBraceToken)) { - range = originalRange; - result.append(range.consume()); - return; - } + // TODO(timloh): Should we actually be consuming this? if (range.peek().type() == SemicolonToken) range.consume();
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp index 94afd0d..1dc3583e 100644 --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -327,7 +327,7 @@ treeScope().adoptIfNeeded(*newChild); insertBeforeCommon(nextChild, *newChild); - newChild->updateAncestorConnectedSubframeCountForInsertion(); + ASSERT(newChild->connectedSubframeCount() == 0); ChildListMutationScope(*this).childAdded(*newChild); } @@ -807,7 +807,7 @@ treeScope().adoptIfNeeded(*newChild); appendChildCommon(*newChild); - newChild->updateAncestorConnectedSubframeCountForInsertion(); + ASSERT(newChild->connectedSubframeCount() == 0); ChildListMutationScope(*this).childAdded(*newChild); }
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 81263fb2..a1cf59d 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -3440,7 +3440,6 @@ void Document::setSelectedStylesheetSet(const String& aString) { styleEngine().setSelectedStylesheetSetName(aString); - styleEngine().resolverChanged(FullStyleUpdate); } void Document::evaluateMediaQueryListIfNeeded()
diff --git a/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp b/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp index 8de17ce..028b48bc 100644 --- a/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -62,8 +62,8 @@ if (candidate.isEnabledAndLoading()) { // it is loading but we should still decide which style sheet set to use - if (candidate.hasPreferrableName(engine.preferredStylesheetSetName())) - engine.selectStylesheetSetName(candidate.title()); + if (candidate.hasPreferrableName()) + engine.setPreferredStylesheetSetNameIfNotSet(candidate.title()); continue; } @@ -71,8 +71,8 @@ if (!sheet) continue; - if (candidate.hasPreferrableName(engine.preferredStylesheetSetName())) - engine.selectStylesheetSetName(candidate.title()); + if (candidate.hasPreferrableName()) + engine.setPreferredStylesheetSetNameIfNotSet(candidate.title()); collector.appendSheetForList(sheet); if (candidate.canBeActivated(engine.preferredStylesheetSetName())) collector.appendActiveStyleSheet(toCSSStyleSheet(sheet));
diff --git a/third_party/WebKit/Source/core/dom/Microtask.cpp b/third_party/WebKit/Source/core/dom/Microtask.cpp index 344c9e01..7c3ec6ed 100644 --- a/third_party/WebKit/Source/core/dom/Microtask.cpp +++ b/third_party/WebKit/Source/core/dom/Microtask.cpp
@@ -40,9 +40,13 @@ void Microtask::performCheckpoint(v8::Isolate* isolate) { - if (ScriptForbiddenScope::isScriptForbidden()) + V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate); + ASSERT(isolateData); + if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint() || isolateData->destructionPending() || ScriptForbiddenScope::isScriptForbidden()) return; - v8::MicrotasksScope::PerformCheckpoint(isolate); + isolateData->setPerformingMicrotaskCheckpoint(true); + isolate->RunMicrotasks(); + isolateData->setPerformingMicrotaskCheckpoint(false); } static void microtaskFunctionCallback(void* data)
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp index a9c7a70..604f1c7 100644 --- a/third_party/WebKit/Source/core/dom/Node.cpp +++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2234,27 +2234,15 @@ return hasRareData() ? rareData()->connectedSubframeCount() : 0; } -void Node::incrementConnectedSubframeCount(unsigned amount) +void Node::incrementConnectedSubframeCount() { ASSERT(isContainerNode()); - ensureRareData().incrementConnectedSubframeCount(amount); + ensureRareData().incrementConnectedSubframeCount(); } -void Node::decrementConnectedSubframeCount(unsigned amount) +void Node::decrementConnectedSubframeCount() { - rareData()->decrementConnectedSubframeCount(amount); -} - -void Node::updateAncestorConnectedSubframeCountForInsertion() const -{ - unsigned count = connectedSubframeCount(); - - if (!count) - return; - - ScriptForbiddenScope forbidScriptDuringRawIteration; - for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode()) - node->incrementConnectedSubframeCount(count); + rareData()->decrementConnectedSubframeCount(); } PassRefPtrWillBeRawPtr<StaticNodeList> Node::getDestinationInsertionPoints()
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h index 8f3aead06f..b6749f7 100644 --- a/third_party/WebKit/Source/core/dom/Node.h +++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -665,9 +665,8 @@ void notifyMutationObserversNodeWillDetach(); unsigned connectedSubframeCount() const; - void incrementConnectedSubframeCount(unsigned amount = 1); - void decrementConnectedSubframeCount(unsigned amount = 1); - void updateAncestorConnectedSubframeCountForInsertion() const; + void incrementConnectedSubframeCount(); + void decrementConnectedSubframeCount(); PassRefPtrWillBeRawPtr<StaticNodeList> getDestinationInsertionPoints(); HTMLSlotElement* assignedSlot() const;
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.cpp b/third_party/WebKit/Source/core/dom/NodeRareData.cpp index 7ed6f61..8805a2b8 100644 --- a/third_party/WebKit/Source/core/dom/NodeRareData.cpp +++ b/third_party/WebKit/Source/core/dom/NodeRareData.cpp
@@ -73,10 +73,10 @@ this->~NodeRareData(); } -void NodeRareData::incrementConnectedSubframeCount(unsigned amount) +void NodeRareData::incrementConnectedSubframeCount() { - RELEASE_ASSERT_WITH_SECURITY_IMPLICATION((m_connectedFrameCount + amount) <= FrameHost::maxNumberOfFrames); - m_connectedFrameCount += amount; + RELEASE_ASSERT_WITH_SECURITY_IMPLICATION((m_connectedFrameCount + 1) <= FrameHost::maxNumberOfFrames); + ++m_connectedFrameCount; } // Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.h b/third_party/WebKit/Source/core/dom/NodeRareData.h index 4621a0c..3cf6e50 100644 --- a/third_party/WebKit/Source/core/dom/NodeRareData.h +++ b/third_party/WebKit/Source/core/dom/NodeRareData.h
@@ -82,12 +82,11 @@ } unsigned connectedSubframeCount() const { return m_connectedFrameCount; } - void incrementConnectedSubframeCount(unsigned amount); - void decrementConnectedSubframeCount(unsigned amount) + void incrementConnectedSubframeCount(); + void decrementConnectedSubframeCount() { ASSERT(m_connectedFrameCount); - ASSERT(amount <= m_connectedFrameCount); - m_connectedFrameCount -= amount; + --m_connectedFrameCount; } bool hasElementFlag(ElementFlags mask) const { return m_elementFlags & mask; }
diff --git a/third_party/WebKit/Source/core/dom/StyleChangeReason.cpp b/third_party/WebKit/Source/core/dom/StyleChangeReason.cpp index e3eda0fe..659990e 100644 --- a/third_party/WebKit/Source/core/dom/StyleChangeReason.cpp +++ b/third_party/WebKit/Source/core/dom/StyleChangeReason.cpp
@@ -35,6 +35,7 @@ const char SVGContainerSizeChange[] = "SVGContainerSizeChange"; const char SVGCursor[] = "SVGCursor"; const char SVGFilterLayerUpdate[] = "SVGFilterLayerUpdate"; +const char Settings[] = "Settings"; const char Shadow[] = "Shadow"; const char SiblingSelector[] = "SiblingSelector"; const char StyleInvalidator[] = "StyleInvalidator";
diff --git a/third_party/WebKit/Source/core/dom/StyleChangeReason.h b/third_party/WebKit/Source/core/dom/StyleChangeReason.h index f9ca4ebd..62414193 100644 --- a/third_party/WebKit/Source/core/dom/StyleChangeReason.h +++ b/third_party/WebKit/Source/core/dom/StyleChangeReason.h
@@ -39,6 +39,7 @@ extern const char SVGContainerSizeChange[]; extern const char SVGCursor[]; extern const char SVGFilterLayerUpdate[]; +extern const char Settings[]; extern const char Shadow[]; extern const char SiblingSelector[]; extern const char StyleInvalidator[];
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp index 284f782..62bc9c8 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp +++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -723,6 +723,38 @@ m_styleResolverStats->reset(); } +void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name) +{ + if (!m_preferredStylesheetSetName.isEmpty()) + return; + m_preferredStylesheetSetName = name; + // TODO(rune@opera.com): Setting the selected set here is wrong if the set + // has been previously set by through Document.selectedStylesheetSet. Our + // current implementation ignores the effect of Document.selectedStylesheetSet + // and either only collects persistent style, or additionally preferred + // style when present. We are currently not marking the document scope dirty + // because preferred style is updated during active stylesheet update which + // would make this method re-entrant. Will need to change for async update. + m_selectedStylesheetSetName = name; +} + +void StyleEngine::setSelectedStylesheetSetName(const String& name) +{ + m_selectedStylesheetSetName = name; + // TODO(rune@opera.com): Setting Document.selectedStylesheetSet currently + // has no other effect than the ability to read back the set value using + // the same api. If it did have an effect, we should have marked the + // document scope dirty and triggered an update of the active stylesheets + // from here. +} + +void StyleEngine::setHttpDefaultStyle(const String& content) +{ + setPreferredStylesheetSetNameIfNotSet(content); + markDocumentDirty(); + resolverChanged(FullStyleUpdate); +} + DEFINE_TRACE(StyleEngine) { #if ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.h b/third_party/WebKit/Source/core/dom/StyleEngine.h index 96d41060..b44b364 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.h +++ b/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -100,14 +100,9 @@ String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; } String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; } - void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; } - void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; } - - void selectStylesheetSetName(const String& name) - { - setPreferredStylesheetSetName(name); - setSelectedStylesheetSetName(name); - } + void setPreferredStylesheetSetNameIfNotSet(const String&); + void setSelectedStylesheetSetName(const String&); + void setHttpDefaultStyle(const String&); void addPendingSheet(); void removePendingSheet(Node* styleSheetCandidateNode);
diff --git a/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp b/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp index 4db3173b..f4e5551a 100644 --- a/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp +++ b/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp
@@ -82,10 +82,10 @@ return isHTMLLink() && !toHTMLLinkElement(node()).isDisabled() && toHTMLLinkElement(node()).styleSheetIsLoading(); } -bool StyleSheetCandidate::hasPreferrableName(const String& currentPreferrableName) const +bool StyleSheetCandidate::hasPreferrableName() const { ASSERT(isEnabledAndLoading() || sheet()); - return !isEnabledViaScript() && !title().isEmpty() && !isAlternate() && currentPreferrableName.isEmpty(); + return !isEnabledViaScript() && !title().isEmpty() && !isAlternate(); } bool StyleSheetCandidate::canBeActivated(const String& currentPreferrableName) const
diff --git a/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h b/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h index 366e30cb..7d38b71 100644 --- a/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h +++ b/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h
@@ -57,7 +57,7 @@ bool isAlternate() const; bool isEnabledViaScript() const; bool isEnabledAndLoading() const; - bool hasPreferrableName(const String& currentPreferrableName) const; + bool hasPreferrableName() const; bool canBeActivated(const String& currentPreferrableName) const; bool isCSSStyle() const;
diff --git a/third_party/WebKit/Source/core/editing/EditingTestBase.cpp b/third_party/WebKit/Source/core/editing/EditingTestBase.cpp index 825df36..13afe508 100644 --- a/third_party/WebKit/Source/core/editing/EditingTestBase.cpp +++ b/third_party/WebKit/Source/core/editing/EditingTestBase.cpp
@@ -35,20 +35,18 @@ { RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = scope.getElementById(AtomicString::fromUTF8(hostElementID))->createShadowRootInternal(ShadowRootType::V0, ASSERT_NO_EXCEPTION); shadowRoot->setInnerHTML(String::fromUTF8(shadowRootContent), ASSERT_NO_EXCEPTION); - scope.document().view()->updateAllLifecyclePhases(); return shadowRoot.release(); } void EditingTestBase::setBodyContent(const char* bodyContent) { document().body()->setInnerHTML(String::fromUTF8(bodyContent), ASSERT_NO_EXCEPTION); - updateLayoutAndStyleForPainting(); } PassRefPtrWillBeRawPtr<ShadowRoot> EditingTestBase::setShadowContent(const char* shadowContent, const char* host) { RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = createShadowRootForElementWithIDAndSetInnerHTML(document(), host, shadowContent); - updateLayoutAndStyleForPainting(); + document().updateDistribution(); return shadowRoot.release(); }
diff --git a/third_party/WebKit/Source/core/editing/PlainTextRange.cpp b/third_party/WebKit/Source/core/editing/PlainTextRange.cpp index 3fb2866..7cfb84d 100644 --- a/third_party/WebKit/Source/core/editing/PlainTextRange.cpp +++ b/third_party/WebKit/Source/core/editing/PlainTextRange.cpp
@@ -82,11 +82,6 @@ if (getRangeFor == ForSelection) behaviorFlags |= TextIteratorEmitsCharactersBetweenAllVisiblePositions; auto range = EphemeralRange::rangeOfContents(scope); - - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - scope.document().updateLayoutIgnorePendingStylesheets(); - TextIterator it(range.startPosition(), range.endPosition(), behaviorFlags); // FIXME: the atEnd() check shouldn't be necessary, workaround for
diff --git a/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.cpp deleted file mode 100644 index 4cfbda5..0000000 --- a/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.cpp +++ /dev/null
@@ -1,56 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core/editing/commands/TextInsertionBaseCommand.h" - -#include "bindings/core/v8/ExceptionStatePlaceholder.h" -#include "core/dom/Element.h" -#include "core/dom/Node.h" -#include "core/editing/FrameSelection.h" -#include "core/events/BeforeTextInsertedEvent.h" -#include "core/frame/LocalFrame.h" - -namespace blink { - -TextInsertionBaseCommand::TextInsertionBaseCommand(Document& document) - : CompositeEditCommand(document) -{ -} - -void TextInsertionBaseCommand::applyTextInsertionCommand(LocalFrame* frame, PassRefPtrWillBeRawPtr<TextInsertionBaseCommand> command, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection) -{ - bool changeSelection = !equalSelectionsInDOMTree(selectionForInsertion, endingSelection); - if (changeSelection) { - command->setStartingSelection(selectionForInsertion); - command->setEndingSelection(selectionForInsertion); - } - command->apply(); - if (changeSelection) { - command->setEndingSelection(endingSelection); - frame->selection().setSelection(endingSelection); - } -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h b/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h deleted file mode 100644 index 40c0f01c..0000000 --- a/third_party/WebKit/Source/core/editing/commands/TextInsertionBaseCommand.h +++ /dev/null
@@ -1,48 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TextInsertionBaseCommand_h -#define TextInsertionBaseCommand_h - -#include "core/editing/VisibleSelection.h" -#include "core/editing/commands/CompositeEditCommand.h" -#include "wtf/text/WTFString.h" - -namespace blink { - -class Document; - -class TextInsertionBaseCommand : public CompositeEditCommand { -public: - ~TextInsertionBaseCommand() override { } - -protected: - explicit TextInsertionBaseCommand(Document&); - static void applyTextInsertionCommand(LocalFrame*, PassRefPtrWillBeRawPtr<TextInsertionBaseCommand>, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection); -}; - -} // namespace blink - -#endif
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp index 65a3e20..38456b6d 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
@@ -48,41 +48,8 @@ using namespace HTMLNames; -class TypingCommandLineOperation { - STACK_ALLOCATED(); -public: - TypingCommandLineOperation(TypingCommand* typingCommand, bool selectInsertedText, const String& text) - : m_typingCommand(typingCommand) - , m_selectInsertedText(selectInsertedText) - , m_text(text) - { } - - void operator()(size_t lineOffset, size_t lineLength, bool isLastLine, EditingState* editingState) const - { - if (isLastLine) { - if (!lineOffset || lineLength > 0) { - m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), m_selectInsertedText, editingState); - if (editingState->isAborted()) - return; - } - } else { - if (lineLength > 0) { - m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), false, editingState); - if (editingState->isAborted()) - return; - } - m_typingCommand->insertParagraphSeparator(editingState); - } - } - -private: - RawPtrWillBeMember<TypingCommand> m_typingCommand; - bool m_selectInsertedText; - const String& m_text; -}; - TypingCommand::TypingCommand(Document& document, ETypingCommand commandType, const String &textToInsert, Options options, TextGranularity granularity, TextCompositionType compositionType) - : TextInsertionBaseCommand(document) + : CompositeEditCommand(document) , m_commandType(commandType) , m_textToInsert(textToInsert) , m_openForMoreTyping(true) @@ -222,8 +189,17 @@ return; } - RefPtrWillBeRawPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, options, compositionType); - applyTextInsertionCommand(frame.get(), cmd, selectionForInsertion, currentSelection); + RefPtrWillBeRawPtr<TypingCommand> command = TypingCommand::create(document, InsertText, newText, options, compositionType); + bool changeSelection = !equalSelectionsInDOMTree(selectionForInsertion, currentSelection); + if (changeSelection) { + command->setStartingSelection(selectionForInsertion); + command->setEndingSelection(selectionForInsertion); + } + command->apply(); + if (changeSelection) { + command->setEndingSelection(currentSelection); + frame->selection().setSelection(currentSelection); + } } bool TypingCommand::insertLineBreak(Document& document) @@ -365,37 +341,42 @@ frame->editor().appliedEditing(this); } -// LineOperation should define member function "opeartor (size_t lineOffset, size_t lineLength, bool isLastLine)". -// lienLength doesn't include the newline character. So the value of lineLength could be 0. -template <class LineOperation> -static void forEachLineInString(const String& string, const LineOperation& operation, EditingState* editingState) -{ - unsigned offset = 0; - size_t newline; - while ((newline = string.find('\n', offset)) != kNotFound) { - operation(offset, newline - offset, false, editingState); - if (editingState->isAborted()) - return; - offset = newline + 1; - } - if (!offset) { - operation(0, string.length(), true, editingState); - } else { - unsigned length = string.length(); - if (length != offset) - operation(offset, length - offset, true, editingState); - } -} - void TypingCommand::insertText(const String &text, bool selectInsertedText, EditingState* editingState) { + if (text.isEmpty()) { + insertTextRunWithoutNewlines(text, selectInsertedText, editingState); + return; + } // FIXME: Need to implement selectInsertedText for cases where more than one insert is involved. // This requires support from insertTextRunWithoutNewlines and insertParagraphSeparator for extending // an existing selection; at the moment they can either put the caret after what's inserted or // select what's inserted, but there's no way to "extend selection" to include both an old selection // that ends just before where we want to insert text and the newly inserted text. - TypingCommandLineOperation operation(this, selectInsertedText, text); - forEachLineInString(text, operation, editingState); + unsigned offset = 0; + size_t newline; + while ((newline = text.find('\n', offset)) != kNotFound) { + if (newline > offset) { + const bool notSelectInsertedText = false; + insertTextRunWithoutNewlines(text.substring(offset, newline - offset), notSelectInsertedText, editingState); + if (editingState->isAborted()) + return; + } + + insertParagraphSeparator(editingState); + if (editingState->isAborted()) + return; + + offset = newline + 1; + } + + if (!offset) { + insertTextRunWithoutNewlines(text, selectInsertedText, editingState); + return; + } + + if (text.length() > offset) + insertTextRunWithoutNewlines(text.substring(offset, text.length() - offset), selectInsertedText, editingState); + } void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText, EditingState* editingState)
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.h b/third_party/WebKit/Source/core/editing/commands/TypingCommand.h index a2fc7f7..56120ab 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.h
@@ -26,11 +26,11 @@ #ifndef TypingCommand_h #define TypingCommand_h -#include "core/editing/commands/TextInsertionBaseCommand.h" +#include "core/editing/commands/CompositeEditCommand.h" namespace blink { -class TypingCommand final : public TextInsertionBaseCommand { +class TypingCommand final : public CompositeEditCommand { public: enum ETypingCommand { DeleteSelection,
diff --git a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp index e22ad5a..f9d370e 100644 --- a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp
@@ -434,9 +434,6 @@ TextIteratorBehaviorFlags behavior = iteratorFlagsForFindPlainText; if (options & FindAPICall) behavior |= TextIteratorForWindowFind; - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - inputRange.startPosition().document()->updateLayoutIgnorePendingStylesheets(); CharacterIteratorAlgorithm<Strategy> findIterator(inputRange, behavior); matchLength = findPlainTextInternal(findIterator, target, options, matchStart); if (!matchLength)
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp index a7f1da5..3fbca07 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
@@ -146,11 +146,9 @@ { ASSERT(start.isNotNull()); ASSERT(end.isNotNull()); - - // TODO(dglazkov): TextIterator should not be created for documents that don't have a frame, - // but it currently still happens in some cases. See http://crbug.com/591877 for details. - ASSERT(!start.document()->view() || !start.document()->view()->needsLayout()); - ASSERT(!start.document()->needsLayoutTreeUpdate()); + // Updates layout here since, |Position.compareTo()| and |initialize()| + // assume layout tree is up-to-date. + start.document()->updateLayoutIgnorePendingStylesheets(); if (start.compareTo(end) > 0) { initialize(end.computeContainerNode(), end.computeOffsetInContainerNode(), start.computeContainerNode(), start.computeOffsetInContainerNode()); return; @@ -1092,10 +1090,6 @@ template<typename Strategy> int TextIteratorAlgorithm<Strategy>::rangeLength(const PositionTemplate<Strategy>& start, const PositionTemplate<Strategy>& end, bool forSelectionPreservation) { - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - start.document()->updateLayoutIgnorePendingStylesheets(); - int length = 0; TextIteratorBehaviorFlags behaviorFlags = TextIteratorEmitsObjectReplacementCharacter; if (forSelectionPreservation) @@ -1150,10 +1144,6 @@ if (range.isNull()) return emptyString(); - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - range.startPosition().document()->updateLayoutIgnorePendingStylesheets(); - TextIteratorAlgorithm<Strategy> it(range.startPosition(), range.endPosition(), behavior); if (it.atEnd())
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp index 2cc2a91a..b7211a6 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
@@ -99,11 +99,6 @@ void DocumentMarkerController::addMarker(const Position& start, const Position& end, DocumentMarker::MarkerType type, const String& description, uint32_t hash) { - - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - start.document()->updateLayoutIgnorePendingStylesheets(); - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(start, end); !markedText.atEnd(); markedText.advance()) { addMarker(markedText.currentContainer(), DocumentMarker(type, markedText.startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), description, hash)); @@ -112,10 +107,6 @@ void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch) { - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - range->startPosition().document()->updateLayoutIgnorePendingStylesheets(); - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range->startPosition(), range->endPosition()); !markedText.atEnd(); markedText.advance()) addMarker(markedText.currentContainer(), DocumentMarker(markedText.startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), activeMatch)); @@ -124,10 +115,6 @@ void DocumentMarkerController::addCompositionMarker(const Position& start, const Position& end, Color underlineColor, bool thick, Color backgroundColor) { - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - start.document()->updateLayoutIgnorePendingStylesheets(); - for (TextIterator markedText(start, end); !markedText.atEnd(); markedText.advance()) addMarker(markedText.currentContainer(), DocumentMarker(markedText.startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), underlineColor, thick, backgroundColor)); } @@ -152,10 +139,6 @@ void DocumentMarkerController::removeMarkers(const EphemeralRange& range, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker) { - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - range.startPosition().document()->updateLayoutIgnorePendingStylesheets(); - TextIterator markedText(range.startPosition(), range.endPosition()); DocumentMarkerController::removeMarkers(markedText, markerTypes, shouldRemovePartiallyOverlappingMarker); }
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp index 1ccce6f1d..ea5dd9c8 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp
@@ -236,10 +236,6 @@ String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, bool markAll) { - // TODO(dglazkov): The use of updateLayoutIgnorePendingStylesheets needs to be audited. - // see http://crbug.com/590369 for more details. - m_start.document()->updateLayoutIgnorePendingStylesheets(); - WordAwareIterator it(m_start, m_end); firstMisspellingOffset = 0;
diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp index 93a646b..b7294bf0 100644 --- a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
@@ -722,6 +722,7 @@ setChecked(!value.isNull()); m_reflectsCheckedAttribute = true; } + pseudoStateChanged(CSSSelector::PseudoDefault); } else if (name == maxlengthAttr) { parseMaxLengthAttribute(value); } else if (name == minlengthAttr) {
diff --git a/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp b/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp index 3a1b25d0..f159f098 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
@@ -216,6 +216,7 @@ } else if (name == selectedAttr) { if (oldValue.isNull() != value.isNull() && !m_isDirty) setSelected(!value.isNull()); + pseudoStateChanged(CSSSelector::PseudoDefault); } else if (name == labelAttr) { updateLabel(); } else {
diff --git a/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp b/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp index 4c602ca..89198c3 100644 --- a/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
@@ -74,8 +74,11 @@ { RefPtrWillBeRawPtr<HTMLCollection> children = rows(); int numRows = children ? (int)children->length() : 0; - if (index == -1) + if (index == -1) { + if (!numRows) + return; index = numRows - 1; + } if (index >= 0 && index < numRows) { RefPtrWillBeRawPtr<Element> row = children->item(index); HTMLElement::removeChild(row.get(), exceptionState);
diff --git a/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp index f2ad8b4..22cce6c 100644 --- a/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp +++ b/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp
@@ -168,7 +168,13 @@ } } -TEST_F(HTMLTextFormControlElementTest, WordAndSentenceBoundary) +// Flakily failing under MAC ASAN. See https://crbug.com/592880. +#if OS(MACOSX) && defined(ADDRESS_SANITIZER) +#define MAYBE_WordAndSentenceBoundary DISABLED_WordAndSentenceBoundary +#else +#define MAYBE_WordAndSentenceBoundary WordAndSentenceBoundary +#endif +TEST_F(HTMLTextFormControlElementTest, MAYBE_WordAndSentenceBoundary) { HTMLElement* innerText = textControl().innerEditorElement(); {
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLVideoElementTest.cpp index 47686fe..4a605ce 100644 --- a/third_party/WebKit/Source/core/html/HTMLVideoElementTest.cpp +++ b/third_party/WebKit/Source/core/html/HTMLVideoElementTest.cpp
@@ -46,8 +46,8 @@ double mediaTimeForTimeValue(double timeValue) const override { return timeValue; }; unsigned decodedFrameCount() const override { return 0; }; unsigned droppedFrameCount() const override { return 0; }; - unsigned audioDecodedByteCount() const override { return 0; }; - unsigned videoDecodedByteCount() const override { return 0; }; + size_t audioDecodedByteCount() const override { return 0; }; + size_t videoDecodedByteCount() const override { return 0; }; void paint(WebCanvas*, const WebRect&, unsigned char alpha, SkXfermode::Mode) override { }; };
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index 14935387..3900487 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -28,7 +28,6 @@ #include "core/CoreExport.h" #include "core/html/HTMLCanvasElement.h" -#include "platform/heap/Handle.h" #include "wtf/HashSet.h" #include "wtf/Noncopyable.h" #include "wtf/text/StringHash.h" @@ -126,7 +125,6 @@ protected: CanvasRenderingContext(HTMLCanvasElement*); DECLARE_VIRTUAL_TRACE(); - virtual void stop() = 0; private:
diff --git a/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.cpp b/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.cpp deleted file mode 100644 index c227f47..0000000 --- a/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.cpp +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/html/canvas/OffscreenCanvas.h" - -#include "wtf/MathExtras.h" - -namespace blink { - -OffscreenCanvas* OffscreenCanvas::create(unsigned width, unsigned height) -{ - return new OffscreenCanvas(IntSize(clampTo<int>(width), clampTo<int>(height))); -} - -void OffscreenCanvas::setWidth(unsigned width) -{ - m_size.setWidth(clampTo<int>(width)); -} - -void OffscreenCanvas::setHeight(unsigned height) -{ - m_size.setHeight(clampTo<int>(height)); -} - -OffscreenCanvas::OffscreenCanvas(const IntSize& size) - : m_size(size) -{ -} - -DEFINE_TRACE(OffscreenCanvas) -{ -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.h b/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.h deleted file mode 100644 index a9a14b2..0000000 --- a/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef OffscreenCanvas_h -#define OffscreenCanvas_h - -#include "bindings/core/v8/ScriptPromise.h" -#include "bindings/core/v8/ScriptState.h" -#include "bindings/core/v8/ScriptWrappable.h" -#include "core/CoreExport.h" -#include "platform/geometry/IntSize.h" -#include "platform/heap/Handle.h" - -namespace blink { - -class CORE_EXPORT OffscreenCanvas final : public GarbageCollectedFinalized<OffscreenCanvas>, public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); -public: - static OffscreenCanvas* create(unsigned width, unsigned height); - - IntSize size() const { return m_size; } - unsigned width() const { return m_size.width(); } - unsigned height() const { return m_size.height(); } - - void setWidth(unsigned); - void setHeight(unsigned); - - DECLARE_VIRTUAL_TRACE(); - -private: - OffscreenCanvas(const IntSize&); - - IntSize m_size; -}; - -} // namespace blink - -#endif // OffscreenCanvas_h
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp index 1179aa8..3ae14e61 100644 --- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp +++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -100,11 +100,13 @@ // Sends node transition events (pointer|mouse)(out|leave|over|enter) to the corresponding targets void PointerEventManager::sendNodeTransitionEvents( - PassRefPtrWillBeRawPtr<Node> exitedNode, - PassRefPtrWillBeRawPtr<Node> enteredNode, + PassRefPtrWillBeRawPtr<Node> prpExitedNode, + PassRefPtrWillBeRawPtr<Node> prpEnteredNode, const PlatformMouseEvent& mouseEvent, PassRefPtrWillBeRawPtr<AbstractView> view) { + RefPtrWillBeRawPtr<Node> exitedNode = prpExitedNode; + RefPtrWillBeRawPtr<Node> enteredNode = prpEnteredNode; RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent, nullptr, view); @@ -272,11 +274,10 @@ } } -void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<EventTarget> target, - const PlatformTouchPoint& point) +void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<EventTarget> prpTarget, const PlatformTouchPoint& point) { - RefPtrWillBeRawPtr<PointerEvent> pointerEvent = - m_pointerEventFactory.createPointerCancel(point); + RefPtrWillBeRawPtr<EventTarget> target = prpTarget; + RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.createPointerCancel(point); processPendingPointerCapture(pointerEvent, target); @@ -322,11 +323,12 @@ } WebInputEventResult PointerEventManager::sendMousePointerEvent( - PassRefPtrWillBeRawPtr<Node> target, const AtomicString& mouseEventType, + PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType, int clickCount, const PlatformMouseEvent& mouseEvent, PassRefPtrWillBeRawPtr<Node> relatedTarget, PassRefPtrWillBeRawPtr<AbstractView> view) { + RefPtrWillBeRawPtr<Node> target = prpTarget; RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.create(mouseEventType, mouseEvent, relatedTarget, view); @@ -449,8 +451,9 @@ } void PointerEventManager::removePointer( - const PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent) + const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent) { + RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; if (m_pointerEventFactory.remove(pointerEvent)) { int pointerId = pointerEvent->pointerId(); m_pendingPointerCaptureTarget.remove(pointerId);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp index f7c413e7..cc61a139 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -690,93 +690,6 @@ return minimumValueForLength(padding, w); } -static inline LayoutUnit resolveWidthForRatio(LayoutUnit height, const FloatSize& intrinsicRatio) -{ - return LayoutUnit(height * intrinsicRatio.width() / intrinsicRatio.height()); -} - -static inline LayoutUnit resolveHeightForRatio(LayoutUnit width, const FloatSize& intrinsicRatio) -{ - return LayoutUnit(width * intrinsicRatio.height() / intrinsicRatio.width()); -} - -static inline LayoutSize resolveAgainstIntrinsicWidthOrHeightAndRatio(const LayoutSize& size, const FloatSize& intrinsicRatio, LayoutUnit useWidth, LayoutUnit useHeight) -{ - if (intrinsicRatio.isEmpty()) { - if (useWidth) - return LayoutSize(useWidth, size.height()); - return LayoutSize(size.width(), useHeight); - } - - if (useWidth) - return LayoutSize(useWidth, resolveHeightForRatio(useWidth, intrinsicRatio)); - return LayoutSize(resolveWidthForRatio(useHeight, intrinsicRatio), useHeight); -} - -static inline LayoutSize resolveAgainstIntrinsicRatio(const LayoutSize& size, const FloatSize& intrinsicRatio) -{ - // Two possible solutions: (size.width(), solutionHeight) or (solutionWidth, size.height()) - // "... must be assumed to be the largest dimensions..." = easiest answer: the rect with the largest surface area. - - LayoutUnit solutionWidth = resolveWidthForRatio(size.height(), intrinsicRatio); - LayoutUnit solutionHeight = resolveHeightForRatio(size.width(), intrinsicRatio); - if (solutionWidth <= size.width()) { - if (solutionHeight <= size.height()) { - // If both solutions fit, choose the one covering the larger area. - LayoutUnit areaOne = solutionWidth * size.height(); - LayoutUnit areaTwo = size.width() * solutionHeight; - if (areaOne < areaTwo) - return LayoutSize(size.width(), solutionHeight); - return LayoutSize(solutionWidth, size.height()); - } - - // Only the first solution fits. - return LayoutSize(solutionWidth, size.height()); - } - - // Only the second solution fits, assert that. - ASSERT(solutionHeight <= size.height()); - return LayoutSize(size.width(), solutionHeight); -} - -LayoutSize LayoutBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const LayoutSize& positioningAreaSize, ScaleByEffectiveZoomOrNot shouldScaleOrNot) const -{ - // A generated image without a fixed size, will always return the container size as intrinsic size. - if (image->isGeneratedImage() && image->usesImageContainerSize()) - return positioningAreaSize; - - FloatSize intrinsicSize; - FloatSize intrinsicRatio; - image->computeIntrinsicDimensions(this, intrinsicSize, intrinsicRatio); - - LayoutSize resolvedSize(intrinsicSize); - LayoutSize minimumSize(resolvedSize.width() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit(), - resolvedSize.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit()); - if (shouldScaleOrNot == ScaleByEffectiveZoom) - resolvedSize.scale(style()->effectiveZoom()); - resolvedSize.clampToMinimumSize(minimumSize); - - if (!resolvedSize.isEmpty()) - return resolvedSize; - - // If the image has one of either an intrinsic width or an intrinsic height: - // * and an intrinsic aspect ratio, then the missing dimension is calculated from the given dimension and the ratio. - // * and no intrinsic aspect ratio, then the missing dimension is assumed to be the size of the rectangle that - // establishes the coordinate system for the 'background-position' property. - if (resolvedSize.width() > LayoutUnit() || resolvedSize.height() > LayoutUnit()) - return resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, resolvedSize.width(), resolvedSize.height()); - - // If the image has no intrinsic dimensions and has an intrinsic ratio the dimensions must be assumed to be the - // largest dimensions at that ratio such that neither dimension exceeds the dimensions of the rectangle that - // establishes the coordinate system for the 'background-position' property. - if (!intrinsicRatio.isEmpty()) - return resolveAgainstIntrinsicRatio(positioningAreaSize, intrinsicRatio); - - // If the image has no intrinsic ratio either, then the dimensions must be assumed to be the rectangle that - // establishes the coordinate system for the 'background-position' property. - return positioningAreaSize; -} - bool LayoutBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance bleedAvoidance, const InlineFlowBox* inlineFlowBox) const { if (bleedAvoidance != BackgroundBleedNone)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h index 05730ac..1301c75 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -353,9 +353,6 @@ } virtual void moveChildrenTo(LayoutBoxModelObject* toBoxModelObject, LayoutObject* startChild, LayoutObject* endChild, LayoutObject* beforeChild, bool fullRemoveInsert = false); - enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom }; - LayoutSize calculateImageIntrinsicDimensions(StyleImage*, const LayoutSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const; - private: void createLayer(PaintLayerType);
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h index 284bb93..80bcdbe 100644 --- a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h +++ b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h
@@ -51,7 +51,11 @@ bool imageHasRelativeSize() const override { return m_styleImage->imageHasRelativeSize(); } - LayoutSize imageSize(float multiplier) const override { return m_styleImage->imageSize(m_layoutObject, multiplier); } + LayoutSize imageSize(float multiplier) const override + { + // TODO(davve): Find out the default object size, if any, in this context. + return m_styleImage->imageSize(m_layoutObject, multiplier, LayoutSize()); + } WrappedImagePtr imagePtr() const override { return m_styleImage->data(); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp index de63ab1..0cc2c5c6 100644 --- a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
@@ -72,8 +72,7 @@ // become particularly useful until we support the CSS3 marker pseudoclass to allow control over // the width and height of the marker box. LayoutUnit bulletWidth = style()->fontMetrics().ascent() / LayoutUnit(2); - LayoutSize defaultBulletSize(bulletWidth, bulletWidth); - return calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom); + return m_image->imageSize(this, style()->effectiveZoom(), LayoutSize(bulletWidth, bulletWidth)); } void LayoutListMarker::styleWillChange(StyleDifference diff, const ComputedStyle& newStyle)
diff --git a/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp b/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp index 6abfec0a..9aafdd4 100644 --- a/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp +++ b/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp
@@ -121,7 +121,7 @@ PassOwnPtr<Shape> ShapeOutsideInfo::createShapeForImage(StyleImage* styleImage, float shapeImageThreshold, WritingMode writingMode, float margin) const { - const LayoutSize& imageSize = m_layoutBox.calculateImageIntrinsicDimensions(styleImage, m_referenceBoxLogicalSize, LayoutImage::ScaleByEffectiveZoom); + const LayoutSize& imageSize = styleImage->imageSize(&m_layoutBox, m_layoutBox.style()->effectiveZoom(), m_referenceBoxLogicalSize); const LayoutRect& marginRect = getShapeImageMarginRect(m_layoutBox, m_referenceBoxLogicalSize); const LayoutRect& imageRect = (m_layoutBox.isLayoutImage())
diff --git a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp index e6537eea..2f5f664 100644 --- a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp +++ b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
@@ -69,15 +69,7 @@ void HttpEquiv::processHttpEquivDefaultStyle(Document& document, const AtomicString& content) { - // The preferred style set has been overridden as per section - // 14.3.2 of the HTML4.0 specification. We need to update the - // sheet used variable and then update our style selector. - // For more info, see the test at: - // http://www.hixie.ch/tests/evil/css/import/main/preferred.html - // -dwh - document.styleEngine().setSelectedStylesheetSetName(content); - document.styleEngine().setPreferredStylesheetSetName(content); - document.styleEngine().resolverChanged(FullStyleUpdate); + document.styleEngine().setHttpDefaultStyle(content); } void HttpEquiv::processHttpEquivRefresh(Document& document, const AtomicString& content)
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp index 474628f9..20c93d47 100644 --- a/third_party/WebKit/Source/core/page/Page.cpp +++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -21,6 +21,7 @@ #include "core/css/resolver/ViewportStyleResolver.h" #include "core/dom/ClientRectList.h" +#include "core/dom/StyleChangeReason.h" #include "core/dom/VisitedLinkState.h" #include "core/editing/DragCaretController.h" #include "core/editing/commands/UndoStack.h" @@ -241,7 +242,7 @@ { for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) { if (frame->isLocalFrame()) - toLocalFrame(frame)->document()->styleEngine().resolverChanged(FullStyleUpdate); + toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Settings)); } } @@ -315,7 +316,6 @@ return; m_deviceScaleFactor = scaleFactor; - setNeedsRecalcStyleInAllFrames(); if (mainFrame() && mainFrame()->isLocalFrame()) deprecatedLocalMainFrame()->deviceScaleFactorChanged(); @@ -443,7 +443,6 @@ if (frame->isLocalFrame()) toLocalFrame(frame)->document()->styleEngine().updateGenericFontFamilySettings(); } - setNeedsRecalcStyleInAllFrames(); break; case SettingsDelegate::AcceleratedCompositingChange: updateAcceleratedCompositingSettings();
diff --git a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp index 5de58bf..06a8269 100644 --- a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp +++ b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
@@ -53,8 +53,7 @@ StyleImage* image = fillLayer.image(); EFillSizeType type = fillLayer.size().type; - LayoutSize imageIntrinsicSize = obj.calculateImageIntrinsicDimensions(image, positioningAreaSize, LayoutBoxModelObject::ScaleByEffectiveZoom); - imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor()); + LayoutSize imageIntrinsicSize = image->imageSize(&obj, obj.style()->effectiveZoom(), positioningAreaSize); switch (type) { case SizeLength: { LayoutSize tileSize(positioningAreaSize);
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp index 94500cd3..d1d135e 100644 --- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp +++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -136,9 +136,11 @@ bool BoxPainter::isFillLayerOpaque(const FillLayer& layer, const LayoutObject& imageClient) { + // The default object size passed down to imageSize is empty with the implication that images + // with no intrinsic size are treated as empty. return layer.hasOpaqueImage(&imageClient) && layer.image()->canRender() - && !layer.image()->imageSize(&imageClient, imageClient.style()->effectiveZoom()).isEmpty() + && !layer.image()->imageSize(&imageClient, imageClient.style()->effectiveZoom(), LayoutSize()).isEmpty() && layer.hasRepeatXY(); }
diff --git a/third_party/WebKit/Source/core/paint/NinePieceImageGrid.cpp b/third_party/WebKit/Source/core/paint/NinePieceImageGrid.cpp index 2feb67c..16c1dad 100644 --- a/third_party/WebKit/Source/core/paint/NinePieceImageGrid.cpp +++ b/third_party/WebKit/Source/core/paint/NinePieceImageGrid.cpp
@@ -35,14 +35,10 @@ , m_verticalTileRule((Image::TileRule)ninePieceImage.verticalRule()) , m_fill(ninePieceImage.fill()) { - StyleImage* styleImage = ninePieceImage.image(); - ASSERT(styleImage); - - float imageScaleFactor = styleImage->imageScaleFactor(); - m_top.slice = computeEdgeSlice(ninePieceImage.imageSlices().top(), imageSize.height()) * imageScaleFactor; - m_right.slice = computeEdgeSlice(ninePieceImage.imageSlices().right(), imageSize.width()) * imageScaleFactor; - m_bottom.slice = computeEdgeSlice(ninePieceImage.imageSlices().bottom(), imageSize.height()) * imageScaleFactor; - m_left.slice = computeEdgeSlice(ninePieceImage.imageSlices().left(), imageSize.width()) * imageScaleFactor; + m_top.slice = computeEdgeSlice(ninePieceImage.imageSlices().top(), imageSize.height()); + m_right.slice = computeEdgeSlice(ninePieceImage.imageSlices().right(), imageSize.width()); + m_bottom.slice = computeEdgeSlice(ninePieceImage.imageSlices().bottom(), imageSize.height()); + m_left.slice = computeEdgeSlice(ninePieceImage.imageSlices().left(), imageSize.width()); m_top.width = computeEdgeWidth(ninePieceImage.borderSlices().top(), borderWidths.top(), m_top.slice, borderImageArea.height());
diff --git a/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp b/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp index 6518917..bbc4941 100644 --- a/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp +++ b/third_party/WebKit/Source/core/paint/NinePieceImagePainter.cpp
@@ -49,8 +49,7 @@ rectWithOutsets.expand(style.imageOutsets(ninePieceImage)); LayoutRect borderImageRect = rectWithOutsets; - IntSize imageSize = roundedIntSize(m_layoutObject.calculateImageIntrinsicDimensions(styleImage, borderImageRect.size(), - LayoutBoxModelObject::DoNotScaleByEffectiveZoom)); + IntSize imageSize = roundedIntSize(styleImage->imageSize(&m_layoutObject, 1, borderImageRect.size())); IntRectOutsets borderWidths(style.borderTopWidth(), style.borderRightWidth(), style.borderBottomWidth(), style.borderLeftWidth()); @@ -68,6 +67,10 @@ for (NinePiece piece = MinPiece; piece < MaxPiece; ++piece) { NinePieceImageGrid::NinePieceDrawInfo drawInfo = grid.getNinePieceDrawInfo(piece); + // The nine piece grid is computed in unscaled image coordinates but must be drawn using + // scaled image coordinates. + drawInfo.source.scale(styleImage->imageScaleFactor()); + if (drawInfo.isDrawable) { if (drawInfo.isCornerPiece) { graphicsContext.drawImage(image.get(), drawInfo.destination, drawInfo.source, op);
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp index 352a30f..f7e12f89 100644 --- a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp +++ b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
@@ -179,7 +179,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("AbortError: the reader is already released", onRejected); @@ -208,7 +208,7 @@ EXPECT_FALSE(result.isSet); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(result.isSet); EXPECT_EQ("TypeError: the reader is already released", onRejected); @@ -250,7 +250,7 @@ EXPECT_FALSE(result.isSet); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(result.isSet); EXPECT_FALSE(result.isDone); @@ -264,7 +264,7 @@ EXPECT_FALSE(result2.isSet); EXPECT_TRUE(onRejected2.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(result2.isSet); EXPECT_FALSE(result2.isDone); @@ -290,7 +290,7 @@ EXPECT_FALSE(result2.isSet); EXPECT_TRUE(onRejected2.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(result.isSet); EXPECT_TRUE(onRejected.isNull()); @@ -298,7 +298,7 @@ EXPECT_TRUE(onRejected2.isNull()); m_stream->enqueue("hello"); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(result.isSet); EXPECT_FALSE(result.isDone); @@ -308,7 +308,7 @@ EXPECT_TRUE(onRejected2.isNull()); m_stream->enqueue("world"); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(result2.isSet); EXPECT_FALSE(result2.isDone); @@ -330,7 +330,7 @@ String onClosedFulfilled, onClosedRejected; ReadResult result; String onReadRejected; - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); reader->closed(scriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected)); reader->read(scriptState()).then(createResultCaptor(&result), createCaptor(&onReadRejected)); EXPECT_TRUE(onClosedFulfilled.isNull()); @@ -338,7 +338,7 @@ EXPECT_FALSE(result.isSet); EXPECT_TRUE(onReadRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onClosedFulfilled); EXPECT_TRUE(onClosedRejected.isNull()); EXPECT_TRUE(result.isSet); @@ -361,7 +361,7 @@ String onClosedFulfilled, onClosedRejected; String onReadFulfilled, onReadRejected; - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); reader->closed(scriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected)); reader->read(scriptState()).then(createCaptor(&onReadFulfilled), createCaptor(&onReadRejected)); EXPECT_TRUE(onClosedFulfilled.isNull()); @@ -369,7 +369,7 @@ EXPECT_TRUE(onReadFulfilled.isNull()); EXPECT_TRUE(onReadRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onClosedFulfilled.isNull()); EXPECT_EQ("SyntaxError: some error", onClosedRejected); EXPECT_TRUE(onReadFulfilled.isNull()); @@ -389,7 +389,7 @@ reader->read(scriptState()).then(createResultCaptor(&result), createCaptor(&onRejected)); reader->read(scriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2)); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(result.isSet); EXPECT_TRUE(onRejected.isNull()); EXPECT_FALSE(result2.isSet); @@ -401,7 +401,7 @@ EXPECT_FALSE(result2.isSet); EXPECT_TRUE(onRejected2.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(result.isSet); EXPECT_TRUE(result.isDone); @@ -427,7 +427,7 @@ reader->read(scriptState()).then(createCaptor(&onFulfilled), createCaptor(&onRejected)); reader->read(scriptState()).then(createCaptor(&onFulfilled2), createCaptor(&onRejected2)); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); EXPECT_TRUE(onFulfilled2.isNull()); @@ -439,7 +439,7 @@ EXPECT_TRUE(onFulfilled2.isNull()); EXPECT_TRUE(onRejected2.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ(onRejected, "SyntaxError: some error"); @@ -460,7 +460,7 @@ reader->read(scriptState()).then(createResultCaptor(&result), createCaptor(&onRejected)); reader->read(scriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2)); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_FALSE(result.isSet); EXPECT_TRUE(onRejected.isNull()); EXPECT_FALSE(result2.isSet); @@ -473,7 +473,7 @@ EXPECT_FALSE(result2.isSet); EXPECT_TRUE(onRejected2.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(result.isSet); EXPECT_TRUE(result.isDone); @@ -502,7 +502,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("TypeError: the reader is already released", onRejected); @@ -528,7 +528,7 @@ EXPECT_TRUE(onCancelFulfilled.isNull()); EXPECT_TRUE(onCancelRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onClosedFulfilled); EXPECT_TRUE(onClosedRejected.isNull()); EXPECT_EQ("undefined", onCancelFulfilled); @@ -552,7 +552,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onFulfilled); EXPECT_TRUE(onRejected.isNull()); EXPECT_FALSE(exceptionState.hadException()); @@ -574,7 +574,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("SyntaxError: some error", onRejected); EXPECT_FALSE(exceptionState.hadException());
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp index 031ecdd..fb52f46 100644 --- a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp +++ b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
@@ -304,7 +304,7 @@ stream->read(scriptState()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ(ReadableStream::Readable, stream->stateInternal()); EXPECT_FALSE(stream->isPulling()); @@ -335,7 +335,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onFulfilled); EXPECT_TRUE(onRejected.isNull()); } @@ -358,7 +358,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("NotFoundError: error", onRejected); } @@ -392,7 +392,7 @@ EXPECT_TRUE(onCancelFulfilled.isNull()); EXPECT_TRUE(onCancelRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onCancelFulfilled); EXPECT_TRUE(onCancelRejected.isNull()); } @@ -416,7 +416,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("TypeError: this stream is locked to a ReadableStreamReader", onRejected); @@ -563,7 +563,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onFulfilled); EXPECT_TRUE(onRejected.isNull()); } @@ -586,7 +586,7 @@ EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("SyntaxError: some error", onRejected); }
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp index 938f53e..94a3d82 100644 --- a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp +++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
@@ -91,9 +91,17 @@ return m_image->errorOccurred(); } -LayoutSize StyleFetchedImage::imageSize(const LayoutObject* layoutObject, float multiplier) const +LayoutSize StyleFetchedImage::imageSize(const LayoutObject* layoutObject, float multiplier, const LayoutSize& defaultObjectSize) const { - return m_image->imageSize(LayoutObject::shouldRespectImageOrientation(layoutObject), multiplier); + if (m_image->image() && m_image->image()->isSVGImage()) + return imageSizeForSVGImage(toSVGImage(m_image->image()), multiplier, defaultObjectSize); + + // Image orientation should only be respected for content images, + // not decorative images such as StyleImage (backgrounds, + // border-image, etc.) + // + // https://drafts.csswg.org/css-images-3/#the-image-orientation + return m_image->imageSize(DoNotRespectImageOrientation, multiplier); } bool StyleFetchedImage::imageHasRelativeSize() const
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.h b/third_party/WebKit/Source/core/style/StyleFetchedImage.h index b20b31ad..863852d 100644 --- a/third_party/WebKit/Source/core/style/StyleFetchedImage.h +++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.h
@@ -50,7 +50,7 @@ bool canRender() const override; bool isLoaded() const override; bool errorOccurred() const override; - LayoutSize imageSize(const LayoutObject*, float multiplier) const override; + LayoutSize imageSize(const LayoutObject*, float multiplier, const LayoutSize& defaultObjectSize) const override; bool imageHasRelativeSize() const override; void computeIntrinsicDimensions(const LayoutObject*, FloatSize& intrinsicSize, FloatSize& intrinsicRatio) override; bool usesImageContainerSize() const override;
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp index e42aefb..f3c10499 100644 --- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp +++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
@@ -93,9 +93,17 @@ return m_bestFitImage->errorOccurred(); } -LayoutSize StyleFetchedImageSet::imageSize(const LayoutObject* layoutObject, float multiplier) const +LayoutSize StyleFetchedImageSet::imageSize(const LayoutObject*, float multiplier, const LayoutSize& defaultObjectSize) const { - LayoutSize scaledImageSize = m_bestFitImage->imageSize(LayoutObject::shouldRespectImageOrientation(layoutObject), multiplier); + if (m_bestFitImage->image() && m_bestFitImage->image()->isSVGImage()) + return imageSizeForSVGImage(toSVGImage(m_bestFitImage->image()), multiplier, defaultObjectSize); + + // Image orientation should only be respected for content images, + // not decorative ones such as StyleImage (backgrounds, + // border-image, etc.) + // + // https://drafts.csswg.org/css-images-3/#the-image-orientation + LayoutSize scaledImageSize = m_bestFitImage->imageSize(DoNotRespectImageOrientation, multiplier); scaledImageSize.scale(1 / m_imageScaleFactor); return scaledImageSize; }
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h index 615eeff..1703d2f 100644 --- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h +++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
@@ -62,7 +62,7 @@ bool canRender() const override; bool isLoaded() const override; bool errorOccurred() const override; - LayoutSize imageSize(const LayoutObject*, float multiplier) const override; + LayoutSize imageSize(const LayoutObject*, float multiplier, const LayoutSize& defaultObjectSize) const override; bool imageHasRelativeSize() const override; void computeIntrinsicDimensions(const LayoutObject*, FloatSize& intrinsicSize, FloatSize& intrinsicRatio) override; bool usesImageContainerSize() const override;
diff --git a/third_party/WebKit/Source/core/style/StyleGeneratedImage.cpp b/third_party/WebKit/Source/core/style/StyleGeneratedImage.cpp index 68aaf42..435b937 100644 --- a/third_party/WebKit/Source/core/style/StyleGeneratedImage.cpp +++ b/third_party/WebKit/Source/core/style/StyleGeneratedImage.cpp
@@ -46,33 +46,21 @@ return m_imageGeneratorValue->valueWithURLsMadeAbsolute(); } -LayoutSize StyleGeneratedImage::imageSize(const LayoutObject* layoutObject, float multiplier) const +LayoutSize StyleGeneratedImage::imageSize(const LayoutObject* layoutObject, float multiplier, const LayoutSize& defaultObjectSize) const { if (m_fixedSize) { - LayoutSize fixedSize(m_imageGeneratorValue->fixedSize(layoutObject)); - if (multiplier == 1.0f) - return fixedSize; - - LayoutUnit width(fixedSize.width() * multiplier); - LayoutUnit height(fixedSize.height() * multiplier); - - // Don't let images that have a width/height >= 1 shrink below 1 when zoomed. - if (fixedSize.width() > LayoutUnit()) - width = max(LayoutUnit(1), width); - - if (fixedSize.height() > LayoutUnit()) - height = max(LayoutUnit(1), height); - - return LayoutSize(width, height); + FloatSize unzoomedDefaultObjectSize(defaultObjectSize); + unzoomedDefaultObjectSize.scale(1 / multiplier); + return applyZoom(LayoutSize(m_imageGeneratorValue->fixedSize(layoutObject, unzoomedDefaultObjectSize)), multiplier); } - return LayoutSize(); + return defaultObjectSize; } void StyleGeneratedImage::computeIntrinsicDimensions(const LayoutObject* layoutObject, FloatSize& intrinsicSize, FloatSize& intrinsicRatio) { // At a zoom level of 1 the image is guaranteed to have an integer size. - LayoutSize size = imageSize(layoutObject, 1); + LayoutSize size = imageSize(layoutObject, 1, LayoutSize()); ASSERT(size.fraction().isZero()); intrinsicSize = intrinsicRatio = FloatSize(size); }
diff --git a/third_party/WebKit/Source/core/style/StyleGeneratedImage.h b/third_party/WebKit/Source/core/style/StyleGeneratedImage.h index 17a4cdd..2b94f78 100644 --- a/third_party/WebKit/Source/core/style/StyleGeneratedImage.h +++ b/third_party/WebKit/Source/core/style/StyleGeneratedImage.h
@@ -44,7 +44,7 @@ PassRefPtrWillBeRawPtr<CSSValue> cssValue() const override; PassRefPtrWillBeRawPtr<CSSValue> computedCSSValue() const override; - LayoutSize imageSize(const LayoutObject*, float multiplier) const override; + LayoutSize imageSize(const LayoutObject*, float multiplier, const LayoutSize& defaultObjectSize) const override; bool imageHasRelativeSize() const override { return !m_fixedSize; } void computeIntrinsicDimensions(const LayoutObject*, FloatSize& intrinsicSize, FloatSize& intrinsicRatio) override; bool usesImageContainerSize() const override { return !m_fixedSize; }
diff --git a/third_party/WebKit/Source/core/style/StyleImage.cpp b/third_party/WebKit/Source/core/style/StyleImage.cpp new file mode 100644 index 0000000..b56d90dd --- /dev/null +++ b/third_party/WebKit/Source/core/style/StyleImage.cpp
@@ -0,0 +1,37 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/style/StyleImage.h" + +#include "core/svg/graphics/SVGImage.h" +#include "core/svg/graphics/SVGImageForContainer.h" + +namespace blink { + +LayoutSize StyleImage::applyZoom(const LayoutSize& size, float multiplier) +{ + if (multiplier == 1.0f) + return size; + + LayoutUnit width(size.width() * multiplier); + LayoutUnit height(size.height() * multiplier); + + // Don't let images that have a width/height >= 1 shrink below 1 when zoomed. + if (size.width() > LayoutUnit()) + width = std::max(LayoutUnit(1), width); + + if (size.height() > LayoutUnit()) + height = std::max(LayoutUnit(1), height); + + return LayoutSize(width, height); +} + +LayoutSize StyleImage::imageSizeForSVGImage(SVGImage* svgImage, float multiplier, const LayoutSize& defaultObjectSize) const +{ + FloatSize unzoomedDefaultObjectSize(defaultObjectSize); + unzoomedDefaultObjectSize.scale(1 / multiplier); + return applyZoom(LayoutSize(svgImage->concreteObjectSize(svgImage->concreteObjectSize(unzoomedDefaultObjectSize))), multiplier); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/style/StyleImage.h b/third_party/WebKit/Source/core/style/StyleImage.h index 49a050c5..4caa2c42 100644 --- a/third_party/WebKit/Source/core/style/StyleImage.h +++ b/third_party/WebKit/Source/core/style/StyleImage.h
@@ -38,6 +38,7 @@ class ImageResource; class CSSValue; class LayoutObject; +class SVGImage; typedef void* WrappedImagePtr; @@ -56,7 +57,7 @@ virtual bool canRender() const { return true; } virtual bool isLoaded() const { return true; } virtual bool errorOccurred() const { return false; } - virtual LayoutSize imageSize(const LayoutObject*, float multiplier) const = 0; + virtual LayoutSize imageSize(const LayoutObject*, float multiplier, const LayoutSize& defaultObjectSize) const = 0; virtual void computeIntrinsicDimensions(const LayoutObject*, FloatSize& intrinsicSize, FloatSize& intrinsicRatio) = 0; virtual bool imageHasRelativeSize() const = 0; virtual bool usesImageContainerSize() const = 0; @@ -90,6 +91,9 @@ bool m_isGeneratedImage:1; bool m_isImageResourceSet:1; bool m_isInvalidImage:1; + + static LayoutSize applyZoom(const LayoutSize&, float multiplier); + LayoutSize imageSizeForSVGImage(SVGImage*, float multiplier, const LayoutSize& defaultObjectSize) const; }; #define DEFINE_STYLE_IMAGE_TYPE_CASTS(thisType, function) \
diff --git a/third_party/WebKit/Source/core/style/StyleInvalidImage.h b/third_party/WebKit/Source/core/style/StyleInvalidImage.h index d1004022..79e78993 100644 --- a/third_party/WebKit/Source/core/style/StyleInvalidImage.h +++ b/third_party/WebKit/Source/core/style/StyleInvalidImage.h
@@ -23,7 +23,7 @@ PassRefPtrWillBeRawPtr<CSSValue> computedCSSValue() const override { return cssValue(); } - LayoutSize imageSize(const LayoutObject*, float /*multiplier*/) const override { return LayoutSize(); } + LayoutSize imageSize(const LayoutObject*, float /*multiplier*/, const LayoutSize& /*defaultObjectSize*/) const override { return LayoutSize(); } bool imageHasRelativeSize() const override { return false; } void computeIntrinsicDimensions(const LayoutObject*, FloatSize& /* intrinsicSize */, FloatSize& /* intrinsicRatio */) override { } bool usesImageContainerSize() const override { return false; }
diff --git a/third_party/WebKit/Source/core/style/StylePendingImage.h b/third_party/WebKit/Source/core/style/StylePendingImage.h index 95f8c6e1..ee165802 100644 --- a/third_party/WebKit/Source/core/style/StylePendingImage.h +++ b/third_party/WebKit/Source/core/style/StylePendingImage.h
@@ -61,7 +61,7 @@ CSSCursorImageValue* cssCursorImageValue() const { return m_value->isCursorImageValue() ? toCSSCursorImageValue(m_value.get()) : 0; } CSSImageSetValue* cssImageSetValue() const { return m_value->isImageSetValue() ? toCSSImageSetValue(m_value.get()) : 0; } - LayoutSize imageSize(const LayoutObject*, float /*multiplier*/) const override { return LayoutSize(); } + LayoutSize imageSize(const LayoutObject*, float /*multiplier*/, const LayoutSize& /*defaultObjectSize*/) const override { return LayoutSize(); } bool imageHasRelativeSize() const override { return false; } void computeIntrinsicDimensions(const LayoutObject*, FloatSize& /* intrinsicSize */, FloatSize& /* intrinsicRatio */) override { } bool usesImageContainerSize() const override { return false; }
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index b1141564..aaccff3 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -155,7 +155,7 @@ ASSERT(layoutObject->style()->effectiveZoom() == 1); // No set container size; use concrete object size. - return m_concreteObjectSize; + return m_intrinsicSize; } static float resolveWidthForRatio(float height, const FloatSize& intrinsicRatio) @@ -168,7 +168,7 @@ return width * intrinsicRatio.height() / intrinsicRatio.width(); } -FloatSize SVGImage::calculateConcreteObjectSize(const FloatSize& defaultObjectSize) const +FloatSize SVGImage::concreteObjectSize(const FloatSize& defaultObjectSize) const { SVGSVGElement* svg = svgRootElement(m_page.get()); if (!svg) @@ -208,11 +208,25 @@ } if (!intrinsicSizingInfo.aspectRatio.isEmpty()) { - // TODO(davve): According to the specification, the concrete object size should resolve as a - // contain constraint against the default object size at this stage. Until the - // defaultObjectSize is context sensitive, right now it's hard-coded to 300x150, we have to - // preserve legacy behavior by returning the aspectRatio as the concrete object size. - return intrinsicSizingInfo.aspectRatio; + // "A contain constraint is resolved by setting the concrete object size to the largest + // rectangle that has the object's intrinsic aspect ratio and additionally has neither + // width nor height larger than the constraint rectangle's width and height, respectively." + float solutionWidth = resolveWidthForRatio(defaultObjectSize.height(), intrinsicSizingInfo.aspectRatio); + float solutionHeight = resolveHeightForRatio(defaultObjectSize.width(), intrinsicSizingInfo.aspectRatio); + if (solutionWidth <= defaultObjectSize.width()) { + if (solutionHeight <= defaultObjectSize.height()) { + float areaOne = solutionWidth * defaultObjectSize.height(); + float areaTwo = defaultObjectSize.width() * solutionHeight; + if (areaOne < areaTwo) + return FloatSize(defaultObjectSize.width(), solutionHeight); + return FloatSize(solutionWidth, defaultObjectSize.height()); + } + + return FloatSize(solutionWidth, defaultObjectSize.height()); + } + + ASSERT(solutionHeight <= defaultObjectSize.height()); + return FloatSize(defaultObjectSize.width(), solutionHeight); } return defaultObjectSize; @@ -535,7 +549,7 @@ AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad))); // Set the concrete object size before a container size is available. - m_concreteObjectSize = roundedIntSize(calculateConcreteObjectSize(FloatSize(300, 150))); + m_intrinsicSize = roundedIntSize(concreteObjectSize(FloatSize(300, 150))); } return m_page;
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h index 8fc42e6..903b9a8 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -55,7 +55,7 @@ bool isSVGImage() const override { return true; } bool isTextureBacked() override { return false; } - IntSize size() const override { return m_concreteObjectSize; } + IntSize size() const override { return m_intrinsicSize; } bool currentFrameHasSingleSecurityOrigin() const override; @@ -77,6 +77,8 @@ void updateUseCounters(Document&) const; + FloatSize concreteObjectSize(const FloatSize&) const; + // DisplayItemClient methods. String debugName() const final { return "SVGImage"; } LayoutRect visualRect() const override; @@ -90,7 +92,6 @@ String filenameExtension() const override; - FloatSize calculateConcreteObjectSize(const FloatSize&) const; IntSize containerSize() const; bool usesContainerSize() const override { return true; } void computeIntrinsicDimensions(FloatSize& intrinsicSize, FloatSize& intrinsicRatio) override; @@ -116,18 +117,13 @@ OwnPtrWillBePersistent<SVGImageChromeClient> m_chromeClient; OwnPtrWillBePersistent<Page> m_page; - // "The concrete object size is the result of combining an - // object’s intrinsic dimensions and specified size with the - // default object size of the context it’s used in, producing a - // rectangle with a definite width and height." - // - // https://drafts.csswg.org/css-images-3/#concrete-object-size - // - // Note: For SVGImage there are no specified size - // constraints. Such constraints are handled by the layout - // machinery in LayoutReplaced. An image has only intrinsic size, - // aspect ratio and default object size to consider. - IntSize m_concreteObjectSize; + // When an SVG image has no intrinsic size the size depends on the + // default object size, which in turn depends on the + // container. SVGImage may belong to multiple containers so the + // final image size can't be known in + // SVGImage. SVGImageForContainer carried the final image size, + // also called concrete object size. + IntSize m_intrinsicSize; }; DEFINE_IMAGE_TYPE_CASTS(SVGImage);
diff --git a/third_party/WebKit/Source/modules/InitModules.cpp b/third_party/WebKit/Source/modules/InitModules.cpp index 539c6b25..031048d 100644 --- a/third_party/WebKit/Source/modules/InitModules.cpp +++ b/third_party/WebKit/Source/modules/InitModules.cpp
@@ -16,6 +16,8 @@ #include "modules/canvas2d/CanvasRenderingContext2D.h" #include "modules/filesystem/DraggedIsolatedFileSystemImpl.h" #include "modules/imagebitmap/ImageBitmapRenderingContext.h" +#include "modules/offscreencanvas/OffscreenCanvas.h" +#include "modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h" #include "modules/webdatabase/DatabaseManager.h" #include "modules/webgl/WebGL2RenderingContext.h" #include "modules/webgl/WebGLRenderingContext.h" @@ -48,6 +50,9 @@ HTMLCanvasElement::registerRenderingContextFactory(adoptPtr(new WebGL2RenderingContext::Factory())); HTMLCanvasElement::registerRenderingContextFactory(adoptPtr(new ImageBitmapRenderingContext::Factory())); + // OffscreenCanvas context types must be registered with the OffscreenCanvas. + OffscreenCanvas::registerRenderingContextFactory(adoptPtr(new OffscreenCanvasRenderingContext2D::Factory())); + ASSERT(isInitialized()); }
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp index 1c4030cb..7834ae9 100644 --- a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp +++ b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
@@ -249,7 +249,7 @@ { ScriptValue onReject; promise.then(UnreachableFunction::create(scriptState()), TestFunction::create(scriptState(), &onReject)); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); return onReject; } @@ -263,7 +263,7 @@ { ScriptValue onResolve; promise.then(TestFunction::create(scriptState(), &onResolve), UnreachableFunction::create(scriptState())); - v8::MicrotasksScope::PerformCheckpoint(isolate()); + isolate()->RunMicrotasks(); return onResolve; }
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h index 8003fed1..8021b8e 100644 --- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h
@@ -7,7 +7,6 @@ #include "bindings/core/v8/UnionTypesCore.h" #include "bindings/modules/v8/UnionTypesModules.h" -#include "core/html/canvas/CanvasRenderingContext.h" #include "modules/ModulesExport.h" #include "modules/canvas2d/CanvasGradient.h" #include "modules/canvas2d/CanvasPathMethods.h"
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp index fba225c..9a9daead 100644 --- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp +++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
@@ -8,7 +8,6 @@ #include "bindings/core/v8/ScriptState.h" #include "bindings/core/v8/V8BindingMacros.h" #include "bindings/core/v8/V8GCController.h" -#include "bindings/core/v8/V8RecursionScope.h" #include "core/dom/Document.h" #include "core/testing/DummyPageHolder.h" #include "modules/fetch/DataConsumerHandleTestUtil.h" @@ -60,7 +59,6 @@ { v8::Local<v8::String> source; v8::Local<v8::Script> script; - V8RecursionScope::MicrotaskSuppression microtasks(isolate()); if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) { ADD_FAILURE(); return v8::MaybeLocal<v8::Value>();
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi index 0cd43e1..b06446c 100644 --- a/third_party/WebKit/Source/modules/modules.gypi +++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -150,6 +150,8 @@ 'notifications/Notification.idl', 'notifications/NotificationEvent.idl', 'notifications/NotificationPermissionCallback.idl', + 'offscreencanvas/OffscreenCanvas.idl', + 'offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl', 'payments/PaymentRequest.idl', 'payments/PaymentResponse.idl', 'payments/ShippingAddress.idl', @@ -1318,6 +1320,13 @@ 'notifications/ServiceWorkerGlobalScopeNotifications.h', 'notifications/ServiceWorkerRegistrationNotifications.cpp', 'notifications/ServiceWorkerRegistrationNotifications.h', + 'offscreencanvas/OffscreenCanvas.cpp', + 'offscreencanvas/OffscreenCanvas.h', + 'offscreencanvas/OffscreenCanvasRenderingContext.cpp', + 'offscreencanvas/OffscreenCanvasRenderingContext.h', + 'offscreencanvas/OffscreenCanvasRenderingContextFactory.h', + 'offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp', + 'offscreencanvas2d/OffscreenCanvasRenderingContext2D.h', 'payments/PaymentRequest.cpp', 'payments/PaymentRequest.h', 'payments/PaymentResponse.cpp', @@ -1958,7 +1967,6 @@ 'mediastream/RTCDataChannelTest.cpp', 'notifications/NotificationDataTest.cpp', 'presentation/PresentationAvailabilityTest.cpp', - 'push_messaging/PushManagerTest.cpp', 'push_messaging/PushMessageDataTest.cpp', 'serviceworkers/ServiceWorkerContainerTest.cpp', 'webaudio/AudioBasicProcessorHandlerTest.cpp',
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OWNERS b/third_party/WebKit/Source/modules/offscreencanvas/OWNERS new file mode 100644 index 0000000..28fb2d0 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas/OWNERS
@@ -0,0 +1 @@ +junov@chromium.org
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp new file mode 100644 index 0000000..1a00c5b --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp
@@ -0,0 +1,95 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "modules/offscreencanvas/OffscreenCanvas.h" + +#include "core/html/canvas/CanvasContextCreationAttributes.h" +#include "modules/offscreencanvas/OffscreenCanvasRenderingContext.h" +#include "modules/offscreencanvas/OffscreenCanvasRenderingContextFactory.h" +#include "modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h" +#include "wtf/MathExtras.h" + +namespace blink { + +OffscreenCanvas* OffscreenCanvas::create(unsigned width, unsigned height) +{ + return new OffscreenCanvas(IntSize(clampTo<int>(width), clampTo<int>(height))); +} + +void OffscreenCanvas::setWidth(unsigned width) +{ + m_size.setWidth(clampTo<int>(width)); +} + +void OffscreenCanvas::setHeight(unsigned height) +{ + m_size.setHeight(clampTo<int>(height)); +} + +OffscreenCanvas::OffscreenCanvas(const IntSize& size) + : m_size(size) +{ +} + +OffscreenCanvasRenderingContext2D* OffscreenCanvas::getContext(const String& id, const CanvasContextCreationAttributes& attributes) +{ + OffscreenCanvasRenderingContext::ContextType contextType = OffscreenCanvasRenderingContext::contextTypeFromId(id); + + // Unknown type. + if (contextType == OffscreenCanvasRenderingContext::ContextTypeCount) + return nullptr; + + OffscreenCanvasRenderingContextFactory* factory = getRenderingContextFactory(contextType); + if (!factory) + return nullptr; + + if (m_context) { + if (m_context->contextType() != contextType) { + factory->onError(this, "OffscreenCanvas has an existing context of a different type"); + return nullptr; + } + } else { + m_context = factory->create(this, attributes); + } + + // TODO: When there're more than one context type implemented in the future, + // the return type here should be changed to base class of all Offscreen + // context types. + return static_cast<OffscreenCanvasRenderingContext2D*>(m_context.get()); +} + +OffscreenCanvasRenderingContext2D* OffscreenCanvas::renderingContext() const +{ + // TODO: When there're more than one context type implemented in the future, + // the return type here should be changed to base class of all Offscreen + // context types. + return static_cast<OffscreenCanvasRenderingContext2D*>(m_context.get()); +} + +OffscreenCanvas::ContextFactoryVector& OffscreenCanvas::renderingContextFactories() +{ + DEFINE_STATIC_LOCAL(ContextFactoryVector, s_contextFactories, (OffscreenCanvasRenderingContext::ContextTypeCount)); + return s_contextFactories; +} + +OffscreenCanvasRenderingContextFactory* OffscreenCanvas::getRenderingContextFactory(int type) +{ + ASSERT(type < OffscreenCanvasRenderingContext::ContextTypeCount); + return renderingContextFactories()[type].get(); +} + +void OffscreenCanvas::registerRenderingContextFactory(PassOwnPtr<OffscreenCanvasRenderingContextFactory> renderingContextFactory) +{ + OffscreenCanvasRenderingContext::ContextType type = renderingContextFactory->contextType(); + ASSERT(type < OffscreenCanvasRenderingContext::ContextTypeCount); + ASSERT(!renderingContextFactories()[type]); + renderingContextFactories()[type] = renderingContextFactory; +} + +DEFINE_TRACE(OffscreenCanvas) +{ + visitor->trace(m_context); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h new file mode 100644 index 0000000..abfc419 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h
@@ -0,0 +1,54 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OffscreenCanvas_h +#define OffscreenCanvas_h + +#include "bindings/core/v8/ScriptPromise.h" +#include "bindings/core/v8/ScriptState.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "modules/ModulesExport.h" +#include "platform/geometry/IntSize.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class CanvasContextCreationAttributes; +class OffscreenCanvasRenderingContext; +class OffscreenCanvasRenderingContext2D; +class OffscreenCanvasRenderingContextFactory; + +class MODULES_EXPORT OffscreenCanvas final : public GarbageCollectedFinalized<OffscreenCanvas>, public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); +public: + static OffscreenCanvas* create(unsigned width, unsigned height); + ~OffscreenCanvas() {} + + IntSize size() const { return m_size; } + unsigned width() const { return m_size.width(); } + unsigned height() const { return m_size.height(); } + void setWidth(unsigned); + void setHeight(unsigned); + + OffscreenCanvasRenderingContext2D* getContext(const String&, const CanvasContextCreationAttributes&); + OffscreenCanvasRenderingContext2D* renderingContext() const; + + static void registerRenderingContextFactory(PassOwnPtr<OffscreenCanvasRenderingContextFactory>); + + DECLARE_VIRTUAL_TRACE(); + +private: + OffscreenCanvas(const IntSize&); + + using ContextFactoryVector = Vector<OwnPtr<OffscreenCanvasRenderingContextFactory>>; + static ContextFactoryVector& renderingContextFactories(); + static OffscreenCanvasRenderingContextFactory* getRenderingContextFactory(int); + + Member<OffscreenCanvasRenderingContext> m_context; + IntSize m_size; +}; + +} // namespace blink + +#endif // OffscreenCanvas_h
diff --git a/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.idl b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl similarity index 60% rename from third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.idl rename to third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl index be5bf91..b1436b0 100644 --- a/third_party/WebKit/Source/core/html/canvas/OffscreenCanvas.idl +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Note: If there're more context types implemented, they should be added here +// to form a union type of OffscreenCanvasRenderingContext +typedef OffscreenCanvasRenderingContext2D OffscreenRenderingContext; + [ Constructor([EnforceRange] unsigned long width, [EnforceRange] unsigned long height), GarbageCollected, @@ -10,4 +14,6 @@ ] interface OffscreenCanvas { [EnforceRange] attribute unsigned long width; [EnforceRange] attribute unsigned long height; + + OffscreenRenderingContext? getContext(DOMString contextId, optional CanvasContextCreationAttributes attributes); };
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.cpp b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.cpp new file mode 100644 index 0000000..5b3234c6 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.cpp
@@ -0,0 +1,30 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "modules/offscreencanvas/OffscreenCanvasRenderingContext.h" + +namespace blink { + +OffscreenCanvasRenderingContext::OffscreenCanvasRenderingContext(OffscreenCanvas* canvas) + : m_offscreenCanvas(canvas) +{ +} + +OffscreenCanvasRenderingContext::ContextType OffscreenCanvasRenderingContext::contextTypeFromId(const String& id) +{ + if (id == "2d") + return Context2d; + if (id == "webgl") + return ContextWebgl; + if (id == "webgl2") + return ContextWebgl2; + return ContextTypeCount; +} + +DEFINE_TRACE(OffscreenCanvasRenderingContext) +{ + visitor->trace(m_offscreenCanvas); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h new file mode 100644 index 0000000..b47aa08 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h
@@ -0,0 +1,40 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OffscreenCanvasRenderingContext_h +#define OffscreenCanvasRenderingContext_h + +#include "modules/ModulesExport.h" +#include "modules/offscreencanvas/OffscreenCanvas.h" + +namespace blink { + +class MODULES_EXPORT OffscreenCanvasRenderingContext : public GarbageCollectedFinalized<OffscreenCanvasRenderingContext>, public ScriptWrappable { + WTF_MAKE_NONCOPYABLE(OffscreenCanvasRenderingContext); +public: + virtual ~OffscreenCanvasRenderingContext() { } + enum ContextType { + Context2d = 0, + ContextWebgl = 1, + ContextWebgl2 = 2, + ContextTypeCount + }; + static ContextType contextTypeFromId(const String& id); + + OffscreenCanvas* offscreenCanvas() const { return m_offscreenCanvas; } + virtual ContextType contextType() const = 0; + + virtual bool is2d() const { return false; } + +protected: + OffscreenCanvasRenderingContext(OffscreenCanvas*); + DECLARE_VIRTUAL_TRACE(); + +private: + Member<OffscreenCanvas> m_offscreenCanvas; +}; + +} // namespace blink + +#endif // OffscreenCanvasRenderingContext_h
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContextFactory.h b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContextFactory.h new file mode 100644 index 0000000..9892cc7 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContextFactory.h
@@ -0,0 +1,31 @@ +// Copyright (c) 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OffscreenCanvasRenderingContextFactory_h +#define OffscreenCanvasRenderingContextFactory_h + +#include "wtf/Allocator.h" +#include "wtf/PassRefPtr.h" + +namespace blink { + +class CanvasContextCreationAttributes; +class OffscreenCanvas; +class OffscreenCanvasRenderingContext; + +class OffscreenCanvasRenderingContextFactory { + USING_FAST_MALLOC(OffscreenCanvasRenderingContextFactory); + WTF_MAKE_NONCOPYABLE(OffscreenCanvasRenderingContextFactory); +public: + OffscreenCanvasRenderingContextFactory() = default; + virtual ~OffscreenCanvasRenderingContextFactory() { } + + virtual OffscreenCanvasRenderingContext* create(OffscreenCanvas*, const CanvasContextCreationAttributes&) = 0; + virtual OffscreenCanvasRenderingContext::ContextType contextType() const = 0; + virtual void onError(OffscreenCanvas*, const String& error) = 0; +}; + +} // namespace blink + +#endif // OffscreenCanvasRenderingContextFactory_h
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS b/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS new file mode 100644 index 0000000..28fb2d0 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS
@@ -0,0 +1 @@ +junov@chromium.org
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp new file mode 100644 index 0000000..3349165 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -0,0 +1,128 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h" + +#include "bindings/modules/v8/UnionTypesModules.h" +#include "platform/NotImplemented.h" +#include "wtf/Assertions.h" + +#define UNIMPLEMENTED ASSERT_NOT_REACHED + +namespace blink { + +OffscreenCanvasRenderingContext2D::~OffscreenCanvasRenderingContext2D() +{ +} + +OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(OffscreenCanvas* canvas, const CanvasContextCreationAttributes& attrs) + : OffscreenCanvasRenderingContext(canvas) + , m_hasAlpha(attrs.alpha()) +{ +} + +DEFINE_TRACE(OffscreenCanvasRenderingContext2D) +{ + OffscreenCanvasRenderingContext::trace(visitor); + BaseRenderingContext2D::trace(visitor); +} + +// BaseRenderingContext2D implementation +bool OffscreenCanvasRenderingContext2D::originClean() const +{ + notImplemented(); + return true; +} + +void OffscreenCanvasRenderingContext2D::setOriginTainted() +{ + notImplemented(); +} + +bool OffscreenCanvasRenderingContext2D::wouldTaintOrigin(CanvasImageSource* source) +{ + notImplemented(); + return false; +} + +int OffscreenCanvasRenderingContext2D::width() const +{ + return offscreenCanvas()->height(); +} + +int OffscreenCanvasRenderingContext2D::height() const +{ + return offscreenCanvas()->width(); +} + +bool OffscreenCanvasRenderingContext2D::hasImageBuffer() const +{ + notImplemented(); + return false; +} + +ImageBuffer* OffscreenCanvasRenderingContext2D::imageBuffer() const +{ + notImplemented(); + return nullptr; +} + +bool OffscreenCanvasRenderingContext2D::parseColorOrCurrentColor(Color&, const String& colorString) const +{ + notImplemented(); + return false; +} + +SkCanvas* OffscreenCanvasRenderingContext2D::drawingCanvas() const +{ + notImplemented(); + return nullptr; +} + +SkCanvas* OffscreenCanvasRenderingContext2D::existingDrawingCanvas() const +{ + notImplemented(); + return nullptr; +} + +void OffscreenCanvasRenderingContext2D::disableDeferral(DisableDeferralReason) +{ + notImplemented(); +} + +AffineTransform OffscreenCanvasRenderingContext2D::baseTransform() const +{ + notImplemented(); + return 0; +} + +void OffscreenCanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect) +{ + notImplemented(); +} + +bool OffscreenCanvasRenderingContext2D::stateHasFilter() +{ + notImplemented(); + return false; +} + +SkImageFilter* OffscreenCanvasRenderingContext2D::stateGetFilter() +{ + notImplemented(); + return nullptr; +} + +void OffscreenCanvasRenderingContext2D::validateStateStack() +{ + notImplemented(); +} + +bool OffscreenCanvasRenderingContext2D::isContextLost() const +{ + notImplemented(); + return false; +} + +}
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h new file mode 100644 index 0000000..1401fbc --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -0,0 +1,80 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OffscreenCanvasRenderingContext2D_h +#define OffscreenCanvasRenderingContext2D_h + +#include "core/html/canvas/CanvasContextCreationAttributes.h" +#include "modules/canvas2d/BaseRenderingContext2D.h" +#include "modules/offscreencanvas/OffscreenCanvasRenderingContext.h" +#include "modules/offscreencanvas/OffscreenCanvasRenderingContextFactory.h" + +namespace blink { + +class MODULES_EXPORT OffscreenCanvasRenderingContext2D final : public OffscreenCanvasRenderingContext, public BaseRenderingContext2D { + DEFINE_WRAPPERTYPEINFO(); + WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(OffscreenCanvasRenderingContext2D); +public: + class Factory : public OffscreenCanvasRenderingContextFactory { + public: + Factory() {} + ~Factory() override {} + + OffscreenCanvasRenderingContext* create(OffscreenCanvas* canvas, const CanvasContextCreationAttributes& attrs) override + { + return new OffscreenCanvasRenderingContext2D(canvas, attrs); + } + + OffscreenCanvasRenderingContext::ContextType contextType() const override + { + return OffscreenCanvasRenderingContext::Context2d; + } + + void onError(OffscreenCanvas* canvas, const String& error) override {} + }; + + // OffscreenCanvasRenderingContext implementation + ~OffscreenCanvasRenderingContext2D() override; + ContextType contextType() const override { return Context2d; } + bool is2d() const override { return true; } + + // BaseRenderingContext2D implementation + bool originClean() const final; + void setOriginTainted() final; + bool wouldTaintOrigin(CanvasImageSource*) final; + + int width() const final; + int height() const final; + + bool hasImageBuffer() const final; + ImageBuffer* imageBuffer() const final; + + bool parseColorOrCurrentColor(Color&, const String& colorString) const final; + + SkCanvas* drawingCanvas() const final; + SkCanvas* existingDrawingCanvas() const final; + void disableDeferral(DisableDeferralReason) final; + + AffineTransform baseTransform() const final; + void didDraw(const SkIRect& dirtyRect) final; + + bool stateHasFilter() final; + SkImageFilter* stateGetFilter() final; + + void validateStateStack() final; + + bool hasAlpha() const override { return m_hasAlpha; } + bool isContextLost() const override; + +protected: + OffscreenCanvasRenderingContext2D(OffscreenCanvas*, const CanvasContextCreationAttributes& attrs); + DECLARE_VIRTUAL_TRACE(); + +private: + bool m_hasAlpha; +}; + +} // namespace blink + +#endif // OffscreenCanvasRenderingContext2D_h
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl new file mode 100644 index 0000000..5c33a57 --- /dev/null +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
@@ -0,0 +1,16 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Note: The official spec is WIP at wiki.whatwg.org/wiki/OffscreenCanvas. + +[ + GarbageCollected, + Exposed=(Window,Worker), + RuntimeEnabled=ExperimentalCanvasFeatures, +] interface OffscreenCanvasRenderingContext2D { + // back-reference to the canvas + readonly attribute OffscreenCanvas offscreenCanvas; +}; + +OffscreenCanvasRenderingContext2D implements CanvasPathMethods;
diff --git a/third_party/WebKit/Source/modules/push_messaging/PushManager.cpp b/third_party/WebKit/Source/modules/push_messaging/PushManager.cpp index 7d5eacd0..0f5a2ff 100644 --- a/third_party/WebKit/Source/modules/push_messaging/PushManager.cpp +++ b/third_party/WebKit/Source/modules/push_messaging/PushManager.cpp
@@ -34,29 +34,11 @@ return webPushProvider; } -String bufferSourceToString(const ArrayBufferOrArrayBufferView& applicationServerKey, ExceptionState& exceptionState) +WebPushSubscriptionOptions toWebPushSubscriptionOptions(const PushSubscriptionOptions& options) { - // Check the validity of the sender info. It must be a 65 byte unencrypted key, - // which has the byte 0x04 as the first byte as a marker. - char* input; - int length; - if (applicationServerKey.isArrayBuffer()) { - input = static_cast<char*>( - applicationServerKey.getAsArrayBuffer()->data()); - length = applicationServerKey.getAsArrayBuffer()->byteLength(); - } else if (applicationServerKey.isArrayBufferView()) { - input = static_cast<char*>( - applicationServerKey.getAsArrayBufferView()->buffer()->data()); - length = applicationServerKey.getAsArrayBufferView()->buffer()->byteLength(); - } else { - ASSERT_NOT_REACHED(); - return String(); - } - - if (length == 65 && input[0] == 0x04) - return WebString::fromUTF8(input, length); - exceptionState.throwDOMException(InvalidAccessError, "The provided applicationServerKey is not valid."); - return String(); + WebPushSubscriptionOptions webOptions; + webOptions.userVisibleOnly = options.userVisibleOnly(); + return webOptions; } } // namespace @@ -67,26 +49,11 @@ ASSERT(registration); } -WebPushSubscriptionOptions PushManager::toWebPushSubscriptionOptions(const PushSubscriptionOptions& options, ExceptionState& exceptionState) -{ - WebPushSubscriptionOptions webOptions; - webOptions.userVisibleOnly = options.userVisibleOnly(); - if (options.hasApplicationServerKey()) { - webOptions.applicationServerKey = bufferSourceToString(options.applicationServerKey(), - exceptionState); - } - return webOptions; -} - -ScriptPromise PushManager::subscribe(ScriptState* scriptState, const PushSubscriptionOptions& options, ExceptionState& exceptionState) +ScriptPromise PushManager::subscribe(ScriptState* scriptState, const PushSubscriptionOptions& options) { if (!m_registration->active()) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "Subscription failed - no active Service Worker")); - const WebPushSubscriptionOptions& webOptions = toWebPushSubscriptionOptions(options, exceptionState); - if (exceptionState.hadException()) - return ScriptPromise(); - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); @@ -97,9 +64,9 @@ Document* document = toDocument(scriptState->executionContext()); if (!document->domWindow() || !document->frame()) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "Document is detached from window.")); - PushController::clientFrom(document->frame()).subscribe(m_registration->webRegistration(), webOptions, new PushSubscriptionCallbacks(resolver, m_registration)); + PushController::clientFrom(document->frame()).subscribe(m_registration->webRegistration(), toWebPushSubscriptionOptions(options), new PushSubscriptionCallbacks(resolver, m_registration)); } else { - pushProvider()->subscribe(m_registration->webRegistration(), webOptions, new PushSubscriptionCallbacks(resolver, m_registration)); + pushProvider()->subscribe(m_registration->webRegistration(), toWebPushSubscriptionOptions(options), new PushSubscriptionCallbacks(resolver, m_registration)); } return promise; @@ -114,7 +81,7 @@ return promise; } -ScriptPromise PushManager::permissionState(ScriptState* scriptState, const PushSubscriptionOptions& options, ExceptionState& exceptionState) +ScriptPromise PushManager::permissionState(ScriptState* scriptState, const PushSubscriptionOptions& options) { if (scriptState->executionContext()->isDocument()) { Document* document = toDocument(scriptState->executionContext()); @@ -125,7 +92,7 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); - pushProvider()->getPermissionStatus(m_registration->webRegistration(), toWebPushSubscriptionOptions(options, exceptionState), new PushPermissionStatusCallbacks(resolver)); + pushProvider()->getPermissionStatus(m_registration->webRegistration(), toWebPushSubscriptionOptions(options), new PushPermissionStatusCallbacks(resolver)); return promise; }
diff --git a/third_party/WebKit/Source/modules/push_messaging/PushManager.h b/third_party/WebKit/Source/modules/push_messaging/PushManager.h index a4c07292..d6d9cfd 100644 --- a/third_party/WebKit/Source/modules/push_messaging/PushManager.h +++ b/third_party/WebKit/Source/modules/push_messaging/PushManager.h
@@ -6,20 +6,16 @@ #define PushManager_h #include "bindings/core/v8/ScriptWrappable.h" -#include "bindings/modules/v8/UnionTypesModules.h" -#include "modules/ModulesExport.h" #include "platform/heap/Handle.h" namespace blink { -class ExceptionState; class PushSubscriptionOptions; class ScriptPromise; class ScriptState; class ServiceWorkerRegistration; -struct WebPushSubscriptionOptions; -class MODULES_EXPORT PushManager final : public GarbageCollected<PushManager>, public ScriptWrappable { +class PushManager final : public GarbageCollected<PushManager>, public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: static PushManager* create(ServiceWorkerRegistration* registration) @@ -27,17 +23,12 @@ return new PushManager(registration); } - ScriptPromise subscribe(ScriptState*, const PushSubscriptionOptions&, - ExceptionState&); + ScriptPromise subscribe(ScriptState*, const PushSubscriptionOptions&); ScriptPromise getSubscription(ScriptState*); - ScriptPromise permissionState(ScriptState*, const PushSubscriptionOptions&, - ExceptionState&); + ScriptPromise permissionState(ScriptState*, const PushSubscriptionOptions&); DECLARE_TRACE(); - static WebPushSubscriptionOptions toWebPushSubscriptionOptions( - const PushSubscriptionOptions&, ExceptionState&); - private: explicit PushManager(ServiceWorkerRegistration*);
diff --git a/third_party/WebKit/Source/modules/push_messaging/PushManager.idl b/third_party/WebKit/Source/modules/push_messaging/PushManager.idl index 0c4ff864..ddb6139 100644 --- a/third_party/WebKit/Source/modules/push_messaging/PushManager.idl +++ b/third_party/WebKit/Source/modules/push_messaging/PushManager.idl
@@ -9,7 +9,7 @@ GarbageCollected, RuntimeEnabled=PushMessaging, ] interface PushManager { - [CallWith=ScriptState, RaisesException] Promise<PushSubscription> subscribe(optional PushSubscriptionOptions options); + [CallWith=ScriptState] Promise<PushSubscription> subscribe(optional PushSubscriptionOptions options); [CallWith=ScriptState] Promise<PushSubscription?> getSubscription(); - [CallWith=ScriptState, RaisesException] Promise permissionState(optional PushSubscriptionOptions options); + [CallWith=ScriptState] Promise permissionState(optional PushSubscriptionOptions options); };
diff --git a/third_party/WebKit/Source/modules/push_messaging/PushManagerTest.cpp b/third_party/WebKit/Source/modules/push_messaging/PushManagerTest.cpp deleted file mode 100644 index e5e7f8f..0000000 --- a/third_party/WebKit/Source/modules/push_messaging/PushManagerTest.cpp +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "modules/push_messaging/PushManager.h" - -#include "bindings/modules/v8/UnionTypesModules.h" -#include "core/dom/DOMArrayBuffer.h" -#include "modules/push_messaging/PushSubscriptionOptions.h" -#include "public/platform/WebString.h" -#include "public/platform/modules/push_messaging/WebPushSubscriptionOptions.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace blink { -namespace { - -const char kValidKeyMarker = 0x04; -const unsigned kValidKeyLength = 65; - -TEST(PushManagerTest, ValidSenderKey) -{ - uint8_t senderKey[kValidKeyLength]; - memset(senderKey, 0, sizeof(senderKey)); - senderKey[0] = kValidKeyMarker; - PushSubscriptionOptions options; - options.setApplicationServerKey( - ArrayBufferOrArrayBufferView::fromArrayBuffer( - DOMArrayBuffer::create(senderKey, kValidKeyLength))); - - TrackExceptionState exceptionState; - WebPushSubscriptionOptions output = PushManager::toWebPushSubscriptionOptions(options, exceptionState); - EXPECT_FALSE(exceptionState.hadException()); - EXPECT_EQ(output.applicationServerKey.length(), kValidKeyLength); - EXPECT_EQ(output.applicationServerKey, WebString::fromUTF8(reinterpret_cast<const char*>(senderKey), kValidKeyLength)); -} - -TEST(PushManagerTest, InvalidSenderKeyMarker) -{ - uint8_t senderKey[kValidKeyLength]; - memset(senderKey, 0, sizeof(senderKey)); - senderKey[0] = 0x05; - PushSubscriptionOptions options; - options.setApplicationServerKey( - ArrayBufferOrArrayBufferView::fromArrayBuffer( - DOMArrayBuffer::create(senderKey, kValidKeyLength))); - - TrackExceptionState exceptionState; - WebPushSubscriptionOptions output = PushManager::toWebPushSubscriptionOptions(options, exceptionState); - EXPECT_TRUE(exceptionState.hadException()); -} - -TEST(PushManagerTest, InvalidSenderKeyLength) -{ - uint8_t senderKey[kValidKeyLength - 1]; - memset(senderKey, 0, sizeof(senderKey)); - senderKey[0] = kValidKeyMarker; - PushSubscriptionOptions options; - options.setApplicationServerKey( - ArrayBufferOrArrayBufferView::fromArrayBuffer( - DOMArrayBuffer::create(senderKey, kValidKeyLength - 1))); - - TrackExceptionState exceptionState; - WebPushSubscriptionOptions output = PushManager::toWebPushSubscriptionOptions(options, exceptionState); - EXPECT_TRUE(exceptionState.hadException()); -} - -} // namespace -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/push_messaging/PushSubscriptionOptions.idl b/third_party/WebKit/Source/modules/push_messaging/PushSubscriptionOptions.idl index 48af6cc..f034242 100644 --- a/third_party/WebKit/Source/modules/push_messaging/PushSubscriptionOptions.idl +++ b/third_party/WebKit/Source/modules/push_messaging/PushSubscriptionOptions.idl
@@ -6,5 +6,4 @@ dictionary PushSubscriptionOptions { boolean userVisibleOnly = false; - [RuntimeEnabled=PushSubscriptionRestrictions] BufferSource applicationServerKey; };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp index cb4e2da8..8c0af13 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
@@ -92,7 +92,7 @@ { StubScriptFunction resolved, rejected; promise.then(resolved.function(scriptState), rejected.function(scriptState)); - v8::MicrotasksScope::PerformCheckpoint(promise.isolate()); + promise.isolate()->RunMicrotasks(); EXPECT_EQ(0ul, resolved.callCount()); EXPECT_EQ(1ul, rejected.callCount()); if (rejected.callCount())
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in index bd06d46..8a0bcf0 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -151,7 +151,6 @@ PromiseRejectionEvent status=stable PushMessaging status=stable PushMessagingData status=stable -PushSubscriptionRestrictions status=experimental QuotaPromise status=experimental ReducedReferrerGranularity RenderingPipelineThrottling status=experimental
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp index 48e587b..39c0c02 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
@@ -45,6 +45,7 @@ #include "platform/fonts/SimpleFontData.h" #include "platform/fonts/shaping/HarfBuzzShaper.h" #include "wtf/HashMap.h" +#include "wtf/MathExtras.h" namespace blink { @@ -138,7 +139,9 @@ static hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value) { - return SkScalarToFixed(value); + // We treat HarfBuzz hb_position_t as 16.16 fixed-point. + static const int kHbPosition1 = 1 << 16; + return clampTo<int>(value * kHbPosition1); } static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint, hb_position_t* width, hb_glyph_extents_t* extents)
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp index 69cbac7..5a67eb1 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.cpp +++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -126,6 +126,7 @@ s_partitionAllocSizeAtLastGC = WTF::Partitions::totalSizeOfCommittedPages(); s_estimatedMarkingTimePerByte = 0.0; s_isLowEndDevice = base::SysInfo::IsLowEndDevice(); + s_lastGCReason = BlinkGC::NumberOfGCReason; #if ENABLE(ASSERT) s_gcGeneration = 1; #endif @@ -138,19 +139,14 @@ void Heap::shutdown() { + ASSERT(s_markingStack); + if (Platform::current() && Platform::current()->currentThread()) Platform::current()->unregisterMemoryDumpProvider(BlinkGCMemoryDumpProvider::instance()); - s_shutdownCalled = true; - ThreadState::shutdownHeapIfNecessary(); -} -void Heap::doShutdown() -{ - // We don't want to call doShutdown() twice. - if (!s_markingStack) - return; + // The main thread must be the last thread that gets detached. + RELEASE_ASSERT(ThreadState::attachedThreads().size() == 0); - ASSERT(!ThreadState::attachedThreads().size()); delete s_heapDoesNotContainCache; s_heapDoesNotContainCache = nullptr; delete s_freePagePool; @@ -425,6 +421,8 @@ DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gcReasonHistogram, new EnumerationHistogram("BlinkGC.GCReason", BlinkGC::NumberOfGCReason)); gcReasonHistogram.count(reason); + s_lastGCReason = reason; + Heap::reportMemoryUsageHistogram(); WTF::Partitions::reportMemoryUsageHistogram(); @@ -690,6 +688,7 @@ size_t Heap::s_partitionAllocSizeAtLastGC = 0; double Heap::s_estimatedMarkingTimePerByte = 0.0; bool Heap::s_isLowEndDevice = false; +BlinkGC::GCReason Heap::s_lastGCReason = BlinkGC::NumberOfGCReason; #if ENABLE(ASSERT) uint16_t Heap::s_gcGeneration = 0; #endif
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h index a2081bd..95fac29 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.h +++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -108,7 +108,6 @@ public: static void init(); static void shutdown(); - static void doShutdown(); static CrossThreadPersistentRegion& crossThreadPersistentRegion(); @@ -296,6 +295,7 @@ static void reportMemoryUsageHistogram(); static void reportMemoryUsageForTracing(); static bool isLowEndDevice() { return s_isLowEndDevice; } + static BlinkGC::GCReason lastGCReason() { return s_lastGCReason; } #if ENABLE(ASSERT) static uint16_t gcGeneration() { return s_gcGeneration; } @@ -330,6 +330,7 @@ static size_t s_partitionAllocSizeAtLastGC; static double s_estimatedMarkingTimePerByte; static bool s_isLowEndDevice; + static BlinkGC::GCReason s_lastGCReason; #if ENABLE(ASSERT) static uint16_t s_gcGeneration; #endif
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp index 01ed8598..8446223 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -235,19 +235,6 @@ attachedThreads().remove(state); state->~ThreadState(); } - shutdownHeapIfNecessary(); -} - -void ThreadState::shutdownHeapIfNecessary() -{ - // We don't need to enter a safe point before acquiring threadAttachMutex - // because this thread is already detached. - - MutexLocker locker(threadAttachMutex()); - // We start shutting down the heap if there is no running thread - // and Heap::shutdown() is already called. - if (!attachedThreads().size() && Heap::s_shutdownCalled) - Heap::doShutdown(); } void ThreadState::attach() @@ -323,7 +310,6 @@ state->cleanup(); RELEASE_ASSERT(state->gcState() == ThreadState::NoGCScheduled); delete state; - shutdownHeapIfNecessary(); } void ThreadState::visitPersistentRoots(Visitor* visitor) @@ -1148,6 +1134,26 @@ collectionRateHistogram.count(static_cast<int>(100 * collectionRate)); DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForSweepHistogram, ("BlinkGC.TimeForSweepingAllObjects", 1, 10 * 1000, 50)); timeForSweepHistogram.count(m_accumulatedSweepingTime); + + +#define COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(GCReason) \ + case BlinkGC::GCReason: { \ + DEFINE_STATIC_LOCAL(CustomCountHistogram, histogram, \ + ("BlinkGC.CollectionRate_" #GCReason, 1, 100, 20)); \ + histogram.count(static_cast<int>(100 * collectionRate)); \ + break; \ + } + + switch (Heap::lastGCReason()) { + COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(IdleGC) + COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(PreciseGC) + COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(ConservativeGC) + COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(ForcedGC) + COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(MemoryPressureGC) + COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(PageNavigationGC) + default: + break; + } } switch (gcState()) { @@ -1340,18 +1346,6 @@ } } -void ThreadState::removeInterruptor(BlinkGCInterruptor* interruptor) -{ - ASSERT(checkThread()); - SafePointScope scope(BlinkGC::HeapPointersOnStack); - { - MutexLocker locker(threadAttachMutex()); - size_t index = m_interruptors.find(interruptor); - RELEASE_ASSERT(index != kNotFound); - m_interruptors.remove(index); - } -} - #if defined(LEAK_SANITIZER) void ThreadState::registerStaticPersistentNode(PersistentNode* node) {
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h index 3337384..ed066d6 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.h +++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -186,7 +186,6 @@ // thread. static void init(); static void shutdown(); - static void shutdownHeapIfNecessary(); bool isTerminating() { return m_isTerminating; } static void attachMainThread(); @@ -343,7 +342,6 @@ bool isAtSafePoint() const { return m_atSafePoint; } void addInterruptor(PassOwnPtr<BlinkGCInterruptor>); - void removeInterruptor(BlinkGCInterruptor*); void recordStackEnd(intptr_t* endOfStack) {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp index 58003b0..474708a 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp
@@ -153,12 +153,20 @@ v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String& string) { - return v8::String::NewFromUtf8(isolate, string.utf8().data(), v8::NewStringType::kNormal).ToLocalChecked(); + if (string.isNull()) + return v8::String::Empty(isolate); + if (string.is8Bit()) + return v8::String::NewFromOneByte(isolate, string.characters8(), v8::NewStringType::kNormal, string.length()).ToLocalChecked(); + return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*>(string.characters16()), v8::NewStringType::kNormal, string.length()).ToLocalChecked(); } v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, const String& string) { - return v8::String::NewFromUtf8(isolate, string.utf8().data(), v8::NewStringType::kInternalized).ToLocalChecked(); + if (string.isNull()) + return v8::String::Empty(isolate); + if (string.is8Bit()) + return v8::String::NewFromOneByte(isolate, string.characters8(), v8::NewStringType::kInternalized, string.length()).ToLocalChecked(); + return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*>(string.characters16()), v8::NewStringType::kInternalized, string.length()).ToLocalChecked(); } String toWTFString(v8::Local<v8::String> value)
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp index 0b34d329..3fa474fa 100644 --- a/third_party/WebKit/Source/web/WebKit.cpp +++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -92,11 +92,20 @@ // Doing so may cause hard to reproduce crashes. static bool s_webKitInitialized = false; +static ModulesInitializer& modulesInitializer() +{ + DEFINE_STATIC_LOCAL(OwnPtr<ModulesInitializer>, initializer, (adoptPtr(new ModulesInitializer))); + return *initializer; +} + void initialize(Platform* platform) { initializeWithoutV8(platform); - V8Initializer::initializeMainThreadIfNeeded(); + modulesInitializer().init(); + setIndexedDBClientCreateFunction(IndexedDBClientImpl::create); + + V8Initializer::initializeMainThread(); OwnPtr<V8IsolateInterruptor> interruptor = adoptPtr(new V8IsolateInterruptor(V8PerIsolateData::mainThreadIsolate())); ThreadState::current()->addInterruptor(interruptor.release()); @@ -141,12 +150,6 @@ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size); } -static ModulesInitializer& modulesInitializer() -{ - DEFINE_STATIC_LOCAL(OwnPtr<ModulesInitializer>, initializer, (adoptPtr(new ModulesInitializer))); - return *initializer; -} - void initializeWithoutV8(Platform* platform) { ASSERT(!s_webKitInitialized); @@ -166,10 +169,6 @@ ASSERT(!s_gcTaskRunner); s_gcTaskRunner = new GCTaskRunner(currentThread); } - - modulesInitializer().init(); - - setIndexedDBClientCreateFunction(IndexedDBClientImpl::create); } void shutdown() @@ -207,10 +206,9 @@ ThreadState::current()->unregisterTraceDOMWrappers(); - v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); - V8PerIsolateData::willBeDestroyed(isolate); + V8Initializer::shutdownMainThread(); - V8PerIsolateData::destroy(isolate); + modulesInitializer().shutdown(); shutdownWithoutV8(); } @@ -218,8 +216,6 @@ void shutdownWithoutV8() { ASSERT(isMainThread()); - modulesInitializer().shutdown(); - // currentThread() is null if we are running on a thread without a message loop. if (Platform::current()->currentThread()) { ASSERT(s_gcTaskRunner);
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index 78c617d0..b9822d6 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -310,6 +310,14 @@ } } +// Flakily failing on Mac ASAN. +// https://crbug.com/592771 +#if OS(MACOSX) && defined(ADDRESS_SANITIZER) +#define MAYBE(test) DISABLED_##test +#else +#define MAYBE(test) test +#endif + INSTANTIATE_TEST_CASE_P(All, ParameterizedWebFrameTest, ::testing::Values( ParameterizedWebFrameTestConfig::Default, ParameterizedWebFrameTestConfig::RootLayerScrolls)); @@ -325,7 +333,6 @@ webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html"); // Now retrieve the frames text and test it only includes visible elements. - webViewHelper.webView()->updateAllLifecyclePhases(); std::string content = WebFrameContentDumper::dumpFrameTreeAsText(webViewHelper.webView()->mainFrame()->toWebLocalFrame(), 1024).utf8(); EXPECT_NE(std::string::npos, content.find(" visible paragraph")); EXPECT_NE(std::string::npos, content.find(" visible iframe")); @@ -499,8 +506,6 @@ FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;"); - webViewHelper.webView()->updateAllLifecyclePhases(); - std::string content = WebFrameContentDumper::dumpFrameTreeAsText(webViewHelper.webView()->mainFrame()->toWebLocalFrame(), 1024).utf8(); EXPECT_EQ("http://internal.test:0/" + fileName, content); } @@ -520,8 +525,6 @@ FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;"); - webViewHelper.webView()->updateAllLifecyclePhases(); - std::string content = WebFrameContentDumper::dumpFrameTreeAsText(webViewHelper.webView()->mainFrame()->toWebLocalFrame(), 1024).utf8(); EXPECT_EQ("http://internal.test:0/" + fileName, content); } @@ -1040,7 +1043,7 @@ EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor()); // Force the layout to happen before leaving the test. - webViewHelper.webView()->updateAllLifecyclePhases(); + WebFrameContentDumper::dumpFrameTreeAsText(webViewHelper.webView()->mainFrame()->toWebLocalFrame(), 1024).utf8(); } TEST_P(ParameterizedWebFrameTest, FixedLayoutInitializeAtMinimumScale) @@ -1383,7 +1386,7 @@ EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor()); } -TEST_P(ParameterizedWebFrameTest, SmallPermanentInitialPageScaleFactorIsClobbered) +TEST_P(ParameterizedWebFrameTest, MAYBE(SmallPermanentInitialPageScaleFactorIsClobbered)) { const char* pages[] = { // These pages trigger the clobbering condition. There must be a matching item in "pageScaleFactors" array. @@ -1635,7 +1638,7 @@ } -TEST_P(ParameterizedWebFrameTest, SetForceZeroLayoutHeightWorksAcrossNavigations) +TEST_P(ParameterizedWebFrameTest, MAYBE(SetForceZeroLayoutHeightWorksAcrossNavigations)) { registerMockedHttpURLLoad("200-by-300.html"); registerMockedHttpURLLoad("large-div.html"); @@ -1677,7 +1680,7 @@ EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height()); } -TEST_P(ParameterizedWebFrameTest, WideViewportAndWideContentWithInitialScale) +TEST_P(ParameterizedWebFrameTest, MAYBE(WideViewportAndWideContentWithInitialScale)) { registerMockedHttpURLLoad("wide_document_width_viewport.html"); registerMockedHttpURLLoad("white-1x1.png"); @@ -1703,7 +1706,7 @@ EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webViewImpl()->minimumPageScaleFactor()); } -TEST_P(ParameterizedWebFrameTest, WideViewportQuirkClobbersHeight) +TEST_P(ParameterizedWebFrameTest, MAYBE(WideViewportQuirkClobbersHeight)) { registerMockedHttpURLLoad("viewport-height-1000.html"); @@ -1726,7 +1729,7 @@ EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor()); } -TEST_P(ParameterizedWebFrameTest, LayoutSize320Quirk) +TEST_P(ParameterizedWebFrameTest, MAYBE(LayoutSize320Quirk)) { registerMockedHttpURLLoad("viewport/viewport-30.html"); @@ -2025,7 +2028,7 @@ EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width()); } -TEST_P(ParameterizedWebFrameTest, targetDensityDpiHigh) +TEST_P(ParameterizedWebFrameTest, MAYBE(targetDensityDpiHigh)) { registerMockedHttpURLLoad("viewport-target-densitydpi-high.html"); @@ -2056,7 +2059,7 @@ } } -TEST_P(ParameterizedWebFrameTest, targetDensityDpiDevice) +TEST_P(ParameterizedWebFrameTest, MAYBE(targetDensityDpiDevice)) { registerMockedHttpURLLoad("viewport-target-densitydpi-device.html"); @@ -2081,7 +2084,7 @@ } } -TEST_P(ParameterizedWebFrameTest, targetDensityDpiDeviceAndFixedWidth) +TEST_P(ParameterizedWebFrameTest, MAYBE(targetDensityDpiDeviceAndFixedWidth)) { registerMockedHttpURLLoad("viewport-target-densitydpi-device-and-fixed-width.html"); @@ -2887,7 +2890,7 @@ EXPECT_RECT_EQ(rectRightBottom, blockBound); } -TEST_P(ParameterizedWebFrameTest, DivMultipleTargetZoomMultipleDivsTest) +TEST_P(ParameterizedWebFrameTest, MAYBE(DivMultipleTargetZoomMultipleDivsTest)) { registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html"); @@ -3163,7 +3166,7 @@ EXPECT_FALSE(needAnimation); } -TEST_P(ParameterizedWebFrameTest, CharacterIndexAtPointWithPinchZoom) +TEST_P(ParameterizedWebFrameTest, MAYBE(CharacterIndexAtPointWithPinchZoom)) { registerMockedHttpURLLoad("sometext.html"); @@ -3614,7 +3617,6 @@ // Make sure it comes out OK. const std::string expected("Foo bar\nbaz"); - webViewHelper.webView()->updateAllLifecyclePhases(); WebString text = WebFrameContentDumper::dumpFrameTreeAsText(frame->toWebLocalFrame(), std::numeric_limits<size_t>::max()); EXPECT_EQ(expected, text.utf8()); @@ -3632,7 +3634,6 @@ ASSERT_TRUE(subframe); FrameTestHelpers::loadHTMLString(subframe, "sub<p>text", testURL); - webViewHelper.webView()->updateAllLifecyclePhases(); text = WebFrameContentDumper::dumpFrameTreeAsText(frame->toWebLocalFrame(), std::numeric_limits<size_t>::max()); EXPECT_EQ("Hello world\n\nsub\ntext", text.utf8()); @@ -3653,8 +3654,6 @@ KURL testURL = toKURL("about:blank"); FrameTestHelpers::loadHTMLString(frame, simpleSource, testURL); - webViewHelper.webView()->updateAllLifecyclePhases(); - WebString text = WebFrameContentDumper::dumpFrameTreeAsText(frame->toWebLocalFrame(), std::numeric_limits<size_t>::max()); EXPECT_EQ("Hello\n\nWorld", text.utf8()); @@ -3665,8 +3664,6 @@ EXPECT_EQ(html, WebFrameContentDumper::dumpAsMarkup(frame->toWebLocalFrame()).utf8()); - webViewHelper.webView()->updateAllLifecyclePhases(); - text = WebFrameContentDumper::dumpFrameTreeAsText(frame->toWebLocalFrame(), std::numeric_limits<size_t>::max()); EXPECT_EQ("Hello\n\nWorld", text.utf8()); @@ -4418,7 +4415,7 @@ // EXPECT_EQ("Editable 1. Editable 2. ]", selectionAsString(frame)); } -TEST_P(ParameterizedWebFrameTest, MoveRangeSelectionExtent) +TEST_P(ParameterizedWebFrameTest, MAYBE(MoveRangeSelectionExtent)) { WebLocalFrameImpl* frame; WebRect startWebRect; @@ -4452,7 +4449,7 @@ EXPECT_EQ("", selectionAsString(frame)); } -TEST_P(ParameterizedWebFrameTest, MoveRangeSelectionExtentCannotCollapse) +TEST_P(ParameterizedWebFrameTest, MAYBE(MoveRangeSelectionExtentCannotCollapse)) { WebLocalFrameImpl* frame; WebRect startWebRect; @@ -4477,7 +4474,7 @@ EXPECT_EQ("This text is initially selected.", selectionAsString(frame)); } -TEST_P(ParameterizedWebFrameTest, MoveRangeSelectionExtentScollsInputField) +TEST_P(ParameterizedWebFrameTest, MAYBE(MoveRangeSelectionExtentScollsInputField)) { WebLocalFrameImpl* frame; WebRect startWebRect; @@ -4839,7 +4836,7 @@ return event; } -TEST_P(ParameterizedWebFrameTest, DisambiguationPopup) +TEST_P(ParameterizedWebFrameTest, MAYBE(DisambiguationPopup)) { const std::string htmlFile = "disambiguation_popup.html"; registerMockedHttpURLLoad(htmlFile); @@ -4893,7 +4890,7 @@ } } -TEST_P(ParameterizedWebFrameTest, DisambiguationPopupNoContainer) +TEST_P(ParameterizedWebFrameTest, MAYBE(DisambiguationPopupNoContainer)) { registerMockedHttpURLLoad("disambiguation_popup_no_container.html"); @@ -4910,7 +4907,7 @@ EXPECT_FALSE(client.triggered()); } -TEST_P(ParameterizedWebFrameTest, DisambiguationPopupMobileSite) +TEST_P(ParameterizedWebFrameTest, MAYBE(DisambiguationPopupMobileSite)) { const std::string htmlFile = "disambiguation_popup_mobile_site.html"; registerMockedHttpURLLoad(htmlFile); @@ -4944,7 +4941,7 @@ } } -TEST_P(ParameterizedWebFrameTest, DisambiguationPopupViewportSite) +TEST_P(ParameterizedWebFrameTest, MAYBE(DisambiguationPopupViewportSite)) { const std::string htmlFile = "disambiguation_popup_viewport_site.html"; registerMockedHttpURLLoad(htmlFile); @@ -5028,7 +5025,7 @@ EXPECT_FALSE(client.triggered()); } -TEST_P(ParameterizedWebFrameTest, DisambiguationPopupBlacklist) +TEST_P(ParameterizedWebFrameTest, MAYBE(DisambiguationPopupBlacklist)) { const unsigned viewportWidth = 500; const unsigned viewportHeight = 1000; @@ -5060,7 +5057,7 @@ EXPECT_FALSE(client.triggered()); } -TEST_P(ParameterizedWebFrameTest, DisambiguationPopupPageScale) +TEST_P(ParameterizedWebFrameTest, MAYBE(DisambiguationPopupPageScale)) { registerMockedHttpURLLoad("disambiguation_popup_page_scale.html"); @@ -5143,8 +5140,6 @@ Platform::current()->unitTestSupport()->registerMockedErrorURL(URLTestHelpers::toKURL(errorURL), response, error); FrameTestHelpers::loadHistoryItem(frame, errorHistoryItem, WebHistoryDifferentDocumentLoad, WebURLRequest::UseProtocolCachePolicy); - webViewHelper.webView()->updateAllLifecyclePhases(); - WebString text = WebFrameContentDumper::dumpFrameTreeAsText(frame->toWebLocalFrame(), std::numeric_limits<size_t>::max()); EXPECT_EQ("This should appear", text.utf8()); EXPECT_TRUE(webFrameClient.commitCalled()); @@ -5258,8 +5253,6 @@ EXPECT_EQ(1U, document->markers().markersInRange(selectionRange, DocumentMarker::Spelling).size()); frame->replaceMisspelledRange("welcome"); - - webViewHelper.webView()->updateAllLifecyclePhases(); EXPECT_EQ("_welcome_.", WebFrameContentDumper::dumpFrameTreeAsText(frame, std::numeric_limits<size_t>::max()).utf8()); } @@ -6421,7 +6414,7 @@ EXPECT_EQ(500, leftRightFixed->offsetWidth()); } -TEST_P(ParameterizedWebFrameTest, FrameViewMoveWithSetFrameRect) +TEST_P(ParameterizedWebFrameTest, MAYBE(FrameViewMoveWithSetFrameRect)) { FrameTestHelpers::WebViewHelper webViewHelper(this); webViewHelper.initializeAndLoad("about:blank"); @@ -6624,7 +6617,7 @@ ASSERT_TRUE(webScrollLayer->userScrollableVertical()); } -TEST_P(ParameterizedWebFrameTest, FullscreenSubframe) +TEST_P(ParameterizedWebFrameTest, MAYBE(FullscreenSubframe)) { FakeCompositingWebViewClient client; registerMockedHttpURLLoad("fullscreen_iframe.html"); @@ -6745,7 +6738,7 @@ EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor()); } -TEST_P(ParameterizedWebFrameTest, LayoutBlockPercentHeightDescendants) +TEST_P(ParameterizedWebFrameTest, MAYBE(LayoutBlockPercentHeightDescendants)) { registerMockedHttpURLLoad("percent-height-descendants.html"); FrameTestHelpers::WebViewHelper webViewHelper(this); @@ -7079,7 +7072,6 @@ // Finally, make sure an embedder triggered load in the local frame swapped // back in works. FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html"); - std::string content = WebFrameContentDumper::dumpFrameTreeAsText(localFrame, 1024).utf8(); EXPECT_EQ("hello", content);
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index 974b3ce0..cd9d0ce6 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -2210,12 +2210,10 @@ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("display_mode.html")); WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "display_mode.html", true); - webView->updateAllLifecyclePhases(); std::string content = WebFrameContentDumper::dumpFrameTreeAsText(webView->mainFrame()->toWebLocalFrame(), 21).utf8(); EXPECT_EQ("regular-ui", content); webView->setDisplayMode(WebDisplayModeMinimalUi); - webView->updateAllLifecyclePhases(); content = WebFrameContentDumper::dumpFrameTreeAsText(webView->mainFrame()->toWebLocalFrame(), 21).utf8(); EXPECT_EQ("minimal-ui", content); m_webViewHelper.reset(); @@ -2687,7 +2685,6 @@ std::string actual = frame->selectionAsText().utf8(); const int kMaxOutputCharacters = 1024; - webView->updateAllLifecyclePhases(); std::string expected = WebFrameContentDumper::dumpFrameTreeAsText(frame, kMaxOutputCharacters).utf8(); EXPECT_EQ(expected, actual); }
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.h b/third_party/WebKit/Source/wtf/TypeTraits.h index 002ec4f..d3ef548 100644 --- a/third_party/WebKit/Source/wtf/TypeTraits.h +++ b/third_party/WebKit/Source/wtf/TypeTraits.h
@@ -64,7 +64,8 @@ static const bool value = __has_trivial_destructor(T); }; -template <typename T, typename U> class IsSubclass { +template <typename T, typename U> struct IsSubclass { +private: typedef char YesType; struct NoType { char padding[8]; @@ -77,7 +78,8 @@ static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); }; -template <typename T, template <typename... V> class U> class IsSubclassOfTemplate { +template <typename T, template <typename... V> class U> struct IsSubclassOfTemplate { +private: typedef char YesType; struct NoType { char padding[8]; @@ -91,7 +93,8 @@ }; template <typename T, template <typename V, size_t W> class U> -class IsSubclassOfTemplateTypenameSize { +struct IsSubclassOfTemplateTypenameSize { +private: typedef char YesType; struct NoType { char padding[8]; @@ -105,7 +108,8 @@ }; template <typename T, template <typename V, size_t W, typename X> class U> -class IsSubclassOfTemplateTypenameSizeTypename { +struct IsSubclassOfTemplateTypenameSizeTypename { +private: typedef char YesType; struct NoType { char padding[8]; @@ -137,13 +141,11 @@ // Here, we use a template specialization for same type case to allow incomplete // types. -template <typename T, typename U> class IsBaseOf { -public: +template <typename T, typename U> struct IsBaseOf { static const bool value = std::is_base_of<T, U>::value; }; -template <typename T> class IsBaseOf<T, T> { -public: +template <typename T> struct IsBaseOf<T, T> { static const bool value = true; };
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.cpp b/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp similarity index 97% rename from third_party/WebKit/Source/wtf/TypeTraits.cpp rename to third_party/WebKit/Source/wtf/TypeTraitsTest.cpp index 9b8c103..12fec33 100644 --- a/third_party/WebKit/Source/wtf/TypeTraits.cpp +++ b/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
@@ -23,8 +23,12 @@ #include "wtf/Noncopyable.h" +// No gtest tests; only static_assert checks. + namespace WTF { +namespace { + struct VirtualClass { virtual void A() { } }; @@ -99,4 +103,6 @@ typedef int IntArray[]; typedef int IntArraySized[4]; +} // anonymous namespace + } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/wtf.gypi b/third_party/WebKit/Source/wtf/wtf.gypi index 226db2c..eaf57275 100644 --- a/third_party/WebKit/Source/wtf/wtf.gypi +++ b/third_party/WebKit/Source/wtf/wtf.gypi
@@ -117,7 +117,6 @@ 'ThreadingPthreads.cpp', 'ThreadingWin.cpp', 'TreeNode.h', - 'TypeTraits.cpp', 'TypeTraits.h', 'TypedArrayBase.h', 'Uint16Array.h', @@ -221,6 +220,7 @@ 'StringHasherTest.cpp', 'TemporaryChangeTest.cpp', 'TreeNodeTest.cpp', + 'TypeTraitsTest.cpp', 'VectorTest.cpp', 'dtoa_test.cpp', 'testing/WTFTestPrintersTest.cpp',
diff --git a/third_party/WebKit/public/platform/WebMediaPlayer.h b/third_party/WebKit/public/platform/WebMediaPlayer.h index aebc9980..68a8803 100644 --- a/third_party/WebKit/public/platform/WebMediaPlayer.h +++ b/third_party/WebKit/public/platform/WebMediaPlayer.h
@@ -156,8 +156,8 @@ virtual unsigned decodedFrameCount() const = 0; virtual unsigned droppedFrameCount() const = 0; virtual unsigned corruptedFrameCount() const { return 0; } - virtual unsigned audioDecodedByteCount() const = 0; - virtual unsigned videoDecodedByteCount() const = 0; + virtual size_t audioDecodedByteCount() const = 0; + virtual size_t videoDecodedByteCount() const = 0; virtual void paint(WebCanvas*, const WebRect&, unsigned char alpha, SkXfermode::Mode) = 0;
diff --git a/third_party/WebKit/public/platform/WebPrivatePtr.h b/third_party/WebKit/public/platform/WebPrivatePtr.h index 4438864..047d32c 100644 --- a/third_party/WebKit/public/platform/WebPrivatePtr.h +++ b/third_party/WebKit/public/platform/WebPrivatePtr.h
@@ -69,7 +69,8 @@ }; template<typename T> -class LifetimeOf { +struct LifetimeOf { +private: static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, GarbageCollected>::value || IsGarbageCollectedMixin<T>::value; static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T, RefCountedGarbageCollected>::value; public:
diff --git a/third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscriptionOptions.h b/third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscriptionOptions.h index ad3db17..bfac23a2 100644 --- a/third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscriptionOptions.h +++ b/third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscriptionOptions.h
@@ -5,8 +5,6 @@ #ifndef WebPushSubscriptionOptions_h #define WebPushSubscriptionOptions_h -#include "public/platform/WebString.h" - namespace blink { struct WebPushSubscriptionOptions { @@ -18,10 +16,6 @@ // Indicates that the subscription will only be used for push messages // that result in UI visible to the user. bool userVisibleOnly; - - // P-256 public key, in uncompressed form, of the app server that can send - // push messages to this subscription. - WebString applicationServerKey; }; } // namespace blink
diff --git a/third_party/blimp_fonts/.gitignore b/third_party/blimp_fonts/.gitignore new file mode 100644 index 0000000..70994af4 --- /dev/null +++ b/third_party/blimp_fonts/.gitignore
@@ -0,0 +1,2 @@ +*.otf +*.ttf
diff --git a/third_party/blimp_fonts/AndroidClock.ttf.sha1 b/third_party/blimp_fonts/AndroidClock.ttf.sha1 new file mode 100644 index 0000000..ab7fba0 --- /dev/null +++ b/third_party/blimp_fonts/AndroidClock.ttf.sha1
@@ -0,0 +1 @@ +c2a20ced561bb57426484d8de4136817b4edcdfb \ No newline at end of file
diff --git a/third_party/blimp_fonts/AndroidClock_Highlight.ttf.sha1 b/third_party/blimp_fonts/AndroidClock_Highlight.ttf.sha1 new file mode 100644 index 0000000..4abd6d36 --- /dev/null +++ b/third_party/blimp_fonts/AndroidClock_Highlight.ttf.sha1
@@ -0,0 +1 @@ +6a7bba11c859c6698addcab7052c257caa762774 \ No newline at end of file
diff --git a/third_party/blimp_fonts/AndroidClock_Solid.ttf.sha1 b/third_party/blimp_fonts/AndroidClock_Solid.ttf.sha1 new file mode 100644 index 0000000..4abd6d36 --- /dev/null +++ b/third_party/blimp_fonts/AndroidClock_Solid.ttf.sha1
@@ -0,0 +1 @@ +6a7bba11c859c6698addcab7052c257caa762774 \ No newline at end of file
diff --git a/third_party/blimp_fonts/BUILD.gn b/third_party/blimp_fonts/BUILD.gn new file mode 100644 index 0000000..0d3154f --- /dev/null +++ b/third_party/blimp_fonts/BUILD.gn
@@ -0,0 +1,217 @@ +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +copy("blimp_fonts") { + sources = [ + "AndroidClock.ttf", + "AndroidClock_Highlight.ttf", + "AndroidClock_Solid.ttf", + "CarroisGothicSC-Regular.ttf", + "Clockopia.ttf", + "ComingSoon.ttf", + "CutiveMono.ttf", + "DancingScript-Bold.ttf", + "DancingScript-Regular.ttf", + "DroidSansFallback.ttf", + "DroidSansFallbackFull.ttf", + "DroidSansMono.ttf", + "LICENSE", + "LICENSE.Apache", + "LICENSE.OFL", + "MTLc3m.ttf", + "MTLmr3m.ttf", + "NanumGothic.ttf", + "NanumGothicBold.ttf", + "NotoColorEmoji.ttf", + "NotoKufiArabic-Bold.ttf", + "NotoKufiArabic-Regular.ttf", + "NotoNaskhArabic-Bold.ttf", + "NotoNaskhArabic-Regular.ttf", + "NotoNaskhArabicUI-Bold.ttf", + "NotoNaskhArabicUI-Regular.ttf", + "NotoSans-Bold.ttf", + "NotoSans-BoldItalic.ttf", + "NotoSans-Italic.ttf", + "NotoSans-Regular.ttf", + "NotoSansArmenian-Bold.ttf", + "NotoSansArmenian-Regular.ttf", + "NotoSansAvestan-Regular.ttf", + "NotoSansBalinese-Regular.ttf", + "NotoSansBamum-Regular.ttf", + "NotoSansBatak-Regular.ttf", + "NotoSansBengali-Bold.ttf", + "NotoSansBengali-Regular.ttf", + "NotoSansBengaliUI-Bold.ttf", + "NotoSansBengaliUI-Regular.ttf", + "NotoSansBrahmi-Regular.ttf", + "NotoSansBuginese-Regular.ttf", + "NotoSansBuhid-Regular.ttf", + "NotoSansCanadianAboriginal-Regular.ttf", + "NotoSansCarian-Regular.ttf", + "NotoSansCham-Bold.ttf", + "NotoSansCham-Regular.ttf", + "NotoSansCherokee-Regular.ttf", + "NotoSansCoptic-Regular.ttf", + "NotoSansCuneiform-Regular.ttf", + "NotoSansCypriot-Regular.ttf", + "NotoSansDeseret-Regular.ttf", + "NotoSansDevanagari-Bold.ttf", + "NotoSansDevanagari-Regular.ttf", + "NotoSansDevanagariUI-Bold.ttf", + "NotoSansDevanagariUI-Regular.ttf", + "NotoSansEgyptianHieroglyphs-Regular.ttf", + "NotoSansEthiopic-Bold.ttf", + "NotoSansEthiopic-Regular.ttf", + "NotoSansGeorgian-Bold.ttf", + "NotoSansGeorgian-Regular.ttf", + "NotoSansGlagolitic-Regular.ttf", + "NotoSansGothic-Regular.ttf", + "NotoSansGujarati-Bold.ttf", + "NotoSansGujarati-Regular.ttf", + "NotoSansGujaratiUI-Bold.ttf", + "NotoSansGujaratiUI-Regular.ttf", + "NotoSansGurmukhi-Bold.ttf", + "NotoSansGurmukhi-Regular.ttf", + "NotoSansGurmukhiUI-Bold.ttf", + "NotoSansGurmukhiUI-Regular.ttf", + "NotoSansHanunoo-Regular.ttf", + "NotoSansHebrew-Bold.ttf", + "NotoSansHebrew-Regular.ttf", + "NotoSansImperialAramaic-Regular.ttf", + "NotoSansInscriptionalPahlavi-Regular.ttf", + "NotoSansInscriptionalParthian-Regular.ttf", + "NotoSansJP-Regular-Subsetted.otf", + "NotoSansJP-Regular.otf", + "NotoSansJavanese-Regular.ttf", + "NotoSansKR-Regular.otf", + "NotoSansKaithi-Regular.ttf", + "NotoSansKannada-Bold.ttf", + "NotoSansKannada-Regular.ttf", + "NotoSansKannadaUI-Bold.ttf", + "NotoSansKannadaUI-Regular.ttf", + "NotoSansKayahLi-Regular.ttf", + "NotoSansKharoshthi-Regular.ttf", + "NotoSansKhmer-Bold.ttf", + "NotoSansKhmer-Regular.ttf", + "NotoSansKhmerUI-Bold.ttf", + "NotoSansKhmerUI-Regular.ttf", + "NotoSansLao-Bold.ttf", + "NotoSansLao-Regular.ttf", + "NotoSansLaoUI-Bold.ttf", + "NotoSansLaoUI-Regular.ttf", + "NotoSansLepcha-Regular.ttf", + "NotoSansLimbu-Regular.ttf", + "NotoSansLinearB-Regular.ttf", + "NotoSansLisu-Regular.ttf", + "NotoSansLycian-Regular.ttf", + "NotoSansLydian-Regular.ttf", + "NotoSansMalayalam-Bold.ttf", + "NotoSansMalayalam-Regular.ttf", + "NotoSansMalayalamUI-Bold.ttf", + "NotoSansMalayalamUI-Regular.ttf", + "NotoSansMandaic-Regular.ttf", + "NotoSansMeeteiMayek-Regular.ttf", + "NotoSansMongolian-Regular.ttf", + "NotoSansMyanmar-Bold.ttf", + "NotoSansMyanmar-Regular.ttf", + "NotoSansMyanmarUI-Bold.ttf", + "NotoSansMyanmarUI-Regular.ttf", + "NotoSansNKo-Regular.ttf", + "NotoSansNewTaiLue-Regular.ttf", + "NotoSansOgham-Regular.ttf", + "NotoSansOlChiki-Regular.ttf", + "NotoSansOldItalic-Regular.ttf", + "NotoSansOldPersian-Regular.ttf", + "NotoSansOldSouthArabian-Regular.ttf", + "NotoSansOldTurkic-Regular.ttf", + "NotoSansOriya-Bold.ttf", + "NotoSansOriya-Regular.ttf", + "NotoSansOriyaUI-Bold.ttf", + "NotoSansOriyaUI-Regular.ttf", + "NotoSansOsmanya-Regular.ttf", + "NotoSansPhagsPa-Regular.ttf", + "NotoSansPhoenician-Regular.ttf", + "NotoSansRejang-Regular.ttf", + "NotoSansRunic-Regular.ttf", + "NotoSansSC-Regular.otf", + "NotoSansSamaritan-Regular.ttf", + "NotoSansSaurashtra-Regular.ttf", + "NotoSansShavian-Regular.ttf", + "NotoSansSinhala-Bold.ttf", + "NotoSansSinhala-Regular.ttf", + "NotoSansSundanese-Regular.ttf", + "NotoSansSylotiNagri-Regular.ttf", + "NotoSansSymbols-Regular-Subsetted.ttf", + "NotoSansSymbols-Regular.ttf", + "NotoSansSyriacEastern-Regular.ttf", + "NotoSansSyriacEstrangela-Regular.ttf", + "NotoSansSyriacWestern-Regular.ttf", + "NotoSansTC-Regular.otf", + "NotoSansTagalog-Regular.ttf", + "NotoSansTagbanwa-Regular.ttf", + "NotoSansTaiLe-Regular.ttf", + "NotoSansTaiTham-Regular.ttf", + "NotoSansTaiViet-Regular.ttf", + "NotoSansTamil-Bold.ttf", + "NotoSansTamil-Regular.ttf", + "NotoSansTamilUI-Bold.ttf", + "NotoSansTamilUI-Regular.ttf", + "NotoSansTelugu-Bold.ttf", + "NotoSansTelugu-Regular.ttf", + "NotoSansTeluguUI-Bold.ttf", + "NotoSansTeluguUI-Regular.ttf", + "NotoSansThaana-Bold.ttf", + "NotoSansThaana-Regular.ttf", + "NotoSansThai-Bold.ttf", + "NotoSansThai-Regular.ttf", + "NotoSansThaiUI-Bold.ttf", + "NotoSansThaiUI-Regular.ttf", + "NotoSansTibetan-Regular.ttf", + "NotoSansTifinagh-Regular.ttf", + "NotoSansUI-Bold.ttf", + "NotoSansUI-BoldItalic.ttf", + "NotoSansUI-Italic.ttf", + "NotoSansUI-Regular.ttf", + "NotoSansUgaritic-Regular.ttf", + "NotoSansVai-Regular.ttf", + "NotoSansYi-Regular.ttf", + "NotoSerif-Bold.ttf", + "NotoSerif-BoldItalic.ttf", + "NotoSerif-Italic.ttf", + "NotoSerif-Regular.ttf", + "NotoSerifArmenian-Bold.ttf", + "NotoSerifArmenian-Regular.ttf", + "NotoSerifGeorgian-Bold.ttf", + "NotoSerifGeorgian-Regular.ttf", + "NotoSerifKhmer-Bold.ttf", + "NotoSerifKhmer-Regular.ttf", + "NotoSerifLao-Bold.ttf", + "NotoSerifLao-Regular.ttf", + "NotoSerifThai-Bold.ttf", + "NotoSerifThai-Regular.ttf", + "Roboto-Black.ttf", + "Roboto-BlackItalic.ttf", + "Roboto-Bold.ttf", + "Roboto-BoldItalic.ttf", + "Roboto-Italic.ttf", + "Roboto-Light.ttf", + "Roboto-LightItalic.ttf", + "Roboto-Medium.ttf", + "Roboto-MediumItalic.ttf", + "Roboto-Regular.ttf", + "Roboto-Thin.ttf", + "Roboto-ThinItalic.ttf", + "RobotoCondensed-Bold.ttf", + "RobotoCondensed-BoldItalic.ttf", + "RobotoCondensed-Italic.ttf", + "RobotoCondensed-Light.ttf", + "RobotoCondensed-LightItalic.ttf", + "RobotoCondensed-Regular.ttf", + "fonts.xml", + ] + + outputs = [ + "$target_gen_dir/{{source_file_part}}", + ] +}
diff --git a/third_party/blimp_fonts/CarroisGothicSC-Regular.ttf.sha1 b/third_party/blimp_fonts/CarroisGothicSC-Regular.ttf.sha1 new file mode 100644 index 0000000..f9120e0 --- /dev/null +++ b/third_party/blimp_fonts/CarroisGothicSC-Regular.ttf.sha1
@@ -0,0 +1 @@ +009d2696ba2ceb4d58dca2a6535b7c74f252caf2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/Clockopia.ttf.sha1 b/third_party/blimp_fonts/Clockopia.ttf.sha1 new file mode 100644 index 0000000..ca93d0fd --- /dev/null +++ b/third_party/blimp_fonts/Clockopia.ttf.sha1
@@ -0,0 +1 @@ +8175e3bc43ae590f513e5bf38baa5860c81458a1 \ No newline at end of file
diff --git a/third_party/blimp_fonts/ComingSoon.ttf.sha1 b/third_party/blimp_fonts/ComingSoon.ttf.sha1 new file mode 100644 index 0000000..f93b6c9 --- /dev/null +++ b/third_party/blimp_fonts/ComingSoon.ttf.sha1
@@ -0,0 +1 @@ +a6fc4d9e7339c7d9c6dd9b994a00e4a965c91df4 \ No newline at end of file
diff --git a/third_party/blimp_fonts/CutiveMono.ttf.sha1 b/third_party/blimp_fonts/CutiveMono.ttf.sha1 new file mode 100644 index 0000000..428ebc7 --- /dev/null +++ b/third_party/blimp_fonts/CutiveMono.ttf.sha1
@@ -0,0 +1 @@ +e4837f21d7581c3f0418a02b2bedf15909df7569 \ No newline at end of file
diff --git a/third_party/blimp_fonts/DancingScript-Bold.ttf.sha1 b/third_party/blimp_fonts/DancingScript-Bold.ttf.sha1 new file mode 100644 index 0000000..9f007c3 --- /dev/null +++ b/third_party/blimp_fonts/DancingScript-Bold.ttf.sha1
@@ -0,0 +1 @@ +489aa561aca5ef5a8e9884b183cad31a2e52bd9f \ No newline at end of file
diff --git a/third_party/blimp_fonts/DancingScript-Regular.ttf.sha1 b/third_party/blimp_fonts/DancingScript-Regular.ttf.sha1 new file mode 100644 index 0000000..5a0a8f6 --- /dev/null +++ b/third_party/blimp_fonts/DancingScript-Regular.ttf.sha1
@@ -0,0 +1 @@ +1298686a3510db5dc99a1a73872e0454112a626e \ No newline at end of file
diff --git a/third_party/blimp_fonts/DroidSansFallback.ttf.sha1 b/third_party/blimp_fonts/DroidSansFallback.ttf.sha1 new file mode 100644 index 0000000..7cbbc30 --- /dev/null +++ b/third_party/blimp_fonts/DroidSansFallback.ttf.sha1
@@ -0,0 +1 @@ +408db827c9555c10618707d47314083ebf496f59 \ No newline at end of file
diff --git a/third_party/blimp_fonts/DroidSansFallbackFull.ttf.sha1 b/third_party/blimp_fonts/DroidSansFallbackFull.ttf.sha1 new file mode 100644 index 0000000..9b18446 --- /dev/null +++ b/third_party/blimp_fonts/DroidSansFallbackFull.ttf.sha1
@@ -0,0 +1 @@ +53c637979f023ea3933cd09befb6518aef5baa92 \ No newline at end of file
diff --git a/third_party/blimp_fonts/DroidSansMono.ttf.sha1 b/third_party/blimp_fonts/DroidSansMono.ttf.sha1 new file mode 100644 index 0000000..536bde4 --- /dev/null +++ b/third_party/blimp_fonts/DroidSansMono.ttf.sha1
@@ -0,0 +1 @@ +0b75601f8ef8e111babb6ed11de6573f7178ce44 \ No newline at end of file
diff --git a/third_party/blimp_fonts/LICENSE b/third_party/blimp_fonts/LICENSE new file mode 100644 index 0000000..78d4582 --- /dev/null +++ b/third_party/blimp_fonts/LICENSE
@@ -0,0 +1,230 @@ +Fonts under Apache License Version 2.0 license: + +AndroidClock.ttf +AndroidClock_Highlight.ttf +AndroidClock_Solid.ttf +Clockopia.ttf +ComingSoon.ttf +DroidSansFallback.ttf +DroidSansFallbackFull.ttf +DroidSansMono.ttf +MTLc3m.ttf +MTLmr3m.ttf +NotoColorEmoji.ttf +NotoKufiArabic-Bold.ttf +NotoKufiArabic-Regular.ttf +NotoNaskhArabic-Bold.ttf +NotoNaskhArabic-Regular.ttf +NotoNaskhArabicUI-Bold.ttf +NotoNaskhArabicUI-Regular.ttf +NotoSansArmenian-Bold.ttf +NotoSansArmenian-Regular.ttf +NotoSansAvestan-Regular.ttf +NotoSansBalinese-Regular.ttf +NotoSansBamum-Regular.ttf +NotoSansBatak-Regular.ttf +NotoSansBengali-Bold.ttf +NotoSansBengali-Regular.ttf +NotoSansBengaliUI-Bold.ttf +NotoSansBengaliUI-Regular.ttf +NotoSans-BoldItalic.ttf +NotoSans-Bold.ttf +NotoSansBrahmi-Regular.ttf +NotoSansBuginese-Regular.ttf +NotoSansBuhid-Regular.ttf +NotoSansCanadianAboriginal-Regular.ttf +NotoSansCarian-Regular.ttf +NotoSansCham-Bold.ttf +NotoSansCham-Regular.ttf +NotoSansCherokee-Regular.ttf +NotoSansCoptic-Regular.ttf +NotoSansCuneiform-Regular.ttf +NotoSansCypriot-Regular.ttf +NotoSansDeseret-Regular.ttf +NotoSansDevanagari-Bold.ttf +NotoSansDevanagari-Regular.ttf +NotoSansDevanagariUI-Bold.ttf +NotoSansDevanagariUI-Regular.ttf +NotoSansEgyptianHieroglyphs-Regular.ttf +NotoSansEthiopic-Bold.ttf +NotoSansEthiopic-Regular.ttf +NotoSansGeorgian-Bold.ttf +NotoSansGeorgian-Regular.ttf +NotoSansGlagolitic-Regular.ttf +NotoSansGothic-Regular.ttf +NotoSansGujarati-Bold.ttf +NotoSansGujarati-Regular.ttf +NotoSansGujaratiUI-Bold.ttf +NotoSansGujaratiUI-Regular.ttf +NotoSansGurmukhi-Bold.ttf +NotoSansGurmukhi-Regular.ttf +NotoSansGurmukhiUI-Bold.ttf +NotoSansGurmukhiUI-Regular.ttf +NotoSansHanunoo-Regular.ttf +NotoSansHebrew-Bold.ttf +NotoSansHebrew-Regular.ttf +NotoSansImperialAramaic-Regular.ttf +NotoSansInscriptionalPahlavi-Regular.ttf +NotoSansInscriptionalParthian-Regular.ttf +NotoSans-Italic.ttf +NotoSansJavanese-Regular.ttf +NotoSansKaithi-Regular.ttf +NotoSansKannada-Bold.ttf +NotoSansKannada-Regular.ttf +NotoSansKannadaUI-Bold.ttf +NotoSansKannadaUI-Regular.ttf +NotoSansKayahLi-Regular.ttf +NotoSansKharoshthi-Regular.ttf +NotoSansKhmer-Bold.ttf +NotoSansKhmer-Regular.ttf +NotoSansKhmerUI-Bold.ttf +NotoSansKhmerUI-Regular.ttf +NotoSansLao-Bold.ttf +NotoSansLao-Regular.ttf +NotoSansLaoUI-Bold.ttf +NotoSansLaoUI-Regular.ttf +NotoSansLepcha-Regular.ttf +NotoSansLimbu-Regular.ttf +NotoSansLinearB-Regular.ttf +NotoSansLisu-Regular.ttf +NotoSansLycian-Regular.ttf +NotoSansLydian-Regular.ttf +NotoSansMalayalam-Bold.ttf +NotoSansMalayalam-Regular.ttf +NotoSansMalayalamUI-Bold.ttf +NotoSansMalayalamUI-Regular.ttf +NotoSansMandaic-Regular.ttf +NotoSansMeeteiMayek-Regular.ttf +NotoSansMongolian-Regular.ttf +NotoSansMyanmar-Bold.ttf +NotoSansMyanmar-Regular.ttf +NotoSansMyanmarUI-Bold.ttf +NotoSansMyanmarUI-Regular.ttf +NotoSansNewTaiLue-Regular.ttf +NotoSansNKo-Regular.ttf +NotoSansOgham-Regular.ttf +NotoSansOlChiki-Regular.ttf +NotoSansOldItalic-Regular.ttf +NotoSansOldPersian-Regular.ttf +NotoSansOldSouthArabian-Regular.ttf +NotoSansOldTurkic-Regular.ttf +NotoSansOriya-Bold.ttf +NotoSansOriya-Regular.ttf +NotoSansOriyaUI-Bold.ttf +NotoSansOriyaUI-Regular.ttf +NotoSansOsmanya-Regular.ttf +NotoSansPhagsPa-Regular.ttf +NotoSansPhoenician-Regular.ttf +NotoSans-Regular.ttf +NotoSansRejang-Regular.ttf +NotoSansRunic-Regular.ttf +NotoSansSamaritan-Regular.ttf +NotoSansSaurashtra-Regular.ttf +NotoSansShavian-Regular.ttf +NotoSansSinhala-Bold.ttf +NotoSansSinhala-Regular.ttf +NotoSansSundanese-Regular.ttf +NotoSansSylotiNagri-Regular.ttf +NotoSansSymbols-Regular-Subsetted.ttf +NotoSansSymbols-Regular.ttf +NotoSansSyriacEastern-Regular.ttf +NotoSansSyriacEstrangela-Regular.ttf +NotoSansSyriacWestern-Regular.ttf +NotoSansTagalog-Regular.ttf +NotoSansTagbanwa-Regular.ttf +NotoSansTaiLe-Regular.ttf +NotoSansTaiTham-Regular.ttf +NotoSansTaiViet-Regular.ttf +NotoSansTamil-Bold.ttf +NotoSansTamil-Regular.ttf +NotoSansTamilUI-Bold.ttf +NotoSansTamilUI-Regular.ttf +NotoSansTelugu-Bold.ttf +NotoSansTelugu-Regular.ttf +NotoSansTeluguUI-Bold.ttf +NotoSansTeluguUI-Regular.ttf +NotoSansThaana-Bold.ttf +NotoSansThaana-Regular.ttf +NotoSansThai-Bold.ttf +NotoSansThai-Regular.ttf +NotoSansThaiUI-Bold.ttf +NotoSansThaiUI-Regular.ttf +NotoSansTibetan-Regular.ttf +NotoSansTifinagh-Regular.ttf +NotoSansUgaritic-Regular.ttf +NotoSansUI-BoldItalic.ttf +NotoSansUI-Bold.ttf +NotoSansUI-Italic.ttf +NotoSansUI-Regular.ttf +NotoSansVai-Regular.ttf +NotoSansYi-Regular.ttf +NotoSerifArmenian-Bold.ttf +NotoSerifArmenian-Regular.ttf +NotoSerif-BoldItalic.ttf +NotoSerif-Bold.ttf +NotoSerifGeorgian-Bold.ttf +NotoSerifGeorgian-Regular.ttf +NotoSerif-Italic.ttf +NotoSerifKhmer-Bold.ttf +NotoSerifKhmer-Regular.ttf +NotoSerifLao-Bold.ttf +NotoSerifLao-Regular.ttf +NotoSerif-Regular.ttf +NotoSerifThai-Bold.ttf +NotoSerifThai-Regular.ttf +Roboto-BlackItalic.ttf +Roboto-Black.ttf +Roboto-BoldItalic.ttf +Roboto-Bold.ttf +RobotoCondensed-BoldItalic.ttf +RobotoCondensed-Bold.ttf +RobotoCondensed-Italic.ttf +RobotoCondensed-LightItalic.ttf +RobotoCondensed-Light.ttf +RobotoCondensed-Regular.ttf +Roboto-Italic.ttf +Roboto-LightItalic.ttf +Roboto-Light.ttf +Roboto-MediumItalic.ttf +Roboto-Medium.ttf +Roboto-Regular.ttf +Roboto-ThinItalic.ttf +Roboto-Thin.ttf + + +Fonts under SIL Open Font License, Version 1.1: +(Full license in LICENSE.OFL) + +NotoSansJP-Regular.otf +NotoSansJP-Regular-Subsetted.otf +NotoSansKR-Regular.otf +NotoSansSC-Regular.otf +NotoSansTC-Regular.otf + + +Copyright (c) 2011 by Ralph du Carrois, with Reserved Font Name 'Carrois' +This Font Software is licensed under the SIL Open Font License, Version 1.1 +(Full license in LICENSE.OFL) +CarroisGothicSC-Regular.ttf + + +Copyright (c) 2010, Pablo Impallari (www.impallari.com|impallari@gmail.com), +Copyright (c) 2010, Igino Marini. (www.ikern.com|mail@iginomarini.com), +with Reserved Font Name Dancing Script. +This Font Software is licensed under the SIL Open Font License, Version 1.1. +(Full license in LICENSE.OFL) + +DancingScript-Bold.ttf +DancingScript-Regular.ttf +CutiveMono.ttf + + +Copyright (c) 2010, NHN Corporation (http://www.nhncorp.com), + (http://hangeul.naver.com/font) +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +(Full license in LICENSE.OFL) + +NanumGothicBold.ttf +NanumGothic.ttf
diff --git a/third_party/blimp_fonts/LICENSE.Apache b/third_party/blimp_fonts/LICENSE.Apache new file mode 100644 index 0000000..a3711ba6 --- /dev/null +++ b/third_party/blimp_fonts/LICENSE.Apache
@@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.
diff --git a/third_party/blimp_fonts/LICENSE.OFL b/third_party/blimp_fonts/LICENSE.OFL new file mode 100644 index 0000000..d952d62 --- /dev/null +++ b/third_party/blimp_fonts/LICENSE.OFL
@@ -0,0 +1,92 @@ +This Font Software is licensed under the SIL Open Font License, +Version 1.1. + +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font +creation efforts of academic and linguistic communities, and to +provide a free and open framework in which fonts may be shared and +improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply to +any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software +components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, +deleting, or substituting -- in part or in whole -- any of the +components of the Original Version, by changing formats or by porting +the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, +modify, redistribute, and sell modified and unmodified copies of the +Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in +Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the +corresponding Copyright Holder. This restriction only applies to the +primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created using +the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/third_party/blimp_fonts/MTLc3m.ttf.sha1 b/third_party/blimp_fonts/MTLc3m.ttf.sha1 new file mode 100644 index 0000000..fe44a8d --- /dev/null +++ b/third_party/blimp_fonts/MTLc3m.ttf.sha1
@@ -0,0 +1 @@ +3c204b67777ea8d9a5b68b1c10eb606bb72cb5ab \ No newline at end of file
diff --git a/third_party/blimp_fonts/MTLmr3m.ttf.sha1 b/third_party/blimp_fonts/MTLmr3m.ttf.sha1 new file mode 100644 index 0000000..fe932746 --- /dev/null +++ b/third_party/blimp_fonts/MTLmr3m.ttf.sha1
@@ -0,0 +1 @@ +6084cd39578214d7a4dec3fe46b10fdb7d335e50 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NanumGothic.ttf.sha1 b/third_party/blimp_fonts/NanumGothic.ttf.sha1 new file mode 100644 index 0000000..f523180 --- /dev/null +++ b/third_party/blimp_fonts/NanumGothic.ttf.sha1
@@ -0,0 +1 @@ +f6844b0169c0a453778980b65b28fa4b15014246 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NanumGothicBold.ttf.sha1 b/third_party/blimp_fonts/NanumGothicBold.ttf.sha1 new file mode 100644 index 0000000..c453c733d --- /dev/null +++ b/third_party/blimp_fonts/NanumGothicBold.ttf.sha1
@@ -0,0 +1 @@ +da02b0bb41d80957c8ffdde238b2c85c21f02361 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoColorEmoji.ttf.sha1 b/third_party/blimp_fonts/NotoColorEmoji.ttf.sha1 new file mode 100644 index 0000000..f9073838 --- /dev/null +++ b/third_party/blimp_fonts/NotoColorEmoji.ttf.sha1
@@ -0,0 +1 @@ +d4af84777101e3083886decc94a87b7ab8c370e5 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoKufiArabic-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoKufiArabic-Bold.ttf.sha1 new file mode 100644 index 0000000..7d430f8 --- /dev/null +++ b/third_party/blimp_fonts/NotoKufiArabic-Bold.ttf.sha1
@@ -0,0 +1 @@ +1e586ea25cf9ab4fd959280e1248f8a44c4a59d9 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoKufiArabic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoKufiArabic-Regular.ttf.sha1 new file mode 100644 index 0000000..b1753b7 --- /dev/null +++ b/third_party/blimp_fonts/NotoKufiArabic-Regular.ttf.sha1
@@ -0,0 +1 @@ +3a3f060aaf35f60e543d5e762a33c6ea66d80c9c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoNaskhArabic-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoNaskhArabic-Bold.ttf.sha1 new file mode 100644 index 0000000..87386afb --- /dev/null +++ b/third_party/blimp_fonts/NotoNaskhArabic-Bold.ttf.sha1
@@ -0,0 +1 @@ +b81530fa957843ba04e9c91dd1ee5cba8e737345 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoNaskhArabic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoNaskhArabic-Regular.ttf.sha1 new file mode 100644 index 0000000..cffe28e --- /dev/null +++ b/third_party/blimp_fonts/NotoNaskhArabic-Regular.ttf.sha1
@@ -0,0 +1 @@ +651752e1b267194a463b4fb211ee8579576e9c0f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoNaskhArabicUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoNaskhArabicUI-Bold.ttf.sha1 new file mode 100644 index 0000000..fdaa035 --- /dev/null +++ b/third_party/blimp_fonts/NotoNaskhArabicUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +43c827c0770e68d211b2f64f7796e4773665439f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoNaskhArabicUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoNaskhArabicUI-Regular.ttf.sha1 new file mode 100644 index 0000000..909aa1f --- /dev/null +++ b/third_party/blimp_fonts/NotoNaskhArabicUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +4dfe8336947e6e52502f2f8156371e85553ab600 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSans-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSans-Bold.ttf.sha1 new file mode 100644 index 0000000..bfeded8 --- /dev/null +++ b/third_party/blimp_fonts/NotoSans-Bold.ttf.sha1
@@ -0,0 +1 @@ +64b897dfb0a6cc8fd573e0793b85028b73dfb4a0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSans-BoldItalic.ttf.sha1 b/third_party/blimp_fonts/NotoSans-BoldItalic.ttf.sha1 new file mode 100644 index 0000000..f6f4b8b --- /dev/null +++ b/third_party/blimp_fonts/NotoSans-BoldItalic.ttf.sha1
@@ -0,0 +1 @@ +0ef56b3baa79415191519532e1c4a9325bb4f5ea \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSans-Italic.ttf.sha1 b/third_party/blimp_fonts/NotoSans-Italic.ttf.sha1 new file mode 100644 index 0000000..bc30332 --- /dev/null +++ b/third_party/blimp_fonts/NotoSans-Italic.ttf.sha1
@@ -0,0 +1 @@ +0d572e04d5d48ce3819ac78e0e2dbe1a6bcb1d47 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSans-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSans-Regular.ttf.sha1 new file mode 100644 index 0000000..9b89352 --- /dev/null +++ b/third_party/blimp_fonts/NotoSans-Regular.ttf.sha1
@@ -0,0 +1 @@ +b0c0c510fbf942d63745dc5248d23f1fe1859c1f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansArmenian-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansArmenian-Bold.ttf.sha1 new file mode 100644 index 0000000..4a057fe6 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansArmenian-Bold.ttf.sha1
@@ -0,0 +1 @@ +eaecc6acfe8e40321429b503e1f4aa55e67b15e7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansArmenian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansArmenian-Regular.ttf.sha1 new file mode 100644 index 0000000..2450a07 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansArmenian-Regular.ttf.sha1
@@ -0,0 +1 @@ +bb1d0b181ee7a3dfd2570be4e29052e2eeb4c4a8 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansAvestan-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansAvestan-Regular.ttf.sha1 new file mode 100644 index 0000000..9dee971e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansAvestan-Regular.ttf.sha1
@@ -0,0 +1 @@ +97993a74daa52ff59031f5c5541dc37459563f77 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBalinese-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBalinese-Regular.ttf.sha1 new file mode 100644 index 0000000..528d2d45 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBalinese-Regular.ttf.sha1
@@ -0,0 +1 @@ +48a782222ccbc6e67036a83dd8ccfef75b766b8c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBamum-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBamum-Regular.ttf.sha1 new file mode 100644 index 0000000..0849897 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBamum-Regular.ttf.sha1
@@ -0,0 +1 @@ +7d3d14ac5ae5df87d7dc9243df011a6220023d30 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBatak-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBatak-Regular.ttf.sha1 new file mode 100644 index 0000000..68996230 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBatak-Regular.ttf.sha1
@@ -0,0 +1 @@ +113c277988592dcd935fad584164814a0c39987c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBengali-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansBengali-Bold.ttf.sha1 new file mode 100644 index 0000000..db8c39a4 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBengali-Bold.ttf.sha1
@@ -0,0 +1 @@ +3ba5b31be8e6715cabe7eb3f6948dad3936a54f6 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBengali-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBengali-Regular.ttf.sha1 new file mode 100644 index 0000000..8a26e7e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBengali-Regular.ttf.sha1
@@ -0,0 +1 @@ +28e762ed4a3b29dddb1cbd591f264f6e6471f0f2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBengaliUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansBengaliUI-Bold.ttf.sha1 new file mode 100644 index 0000000..45745ab --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBengaliUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +1ca4e43f7a865f21890f5a6f2258bbad758ba021 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBengaliUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBengaliUI-Regular.ttf.sha1 new file mode 100644 index 0000000..9b91c21d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBengaliUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +efb13bb61802b122deb2e9445c855a008dd7d6fa \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBrahmi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBrahmi-Regular.ttf.sha1 new file mode 100644 index 0000000..97086ff --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBrahmi-Regular.ttf.sha1
@@ -0,0 +1 @@ +4cedf2d8ca231b81a44d984d04dd920360da4509 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBuginese-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBuginese-Regular.ttf.sha1 new file mode 100644 index 0000000..56cd4fe --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBuginese-Regular.ttf.sha1
@@ -0,0 +1 @@ +bc56fb49234be9e7eddbaa35fc3e8965cde61155 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansBuhid-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansBuhid-Regular.ttf.sha1 new file mode 100644 index 0000000..0909c2f --- /dev/null +++ b/third_party/blimp_fonts/NotoSansBuhid-Regular.ttf.sha1
@@ -0,0 +1 @@ +7b6bc1c7b6444090b45ba5400bd16fedd3f1f310 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCanadianAboriginal-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCanadianAboriginal-Regular.ttf.sha1 new file mode 100644 index 0000000..4f2b208 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCanadianAboriginal-Regular.ttf.sha1
@@ -0,0 +1 @@ +d3977d0e5345ccb2cc7ca1d93d2420f31b4eb558 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCarian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCarian-Regular.ttf.sha1 new file mode 100644 index 0000000..3ae06b4 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCarian-Regular.ttf.sha1
@@ -0,0 +1 @@ +0b51a8b392db852e640393ec34e7c07c10587fa5 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCham-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansCham-Bold.ttf.sha1 new file mode 100644 index 0000000..2d123d0 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCham-Bold.ttf.sha1
@@ -0,0 +1 @@ +4ad98c588ef2214aca74f6634278e58aec681fcd \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCham-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCham-Regular.ttf.sha1 new file mode 100644 index 0000000..bef04f6 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCham-Regular.ttf.sha1
@@ -0,0 +1 @@ +18cd6f3b26410a70c1a00bf52ef26d6376874ab0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCherokee-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCherokee-Regular.ttf.sha1 new file mode 100644 index 0000000..9d98d2a1 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCherokee-Regular.ttf.sha1
@@ -0,0 +1 @@ +5be65ab8dc89fcdca48018ba3c863620ce95ac37 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCoptic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCoptic-Regular.ttf.sha1 new file mode 100644 index 0000000..64df8346 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCoptic-Regular.ttf.sha1
@@ -0,0 +1 @@ +08f262f76db5a9a53ac48c62b03d0dcefef0f5a7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCuneiform-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCuneiform-Regular.ttf.sha1 new file mode 100644 index 0000000..c6535d2 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCuneiform-Regular.ttf.sha1
@@ -0,0 +1 @@ +1731ae2d4b5b363efe9e86f9b6d4e77d590ceac2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansCypriot-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansCypriot-Regular.ttf.sha1 new file mode 100644 index 0000000..f9d715e5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansCypriot-Regular.ttf.sha1
@@ -0,0 +1 @@ +1e61adaf72b89c8b2c640c5deb3166048b9935ab \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansDeseret-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansDeseret-Regular.ttf.sha1 new file mode 100644 index 0000000..feb1fb6d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansDeseret-Regular.ttf.sha1
@@ -0,0 +1 @@ +12610cd362930ce2bf2464d71391df11fa05e041 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansDevanagari-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansDevanagari-Bold.ttf.sha1 new file mode 100644 index 0000000..1db540a5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansDevanagari-Bold.ttf.sha1
@@ -0,0 +1 @@ +7d2e8e7960e6e74507e974c1abb60c7118c5ec70 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansDevanagari-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansDevanagari-Regular.ttf.sha1 new file mode 100644 index 0000000..6f19fe39 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansDevanagari-Regular.ttf.sha1
@@ -0,0 +1 @@ +e043644bd7ca723c03a6482a472b8da6e7a6d87b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansDevanagariUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansDevanagariUI-Bold.ttf.sha1 new file mode 100644 index 0000000..0201754 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansDevanagariUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +d2cb268c25df9f8f6f834aeb5cd823603be1d202 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansDevanagariUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansDevanagariUI-Regular.ttf.sha1 new file mode 100644 index 0000000..794a5d7 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansDevanagariUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +167c6949556960b8dd779baf68a9a6be51e788de \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansEgyptianHieroglyphs-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansEgyptianHieroglyphs-Regular.ttf.sha1 new file mode 100644 index 0000000..d75145b --- /dev/null +++ b/third_party/blimp_fonts/NotoSansEgyptianHieroglyphs-Regular.ttf.sha1
@@ -0,0 +1 @@ +f751cc4b4b0cf4c97f608ae4f7741a36fe9ff66c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansEthiopic-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansEthiopic-Bold.ttf.sha1 new file mode 100644 index 0000000..62e8a19 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansEthiopic-Bold.ttf.sha1
@@ -0,0 +1 @@ +514908c4ec5afc786ebf6979b654a48649cd0eca \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansEthiopic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansEthiopic-Regular.ttf.sha1 new file mode 100644 index 0000000..d64850d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansEthiopic-Regular.ttf.sha1
@@ -0,0 +1 @@ +b4e7246f78ff5d94de75c9fd5c6aec7c0540ee34 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGeorgian-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansGeorgian-Bold.ttf.sha1 new file mode 100644 index 0000000..590f36a --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGeorgian-Bold.ttf.sha1
@@ -0,0 +1 @@ +f5ef0c389a715449de4cfc75d188cee902ceab54 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGeorgian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGeorgian-Regular.ttf.sha1 new file mode 100644 index 0000000..c862c47 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGeorgian-Regular.ttf.sha1
@@ -0,0 +1 @@ +0bc21a4a8df1a38699ca008b0771da770bbe4fd2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGlagolitic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGlagolitic-Regular.ttf.sha1 new file mode 100644 index 0000000..5e29582 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGlagolitic-Regular.ttf.sha1
@@ -0,0 +1 @@ +254597fab20087221158855f58d1ce97653f746f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGothic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGothic-Regular.ttf.sha1 new file mode 100644 index 0000000..eb4f3996 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGothic-Regular.ttf.sha1
@@ -0,0 +1 @@ +3e4ca5caf1c40d5b7509269b57319f5542338d46 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGujarati-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansGujarati-Bold.ttf.sha1 new file mode 100644 index 0000000..70f57bbe --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGujarati-Bold.ttf.sha1
@@ -0,0 +1 @@ +8c8fb46985f818e921ffedb9a9bde0fcf7828911 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGujarati-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGujarati-Regular.ttf.sha1 new file mode 100644 index 0000000..8f4ac71 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGujarati-Regular.ttf.sha1
@@ -0,0 +1 @@ +24c133d6352b25c120bcf33d989bf26723e24279 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGujaratiUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansGujaratiUI-Bold.ttf.sha1 new file mode 100644 index 0000000..8d4f7d5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGujaratiUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +fbe9d746123474703345067ad016aa1f14cf6dc9 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGujaratiUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGujaratiUI-Regular.ttf.sha1 new file mode 100644 index 0000000..2002b08 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGujaratiUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +a1ba64256d731eb3bdbf31446bbeedaa6c6d905e \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGurmukhi-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansGurmukhi-Bold.ttf.sha1 new file mode 100644 index 0000000..eb08537 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGurmukhi-Bold.ttf.sha1
@@ -0,0 +1 @@ +66b46c24dd6ece64d41283f0734ec23380bb6417 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGurmukhi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGurmukhi-Regular.ttf.sha1 new file mode 100644 index 0000000..42f69e9 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGurmukhi-Regular.ttf.sha1
@@ -0,0 +1 @@ +329adf9d083e73e6e0393dae62e281a991c8b103 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGurmukhiUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansGurmukhiUI-Bold.ttf.sha1 new file mode 100644 index 0000000..3eaf4b4 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGurmukhiUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +2410178072dcc690b52acc6897e778a0bffff452 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansGurmukhiUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansGurmukhiUI-Regular.ttf.sha1 new file mode 100644 index 0000000..e0ea527 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansGurmukhiUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +0eae03dbbad4d205e039651899ea9a5310736c6e \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansHanunoo-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansHanunoo-Regular.ttf.sha1 new file mode 100644 index 0000000..799bed7 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansHanunoo-Regular.ttf.sha1
@@ -0,0 +1 @@ +fe0cca164f425b39f8540da5b6463ce77bee640c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansHebrew-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansHebrew-Bold.ttf.sha1 new file mode 100644 index 0000000..87e69d1 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansHebrew-Bold.ttf.sha1
@@ -0,0 +1 @@ +d981044b3ff2607b13ad0051d3b3db7f88007748 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansHebrew-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansHebrew-Regular.ttf.sha1 new file mode 100644 index 0000000..ae16cc0 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansHebrew-Regular.ttf.sha1
@@ -0,0 +1 @@ +083d168f4d033ce85bdc3919081e3880a6136578 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansImperialAramaic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansImperialAramaic-Regular.ttf.sha1 new file mode 100644 index 0000000..240ff2f --- /dev/null +++ b/third_party/blimp_fonts/NotoSansImperialAramaic-Regular.ttf.sha1
@@ -0,0 +1 @@ +660288815e06bf6fb63f746012ca739958135bab \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansInscriptionalPahlavi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansInscriptionalPahlavi-Regular.ttf.sha1 new file mode 100644 index 0000000..e43ac54 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansInscriptionalPahlavi-Regular.ttf.sha1
@@ -0,0 +1 @@ +296c6ba342b1937b6c98ef7428a3bfbd9fed2df3 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansInscriptionalParthian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansInscriptionalParthian-Regular.ttf.sha1 new file mode 100644 index 0000000..e1e8f95 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansInscriptionalParthian-Regular.ttf.sha1
@@ -0,0 +1 @@ +097d726c7477b9261fb5bf01dc4686610a3fbc97 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansJP-Regular-Subsetted.otf.sha1 b/third_party/blimp_fonts/NotoSansJP-Regular-Subsetted.otf.sha1 new file mode 100644 index 0000000..7d4fce5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansJP-Regular-Subsetted.otf.sha1
@@ -0,0 +1 @@ +8afcd909334ce92647a82c2e4aaac408a93bf8ef \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansJP-Regular.otf.sha1 b/third_party/blimp_fonts/NotoSansJP-Regular.otf.sha1 new file mode 100644 index 0000000..2ad4564 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansJP-Regular.otf.sha1
@@ -0,0 +1 @@ +685c52a8ad0b41098e85c099a6e5be0d09ef2f02 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansJavanese-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansJavanese-Regular.ttf.sha1 new file mode 100644 index 0000000..6eee177 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansJavanese-Regular.ttf.sha1
@@ -0,0 +1 @@ +2542883c305f0121e332c658aa8ee22813952fd2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKR-Regular.otf.sha1 b/third_party/blimp_fonts/NotoSansKR-Regular.otf.sha1 new file mode 100644 index 0000000..b5396b3 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKR-Regular.otf.sha1
@@ -0,0 +1 @@ +82e49c4d7e4eced8a0bce49ef901a86459547d8c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKaithi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKaithi-Regular.ttf.sha1 new file mode 100644 index 0000000..277134f --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKaithi-Regular.ttf.sha1
@@ -0,0 +1 @@ +7b6c562b4b0ed7891791a39e1a115eb363ac133f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKannada-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansKannada-Bold.ttf.sha1 new file mode 100644 index 0000000..2d30174 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKannada-Bold.ttf.sha1
@@ -0,0 +1 @@ +709a295c58dee0715dbb3c5d797006281afa6f87 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKannada-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKannada-Regular.ttf.sha1 new file mode 100644 index 0000000..c000026 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKannada-Regular.ttf.sha1
@@ -0,0 +1 @@ +d9293ef195260469a8b3e284e9e6c6e919381c19 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKannadaUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansKannadaUI-Bold.ttf.sha1 new file mode 100644 index 0000000..20a8884 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKannadaUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +0803c674ee4f28199fca9c9624886f3c899a6d1c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKannadaUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKannadaUI-Regular.ttf.sha1 new file mode 100644 index 0000000..9e6e64f6 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKannadaUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +d053741efb996673ba31f1322734148fc95ee13c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKayahLi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKayahLi-Regular.ttf.sha1 new file mode 100644 index 0000000..ba70921 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKayahLi-Regular.ttf.sha1
@@ -0,0 +1 @@ +870b4a50663afb8af3f661ebc3e18ca7a6dda8d3 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKharoshthi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKharoshthi-Regular.ttf.sha1 new file mode 100644 index 0000000..4587667 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKharoshthi-Regular.ttf.sha1
@@ -0,0 +1 @@ +4e09bd089479532dd29d222ad958e58497038b86 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKhmer-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansKhmer-Bold.ttf.sha1 new file mode 100644 index 0000000..9876e5b --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKhmer-Bold.ttf.sha1
@@ -0,0 +1 @@ +680eddbf617b19705a0e067e582da240281b599e \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKhmer-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKhmer-Regular.ttf.sha1 new file mode 100644 index 0000000..d77a6ac --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKhmer-Regular.ttf.sha1
@@ -0,0 +1 @@ +0b7a86319c4f2e19b861d0a9acc92b7670245da2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKhmerUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansKhmerUI-Bold.ttf.sha1 new file mode 100644 index 0000000..036cb9d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKhmerUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +377f97bb928e4634e779d30c2791dec8416ea49f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansKhmerUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansKhmerUI-Regular.ttf.sha1 new file mode 100644 index 0000000..626c7f0 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansKhmerUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +cea1075973e5f15a4a5073ef2f46679e62e6e6a1 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLao-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansLao-Bold.ttf.sha1 new file mode 100644 index 0000000..ff05d6e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLao-Bold.ttf.sha1
@@ -0,0 +1 @@ +4fc0c98ee2c4942f44ce6b48b58a49c5cb0c8be0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLao-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLao-Regular.ttf.sha1 new file mode 100644 index 0000000..6c3c40e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLao-Regular.ttf.sha1
@@ -0,0 +1 @@ +ad401524474b290c3ae2703e5310e37ef604b58b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLaoUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansLaoUI-Bold.ttf.sha1 new file mode 100644 index 0000000..60d9cd5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLaoUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +c8e61bb2c6484c32f3a6f7a9dc5af6b550f78baf \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLaoUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLaoUI-Regular.ttf.sha1 new file mode 100644 index 0000000..46d37b2 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLaoUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +d417ad2d7239079958c786123b885e483d771b26 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLepcha-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLepcha-Regular.ttf.sha1 new file mode 100644 index 0000000..a6b40a7 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLepcha-Regular.ttf.sha1
@@ -0,0 +1 @@ +fdb5fad01f714ad8f84637a2a31db004e6e670c8 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLimbu-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLimbu-Regular.ttf.sha1 new file mode 100644 index 0000000..54accd2c --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLimbu-Regular.ttf.sha1
@@ -0,0 +1 @@ +5a13f322a26cd1247dc8b88056952faad256b6c9 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLinearB-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLinearB-Regular.ttf.sha1 new file mode 100644 index 0000000..f73226f --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLinearB-Regular.ttf.sha1
@@ -0,0 +1 @@ +df9cba01d31a0309b9c2a0e9f01f2aec5ffe70da \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLisu-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLisu-Regular.ttf.sha1 new file mode 100644 index 0000000..bb0e9b4 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLisu-Regular.ttf.sha1
@@ -0,0 +1 @@ +bf95b975fb4f961167c71c5836ea7a4660931b03 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLycian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLycian-Regular.ttf.sha1 new file mode 100644 index 0000000..e069c167 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLycian-Regular.ttf.sha1
@@ -0,0 +1 @@ +da92da0f24ad080c36190c2f18f942daaad2868e \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansLydian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansLydian-Regular.ttf.sha1 new file mode 100644 index 0000000..ee5710b --- /dev/null +++ b/third_party/blimp_fonts/NotoSansLydian-Regular.ttf.sha1
@@ -0,0 +1 @@ +a2f852b9b962d07e72af6304299ef0d435f05bd1 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMalayalam-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansMalayalam-Bold.ttf.sha1 new file mode 100644 index 0000000..6d6fb1d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMalayalam-Bold.ttf.sha1
@@ -0,0 +1 @@ +e020a0103265f2c1dd71261bb6dfdd0ad18bbeab \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMalayalam-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMalayalam-Regular.ttf.sha1 new file mode 100644 index 0000000..3c93dd9 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMalayalam-Regular.ttf.sha1
@@ -0,0 +1 @@ +0e3b4ad160c5e8ffdbe262492b33d2f425e836dc \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMalayalamUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansMalayalamUI-Bold.ttf.sha1 new file mode 100644 index 0000000..8108cdb --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMalayalamUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +00d98bf5b71b2c2715f9fb04168129b7b19d9385 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMalayalamUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMalayalamUI-Regular.ttf.sha1 new file mode 100644 index 0000000..713700a --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMalayalamUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +67d3ad87a313ae88628c67c89b03624aa9b6649f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMandaic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMandaic-Regular.ttf.sha1 new file mode 100644 index 0000000..6a8c1984 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMandaic-Regular.ttf.sha1
@@ -0,0 +1 @@ +370382717a5a166f90343f68f365d5c932f768f5 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMeeteiMayek-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMeeteiMayek-Regular.ttf.sha1 new file mode 100644 index 0000000..9fd6166 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMeeteiMayek-Regular.ttf.sha1
@@ -0,0 +1 @@ +0e3e035dcb6244602125b17e3f374e79583088b7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMongolian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMongolian-Regular.ttf.sha1 new file mode 100644 index 0000000..8c3bea8 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMongolian-Regular.ttf.sha1
@@ -0,0 +1 @@ +514c23daa829d986fb83ce1db7e0db97b6983a72 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMyanmar-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansMyanmar-Bold.ttf.sha1 new file mode 100644 index 0000000..a77727e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMyanmar-Bold.ttf.sha1
@@ -0,0 +1 @@ +eb1bc4722a6e4c62b2d746a6d6a2f90de480821f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMyanmar-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMyanmar-Regular.ttf.sha1 new file mode 100644 index 0000000..b3056c0 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMyanmar-Regular.ttf.sha1
@@ -0,0 +1 @@ +0469de145d807dc3a7565f2d7da1867042ec8e7a \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMyanmarUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansMyanmarUI-Bold.ttf.sha1 new file mode 100644 index 0000000..c9f06d0 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMyanmarUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +594b7d3d54bfe2edbf073f044bcba39b9a75a8bf \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansMyanmarUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansMyanmarUI-Regular.ttf.sha1 new file mode 100644 index 0000000..a48da98 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansMyanmarUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +42a45af174c35216b596085e646425a768717952 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansNKo-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansNKo-Regular.ttf.sha1 new file mode 100644 index 0000000..29bbdf5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansNKo-Regular.ttf.sha1
@@ -0,0 +1 @@ +335ea7c2d3be7d88a1ebfaa0de41336037ec2595 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansNewTaiLue-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansNewTaiLue-Regular.ttf.sha1 new file mode 100644 index 0000000..3c52e91 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansNewTaiLue-Regular.ttf.sha1
@@ -0,0 +1 @@ +81a9a9c1d9a4c29b41bca01418108d52216b5559 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOgham-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOgham-Regular.ttf.sha1 new file mode 100644 index 0000000..abec25e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOgham-Regular.ttf.sha1
@@ -0,0 +1 @@ +18f2332625c8aadb2e0359164a23ea60bf3bb306 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOlChiki-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOlChiki-Regular.ttf.sha1 new file mode 100644 index 0000000..6cdd6d60 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOlChiki-Regular.ttf.sha1
@@ -0,0 +1 @@ +0ece2465241ff335139f95589d55f0e42274f81b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOldItalic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOldItalic-Regular.ttf.sha1 new file mode 100644 index 0000000..f53ed579 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOldItalic-Regular.ttf.sha1
@@ -0,0 +1 @@ +e92907af55b187bb9ebb1e2fbbb1341c07d9f01f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOldPersian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOldPersian-Regular.ttf.sha1 new file mode 100644 index 0000000..c24c8e3b --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOldPersian-Regular.ttf.sha1
@@ -0,0 +1 @@ +f3169cd736266f67a6909d588de7dc77389cb219 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOldSouthArabian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOldSouthArabian-Regular.ttf.sha1 new file mode 100644 index 0000000..ff115366 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOldSouthArabian-Regular.ttf.sha1
@@ -0,0 +1 @@ +a858eff985bb1b94112bc38ce783594c4f2678a7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOldTurkic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOldTurkic-Regular.ttf.sha1 new file mode 100644 index 0000000..149144a1 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOldTurkic-Regular.ttf.sha1
@@ -0,0 +1 @@ +65662c0178078729fec1dd0e74549e687ea09ed7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOriya-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansOriya-Bold.ttf.sha1 new file mode 100644 index 0000000..7e7e7c7 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOriya-Bold.ttf.sha1
@@ -0,0 +1 @@ +05f5bae5d05f853a6cc4b3a24849aec652c90718 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOriya-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOriya-Regular.ttf.sha1 new file mode 100644 index 0000000..712235d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOriya-Regular.ttf.sha1
@@ -0,0 +1 @@ +b0635a39a23b71f88085c403b3aef269bf7b58c4 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOriyaUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansOriyaUI-Bold.ttf.sha1 new file mode 100644 index 0000000..98c0488 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOriyaUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +541170c878075daadfcf1d2a792b6a7312fd4096 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOriyaUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOriyaUI-Regular.ttf.sha1 new file mode 100644 index 0000000..c0e2598a --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOriyaUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +931f507e2ed32d87284c8109ffe027f1e795aaed \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansOsmanya-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansOsmanya-Regular.ttf.sha1 new file mode 100644 index 0000000..0c6e3681 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansOsmanya-Regular.ttf.sha1
@@ -0,0 +1 @@ +ec7b494463ee46dffae8e7d4e234c43dc004ec60 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansPhagsPa-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansPhagsPa-Regular.ttf.sha1 new file mode 100644 index 0000000..6fba4c3 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansPhagsPa-Regular.ttf.sha1
@@ -0,0 +1 @@ +feead638b84c697d770d49c18e6e0a8fdfa62ce9 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansPhoenician-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansPhoenician-Regular.ttf.sha1 new file mode 100644 index 0000000..3dead6e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansPhoenician-Regular.ttf.sha1
@@ -0,0 +1 @@ +59f539be1b6bc8b4e86be3437e1693cc896948c0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansRejang-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansRejang-Regular.ttf.sha1 new file mode 100644 index 0000000..f917711 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansRejang-Regular.ttf.sha1
@@ -0,0 +1 @@ +34c7b71548c9b532167b08facb1c871bb4196056 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansRunic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansRunic-Regular.ttf.sha1 new file mode 100644 index 0000000..ca2daa76 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansRunic-Regular.ttf.sha1
@@ -0,0 +1 @@ +78e7364b4d720528c62ef2038154c78e92c17444 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSC-Regular.otf.sha1 b/third_party/blimp_fonts/NotoSansSC-Regular.otf.sha1 new file mode 100644 index 0000000..e74636c --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSC-Regular.otf.sha1
@@ -0,0 +1 @@ +fd0e99f14fe21661a0d528fb9882c833979f3386 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSamaritan-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSamaritan-Regular.ttf.sha1 new file mode 100644 index 0000000..5172b5d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSamaritan-Regular.ttf.sha1
@@ -0,0 +1 @@ +91bbc172f85eb4f3ae37a8b98128d3ea5dc0e7cf \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSaurashtra-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSaurashtra-Regular.ttf.sha1 new file mode 100644 index 0000000..b677b37 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSaurashtra-Regular.ttf.sha1
@@ -0,0 +1 @@ +6e338de732880469c09e61f5de509189f05225f3 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansShavian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansShavian-Regular.ttf.sha1 new file mode 100644 index 0000000..bdaf32b --- /dev/null +++ b/third_party/blimp_fonts/NotoSansShavian-Regular.ttf.sha1
@@ -0,0 +1 @@ +eb7afe2ae1fd731c6d7e061403589a48df76da0d \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSinhala-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansSinhala-Bold.ttf.sha1 new file mode 100644 index 0000000..0be0a3d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSinhala-Bold.ttf.sha1
@@ -0,0 +1 @@ +ff78425befdaf0bdd24b97a075e66819665ab257 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSinhala-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSinhala-Regular.ttf.sha1 new file mode 100644 index 0000000..08a75bb2 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSinhala-Regular.ttf.sha1
@@ -0,0 +1 @@ +c3dcca37adf3b98add716876f93e30e7d28d5730 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSundanese-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSundanese-Regular.ttf.sha1 new file mode 100644 index 0000000..74936e46 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSundanese-Regular.ttf.sha1
@@ -0,0 +1 @@ +b8990d9647be086ff2ef3c2eeae53536ec3cd98f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSylotiNagri-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSylotiNagri-Regular.ttf.sha1 new file mode 100644 index 0000000..133b5f5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSylotiNagri-Regular.ttf.sha1
@@ -0,0 +1 @@ +a862f457f067fde48161f6865d9418643b37c029 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSymbols-Regular-Subsetted.ttf.sha1 b/third_party/blimp_fonts/NotoSansSymbols-Regular-Subsetted.ttf.sha1 new file mode 100644 index 0000000..1f18c96 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSymbols-Regular-Subsetted.ttf.sha1
@@ -0,0 +1 @@ +e5e8d7c88162df4cfe8cd6405bafa3d3b1cc3166 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSymbols-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSymbols-Regular.ttf.sha1 new file mode 100644 index 0000000..7cd8f19 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSymbols-Regular.ttf.sha1
@@ -0,0 +1 @@ +8b4ac8bf6c801dd39ccadde9f12bade82615f35a \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSyriacEastern-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSyriacEastern-Regular.ttf.sha1 new file mode 100644 index 0000000..35096cb --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSyriacEastern-Regular.ttf.sha1
@@ -0,0 +1 @@ +fdba9e07d99e4a95d248fa7ef9eb96e969859e62 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSyriacEstrangela-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSyriacEstrangela-Regular.ttf.sha1 new file mode 100644 index 0000000..e54fa50 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSyriacEstrangela-Regular.ttf.sha1
@@ -0,0 +1 @@ +7834dfb6bfd02a0b35bcbc23b6ab1d0caa681af6 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansSyriacWestern-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansSyriacWestern-Regular.ttf.sha1 new file mode 100644 index 0000000..511afba4 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansSyriacWestern-Regular.ttf.sha1
@@ -0,0 +1 @@ +15443875b09c934e251da0c8653a12a44264278a \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTC-Regular.otf.sha1 b/third_party/blimp_fonts/NotoSansTC-Regular.otf.sha1 new file mode 100644 index 0000000..4cb9f878 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTC-Regular.otf.sha1
@@ -0,0 +1 @@ +2c4bf5559ca000201c572fc05d46d7b9b4ac9de4 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTagalog-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTagalog-Regular.ttf.sha1 new file mode 100644 index 0000000..1b6b6db --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTagalog-Regular.ttf.sha1
@@ -0,0 +1 @@ +c11711b924f9c0b20716cb82625e4fada3d0c33b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTagbanwa-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTagbanwa-Regular.ttf.sha1 new file mode 100644 index 0000000..082e917 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTagbanwa-Regular.ttf.sha1
@@ -0,0 +1 @@ +e933217646423187bac1196bd2c1ab3ba48adf4d \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTaiLe-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTaiLe-Regular.ttf.sha1 new file mode 100644 index 0000000..ea0a2fe --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTaiLe-Regular.ttf.sha1
@@ -0,0 +1 @@ +155df213be34c45269925ea1581354ec02179c03 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTaiTham-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTaiTham-Regular.ttf.sha1 new file mode 100644 index 0000000..fd3c0a0 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTaiTham-Regular.ttf.sha1
@@ -0,0 +1 @@ +0d1bf0f83c66ea3b92deaaeafa3bd5466a54ee7f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTaiViet-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTaiViet-Regular.ttf.sha1 new file mode 100644 index 0000000..b79c3d4 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTaiViet-Regular.ttf.sha1
@@ -0,0 +1 @@ +508064c86453713ed578ab1428b2686a813501f7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTamil-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansTamil-Bold.ttf.sha1 new file mode 100644 index 0000000..ef28710 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTamil-Bold.ttf.sha1
@@ -0,0 +1 @@ +8f3644c86def39f6bb79631b28ef1174108a63fa \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTamil-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTamil-Regular.ttf.sha1 new file mode 100644 index 0000000..feb6fc8 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTamil-Regular.ttf.sha1
@@ -0,0 +1 @@ +49635e1da5596cd05c764398dfb347dc6ae81ea0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTamilUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansTamilUI-Bold.ttf.sha1 new file mode 100644 index 0000000..f334b54c --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTamilUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +89142481ceb5891f31f5e56420299e32ffd466a2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTamilUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTamilUI-Regular.ttf.sha1 new file mode 100644 index 0000000..44a87b7 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTamilUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +7a05209d7198ca0b0a324770f74998e312e5a57f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTelugu-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansTelugu-Bold.ttf.sha1 new file mode 100644 index 0000000..70cf710 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTelugu-Bold.ttf.sha1
@@ -0,0 +1 @@ +14a8d5b42b1670b0b1673ef92e562f16b6b4d5f5 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTelugu-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTelugu-Regular.ttf.sha1 new file mode 100644 index 0000000..d45d2091 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTelugu-Regular.ttf.sha1
@@ -0,0 +1 @@ +439d61e6aacbf4ce5826b863d5075ce9bbbdae34 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTeluguUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansTeluguUI-Bold.ttf.sha1 new file mode 100644 index 0000000..c2187e21 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTeluguUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +5af88b54631e6b70162ae063903955bbe3cd2f8b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTeluguUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTeluguUI-Regular.ttf.sha1 new file mode 100644 index 0000000..5d7b35b5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTeluguUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +923e09cbca1ad94f2c0ac9932d9b5db784fcfa25 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansThaana-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansThaana-Bold.ttf.sha1 new file mode 100644 index 0000000..103cea2 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansThaana-Bold.ttf.sha1
@@ -0,0 +1 @@ +9585cb2672e485f86216870a450e22ef9125fd33 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansThaana-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansThaana-Regular.ttf.sha1 new file mode 100644 index 0000000..e475a9d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansThaana-Regular.ttf.sha1
@@ -0,0 +1 @@ +bc685050058ca472fdd67f8a7a43699252bbf3ef \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansThai-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansThai-Bold.ttf.sha1 new file mode 100644 index 0000000..f97107a --- /dev/null +++ b/third_party/blimp_fonts/NotoSansThai-Bold.ttf.sha1
@@ -0,0 +1 @@ +f9332a74751a1c9a8ae5915a094279e8a716387f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansThai-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansThai-Regular.ttf.sha1 new file mode 100644 index 0000000..c91bff1e --- /dev/null +++ b/third_party/blimp_fonts/NotoSansThai-Regular.ttf.sha1
@@ -0,0 +1 @@ +c4fa534578248260321cc8da6a090dc021c47126 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansThaiUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansThaiUI-Bold.ttf.sha1 new file mode 100644 index 0000000..b6962b8 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansThaiUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +a3d4349b3cf5e8b737ebad1eea37f86f3274749d \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansThaiUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansThaiUI-Regular.ttf.sha1 new file mode 100644 index 0000000..7b7a483 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansThaiUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +947be6d319b4a67796fe3410d64d365ff1bc5d7c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTibetan-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTibetan-Regular.ttf.sha1 new file mode 100644 index 0000000..dc5c23c --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTibetan-Regular.ttf.sha1
@@ -0,0 +1 @@ +4b769855dc15edebf6d6e13afdc044c96c98c680 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansTifinagh-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansTifinagh-Regular.ttf.sha1 new file mode 100644 index 0000000..42d4b27bb --- /dev/null +++ b/third_party/blimp_fonts/NotoSansTifinagh-Regular.ttf.sha1
@@ -0,0 +1 @@ +e8600002e8d4e60a43c9c4084b527aa25d8ed1c4 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansUI-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSansUI-Bold.ttf.sha1 new file mode 100644 index 0000000..488e798 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansUI-Bold.ttf.sha1
@@ -0,0 +1 @@ +f8c365a95bdd3a4d60bdb6c43995660223afaee0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansUI-BoldItalic.ttf.sha1 b/third_party/blimp_fonts/NotoSansUI-BoldItalic.ttf.sha1 new file mode 100644 index 0000000..0601892 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansUI-BoldItalic.ttf.sha1
@@ -0,0 +1 @@ +efe7c88a6fb0c7711cc29ec4206c93dba319150b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansUI-Italic.ttf.sha1 b/third_party/blimp_fonts/NotoSansUI-Italic.ttf.sha1 new file mode 100644 index 0000000..84f7ac5 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansUI-Italic.ttf.sha1
@@ -0,0 +1 @@ +9cf96f38e211a21d71a2c21f2c5e6e2ee34024eb \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansUI-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansUI-Regular.ttf.sha1 new file mode 100644 index 0000000..ef4bb52 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansUI-Regular.ttf.sha1
@@ -0,0 +1 @@ +6930143f0077b8e43b0677df8739e7a3c30caa69 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansUgaritic-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansUgaritic-Regular.ttf.sha1 new file mode 100644 index 0000000..6cf0e7d --- /dev/null +++ b/third_party/blimp_fonts/NotoSansUgaritic-Regular.ttf.sha1
@@ -0,0 +1 @@ +8f8ebc30c66a06dbe2997b1a07e0668e105ed067 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansVai-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansVai-Regular.ttf.sha1 new file mode 100644 index 0000000..1502e6a --- /dev/null +++ b/third_party/blimp_fonts/NotoSansVai-Regular.ttf.sha1
@@ -0,0 +1 @@ +4ce9208384bfb5a21767ab85311837277d8b9978 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSansYi-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSansYi-Regular.ttf.sha1 new file mode 100644 index 0000000..66d1962 --- /dev/null +++ b/third_party/blimp_fonts/NotoSansYi-Regular.ttf.sha1
@@ -0,0 +1 @@ +ea20e1e87a943b37262ab10e3003525861d95d60 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerif-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSerif-Bold.ttf.sha1 new file mode 100644 index 0000000..f9bf271 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerif-Bold.ttf.sha1
@@ -0,0 +1 @@ +82b243fd7bdba883b5a6a73ac6d68b3da1b3b97b \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerif-BoldItalic.ttf.sha1 b/third_party/blimp_fonts/NotoSerif-BoldItalic.ttf.sha1 new file mode 100644 index 0000000..6800f8f9 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerif-BoldItalic.ttf.sha1
@@ -0,0 +1 @@ +39141b42604ed41d8a6d85366c775cded1d6752c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerif-Italic.ttf.sha1 b/third_party/blimp_fonts/NotoSerif-Italic.ttf.sha1 new file mode 100644 index 0000000..fccb33ec --- /dev/null +++ b/third_party/blimp_fonts/NotoSerif-Italic.ttf.sha1
@@ -0,0 +1 @@ +2e2e8b537d7d86e1f5c2e0d3338720d0d853c09f \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerif-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSerif-Regular.ttf.sha1 new file mode 100644 index 0000000..d77fdd1 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerif-Regular.ttf.sha1
@@ -0,0 +1 @@ +8608d1f96bb9482ea8942ebd6545cdb9e2921ed9 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifArmenian-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSerifArmenian-Bold.ttf.sha1 new file mode 100644 index 0000000..12b87be --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifArmenian-Bold.ttf.sha1
@@ -0,0 +1 @@ +d9952506333e6076a6ad1fe237b590d3a124e3da \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifArmenian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSerifArmenian-Regular.ttf.sha1 new file mode 100644 index 0000000..e511251 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifArmenian-Regular.ttf.sha1
@@ -0,0 +1 @@ +54fffecfd5fb8f33fa0b88d752a532dd767b8d90 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifGeorgian-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSerifGeorgian-Bold.ttf.sha1 new file mode 100644 index 0000000..7a018ab --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifGeorgian-Bold.ttf.sha1
@@ -0,0 +1 @@ +fd2cc6de838f77ac7692725d249e29443560a8bc \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifGeorgian-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSerifGeorgian-Regular.ttf.sha1 new file mode 100644 index 0000000..f7247c43 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifGeorgian-Regular.ttf.sha1
@@ -0,0 +1 @@ +16c1f30c13622a6a080d910ea5db3fa7815c11e8 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifKhmer-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSerifKhmer-Bold.ttf.sha1 new file mode 100644 index 0000000..31bc23f --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifKhmer-Bold.ttf.sha1
@@ -0,0 +1 @@ +fcb63dfd57dc35d81eef4d9b91598f6e7e93000c \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifKhmer-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSerifKhmer-Regular.ttf.sha1 new file mode 100644 index 0000000..e778e05 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifKhmer-Regular.ttf.sha1
@@ -0,0 +1 @@ +a4000457e9f5db03fd4161ed420b9e426bdb0d87 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifLao-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSerifLao-Bold.ttf.sha1 new file mode 100644 index 0000000..911d2960 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifLao-Bold.ttf.sha1
@@ -0,0 +1 @@ +ab67b00c5092b0094af2ad54cfdb9018b8299ab4 \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifLao-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSerifLao-Regular.ttf.sha1 new file mode 100644 index 0000000..a809edda --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifLao-Regular.ttf.sha1
@@ -0,0 +1 @@ +cca411f1874c4a03386078b0712ca849e8a7f9bf \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifThai-Bold.ttf.sha1 b/third_party/blimp_fonts/NotoSerifThai-Bold.ttf.sha1 new file mode 100644 index 0000000..668c5a31 --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifThai-Bold.ttf.sha1
@@ -0,0 +1 @@ +ced1a6c362d127948b5a4d36548732f9de033c1d \ No newline at end of file
diff --git a/third_party/blimp_fonts/NotoSerifThai-Regular.ttf.sha1 b/third_party/blimp_fonts/NotoSerifThai-Regular.ttf.sha1 new file mode 100644 index 0000000..c5831fcc --- /dev/null +++ b/third_party/blimp_fonts/NotoSerifThai-Regular.ttf.sha1
@@ -0,0 +1 @@ +8db9bbb5f1d3f71829a4130d953b676c8bdf0625 \ No newline at end of file
diff --git a/third_party/blimp_fonts/OWNERS b/third_party/blimp_fonts/OWNERS new file mode 100644 index 0000000..d7dfb92 --- /dev/null +++ b/third_party/blimp_fonts/OWNERS
@@ -0,0 +1,5 @@ +dtrainor@chromium.org +haibinlu@chromium.org +kmarshall@chromium.org +nyquist@chromium.org +wez@chromium.org
diff --git a/third_party/blimp_fonts/README.chromium b/third_party/blimp_fonts/README.chromium new file mode 100644 index 0000000..380be7c8 --- /dev/null +++ b/third_party/blimp_fonts/README.chromium
@@ -0,0 +1,49 @@ +Name: blimp_fonts +URL: See below +Version: unknown +License: Apache Version 2.0 and SIL Open Font License, Version 1.1 +Security Critical: yes + +Description: +A collection of fonts that are necessary to bundle with the blimp engine to be +able to render the correct fonts for different clients. + +How to update: +See //blimp/docs/fonts.md. + +Local Modifications: +Not all files from the external repositories are used. +- *.otf, *.ttf: From the various repositories. +- .gitignore: Added. +- BUILD.gn: Added. +- LICENSE: Added. +- LICENSE.*: Extracted from license files in the various repositories. +- README.md: Added. +- fonts.xml: From this repository: + https://android.googlesource.com/platform/frameworks/base.git + +Fonts are pulled from the following repositories: +- Git repo: https://android.googlesource.com/platform/frameworks/base.git + Commit: 6a278db4c4a144829353e81420f28dcf2105f767 + Directory: data/fonts/ +- Git repo: https://android.googlesource.com/platform/external/noto-fonts.git + Commit: eb0883544dd538edbfb52cce9a2481509ca5ee9f + Directory: cjk/, other/ +- Git repo: https://android.googlesource.com/platform/external/roboto-fonts.git + Commit: f5cf79102af594c746627b392b4f98eedd254571 + Directory: . +- Git repo: https://android.googlesource.com/platform/external/google-fonts/dancing-script.git + Commit: 7b6623bd54cee3e48ae8a4f477f616366643cc78 + Directory: . +- Git repo: https://android.googlesource.com/platform/external/google-fonts/cutive-mono.git + Commit: bce2136662854076023066602526ba299e6556b2 + Directory: . +- Git repo: https://android.googlesource.com/platform/external/google-fonts/coming-soon.git + Commit: 2c5cb418c690815545bbb0316eae5fd33b9fc859 + Directory: . +- Git repo: https://android.googlesource.com/platform/external/google-fonts/carrois-gothic-sc.git + Commit: 0062a10458d4c357f3082d66bcb129d11913aaae + Directory: . +- Git repo: https://android.googlesource.com/platform/external/naver-fonts.git + Commit: 91e6e9f94d1d769a8f742649674149ba98ce7d45 + Directory: .
diff --git a/third_party/blimp_fonts/Roboto-Black.ttf.sha1 b/third_party/blimp_fonts/Roboto-Black.ttf.sha1 new file mode 100644 index 0000000..6ee8a62 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Black.ttf.sha1
@@ -0,0 +1 @@ +d3ecadec65a1ed2765a0f6b47b6bf2000e8491d5 \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-BlackItalic.ttf.sha1 b/third_party/blimp_fonts/Roboto-BlackItalic.ttf.sha1 new file mode 100644 index 0000000..9b159021 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-BlackItalic.ttf.sha1
@@ -0,0 +1 @@ +82960419d7bdadc88fa3a94a016bd93538666769 \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-Bold.ttf.sha1 b/third_party/blimp_fonts/Roboto-Bold.ttf.sha1 new file mode 100644 index 0000000..59a0f18a --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Bold.ttf.sha1
@@ -0,0 +1 @@ +ce209e7a825828599429bf4d0d134272d20adf3d \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-BoldItalic.ttf.sha1 b/third_party/blimp_fonts/Roboto-BoldItalic.ttf.sha1 new file mode 100644 index 0000000..20dad84 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-BoldItalic.ttf.sha1
@@ -0,0 +1 @@ +0982eed1d138c584407ac6dd04448eb643bef2b0 \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-Italic.ttf.sha1 b/third_party/blimp_fonts/Roboto-Italic.ttf.sha1 new file mode 100644 index 0000000..c875f750 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Italic.ttf.sha1
@@ -0,0 +1 @@ +d701e916ba7ef08efef9b924b0e220ac0623a75a \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-Light.ttf.sha1 b/third_party/blimp_fonts/Roboto-Light.ttf.sha1 new file mode 100644 index 0000000..c62d9d0 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Light.ttf.sha1
@@ -0,0 +1 @@ +1ce31afef046a5f38dbcb6e212d827eb69d56569 \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-LightItalic.ttf.sha1 b/third_party/blimp_fonts/Roboto-LightItalic.ttf.sha1 new file mode 100644 index 0000000..5aac8f52 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-LightItalic.ttf.sha1
@@ -0,0 +1 @@ +a2ec190ac6d148c53128eb1ed61c638b3006ed5d \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-Medium.ttf.sha1 b/third_party/blimp_fonts/Roboto-Medium.ttf.sha1 new file mode 100644 index 0000000..ebce56d --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Medium.ttf.sha1
@@ -0,0 +1 @@ +92d678bb9f3c07deabfaa4e62b9de0aeab45888a \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-MediumItalic.ttf.sha1 b/third_party/blimp_fonts/Roboto-MediumItalic.ttf.sha1 new file mode 100644 index 0000000..943de92 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-MediumItalic.ttf.sha1
@@ -0,0 +1 @@ +4bc89e68bb659347904cae4543e9e22eb06e43dc \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-Regular.ttf.sha1 b/third_party/blimp_fonts/Roboto-Regular.ttf.sha1 new file mode 100644 index 0000000..ce967ad --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Regular.ttf.sha1
@@ -0,0 +1 @@ +9475dcae6d4d43961baecbe3049d70eaef1ba2e2 \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-Thin.ttf.sha1 b/third_party/blimp_fonts/Roboto-Thin.ttf.sha1 new file mode 100644 index 0000000..2c13ddc --- /dev/null +++ b/third_party/blimp_fonts/Roboto-Thin.ttf.sha1
@@ -0,0 +1 @@ +a1d984651a0481e5232ee925e2c37895a375d11c \ No newline at end of file
diff --git a/third_party/blimp_fonts/Roboto-ThinItalic.ttf.sha1 b/third_party/blimp_fonts/Roboto-ThinItalic.ttf.sha1 new file mode 100644 index 0000000..dfdff321 --- /dev/null +++ b/third_party/blimp_fonts/Roboto-ThinItalic.ttf.sha1
@@ -0,0 +1 @@ +e828ca5fede8ae7dc78a09a718506412fe8851a7 \ No newline at end of file
diff --git a/third_party/blimp_fonts/RobotoCondensed-Bold.ttf.sha1 b/third_party/blimp_fonts/RobotoCondensed-Bold.ttf.sha1 new file mode 100644 index 0000000..a28bd78 --- /dev/null +++ b/third_party/blimp_fonts/RobotoCondensed-Bold.ttf.sha1
@@ -0,0 +1 @@ +ddd594ab7c3b7e2a0a36fd812afe2ec40c509fce \ No newline at end of file
diff --git a/third_party/blimp_fonts/RobotoCondensed-BoldItalic.ttf.sha1 b/third_party/blimp_fonts/RobotoCondensed-BoldItalic.ttf.sha1 new file mode 100644 index 0000000..7987f563 --- /dev/null +++ b/third_party/blimp_fonts/RobotoCondensed-BoldItalic.ttf.sha1
@@ -0,0 +1 @@ +ca1359cb1d5d82a8d7956e4b469bd031e63b5ab3 \ No newline at end of file
diff --git a/third_party/blimp_fonts/RobotoCondensed-Italic.ttf.sha1 b/third_party/blimp_fonts/RobotoCondensed-Italic.ttf.sha1 new file mode 100644 index 0000000..00db36f --- /dev/null +++ b/third_party/blimp_fonts/RobotoCondensed-Italic.ttf.sha1
@@ -0,0 +1 @@ +fd09eff1019edb33d3d3a4af9c9e8efd109eff06 \ No newline at end of file
diff --git a/third_party/blimp_fonts/RobotoCondensed-Light.ttf.sha1 b/third_party/blimp_fonts/RobotoCondensed-Light.ttf.sha1 new file mode 100644 index 0000000..6038de8 --- /dev/null +++ b/third_party/blimp_fonts/RobotoCondensed-Light.ttf.sha1
@@ -0,0 +1 @@ +810a20524f675f6633de3a6ee0a5cdd5741c5139 \ No newline at end of file
diff --git a/third_party/blimp_fonts/RobotoCondensed-LightItalic.ttf.sha1 b/third_party/blimp_fonts/RobotoCondensed-LightItalic.ttf.sha1 new file mode 100644 index 0000000..af7a5747 --- /dev/null +++ b/third_party/blimp_fonts/RobotoCondensed-LightItalic.ttf.sha1
@@ -0,0 +1 @@ +66891ba5c00b998aa4796f95191b2d3864e7d07a \ No newline at end of file
diff --git a/third_party/blimp_fonts/RobotoCondensed-Regular.ttf.sha1 b/third_party/blimp_fonts/RobotoCondensed-Regular.ttf.sha1 new file mode 100644 index 0000000..4cb0246 --- /dev/null +++ b/third_party/blimp_fonts/RobotoCondensed-Regular.ttf.sha1
@@ -0,0 +1 @@ +fb9c9c896f5cc2b6b90a8359ce213144bb0716f1 \ No newline at end of file
diff --git a/third_party/blimp_fonts/fonts.xml b/third_party/blimp_fonts/fonts.xml new file mode 100644 index 0000000..dbe81fa --- /dev/null +++ b/third_party/blimp_fonts/fonts.xml
@@ -0,0 +1,371 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + NOTE: this is the newer (L) version of the system font configuration, + supporting richer weight selection. Some apps will expect the older + version, so please keep system_fonts.xml and fallback_fonts.xml in sync + with any changes, even though framework will only read this file. + + All fonts withohut names are added to the default list. Fonts are chosen + based on a match: full BCP-47 language tag including script, then just + language, and finally order (the first font containing the glyph). + + Order of appearance is also the tiebreaker for weight matching. This is + the reason why the 900 weights of Roboto precede the 700 weights - we + prefer the former when an 800 weight is requested. Since bold spans + effectively add 300 to the weight, this ensures that 900 is the bold + paired with the 500 weight, ensuring adequate contrast. +--> +<familyset version="22"> + <!-- first font is default --> + <family name="sans-serif"> + <font weight="100" style="normal">Roboto-Thin.ttf</font> + <font weight="100" style="italic">Roboto-ThinItalic.ttf</font> + <font weight="300" style="normal">Roboto-Light.ttf</font> + <font weight="300" style="italic">Roboto-LightItalic.ttf</font> + <font weight="400" style="normal">Roboto-Regular.ttf</font> + <font weight="400" style="italic">Roboto-Italic.ttf</font> + <font weight="500" style="normal">Roboto-Medium.ttf</font> + <font weight="500" style="italic">Roboto-MediumItalic.ttf</font> + <font weight="900" style="normal">Roboto-Black.ttf</font> + <font weight="900" style="italic">Roboto-BlackItalic.ttf</font> + <font weight="700" style="normal">Roboto-Bold.ttf</font> + <font weight="700" style="italic">Roboto-BoldItalic.ttf</font> + </family> + + <!-- Note that aliases must come after the fonts they reference. --> + <alias name="sans-serif-thin" to="sans-serif" weight="100" /> + <alias name="sans-serif-light" to="sans-serif" weight="300" /> + <alias name="sans-serif-medium" to="sans-serif" weight="500" /> + <alias name="sans-serif-black" to="sans-serif" weight="900" /> + <alias name="arial" to="sans-serif" /> + <alias name="helvetica" to="sans-serif" /> + <alias name="tahoma" to="sans-serif" /> + <alias name="verdana" to="sans-serif" /> + + <family name="sans-serif-condensed"> + <font weight="300" style="normal">RobotoCondensed-Light.ttf</font> + <font weight="300" style="italic">RobotoCondensed-LightItalic.ttf</font> + <font weight="400" style="normal">RobotoCondensed-Regular.ttf</font> + <font weight="400" style="italic">RobotoCondensed-Italic.ttf</font> + <font weight="700" style="normal">RobotoCondensed-Bold.ttf</font> + <font weight="700" style="italic">RobotoCondensed-BoldItalic.ttf</font> + </family> + <alias name="sans-serif-condensed-light" to="sans-serif-condensed" weight="300" /> + + <family name="serif"> + <font weight="400" style="normal">NotoSerif-Regular.ttf</font> + <font weight="700" style="normal">NotoSerif-Bold.ttf</font> + <font weight="400" style="italic">NotoSerif-Italic.ttf</font> + <font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font> + </family> + <alias name="times" to="serif" /> + <alias name="times new roman" to="serif" /> + <alias name="palatino" to="serif" /> + <alias name="georgia" to="serif" /> + <alias name="baskerville" to="serif" /> + <alias name="goudy" to="serif" /> + <alias name="fantasy" to="serif" /> + <alias name="ITC Stone Serif" to="serif" /> + + <family name="monospace"> + <font weight="400" style="normal">DroidSansMono.ttf</font> + </family> + <alias name="sans-serif-monospace" to="monospace" /> + <alias name="monaco" to="monospace" /> + + <family name="serif-monospace"> + <font weight="400" style="normal">CutiveMono.ttf</font> + </family> + <alias name="courier" to="serif-monospace" /> + <alias name="courier new" to="serif-monospace" /> + + <family name="casual"> + <font weight="400" style="normal">ComingSoon.ttf</font> + </family> + + <family name="cursive"> + <font weight="400" style="normal">DancingScript-Regular.ttf</font> + <font weight="700" style="normal">DancingScript-Bold.ttf</font> + </family> + + <family name="sans-serif-smallcaps"> + <font weight="400" style="normal">CarroisGothicSC-Regular.ttf</font> + </family> + + <!-- fallback fonts --> + <family variant="elegant"> + <font weight="400" style="normal">NotoNaskhArabic-Regular.ttf</font> + <font weight="700" style="normal">NotoNaskhArabic-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoNaskhArabicUI-Regular.ttf</font> + <font weight="700" style="normal">NotoNaskhArabicUI-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font> + <font weight="700" style="normal">NotoSansEthiopic-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font> + <font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansThai-Regular.ttf</font> + <font weight="700" style="normal">NotoSansThai-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font> + <font weight="700" style="normal">NotoSansArmenian-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font> + <font weight="700" style="normal">NotoSansGeorgian-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansDevanagari-Regular.ttf</font> + <font weight="700" style="normal">NotoSansDevanagari-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansDevanagariUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansDevanagariUI-Bold.ttf</font> + </family> + <!-- Gujarati should come after Devanagari --> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font> + <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font> + </family> + <!-- Gurmukhi should come after Devanagari --> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansGurmukhi-Regular.ttf</font> + <font weight="700" style="normal">NotoSansGurmukhi-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansGurmukhiUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansTamil-Regular.ttf</font> + <font weight="700" style="normal">NotoSansTamil-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansTamilUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansTamilUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansMalayalam-Regular.ttf</font> + <font weight="700" style="normal">NotoSansMalayalam-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansMalayalamUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansMalayalamUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansBengali-Regular.ttf</font> + <font weight="700" style="normal">NotoSansBengali-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansBengaliUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansTelugu-Regular.ttf</font> + <font weight="700" style="normal">NotoSansTelugu-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansTeluguUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansKannada-Regular.ttf</font> + <font weight="700" style="normal">NotoSansKannada-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansKannadaUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansOriya-Regular.ttf</font> + <font weight="700" style="normal">NotoSansOriya-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansOriyaUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font> + <font weight="700" style="normal">NotoSansSinhala-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansKhmer-Regular.ttf</font> + <font weight="700" style="normal">NotoSansKhmer-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansLao-Regular.ttf</font> + <font weight="700" style="normal">NotoSansLao-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font> + </family> + <family variant="elegant"> + <font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font> + <font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font> + </family> + <family variant="compact"> + <font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font> + <font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font> + <font weight="700" style="normal">NotoSansThaana-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansCham-Regular.ttf</font> + <font weight="700" style="normal">NotoSansCham-Bold.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansBalinese-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansBamum-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansBatak-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansBuginese-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansBuhid-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansCoptic-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansGlagolitic-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansHanunoo-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansJavanese-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansKayahLi-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansLepcha-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansLimbu-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansLisu-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansMandaic-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansNewTaiLue-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansNKo-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansOlChiki-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansRejang-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansSaurashtra-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansSundanese-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansSylotiNagri-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansSyriacEstrangela-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansTagbanwa-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansTaiTham-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansTaiViet-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansTibetan-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansTifinagh-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansVai-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansYi-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font> + </family> + <family lang="zh-Hans"> + <font weight="400" style="normal">NotoSansSC-Regular.otf</font> + </family> + <family lang="zh-Hant"> + <font weight="400" style="normal">NotoSansTC-Regular.otf</font> + </family> + <family lang="ja"> + <font weight="400" style="normal">NotoSansJP-Regular.otf</font> + </family> + <family lang="ko"> + <font weight="400" style="normal">NotoSansKR-Regular.otf</font> + </family> + <family> + <font weight="400" style="normal">NanumGothic.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoColorEmoji.ttf</font> + </family> + <family> + <font weight="400" style="normal">DroidSansFallback.ttf</font> + </family> + <family lang="ja"> + <font weight="400" style="normal">MTLmr3m.ttf</font> + </family> + <!-- + Tai Le and Mongolian are intentionally kept last, to make sure they don't override + the East Asian punctuation for Chinese. + --> + <family> + <font weight="400" style="normal">NotoSansTaiLe-Regular.ttf</font> + </family> + <family> + <font weight="400" style="normal">NotoSansMongolian-Regular.ttf</font> + </family> +</familyset>
diff --git a/third_party/closure_compiler/compiled_resources.gyp b/third_party/closure_compiler/compiled_resources.gyp index e7a8aeb..eddacdd 100644 --- a/third_party/closure_compiler/compiled_resources.gyp +++ b/third_party/closure_compiler/compiled_resources.gyp
@@ -27,7 +27,6 @@ '../../chrome/browser/resources/options/compiled_resources.gyp:*', '../../chrome/browser/resources/media_router/compiled_resources.gyp:*', '../../chrome/browser/resources/md_extensions/compiled_resources.gyp:*', - '../../chrome/browser/resources/md_history/compiled_resources.gyp:*', '../../chrome/browser/resources/ntp4/compiled_resources.gyp:*', '../../remoting/app_remoting_webapp_compile.gypi:*', '../../remoting/remoting_webapp_compile.gypi:*',
diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp index f04e090..817f782 100644 --- a/third_party/closure_compiler/compiled_resources2.gyp +++ b/third_party/closure_compiler/compiled_resources2.gyp
@@ -18,6 +18,7 @@ '<(DEPTH)/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/history/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/md_downloads/compiled_resources2.gyp:*', + '<(DEPTH)/chrome/browser/resources/md_history/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/settings/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/uber/compiled_resources2.gyp:*', '<(DEPTH)/ui/webui/resources/cr_elements/compiled_resources2.gyp:*',
diff --git a/third_party/libjingle/BUILD.gn b/third_party/libjingle/BUILD.gn index 1c3e5f9..962ec91 100644 --- a/third_party/libjingle/BUILD.gn +++ b/third_party/libjingle/BUILD.gn
@@ -324,6 +324,8 @@ "../webrtc/api/statstypes.h", "../webrtc/api/streamcollection.h", "../webrtc/api/umametrics.h", + "../webrtc/api/videocapturertracksource.cc", + "../webrtc/api/videocapturertracksource.h", "../webrtc/api/videosource.cc", "../webrtc/api/videosource.h", "../webrtc/api/videosourceinterface.h", @@ -332,6 +334,8 @@ "../webrtc/api/videotrack.h", "../webrtc/api/videotrackrenderers.cc", "../webrtc/api/videotrackrenderers.h", + "../webrtc/api/videotracksource.cc", + "../webrtc/api/videotracksource.h", "../webrtc/api/webrtcsdp.cc", "../webrtc/api/webrtcsdp.h", "../webrtc/api/webrtcsession.cc",
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index 4abaaf03..a1fcda4 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://www.webrtc.org Version: unknown -Revision: 11754 +Revision: 11893 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp index 6edf17f9..586368c 100644 --- a/third_party/libjingle/libjingle.gyp +++ b/third_party/libjingle/libjingle.gyp
@@ -289,6 +289,8 @@ '<(DEPTH)/third_party/webrtc/api/statstypes.h', '<(DEPTH)/third_party/webrtc/api/streamcollection.h', '<(DEPTH)/third_party/webrtc/api/umametrics.h', + '<(DEPTH)/third_party/webrtc/api/videocapturertracksource.cc', + '<(DEPTH)/third_party/webrtc/api/videocapturertracksource.h', '<(DEPTH)/third_party/webrtc/api/videosource.cc', '<(DEPTH)/third_party/webrtc/api/videosource.h', '<(DEPTH)/third_party/webrtc/api/videosourceinterface.h', @@ -297,6 +299,8 @@ '<(DEPTH)/third_party/webrtc/api/videotrack.h', '<(DEPTH)/third_party/webrtc/api/videotrackrenderers.cc', '<(DEPTH)/third_party/webrtc/api/videotrackrenderers.h', + '<(DEPTH)/third_party/webrtc/api/videotracksource.cc', + '<(DEPTH)/third_party/webrtc/api/videotracksource.h', '<(DEPTH)/third_party/webrtc/api/webrtcsdp.cc', '<(DEPTH)/third_party/webrtc/api/webrtcsdp.h', '<(DEPTH)/third_party/webrtc/api/webrtcsession.cc',
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium index c3536ee2..33d9f98 100644 --- a/third_party/libxml/README.chromium +++ b/third_party/libxml/README.chromium
@@ -36,6 +36,9 @@ cd libxml2-2.9.2\win32 cscript //E:jscript configure.js compiler=msvc iconv=no icu=yes ftp=no http=no Then copy VC10/config.h and include/libxml/xmlversion.h to win32/ on Linux. +Patch win32/config.h to wrap the #define snprintf with: + #if _MSC_VER < 1900 + #endif Remove: src/doc/
diff --git a/third_party/libxml/win32/config.h b/third_party/libxml/win32/config.h index 8629944e..b9e0e5c0 100644 --- a/third_party/libxml/win32/config.h +++ b/third_party/libxml/win32/config.h
@@ -96,7 +96,9 @@ #if defined(_MSC_VER) #define mkdir(p,m) _mkdir(p) +#if _MSC_VER < 1900 #define snprintf _snprintf +#endif #if _MSC_VER < 1500 #define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a) #endif
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index 2806dab..1f1928e 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -88,15 +88,36 @@ // A method is from Blink if it is from the Blink namespace or overrides a // method from the Blink namespace. bool IsBlinkOrWTFMethod(const clang::CXXMethodDecl& decl) { - if (IsDeclContextInBlinkOrWTF(decl.getDeclContext(), true, true)) - return true; + bool overrides_blink = false; + bool overrides_non_blink = false; for (auto it = decl.begin_overridden_methods(); it != decl.end_overridden_methods(); ++it) { if (IsBlinkOrWTFMethod(**it)) - return true; + overrides_blink = true; + else + overrides_non_blink = true; } - return false; + + // If this fires we have a class overriding a method from a class in blink, + // and also overriding a method of the same name from a class not in blink, + // without a common base class. The blink method will be renamed but the + // non-blink method will not, meaning no matter what we do here we stop + // overriding one of the two which creates a behaviour change. So assert and + // demand the user to fix the code first. T_T + if (overrides_blink || overrides_non_blink) + assert(overrides_blink != overrides_non_blink); + + // If the method overrides something from outside blink then it's not a blink + // method. + if (overrides_non_blink) + return false; + // If the method overrides something from inside blink, then it is also a + // blink method. + if (overrides_blink) + return true; + // Otherwise decide for itself. + return IsDeclContextInBlinkOrWTF(decl.getDeclContext(), true, true); } AST_MATCHER(clang::CXXMethodDecl, isBlinkOrWTFMethod) {
diff --git a/tools/clang/rewrite_to_chrome_style/tests/methods-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/methods-expected.cc index c45df99..343e4e1 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/methods-expected.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/methods-expected.cc
@@ -2,8 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +namespace v8 { + +class InterfaceOutsideOfBlink { + public: + virtual void nonBlinkVirtual() = 0; +}; + +} // namespace v8 + namespace blink { +class InsideOfBlink : public v8::InterfaceOutsideOfBlink { + public: + // This function overrides something outside of blink so don't rename it. + void nonBlinkVirtual() override {} + // This function is in blink so rename it. + virtual void BlinkVirtual() {} +}; + class MyIterator {}; using my_iterator = char*; @@ -110,6 +127,23 @@ return tt; } +class SubclassOfInsideOfBlink : public blink::InsideOfBlink { + public: + // This function overrides something outside of blink so don't rename it. + void nonBlinkVirtual() override {} + // This function overrides something in blink so rename it. + void BlinkVirtual() override {} +}; + +class TestSubclassInsideOfBlink : public SubclassOfInsideOfBlink { + public: + public: + // This function overrides something outside of blink so don't rename it. + void nonBlinkVirtual() override {} + // This function overrides something in blink so rename it. + void BlinkVirtual() override {} +}; + namespace blink { struct StructInBlink {
diff --git a/tools/clang/rewrite_to_chrome_style/tests/methods-original.cc b/tools/clang/rewrite_to_chrome_style/tests/methods-original.cc index 1bd97fa..040582dd 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/methods-original.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/methods-original.cc
@@ -2,8 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +namespace v8 { + +class InterfaceOutsideOfBlink { + public: + virtual void nonBlinkVirtual() = 0; +}; + +} // namespace v8 + namespace blink { +class InsideOfBlink : public v8::InterfaceOutsideOfBlink { + public: + // This function overrides something outside of blink so don't rename it. + void nonBlinkVirtual() override {} + // This function is in blink so rename it. + virtual void blinkVirtual() {} +}; + class MyIterator {}; using my_iterator = char*; @@ -114,6 +131,23 @@ return tt; } +class SubclassOfInsideOfBlink : public blink::InsideOfBlink { + public: + // This function overrides something outside of blink so don't rename it. + void nonBlinkVirtual() override {} + // This function overrides something in blink so rename it. + void blinkVirtual() override {} +}; + +class TestSubclassInsideOfBlink : public SubclassOfInsideOfBlink { + public: + public: + // This function overrides something outside of blink so don't rename it. + void nonBlinkVirtual() override {} + // This function overrides something in blink so rename it. + void blinkVirtual() override {} +}; + namespace blink { struct StructInBlink {
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 3365cb0..09ebfbb 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -18757,6 +18757,14 @@ </summary> </histogram> +<histogram name="Login.PasswordChangeFlow" enum="LoginPasswordChangeFlow"> + <owner>xiyuan@chromium.org</owner> + <owner>omrilio@chromium.org</owner> + <summary> + Records the UI flow after a possible password change is detected. + </summary> +</histogram> + <histogram name="Login.PolicyFilesStatePerBoot" enum="LoginPolicyFilesState"> <owner>cmasone@chromium.org</owner> <summary>The state of Chrome OS owner key and device policy files.</summary> @@ -66221,6 +66229,8 @@ <int value="1108" label="ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY"/> <int value="1109" label="ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY"/> <int value="1110" label="INPUTMETHODPRIVATE_NOTIFYIMEMENUITEMACTIVATED"/> + <int value="1111" label="INPUT_IME_SHOWWINDOW"/> + <int value="1112" label="INPUT_IME_HIDEWINDOW"/> </enum> <enum name="ExtensionInstallCause" type="int"> @@ -69431,6 +69441,8 @@ <int value="1" label="Precise GC"/> <int value="2" label="Conservative GC"/> <int value="3" label="Forced GC for testing"/> + <int value="4" label="Memory pressure GC"/> + <int value="5" label="Page navigation GC"/> </enum> <enum name="GDataAuthResult" type="int"> @@ -72770,6 +72782,11 @@ <int value="1" label="Known user"/> </enum> +<enum name="LoginPasswordChangeFlow" type="int"> + <int value="0" label="Password change"/> + <int value="1" label="Cryptohome failure"/> +</enum> + <enum name="LoginPolicyFilesState" type="int"> <summary>Policy/owner key file state.</summary> <int value="0" label="HEALTHY_R11">Healthy, pre-R11</int> @@ -84283,6 +84300,16 @@ <affected-histogram name="WebRTC.Stun.BatchSuccessPercent.UnknownNAT"/> </histogram_suffixes> +<histogram_suffixes name="BlinkGCReason"> + <suffix name="IdleGC" label="Idle GC"/> + <suffix name="PreciseGC" label="Precise GC"/> + <suffix name="ConservativeGC" label="Conservative GC"/> + <suffix name="ForcedGC" label="Forced GC for testing"/> + <suffix name="MemoryPressureGC" label="Memory pressure GC"/> + <suffix name="PageNavigationGC" label="Page navigation GC"/> + <affected-histogram name="BlinkGC.CollectionRate"/> +</histogram_suffixes> + <histogram_suffixes name="CacheInstance" separator="." ordering="prefix"> <suffix name="App" label="Collected from the HTML5 Application Cache instance."/>
diff --git a/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt b/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt index fffe2ea..f7377a7 100644 --- a/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt +++ b/tools/valgrind/gtest_exclude/browser_tests.gtest-drmemory.txt
@@ -125,3 +125,40 @@ # https://crbug.com/1310994 MetricsServiceBrowserTest.CrashRenderers + +# https://crbug.com/592900 +AppViewTest.TestAppViewWithUndefinedDataShouldSucceed +BasicExtensionSettingsWebUITest.testNonEmptyExtensionList +BookmarkBubbleSignInDelegateTest.OnSignInLinkClickedReusesBlank +BrowserOptionsOverlayWebUITest.testNavigationInBackground +CrashRecoveryBrowserTest.DoubleReloadWithError +CrashRecoveryBrowserTest.ReloadCacheRevalidate +CrExtensionsBrowserTest.ExtensionItemDeveloperStateTest +CrExtensionsBrowserTest.ExtensionItemList +CrExtensionsBrowserTest.ExtensionItemWarningsTest +CrExtensionsBrowserTestWithInstalledExtension.ExtensionServiceProfileSettingsTest +CrExtensionsBrowserTestWithInstalledExtension.ExtensionServiceToggleIncognitoTest +CrExtensionsBrowserTestWithInstalledExtension.ExtensionServiceUninstallTest +CrSettingsRtlTest.DrawerPanelFlips +DownloadTestWithShelf.IncognitoDownload +DurableStorageBrowserTest.Incognito +HostedAppTest.ShouldShowLocationBarForHTTPBookmarkApp +HostedAppTest.ShouldShowLocationBarForHTTPSBookmarkApp +ImageWriterPrivateApiTest.TestWriteFromFile +InlineInstallPrivateApiTestApp.BackgroundInstall +InlineInstallPrivateApiTestApp.SuccessfulInstall +InstallGoodExtensionSettingsWebUITest.showOptions +MaterialHistoryBrowserTest.HistoryItemTest +MimeHandlerViewTest.Abort +MimeHandlerViewTest.EmbeddedDataUrlObject +MultilanguageOptionsWebUIBrowserTest.NotAcceptLanguage +PasswordsPrivateApiTest.RequestPlaintextPassword +PDFExtensionTest.BasicPlugin +PDFExtensionTest.ParamsParser +PDFExtensionTest.TabTitleWithEmbeddedPdf +PDFExtensionTest.TabTitleWithTitle +PushMessagingBrowserTest.SubscribeWithoutKeySuccessNotificationsGranted +SubframeTaskBrowserTest.TaskManagerShowsSubframeTasks +SyncSetupWebUITestAsync.RestoreSyncDataTypes +WebUIWebViewBrowserTest.ExecuteScriptCode +ZoomControllerBrowserTest.NavigationResetsManualMode
diff --git a/ui/accessibility/platform/ax_platform_node.cc b/ui/accessibility/platform/ax_platform_node.cc index 8f889458..adfcc1e 100644 --- a/ui/accessibility/platform/ax_platform_node.cc +++ b/ui/accessibility/platform/ax_platform_node.cc
@@ -4,12 +4,23 @@ #include "ui/accessibility/platform/ax_platform_node.h" +#include "base/containers/hash_tables.h" +#include "base/lazy_instance.h" #include "build/build_config.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" namespace ui { +namespace { + +using UniqueIdMap = base::hash_map<int32_t, AXPlatformNode*>; +// Map from each AXPlatformNode's unique id to its instance. +base::LazyInstance<UniqueIdMap> g_unique_id_map = + LAZY_INSTANCE_INITIALIZER; + +} + #if !defined(PLATFORM_HAS_AX_PLATFORM_NODE_IMPL) // static AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { @@ -28,10 +39,39 @@ } #endif -AXPlatformNode::AXPlatformNode() { +// static +int32_t AXPlatformNode::GetNextUniqueId() { + static int32_t next_unique_id = 1; + int32_t unique_id = next_unique_id; + if (next_unique_id == INT32_MAX) + next_unique_id = 1; + else + next_unique_id++; + + return unique_id; +} + +AXPlatformNode::AXPlatformNode() : unique_id_(GetNextUniqueId()) { + g_unique_id_map.Get()[unique_id_] = this; } AXPlatformNode::~AXPlatformNode() { + if (unique_id_) + g_unique_id_map.Get().erase(unique_id_); +} + +void AXPlatformNode::Destroy() { + g_unique_id_map.Get().erase(unique_id_); + unique_id_ = 0; +} + +AXPlatformNode* AXPlatformNode::GetFromUniqueId(int32_t unique_id) { + UniqueIdMap* unique_ids = g_unique_id_map.Pointer(); + auto iter = unique_ids->find(unique_id); + if (iter != unique_ids->end()) + return iter->second; + + return nullptr; } } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node.h b/ui/accessibility/platform/ax_platform_node.h index 1d0ed51..c9df259 100644 --- a/ui/accessibility/platform/ax_platform_node.h +++ b/ui/accessibility/platform/ax_platform_node.h
@@ -46,9 +46,17 @@ static AXPlatformNode* FromNativeViewAccessible( gfx::NativeViewAccessible accessible); + // Each platform accessibility object has a unique id that's guaranteed + // to be a positive number. (It's stored in an int32_t as opposed to + // uint32_t because some platforms want to negate it, so we want to ensure + // the range is below the signed int max.) This can be used when the + // id has to be unique across multiple frames, since node ids are + // only unique within one tree. + static int32_t GetNextUniqueId(); + // Call Destroy rather than deleting this, because the subclass may // use reference counting. - virtual void Destroy() = 0; + virtual void Destroy(); // Get the platform-specific accessible object type for this instance. // On some platforms this is just a type cast, on others it may be a @@ -65,6 +73,10 @@ protected: AXPlatformNode(); virtual ~AXPlatformNode(); + + AXPlatformNode* GetFromUniqueId(int32_t unique_id); + + int32_t unique_id_; }; } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 2c1bf90..a9d4c1f 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -44,6 +44,7 @@ // AXPlatformNode overrides. void AXPlatformNodeBase::Destroy() { + AXPlatformNode::Destroy(); delegate_ = nullptr; delete this; }
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 168f2fe..95632d8 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -78,34 +78,12 @@ namespace { -typedef base::hash_map<LONG, AXPlatformNodeWin*> UniqueIdWinMap; -// Map from each AXPlatformNodeWin's unique id to its instance. -base::LazyInstance<UniqueIdWinMap> g_unique_id_win_map = - LAZY_INSTANCE_INITIALIZER; - typedef base::hash_set<AXPlatformNodeWin*> AXPlatformNodeWinSet; // Set of all AXPlatformNodeWin objects that were the target of an // alert event. base::LazyInstance<AXPlatformNodeWinSet> g_alert_targets = LAZY_INSTANCE_INITIALIZER; -LONG GetNextNegativeUniqueIdForWinAccessibility(AXPlatformNodeWin* obj) { - static LONG next_unique_id = -1; - LONG unique_id = next_unique_id; - if (next_unique_id == LONG_MIN) - next_unique_id = -1; - else - next_unique_id--; - - g_unique_id_win_map.Get().insert(std::make_pair(unique_id, obj)); - - return unique_id; -} - -void UnregisterNegativeUniqueId(LONG unique_id) { - g_unique_id_win_map.Get().erase(unique_id); -} - base::LazyInstance<base::ObserverList<IAccessible2UsageObserver>> g_iaccessible2_usage_observer_list = LAZY_INSTANCE_INITIALIZER; @@ -156,8 +134,7 @@ // AXPlatformNodeWin // -AXPlatformNodeWin::AXPlatformNodeWin() - : unique_id_win_(GetNextNegativeUniqueIdForWinAccessibility(this)) { +AXPlatformNodeWin::AXPlatformNodeWin() { } AXPlatformNodeWin::~AXPlatformNodeWin() { @@ -170,7 +147,6 @@ void AXPlatformNodeWin::Destroy() { delegate_ = nullptr; - UnregisterNegativeUniqueId(unique_id_win_); RemoveAlertTarget(); Release(); } @@ -194,7 +170,7 @@ if (native_event < EVENT_MIN) return; - ::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, unique_id_win_); + ::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, -unique_id_); // Keep track of objects that are a target of an alert event. if (event_type == ui::AX_EVENT_ALERT) @@ -366,10 +342,10 @@ return E_FAIL; // Negative child ids can be used to map to any descendant. - UniqueIdWinMap* unique_ids = g_unique_id_win_map.Pointer(); - auto iter = unique_ids->find(child_id); - if (iter != unique_ids->end()) { - *disp_child = iter->second; + AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>( + GetFromUniqueId(-child_id)); + if (child) { + *disp_child = child; (*disp_child)->AddRef(); return S_OK; } @@ -531,7 +507,7 @@ STDMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* unique_id) { COM_OBJECT_VALIDATE_1_ARG(unique_id); - *unique_id = unique_id_win_; + *unique_id = -unique_id_; return S_OK; }
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index 3979272..eb747ed4d 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -297,16 +297,6 @@ IA2TextBoundaryType ia2_boundary, LONG start_offset, ui::TextBoundaryDirection direction); - - // A windows-specific unique ID for this object. It's returned in - // IAccessible2::get_uniqueID, but more importantly it's used for - // firing events. On Windows, we fire events on the nearest parent HWND - // and pass the unique ID as the child id parameter. When the client - // wants to retrieve the object the event was fired on, it calls - // get_accChild and passes the child ID. We use negative IDs for the unique - // ID so we can distinguish a request for an arbitrary child from a request - // for an immediate child of an object by its 0-based index. - LONG unique_id_win_; }; } // namespace ui
diff --git a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java index 184172a..e7587e9d 100644 --- a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java +++ b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
@@ -19,6 +19,8 @@ import android.widget.PopupMenu; import android.widget.TextView; +import org.chromium.base.VisibleForTesting; + /** * ClickableSpan isn't accessible by default, so we create a subclass * of TextView that tries to handle the case where a user clicks on a view @@ -118,7 +120,11 @@ return clickableSpans.length > 0; } - private ClickableSpan[] getClickableSpans() { + /** + * Returns the ClickableSpans in this TextView's text. + */ + @VisibleForTesting + public ClickableSpan[] getClickableSpans() { CharSequence text = getText(); if (!(text instanceof SpannableString)) return null;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 45f806f..f83f14f 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -124,6 +124,24 @@ flex-direction: column; } +/* Details pane */ +.details-container { + background-color: rgb(250, 250, 250); + flex: none; + max-width: 30%; + min-width: 100px; + overflow: hidden; + position: relative; +} + +#list-details-splitter:not([activated]) { + display: none; +} + +.details-container:not([activated]) { + display: none; +} + /* Directory tree at the left. */ .dialog-navigation-list { -webkit-border-end: 1px solid rgba(0, 0, 0, 0.15); @@ -449,6 +467,24 @@ display: none; } +#details-button { + /** + * TODO(ryoh): This should be removed after we finally implement details + * panel. + */ + display: none; +} + +#details-button > .icon { + background-image: -webkit-image-set( + url(../images/files/ui/details_white.png) 1x, + url(../images/files/ui/2x/details_white.png) 2x); +} + +body.check-select #details-button { + display: none; +} + #gear-button > .icon { background-image: -webkit-image-set( url(../images/files/ui/menu_white.png) 1x,
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/2x/details_white.png b/ui/file_manager/file_manager/foreground/images/files/ui/2x/details_white.png new file mode 100644 index 0000000..e5b87280 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/2x/details_white.png Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/details_white.png b/ui/file_manager/file_manager/foreground/images/files/ui/details_white.png new file mode 100644 index 0000000..7618185 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/details_white.png Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/js/app_state_controller.js b/ui/file_manager/file_manager/foreground/js/app_state_controller.js index bfaa930..7df9810 100644 --- a/ui/file_manager/file_manager/foreground/js/app_state_controller.js +++ b/ui/file_manager/file_manager/foreground/js/app_state_controller.js
@@ -79,6 +79,7 @@ // Restore preferences. this.ui_.setCurrentListType( this.viewOptions_.listType || ListContainer.ListType.DETAIL); + this.ui_.setDetailsVisibility(!!this.viewOptions_.detailsVisibility); this.directoryModel_.getFileList().sort( this.viewOptions_.sortField || 'modificationTime', this.viewOptions_.sortDirection || 'desc'); @@ -97,7 +98,12 @@ sortField: sortStatus.field, sortDirection: sortStatus.direction, columnConfig: {}, - listType: this.ui_.listContainer.currentListType + listType: this.ui_.listContainer.currentListType, + /** + * TODO(ryoh): Simplify this line after we finally implement details panel. + */ + detailsVisibility: this.ui_.detailsContainer && + this.ui_.detailsContainer.visible || false }; var cm = this.ui_.listContainer.table.columnModel; prefs.columnConfig = cm.exportColumnConfig();
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp index 5031555f..9b9a5da 100644 --- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp +++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -124,6 +124,7 @@ './ui/actions_submenu.js', './ui/banners.js', './ui/default_task_dialog.js', + './ui/details_container.js', './ui/dialog_footer.js', './ui/directory_tree.js', './ui/drag_selector.js',
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js index e826ffd..c7c905ac 100644 --- a/ui/file_manager/file_manager/foreground/js/main_scripts.js +++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -140,6 +140,7 @@ //<include src="ui/actions_submenu.js"> //<include src="ui/banners.js" > //<include src="ui/default_task_dialog.js"> +//<include src="ui/details_container.js"> //<include src="ui/dialog_footer.js"> //<include src="ui/directory_tree.js"> //<include src="ui/drag_selector.js">
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js index 0a1419e..12c83ca 100644 --- a/ui/file_manager/file_manager/foreground/js/main_window_component.js +++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -124,6 +124,8 @@ 'pathclick', this.onBreadcrumbClick_.bind(this)); ui.toggleViewButton.addEventListener( 'click', this.onToggleViewButtonClick_.bind(this)); + ui.detailsButton.addEventListener( + 'click', this.onDetailsButtonClick_.bind(this)); directoryModel.addEventListener( 'directory-changed', this.onDirectoryChanged_.bind(this)); volumeManager.addEventListener( @@ -132,6 +134,8 @@ this.onDriveConnectionChanged_(); document.addEventListener('keydown', this.onKeyDown_.bind(this)); document.addEventListener('keyup', this.onKeyUp_.bind(this)); + selectionHandler.addEventListener('change', + this.onFileSelectionChanged_.bind(this)); } /** @@ -159,6 +163,17 @@ }; /** + * Handles file selection event. + * + * @private + */ +MainWindowComponent.prototype.onFileSelectionChanged_ = function(event) { + if (this.ui_.detailsContainer) { + this.ui_.detailsContainer.onFileSelectionChanged(event); + } +}; + +/** * Handles mouse click or tap. * * @param {Event} event The click event. @@ -236,6 +251,18 @@ }; /** + * Handles click event on the toggle-view button. + * @param {Event} event Click event. + * @private + */ +MainWindowComponent.prototype.onDetailsButtonClick_ = function(event) { + var visible = this.ui_.detailsContainer.visible; + this.ui_.setDetailsVisibility(!visible); + this.appStateController_.saveViewOptions(); + this.ui_.listContainer.focus(); +}; + +/** * KeyDown event handler for the document. * @param {Event} event Key event. * @private
diff --git a/ui/file_manager/file_manager/foreground/js/ui/details_container.js b/ui/file_manager/file_manager/foreground/js/ui/details_container.js new file mode 100644 index 0000000..1d54bad --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/ui/details_container.js
@@ -0,0 +1,63 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @param {!HTMLElement} element + * @param {!Element} splitter + * @param {!Element} button + * @param {!FilesToggleRipple} toggleRipple + * @constructor + * @struct + */ +function DetailsContainer(element, splitter, button, toggleRipple) { + /** + * Container element. + * @private {!HTMLElement} + * @const + */ + this.element_ = element; + /** + * Splitter element between the file list and the details panel. + * @private {!Element} + * @const + */ + this.splitter_ = splitter; + /** + * "View details" button element. + * @private {!Element} + * @const + */ + this.button_ = button; + /** + * Ripple element of "View details" button. + * @private {!Element} + * @const + */ + this.toggleRipple_ = toggleRipple; + /** + * @type {boolean} + */ + this.visible = false; + this.setVisibility(false); +} + +DetailsContainer.prototype.onFileSelectionChanged = function(event) { + var selection = event.target.selection; +}; + +/** + * Sets the details panel visibility + * @param {boolean} visibility True if the details panel is visible. + */ +DetailsContainer.prototype.setVisibility = function(visibility) { + if (visibility) { + this.splitter_.setAttribute('activated', ''); + this.element_.setAttribute('activated', ''); + } else { + this.splitter_.removeAttribute('activated'); + this.element_.removeAttribute('activated'); + } + this.visible = visibility; + this.toggleRipple_.activated = visibility; +};
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index 8f4db8a..4c04632 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -163,6 +163,23 @@ '#sort-button', cr.ui.MenuButton); /** + * The button to open the details panel. + * @type {!Element} + * @const + */ + this.detailsButton = queryRequiredElement( + '#details-button', this.element); + + /** + * Ripple effect of details button. + * @private {!FilesToggleRipple} + * @const + */ + this.detailsButtonToggleRipple_ = + /** @type {!FilesToggleRipple} */ (queryRequiredElement( + 'files-toggle-ripple', this.detailsButton)); + + /** * Ripple effect of sort button. * @private {!FilesToggleRipple} * @const @@ -215,6 +232,12 @@ this.listContainer = null; /** + * Details container. + * @type {DetailsContainer} + */ + this.detailsContainer = null; + + /** * @type {!HTMLElement} */ this.formatPanelError = @@ -327,6 +350,22 @@ this.decorateSplitter_( queryRequiredElement('#navigation-list-splitter', this.element)); + // Details container. + chrome.commandLinePrivate.hasSwitch('enable-files-details-panel', + function(enabled) { + if (enabled) { + this.detailsButton.style.display = 'block'; + var listDetailsSplitter = + queryRequiredElement('#list-details-splitter', this.element); + this.decorateSplitter_(listDetailsSplitter); + this.detailsContainer = new DetailsContainer( + queryRequiredElement('#details-container', this.element), + listDetailsSplitter, + this.detailsButton, + this.detailsButtonToggleRipple_); + } + }.bind(this)); + // Location line. this.locationLine = locationLine; @@ -447,6 +486,17 @@ }; /** + * Sets the details panel visibility + * @param {boolean} visibility True if the details panel is visible. + */ +FileManagerUI.prototype.setDetailsVisibility = function(visibility) { + if (this.detailsContainer) { + this.detailsContainer.setVisibility(visibility); + this.relayout(); + } +}; + +/** * Overrides default handling for clicks on hyperlinks. * In a packaged apps links with targer='_blank' open in a new tab by * default, other links do not open at all.
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index ca17199..3639d5a 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -309,7 +309,13 @@ <files-toggle-ripple></files-toggle-ripple> <div class="icon"></div> </button> - <button id="gear-button" class="icon-button" tabindex="18" + <button id="details-button" class="icon-button" tabindex="18" + i18n-values="aria-label:DETAIL_BUTTON_TOOLTIP" + has-tooltip> + <files-toggle-ripple></files-toggle-ripple> + <div class="icon"></div> + </button> + <button id="gear-button" class="icon-button" tabindex="19" menu="#gear-menu" i18n-values="aria-label:GEAR_BUTTON_TOOLTIP" aria-activedescendant="gear-menu" @@ -342,7 +348,7 @@ <div class="dialog-container"> <div class="dialog-navigation-list"> <div class="dialog-navigation-list-contents"> - <tree id="directory-tree" tabindex="19"></tree> + <tree id="directory-tree" tabindex="20"></tree> </div> <div class="dialog-navigation-list-footer"> <div id="progress-center" hidden> @@ -403,6 +409,9 @@ </div> </div> </div> + <div class="splitter" id="list-details-splitter"></div> + <div id="details-container" class="details-container"> + </div> </div> <div class="dialog-footer progressable" tabindex="-1" visibleif="saveas-file open-file open-multi-file folder upload-folder">
diff --git a/ui/file_manager/gallery/js/slide_mode.js b/ui/file_manager/gallery/js/slide_mode.js index dcad955..1968409 100644 --- a/ui/file_manager/gallery/js/slide_mode.js +++ b/ui/file_manager/gallery/js/slide_mode.js
@@ -1870,6 +1870,12 @@ */ this.lastZoom_ = 1.0; + /** + * @type {number} + * @private + */ + this.mouseWheelZoomOperationId_ = 0; + targetElement.addEventListener('touchstart', this.onTouchStart_.bind(this)); var onTouchEventBound = this.onTouchEvent_.bind(this); targetElement.ownerDocument.addEventListener('touchmove', onTouchEventBound); @@ -2068,20 +2074,28 @@ */ TouchHandler.prototype.onMouseWheel_ = function(event) { var event = assertInstanceof(event, MouseEvent); - var viewport = this.slideMode_.getViewport(); if (!this.enabled_) return; this.stopOperation(); - this.lastZoom_ = viewport.getZoom(); - var zoom = this.lastZoom_; + + var viewport = this.slideMode_.getViewport(); + var zoom = viewport.getZoom(); if (event.wheelDeltaY > 0) { zoom *= TouchHandler.WHEEL_ZOOM_FACTOR; } else { zoom /= TouchHandler.WHEEL_ZOOM_FACTOR; } - viewport.setZoom(zoom); - this.slideMode_.imageView_.applyViewportChange(); + + // Request animation frame not to set zoom more than once in a frame. This is + // a fix for https://crbug.com/591033 + requestAnimationFrame(function(operationId) { + if (this.mouseWheelZoomOperationId_ !== operationId) + return; + + viewport.setZoom(zoom); + this.slideMode_.applyViewportChange(); + }.bind(this, ++this.mouseWheelZoomOperationId_)); }; /**
diff --git a/ui/gfx/geometry/insets.cc b/ui/gfx/geometry/insets.cc index 46fb84c..08ee8f4 100644 --- a/ui/gfx/geometry/insets.cc +++ b/ui/gfx/geometry/insets.cc
@@ -10,6 +10,11 @@ Insets::Insets() : Insets(0, 0, 0, 0) {} +Insets::Insets(int all) : Insets(all, all, all, all) {} + +Insets::Insets(int vertical, int horizontal) + : Insets(vertical, horizontal, vertical, horizontal) {} + Insets::Insets(int top, int left, int bottom, int right) : top_(top), left_(left), bottom_(bottom), right_(right) {}
diff --git a/ui/gfx/geometry/insets.h b/ui/gfx/geometry/insets.h index 0466d94..2fc0d62 100644 --- a/ui/gfx/geometry/insets.h +++ b/ui/gfx/geometry/insets.h
@@ -12,10 +12,11 @@ namespace gfx { -// An integer version of gfx::Insets. class GFX_EXPORT Insets { public: Insets(); + explicit Insets(int all); + Insets(int vertical, int horizontal); Insets(int top, int left, int bottom, int right); ~Insets();
diff --git a/ui/gfx/geometry/insets_f.h b/ui/gfx/geometry/insets_f.h index 90592d77..f159a74 100644 --- a/ui/gfx/geometry/insets_f.h +++ b/ui/gfx/geometry/insets_f.h
@@ -11,7 +11,7 @@ namespace gfx { -// A floating versin of gfx::Insets. +// A floating point version of gfx::Insets. class GFX_EXPORT InsetsF { public: InsetsF();
diff --git a/ui/gfx/harfbuzz_font_skia.cc b/ui/gfx/harfbuzz_font_skia.cc index 723b68ae..e2adeaf 100644 --- a/ui/gfx/harfbuzz_font_skia.cc +++ b/ui/gfx/harfbuzz_font_skia.cc
@@ -16,6 +16,7 @@ #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkTypeface.h" #include "ui/gfx/render_text.h" +#include "ui/gfx/skia_util.h" namespace gfx { @@ -65,14 +66,14 @@ paint->getTextWidths(&glyph, sizeof(glyph), &sk_width, &sk_bounds); if (width) - *width = SkScalarToFixed(sk_width); + *width = SkiaScalarToHarfBuzzUnits(sk_width); if (extents) { // Invert y-axis because Skia is y-grows-down but we set up HarfBuzz to be // y-grows-up. - extents->x_bearing = SkScalarToFixed(sk_bounds.fLeft); - extents->y_bearing = SkScalarToFixed(-sk_bounds.fTop); - extents->width = SkScalarToFixed(sk_bounds.width()); - extents->height = SkScalarToFixed(-sk_bounds.height()); + extents->x_bearing = SkiaScalarToHarfBuzzUnits(sk_bounds.fLeft); + extents->y_bearing = SkiaScalarToHarfBuzzUnits(-sk_bounds.fTop); + extents->width = SkiaScalarToHarfBuzzUnits(sk_bounds.width()); + extents->height = SkiaScalarToHarfBuzzUnits(-sk_bounds.height()); } } @@ -132,7 +133,7 @@ SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); SkScalar size = font_data->paint_.getTextSize(); - return SkScalarToFixed( + return SkiaScalarToHarfBuzzUnits( SkScalarMulDiv(SkIntToScalar(kerning_adjustments[0]), size, upm)); } @@ -271,7 +272,7 @@ face_cache->first.Init(skia_face); hb_font_t* harfbuzz_font = hb_font_create(face_cache->first.get()); - const int scale = SkScalarToFixed(text_size); + const int scale = SkiaScalarToHarfBuzzUnits(text_size); hb_font_set_scale(harfbuzz_font, scale, scale); FontData* hb_font_data = new FontData(&face_cache->second); hb_font_data->paint_.setTypeface(skia_face);
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc index a9a05ef..590537e 100644 --- a/ui/gfx/render_text_harfbuzz.cc +++ b/ui/gfx/render_text_harfbuzz.cc
@@ -28,6 +28,7 @@ #include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/harfbuzz_font_skia.h" #include "ui/gfx/range/range_f.h" +#include "ui/gfx/skia_util.h" #include "ui/gfx/text_utils.h" #include "ui/gfx/utf16_indexing.h" @@ -1503,12 +1504,14 @@ DCHECK_LE(infos[i].codepoint, std::numeric_limits<uint16_t>::max()); run->glyphs[i] = static_cast<uint16_t>(infos[i].codepoint); run->glyph_to_char[i] = infos[i].cluster; - const SkScalar x_offset = SkFixedToScalar(hb_positions[i].x_offset); - const SkScalar y_offset = SkFixedToScalar(hb_positions[i].y_offset); + const SkScalar x_offset = + HarfBuzzUnitsToSkiaScalar(hb_positions[i].x_offset); + const SkScalar y_offset = + HarfBuzzUnitsToSkiaScalar(hb_positions[i].y_offset); run->positions[i].set(run->width + x_offset, -y_offset); run->width += (glyph_width_for_test_ > 0) ? glyph_width_for_test_ - : SkFixedToFloat(hb_positions[i].x_advance); + : HarfBuzzUnitsToFloat(hb_positions[i].x_advance); // Round run widths if subpixel positioning is off to match native behavior. if (!run->render_params.subpixel_positioning) run->width = std::floor(run->width + 0.5f);
diff --git a/ui/gfx/skia_util.cc b/ui/gfx/skia_util.cc index c1e6c18..a971c9f 100644 --- a/ui/gfx/skia_util.cc +++ b/ui/gfx/skia_util.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> +#include "base/numerics/safe_conversions.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorPriv.h" @@ -226,4 +227,21 @@ points[3] = PointFToSkPoint(quad.p4()); } +// We treat HarfBuzz ints as 16.16 fixed-point. +static const int kHbUnit1 = 1 << 16; + +int SkiaScalarToHarfBuzzUnits(SkScalar value) { + return base::saturated_cast<int>(value * kHbUnit1); +} + +SkScalar HarfBuzzUnitsToSkiaScalar(int value) { + static const SkScalar kSkToHbRatio = SK_Scalar1 / kHbUnit1; + return kSkToHbRatio * value; +} + +float HarfBuzzUnitsToFloat(int value) { + static const float kFloatToHbRatio = 1.0f / kHbUnit1; + return kFloatToHbRatio * value; +} + } // namespace gfx
diff --git a/ui/gfx/skia_util.h b/ui/gfx/skia_util.h index 25c96d03..1953e635 100644 --- a/ui/gfx/skia_util.h +++ b/ui/gfx/skia_util.h
@@ -88,6 +88,15 @@ int pixel_width, unsigned char* rgba); +// Converts a Skia floating-point value to an int appropriate for hb_position_t. +GFX_EXPORT int SkiaScalarToHarfBuzzUnits(SkScalar value); + +// Converts an hb_position_t to a Skia floating-point value. +GFX_EXPORT SkScalar HarfBuzzUnitsToSkiaScalar(int value); + +// Converts an hb_position_t to a float. +GFX_EXPORT float HarfBuzzUnitsToFloat(int value); + } // namespace gfx #endif // UI_GFX_SKIA_UTIL_H_
diff --git a/ui/shell_dialogs/BUILD.gn b/ui/shell_dialogs/BUILD.gn index 06ca709..ec6b56d 100644 --- a/ui/shell_dialogs/BUILD.gn +++ b/ui/shell_dialogs/BUILD.gn
@@ -63,13 +63,6 @@ include_dirs = [ "$root_gen_dir/ui" ] libs = [ "jnigraphics" ] } - - if (is_android && use_aura) { - sources += [ - "select_file_dialog_auraandroid.cc", - "select_file_dialog_auraandroid.h", - ] - } } test("shell_dialogs_unittests") {
diff --git a/ui/shell_dialogs/select_file_dialog.cc b/ui/shell_dialogs/select_file_dialog.cc index 2bfacec..fd2a7cf6 100644 --- a/ui/shell_dialogs/select_file_dialog.cc +++ b/ui/shell_dialogs/select_file_dialog.cc
@@ -14,16 +14,6 @@ #include "ui/shell_dialogs/select_file_policy.h" #include "ui/shell_dialogs/selected_file_info.h" -#if defined(OS_WIN) -#include "ui/shell_dialogs/select_file_dialog_win.h" -#elif defined(OS_MACOSX) -#include "ui/shell_dialogs/select_file_dialog_mac.h" -#elif defined(OS_ANDROID) -#include "ui/shell_dialogs/select_file_dialog_android.h" -#elif defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) -#include "ui/shell_dialogs/shell_dialog_linux.h" -#endif - namespace { // Optional dialog factory. Leaked. @@ -79,22 +69,7 @@ return dialog; } -#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) - const ui::ShellDialogLinux* shell_dialogs = ui::ShellDialogLinux::instance(); - if (shell_dialogs) - return shell_dialogs->CreateSelectFileDialog(listener, policy); -#endif - -#if defined(OS_WIN) - return CreateDefaultWinSelectFileDialog(listener, policy); -#elif defined(OS_MACOSX) && !defined(USE_AURA) - return CreateMacSelectFileDialog(listener, policy); -#elif defined(OS_ANDROID) - return CreateAndroidSelectFileDialog(listener, policy); -#else - NOTIMPLEMENTED(); - return NULL; -#endif + return CreateSelectFileDialog(listener, policy); } void SelectFileDialog::SelectFile(
diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h index 041fb4a..e89f686 100644 --- a/ui/shell_dialogs/select_file_dialog.h +++ b/ui/shell_dialogs/select_file_dialog.h
@@ -213,6 +213,8 @@ DISALLOW_COPY_AND_ASSIGN(SelectFileDialog); }; +SelectFileDialog* CreateSelectFileDialog(SelectFileDialog::Listener* listener, + SelectFilePolicy* policy); } // namespace ui #endif // UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_H_
diff --git a/ui/shell_dialogs/select_file_dialog_android.cc b/ui/shell_dialogs/select_file_dialog_android.cc index b0c7532..11b9d4c 100644 --- a/ui/shell_dialogs/select_file_dialog_android.cc +++ b/ui/shell_dialogs/select_file_dialog_android.cc
@@ -145,9 +145,8 @@ return false; } -SelectFileDialog* CreateAndroidSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy) { +SelectFileDialog* CreateSelectFileDialog(SelectFileDialog::Listener* listener, + SelectFilePolicy* policy) { return SelectFileDialogImpl::Create(listener, policy); }
diff --git a/ui/shell_dialogs/select_file_dialog_android.h b/ui/shell_dialogs/select_file_dialog_android.h index 0dba18e..5291cd3 100644 --- a/ui/shell_dialogs/select_file_dialog_android.h +++ b/ui/shell_dialogs/select_file_dialog_android.h
@@ -65,10 +65,6 @@ DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); }; -SelectFileDialog* CreateAndroidSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy); - } // namespace ui #endif // UI_SHELL_DIALOGS_ANDROID_SELECT_FILE_DIALOG_ANDROID_H_
diff --git a/ui/shell_dialogs/select_file_dialog_auraandroid.cc b/ui/shell_dialogs/select_file_dialog_auraandroid.cc deleted file mode 100644 index 185f47e..0000000 --- a/ui/shell_dialogs/select_file_dialog_auraandroid.cc +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "select_file_dialog_auraandroid.h" - -#include "base/logging.h" - -namespace ui { - -// static -SelectFileDialogImpl* SelectFileDialogImpl::Create(Listener* listener, - SelectFilePolicy* policy) { - return new SelectFileDialogImpl(listener, policy); -} - -bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow) const { - return listener_; -} - -void SelectFileDialogImpl::ListenerDestroyed() { - listener_ = NULL; -} - -void SelectFileDialogImpl::SelectFileImpl( - SelectFileDialog::Type type, - const base::string16& title, - const base::FilePath& default_path, - const SelectFileDialog::FileTypeInfo* file_types, - int file_type_index, - const std::string& default_extension, - gfx::NativeWindow owning_window, - void* params) { - NOTIMPLEMENTED(); -} - -SelectFileDialogImpl::~SelectFileDialogImpl() { -} - -SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener, - SelectFilePolicy* policy) - : SelectFileDialog(listener, policy) { -} - -bool SelectFileDialogImpl::HasMultipleFileTypeChoicesImpl() { - NOTIMPLEMENTED(); - return false; -} - -SelectFileDialog* CreateAndroidSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy) { - return SelectFileDialogImpl::Create(listener, policy); -} - -} // namespace ui
diff --git a/ui/shell_dialogs/select_file_dialog_auraandroid.h b/ui/shell_dialogs/select_file_dialog_auraandroid.h deleted file mode 100644 index 5b7a163..0000000 --- a/ui/shell_dialogs/select_file_dialog_auraandroid.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_SHELL_DIALOGS_ANDROID_SELECT_FILE_DIALOG_ANDROID_H_ -#define UI_SHELL_DIALOGS_ANDROID_SELECT_FILE_DIALOG_ANDROID_H_ - -#include "base/macros.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -namespace ui { - -class SelectFileDialogImpl : public SelectFileDialog { - public: - static SelectFileDialogImpl* Create(Listener* listener, - SelectFilePolicy* policy); - - // From SelectFileDialog - bool IsRunning(gfx::NativeWindow) const override; - void ListenerDestroyed() override; - void SelectFileImpl(SelectFileDialog::Type type, - const base::string16& title, - const base::FilePath& default_path, - const SelectFileDialog::FileTypeInfo* file_types, - int file_type_index, - const std::string& default_extension, - gfx::NativeWindow owning_window, - void* params) override; - - protected: - ~SelectFileDialogImpl() override; - - private: - SelectFileDialogImpl(Listener* listener, SelectFilePolicy* policy); - - bool HasMultipleFileTypeChoicesImpl() override; - - DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); -}; - -SelectFileDialog* CreateAndroidSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy); - -} // namespace ui - -#endif // UI_SHELL_DIALOGS_ANDROID_SELECT_FILE_DIALOG_ANDROID_H_ -
diff --git a/ui/shell_dialogs/select_file_dialog_mac.h b/ui/shell_dialogs/select_file_dialog_mac.h index 8915a08..2527f96 100644 --- a/ui/shell_dialogs/select_file_dialog_mac.h +++ b/ui/shell_dialogs/select_file_dialog_mac.h
@@ -5,14 +5,91 @@ #ifndef UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_MAC_H_ #define UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_MAC_H_ +#import <Cocoa/Cocoa.h> + +#include <map> +#include <set> + +#import "base/mac/scoped_nsobject.h" +#include "base/macros.h" #include "ui/gfx/native_widget_types.h" #include "ui/shell_dialogs/select_file_dialog.h" +@class ExtensionDropdownHandler; +@class SelectFileDialogBridge; + namespace ui { -SelectFileDialog* CreateMacSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy); +// Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a +// file or folder. +class SelectFileDialogImpl : public ui::SelectFileDialog { + public: + SelectFileDialogImpl(Listener* listener, ui::SelectFilePolicy* policy); + + // BaseShellDialog implementation. + bool IsRunning(gfx::NativeWindow parent_window) const override; + void ListenerDestroyed() override; + + // Callback from ObjC bridge. + void FileWasSelected(NSSavePanel* dialog, + NSWindow* parent_window, + bool was_cancelled, + bool is_multi, + const std::vector<base::FilePath>& files, + int index); + + protected: + // SelectFileDialog implementation. + // |params| is user data we pass back via the Listener interface. + void SelectFileImpl(Type type, + const base::string16& title, + const base::FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const base::FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params) override; + + private: + // Struct to store data associated with a file dialog while it is showing. + struct DialogData { + DialogData(void* params_, + base::scoped_nsobject<ExtensionDropdownHandler> handler); + + // |params| user data associated with this file dialog. + void* params; + + // Extension dropdown handler corresponding to this file dialog. + base::scoped_nsobject<ExtensionDropdownHandler> extension_dropdown_handler; + + ~DialogData(); + }; + + ~SelectFileDialogImpl() override; + + // Sets the accessory view for the |dialog| and returns the associated + // ExtensionDropdownHandler. + static base::scoped_nsobject<ExtensionDropdownHandler> SetAccessoryView( + NSSavePanel* dialog, + const FileTypeInfo* file_types, + int file_type_index, + const base::FilePath::StringType& default_extension); + + bool HasMultipleFileTypeChoicesImpl() override; + + // The bridge for results from Cocoa to return to us. + base::scoped_nsobject<SelectFileDialogBridge> bridge_; + + // The set of all parent windows for which we are currently running dialogs. + std::set<NSWindow*> parents_; + + // A map from file dialogs to the DialogData associated with them. + std::map<NSSavePanel*, DialogData> dialog_data_map_; + + bool hasMultipleFileTypeChoices_; + + DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); +}; } // namespace ui
diff --git a/ui/shell_dialogs/select_file_dialog_mac.mm b/ui/shell_dialogs/select_file_dialog_mac.mm index e53c389..2a4167c 100644 --- a/ui/shell_dialogs/select_file_dialog_mac.mm +++ b/ui/shell_dialogs/select_file_dialog_mac.mm
@@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/shell_dialogs/select_file_dialog.h" +#include "ui/shell_dialogs/select_file_dialog_mac.h" -#import <Cocoa/Cocoa.h> #include <CoreServices/CoreServices.h> #include <stddef.h> -#include <map> -#include <set> #include <vector> #include "base/files/file_util.h" @@ -18,8 +15,6 @@ #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #include "base/mac/scoped_cftyperef.h" -#import "base/mac/scoped_nsobject.h" -#include "base/macros.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" @@ -55,16 +50,14 @@ } // namespace -class SelectFileDialogImpl; - // A bridge class to act as the modal delegate to the save/open sheet and send // the results to the C++ class. @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> { @private - SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us + ui::SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us } -- (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s; +- (id)initWithSelectFileDialogImpl:(ui::SelectFileDialogImpl*)s; - (void)endedPanel:(NSSavePanel*)panel didCancel:(bool)did_cancel type:(ui::SelectFileDialog::Type)type @@ -92,76 +85,7 @@ - (void)popupAction:(id)sender; @end -// Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a -// file or folder. -class SelectFileDialogImpl : public ui::SelectFileDialog { - public: - explicit SelectFileDialogImpl(Listener* listener, - ui::SelectFilePolicy* policy); - - // BaseShellDialog implementation. - bool IsRunning(gfx::NativeWindow parent_window) const override; - void ListenerDestroyed() override; - - // Callback from ObjC bridge. - void FileWasSelected(NSSavePanel* dialog, - NSWindow* parent_window, - bool was_cancelled, - bool is_multi, - const std::vector<base::FilePath>& files, - int index); - - protected: - // SelectFileDialog implementation. - // |params| is user data we pass back via the Listener interface. - void SelectFileImpl(Type type, - const base::string16& title, - const base::FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const base::FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params) override; - - private: - // Struct to store data associated with a file dialog while it is showing. - struct DialogData { - DialogData(void* params_, - base::scoped_nsobject<ExtensionDropdownHandler> handler) - : params(params_), extension_dropdown_handler(handler) {} - - // |params| user data associated with this file dialog. - void* params; - - // Extension dropdown handler corresponding to this file dialog. - base::scoped_nsobject<ExtensionDropdownHandler> extension_dropdown_handler; - }; - - ~SelectFileDialogImpl() override; - - // Sets the accessory view for the |dialog| and returns the associated - // ExtensionDropdownHandler. - static base::scoped_nsobject<ExtensionDropdownHandler> SetAccessoryView( - NSSavePanel* dialog, - const FileTypeInfo* file_types, - int file_type_index, - const base::FilePath::StringType& default_extension); - - bool HasMultipleFileTypeChoicesImpl() override; - - // The bridge for results from Cocoa to return to us. - base::scoped_nsobject<SelectFileDialogBridge> bridge_; - - // The set of all parent windows for which we are currently running dialogs. - std::set<NSWindow*> parents_; - - // A map from file dialogs to the DialogData associated with them. - std::map<NSSavePanel*, DialogData> dialog_data_map_; - - bool hasMultipleFileTypeChoices_; - - DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); -}; +namespace ui { SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener, ui::SelectFilePolicy* policy) @@ -319,6 +243,13 @@ }]; } +SelectFileDialogImpl::DialogData::DialogData( + void* params_, + base::scoped_nsobject<ExtensionDropdownHandler> handler) + : params(params_), extension_dropdown_handler(handler) {} + +SelectFileDialogImpl::DialogData::~DialogData() {} + SelectFileDialogImpl::~SelectFileDialogImpl() { // Walk through the open dialogs and close them all. Use a temporary vector // to hold the pointers, since we can't delete from the map as we're iterating @@ -429,9 +360,16 @@ return hasMultipleFileTypeChoices_; } +SelectFileDialog* CreateSelectFileDialog(SelectFileDialog::Listener* listener, + SelectFilePolicy* policy) { + return new SelectFileDialogImpl(listener, policy); +} + +} // namespace ui + @implementation SelectFileDialogBridge -- (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s { +- (id)initWithSelectFileDialogImpl:(ui::SelectFileDialogImpl*)s { if ((self = [super init])) { selectFileDialogImpl_ = s; } @@ -509,13 +447,3 @@ } @end - -namespace ui { - -SelectFileDialog* CreateMacSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy) { - return new SelectFileDialogImpl(listener, policy); -} - -} // namespace ui
diff --git a/ui/shell_dialogs/select_file_dialog_win.cc b/ui/shell_dialogs/select_file_dialog_win.cc index dafe050..d455f59c 100644 --- a/ui/shell_dialogs/select_file_dialog_win.cc +++ b/ui/shell_dialogs/select_file_dialog_win.cc
@@ -706,9 +706,8 @@ listener, policy, get_open_file_name_impl, get_save_file_name_impl); } -SelectFileDialog* CreateDefaultWinSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy) { +SelectFileDialog* CreateSelectFileDialog(SelectFileDialog::Listener* listener, + SelectFilePolicy* policy) { return CreateWinSelectFileDialog(listener, policy, base::Bind(&CallBuiltinGetOpenFileName),
diff --git a/ui/shell_dialogs/select_file_dialog_win.h b/ui/shell_dialogs/select_file_dialog_win.h index 646bdb1..e066c65f 100644 --- a/ui/shell_dialogs/select_file_dialog_win.h +++ b/ui/shell_dialogs/select_file_dialog_win.h
@@ -28,10 +28,6 @@ const base::Callback<bool(OPENFILENAME* ofn)>& get_open_file_name_impl, const base::Callback<bool(OPENFILENAME* ofn)>& get_save_file_name_impl); -SelectFileDialog* CreateDefaultWinSelectFileDialog( - SelectFileDialog::Listener* listener, - SelectFilePolicy* policy); - } // namespace ui #endif // UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_WIN_H_
diff --git a/ui/shell_dialogs/shell_dialog_linux.cc b/ui/shell_dialogs/shell_dialog_linux.cc index 62bee5b..685369c 100644 --- a/ui/shell_dialogs/shell_dialog_linux.cc +++ b/ui/shell_dialogs/shell_dialog_linux.cc
@@ -20,4 +20,15 @@ return g_shell_dialog_linux; } +SelectFileDialog* CreateSelectFileDialog(SelectFileDialog::Listener* listener, + SelectFilePolicy* policy) { +#if defined(USE_AURA) && !defined(OS_CHROMEOS) + const ui::ShellDialogLinux* shell_dialogs = ui::ShellDialogLinux::instance(); + if (shell_dialogs) + return shell_dialogs->CreateSelectFileDialog(listener, policy); +#endif + NOTIMPLEMENTED(); + return nullptr; +} + } // namespace ui
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc index bd219a0..77e28178 100644 --- a/ui/views/animation/ink_drop_host_view.cc +++ b/ui/views/animation/ink_drop_host_view.cc
@@ -11,12 +11,12 @@ namespace views { // Default sizes for ink drop effects. -const int kInkDropLargeSize = 32; +const int kInkDropSize = 24; const int kInkDropLargeCornerRadius = 4; -const int kInkDropSmallSize = 24; const int kInkDropSmallCornerRadius = 2; -InkDropHostView::InkDropHostView() {} +InkDropHostView::InkDropHostView() + : ink_drop_size_(kInkDropSize, kInkDropSize) {} InkDropHostView::~InkDropHostView() {} @@ -33,18 +33,19 @@ } scoped_ptr<InkDropAnimation> InkDropHostView::CreateInkDropAnimation() const { + gfx::Size large_drop(ink_drop_size_.width() * 4 / 3, + ink_drop_size_.height() * 4 / 3); + scoped_ptr<InkDropAnimation> animation(new SquareInkDropAnimation( - gfx::Size(kInkDropLargeSize, kInkDropLargeSize), - kInkDropLargeCornerRadius, - gfx::Size(kInkDropSmallSize, kInkDropSmallSize), + large_drop, kInkDropLargeCornerRadius, ink_drop_size_, kInkDropSmallCornerRadius, GetInkDropCenter(), GetInkDropBaseColor())); return animation; } scoped_ptr<InkDropHover> InkDropHostView::CreateInkDropHover() const { - scoped_ptr<InkDropHover> hover(new InkDropHover( - gfx::Size(kInkDropSmallSize, kInkDropSmallSize), - kInkDropSmallCornerRadius, GetInkDropCenter(), GetInkDropBaseColor())); + scoped_ptr<InkDropHover> hover( + new InkDropHover(ink_drop_size_, kInkDropSmallCornerRadius, + GetInkDropCenter(), GetInkDropBaseColor())); return hover; }
diff --git a/ui/views/animation/ink_drop_host_view.h b/ui/views/animation/ink_drop_host_view.h index 87832b7..9467d1e 100644 --- a/ui/views/animation/ink_drop_host_view.h +++ b/ui/views/animation/ink_drop_host_view.h
@@ -7,6 +7,7 @@ #include "base/memory/scoped_ptr.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/geometry/size.h" #include "ui/views/animation/ink_drop_host.h" #include "ui/views/view.h" @@ -27,6 +28,8 @@ scoped_ptr<InkDropAnimation> CreateInkDropAnimation() const override; scoped_ptr<InkDropHover> CreateInkDropHover() const override; + void set_ink_drop_size(const gfx::Size& size) { ink_drop_size_ = size; } + protected: // Overrideable methods to allow views to provide minor tweaks to the default // ink drop. @@ -34,6 +37,8 @@ virtual SkColor GetInkDropBaseColor() const; private: + gfx::Size ink_drop_size_; + DISALLOW_COPY_AND_ASSIGN(InkDropHostView); }; }
diff --git a/ui/views/cocoa/bridged_native_widget_unittest.mm b/ui/views/cocoa/bridged_native_widget_unittest.mm index 5b39b511..7723f238 100644 --- a/ui/views/cocoa/bridged_native_widget_unittest.mm +++ b/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -279,6 +279,8 @@ } void BridgedNativeWidgetTest::TearDown() { + if (bridge()) + bridge()->SetRootView(nullptr); view_.reset(); BridgedNativeWidgetTestBase::TearDown(); }
diff --git a/ui/views/controls/button/custom_button.h b/ui/views/controls/button/custom_button.h index dfd0384..fa0a215 100644 --- a/ui/views/controls/button/custom_button.h +++ b/ui/views/controls/button/custom_button.h
@@ -103,6 +103,8 @@ // Overridden from gfx::AnimationDelegate: void AnimationProgressed(const gfx::Animation* animation) override; + InkDropDelegate* ink_drop_delegate() const { return ink_drop_delegate_; } + protected: // Construct the Button with a Listener. See comment for Button's ctor. explicit CustomButton(ButtonListener* listener); @@ -135,7 +137,6 @@ // state). This does not take into account enabled state. bool ShouldEnterHoveredState(); - InkDropDelegate* ink_drop_delegate() const { return ink_drop_delegate_; } void set_ink_drop_delegate(InkDropDelegate* ink_drop_delegate) { ink_drop_delegate_ = ink_drop_delegate; }
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 635de89..e62394e 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -555,12 +555,12 @@ [[native_parent contentView] addSubview:anchor_view]; // Note: Don't use WidgetTest::CreateChildPlatformWidget because that makes - // windows of TYPE_CONTROL which are automatically made visible. But still - // mark it as a child to test window positioning. + // windows of TYPE_CONTROL which need a parent Widget to obtain the focus + // manager. Widget* child = new Widget; Widget::InitParams init_params; init_params.parent = anchor_view; - init_params.child = true; + init_params.type = Widget::InitParams::TYPE_POPUP; child->Init(init_params); TestWidgetObserver child_observer(child); @@ -577,7 +577,8 @@ NativeWidgetMac::GetBridgeForNativeWindow(child->GetNativeWindow()); EXPECT_EQ(native_parent, bridged_native_widget->parent()->GetNSWindow()); - child->SetBounds(gfx::Rect(50, 50, 200, 100)); + const gfx::Rect child_bounds(50, 50, 200, 100); + child->SetBounds(child_bounds); EXPECT_FALSE(child->IsVisible()); EXPECT_EQ(0u, [[native_parent childWindows] count]); @@ -588,11 +589,9 @@ [[native_parent childWindows] objectAtIndex:0]); EXPECT_EQ(native_parent, [child->GetNativeWindow() parentWindow]); - // Child should be positioned on screen relative to the parent, but note we - // positioned the parent in Cocoa coordinates, so we need to convert. - gfx::Point parent_origin = gfx::ScreenRectFromNSRect(ParentRect()).origin(); - EXPECT_EQ(gfx::Rect(150, parent_origin.y() + 50, 200, 100), - child->GetWindowBoundsInScreen()); + // Only non-toplevel Widgets are positioned relative to the parent, so the + // bounds set above should be in screen coordinates. + EXPECT_EQ(child_bounds, child->GetWindowBoundsInScreen()); // Removing the anchor_view from its view hierarchy is permitted. This should // not break the relationship between the two windows.
diff --git a/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp index c401345..bcfaa7c1 100644 --- a/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp +++ b/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp
@@ -6,10 +6,10 @@ { 'target_name': 'cr_shared_menu', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', - '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:position_util', + '../../js/compiled_resources2.gyp:assert', + '../../js/compiled_resources2.gyp:cr', + '../../js/compiled_resources2.gyp:util', + '../../js/cr/ui/compiled_resources2.gyp:position_util', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], },
diff --git a/ui/webui/resources/js/cr/ui/splitter.js b/ui/webui/resources/js/cr/ui/splitter.js index aacfacee..c457e421 100644 --- a/ui/webui/resources/js/cr/ui/splitter.js +++ b/ui/webui/resources/js/cr/ui/splitter.js
@@ -71,6 +71,15 @@ true); this.addEventListener('touchstart', this.handleTouchStart_.bind(this), true); + this.resizeNextElement_ = false; + }, + + /** + * @param {boolean} resizeNext True if resize the next element. + * By default, splitter resizes previous (left) element. + */ + set resizeNextElement(resizeNext) { + this.resizeNextElement_ = resizeNext; }, /** @@ -129,6 +138,25 @@ }, /** + * @return {Element} + * @private + */ + getResizeTarget_: function() { + return this.resizeNextElement_ ? this.nextElementSibling : + this.previousElementSibling; + }, + + /** + * Calculate width to resize target element. + * @param {number} deltaX horizontal drag amount + * @return {number} + * @private + */ + calcDeltaX_: function(deltaX) { + return this.resizeNextElement_ ? -deltaX : deltaX; + }, + + /** * Handles the mousedown event which starts the dragging of the splitter. * @param {!Event} e The mouse event. * @private @@ -205,10 +233,10 @@ handleSplitterDragStart: function() { // Use the computed width style as the base so that we can ignore what // box sizing the element has. - var leftComponent = this.previousElementSibling; - var doc = leftComponent.ownerDocument; + var targetElement = this.getResizeTarget_(); + var doc = targetElement.ownerDocument; this.startWidth_ = parseFloat( - doc.defaultView.getComputedStyle(leftComponent).width); + doc.defaultView.getComputedStyle(targetElement).width); }, /** @@ -217,8 +245,9 @@ * @protected */ handleSplitterDragMove: function(deltaX) { - var leftComponent = this.previousElementSibling; - leftComponent.style.width = this.startWidth_ + deltaX + 'px'; + var targetElement = this.getResizeTarget_(); + var newWidth = this.startWidth_ + this.calcDeltaX_(deltaX); + targetElement.style.width = newWidth + 'px'; }, /** @@ -228,10 +257,10 @@ */ handleSplitterDragEnd: function() { // Check if the size changed. - var leftComponent = this.previousElementSibling; - var doc = leftComponent.ownerDocument; + var targetElement = this.getResizeTarget_(); + var doc = targetElement.ownerDocument; var computedWidth = parseFloat( - doc.defaultView.getComputedStyle(leftComponent).width); + doc.defaultView.getComputedStyle(targetElement).width); if (this.startWidth_ != computedWidth) cr.dispatchSimpleEvent(this, 'resize'); },