diff --git a/DEPS b/DEPS index ed89047..655b1c8 100644 --- a/DEPS +++ b/DEPS
@@ -64,7 +64,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': '22eb7ae54e4351f70a5a01b0130c8b0dc713586c', + 'pdfium_revision': '0646275cd9c19e9fb97eaa023494bb771e47e095', # 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. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'bdff8501d71be9e9e710f3effa09a5c3a7acaa6a', + 'catapult_revision': 'dc62dbb86964e5fe9b9175588ed10a4b4c229a69', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.cc b/android_webview/browser/aw_safe_browsing_resource_throttle.cc index 8f7815280..a43fe85 100644 --- a/android_webview/browser/aw_safe_browsing_resource_throttle.cc +++ b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
@@ -43,8 +43,7 @@ resource_type, safe_browsing::CreateSBThreatTypeSet( {safe_browsing::SB_THREAT_TYPE_URL_MALWARE, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, - safe_browsing::SB_THREAT_TYPE_URL_UNWANTED}), + safe_browsing::SB_THREAT_TYPE_URL_PHISHING}), database_manager, ui_manager), request_(request) {} @@ -57,17 +56,4 @@ Cancel(); } -void AwSafeBrowsingResourceThrottle::OnCheckBrowseUrlResult( - const GURL& url, - SBThreatType threat_type, - const ThreatMetadata& metadata) { - if (threat_type != safe_browsing::SB_THREAT_TYPE_URL_PHISHING && - threat_type != safe_browsing::SB_THREAT_TYPE_URL_MALWARE) { - // If we don't recognize the threat type, just mark it as safe - threat_type = safe_browsing::SB_THREAT_TYPE_SAFE; - } - - BaseResourceThrottle::OnCheckBrowseUrlResult(url, threat_type, metadata); -} - } // namespace android_webview
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.h b/android_webview/browser/aw_safe_browsing_resource_throttle.h index 5991c84bb..65a17e6 100644 --- a/android_webview/browser/aw_safe_browsing_resource_throttle.h +++ b/android_webview/browser/aw_safe_browsing_resource_throttle.h
@@ -35,10 +35,6 @@ static const void* kUserDataKey; - void OnCheckBrowseUrlResult(const GURL& url, - SBThreatType threat_type, - const ThreatMetadata& metadata) override; - private: AwSafeBrowsingResourceThrottle( net::URLRequest* request,
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper.cc b/android_webview/browser/net/aw_cookie_store_wrapper.cc index 5a92c05b..88b8a60 100644 --- a/android_webview/browser/net/aw_cookie_store_wrapper.cc +++ b/android_webview/browser/net/aw_cookie_store_wrapper.cc
@@ -246,7 +246,7 @@ bool secure_source, bool modify_http_only, SetCookiesCallback callback) { - DCHECK(client_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); PostTaskToCookieStoreTaskRunner(base::BindOnce( &SetCanonicalCookieAsyncOnCookieThread, std::move(cookie), secure_source, modify_http_only, CreateWrappedCallback<bool>(std::move(callback))));
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java index b4a26bf..a1ddd7a 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java
@@ -35,6 +35,8 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.net.test.EmbeddedTestServer; +import java.util.Arrays; + /** * Test suite for SafeBrowsing. * @@ -79,10 +81,9 @@ public static class MockSafeBrowsingApiHandler implements SafeBrowsingApiHandler { private Observer mObserver; private static final String SAFE_METADATA = "{}"; - private static final String PHISHING_METADATA = "{\"matches\":[{\"threat_type\":\"5\"}]}"; - private static final String MALWARE_METADATA = "{\"matches\":[{\"threat_type\":\"4\"}]}"; - private static final String UNWANTED_SOFTWARE_METADATA = - "{\"matches\":[{\"threat_type\":\"3\"}]}"; + private static final int PHISHING_CODE = 5; + private static final int MALWARE_CODE = 4; + private static final int UNWANTED_SOFTWARE_CODE = 3; @Override public boolean init(Context context, Observer result) { @@ -90,15 +91,27 @@ return true; } + private String buildMetadataFromCode(int code) { + return "{\"matches\":[{\"threat_type\":\"" + code + "\"}]}"; + } + @Override public void startUriLookup(final long callbackId, String uri, int[] threatsOfInterest) { final String metadata; - if (uri.endsWith(PHISHING_HTML_PATH)) { - metadata = PHISHING_METADATA; - } else if (uri.endsWith(MALWARE_HTML_PATH)) { - metadata = MALWARE_METADATA; - } else if (uri.endsWith(UNWANTED_SOFTWARE_HTML_PATH)) { - metadata = UNWANTED_SOFTWARE_METADATA; + Arrays.sort(threatsOfInterest); + + // TODO(ntfschr): remove this assert once we support UwS warnings (crbug/729272) + assertEquals(Arrays.binarySearch(threatsOfInterest, UNWANTED_SOFTWARE_CODE), -1); + + if (uri.endsWith(PHISHING_HTML_PATH) + && Arrays.binarySearch(threatsOfInterest, PHISHING_CODE) >= 0) { + metadata = buildMetadataFromCode(PHISHING_CODE); + } else if (uri.endsWith(MALWARE_HTML_PATH) + && Arrays.binarySearch(threatsOfInterest, MALWARE_CODE) >= 0) { + metadata = buildMetadataFromCode(MALWARE_CODE); + } else if (uri.endsWith(UNWANTED_SOFTWARE_HTML_PATH) + && Arrays.binarySearch(threatsOfInterest, UNWANTED_SOFTWARE_CODE) >= 0) { + metadata = buildMetadataFromCode(UNWANTED_SOFTWARE_CODE); } else { metadata = SAFE_METADATA; } @@ -280,8 +293,8 @@ @Feature({"AndroidWebView"}) @CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) public void testSafeBrowsingDoesNotBlockUnwantedSoftwarePages() throws Throwable { - // TODO(ntfschr): this is a temporary check until we add support for Unwanted Software - // warnings + // TODO(ntfschr): this is a temporary check until we add support for UwS warnings + // (crbug/729272) loadGreenPage(); final String responseUrl = mTestServer.getURL(UNWANTED_SOFTWARE_HTML_PATH); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), responseUrl);
diff --git a/ash/ime/ime_controller_unittest.cc b/ash/ime/ime_controller_unittest.cc index 46a93cf..d454d86 100644 --- a/ash/ime/ime_controller_unittest.cc +++ b/ash/ime/ime_controller_unittest.cc
@@ -19,10 +19,9 @@ namespace { // Refreshes the IME list with fake IMEs and fake menu items. -void RefreshImes(const std::string& current_ime_id, - const std::vector<std::string>& ime_ids, - const std::vector<std::string>& menu_item_keys = - std::vector<std::string>()) { +void RefreshImesWithMenuItems(const std::string& current_ime_id, + const std::vector<std::string>& ime_ids, + const std::vector<std::string>& menu_item_keys) { std::vector<mojom::ImeInfoPtr> available_imes; for (const std::string& ime_id : ime_ids) { mojom::ImeInfoPtr ime = mojom::ImeInfo::New(); @@ -39,6 +38,13 @@ current_ime_id, std::move(available_imes), std::move(menu_items)); } +// Refreshes the IME list without adding any menu items. +void RefreshImes(const std::string& current_ime_id, + const std::vector<std::string>& ime_ids) { + const std::vector<std::string> empty_menu_items; + RefreshImesWithMenuItems(current_ime_id, ime_ids, empty_menu_items); +} + class TestImeObserver : public IMEObserver { public: TestImeObserver() = default; @@ -92,7 +98,7 @@ TestImeObserver observer; Shell::Get()->system_tray_notifier()->AddIMEObserver(&observer); - RefreshImes("ime1", {"ime1", "ime2"}, {"menu1"}); + RefreshImesWithMenuItems("ime1", {"ime1", "ime2"}, {"menu1"}); // Cached data was updated. EXPECT_EQ("ime1", controller->current_ime().id);
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h index e1dfd4f..f9af1b5 100644 --- a/base/task_scheduler/task_scheduler_impl.h +++ b/base/task_scheduler/task_scheduler_impl.h
@@ -103,14 +103,10 @@ AtomicFlag join_for_testing_returned_; #endif -#if defined(OS_WIN) -// The check below cannot be &&'ed with defined(OS_WIN) since the preprocessor -// will find that the macro is undefined even if defined(OS_WIN) is not true. -#if COM_INIT_CHECK_HOOK_ENABLED() +#if defined(OS_WIN) && defined(COM_INIT_CHECK_HOOK_ENABLED) // Provides COM initialization verification for supported builds. base::win::ComInitCheckHook com_init_check_hook_; #endif -#endif DISALLOW_COPY_AND_ASSIGN(TaskSchedulerImpl); };
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index d6392d1..ac12aed 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1724,14 +1724,6 @@ # dump_syms, so this is still required (https://crbug.com/622406). cflags += [ "-fno-standalone-debug" ] } - } else if (is_android) { - # Breakpad can't handle DWARF 4 symbols properly yet, so use DWARF 3 - # explicitly on android where we are hitting https://crbug.com/638485. - # The arguments MUST be in this order because of a gcc arg parsing bug. - cflags = [ - "-gdwarf-3", - "-g2", - ] } else { cflags = [ "-g2" ] } @@ -1765,16 +1757,16 @@ cflags = [] ldflags = [ "/DEBUG" ] } else { + cflags = [ "-g1" ] if (is_android) { - # Breakpad can't handle DWARF 4 symbols properly yet, so use DWARF 3 - # explicitly on android where we are hitting https://crbug.com/638485. - # The arguments MUST be in this order because of a gcc arg parsing bug. - cflags = [ - "-gdwarf-3", - "-g1", - ] - } else { - cflags = [ "-g1" ] + # Android defaults to symbol_level=1 builds in production builds + # (https://crbug.com/648948), but clang, unlike gcc, doesn't emit + # DW_AT_linkage_name in -g1 builds. -fdebug-info-for-profiling enables + # that (and a bunch of other things we don't need), so that we get + # qualified names in stacks. + # TODO(thakis): Consider making clang emit DW_AT_linkage_name in -g1 mode; + # failing that consider doing this on non-Android too. + cflags += [ "-fdebug-info-for-profiling" ] } # Note: -gsplit-dwarf implicitly turns on -g2 with clang, so don't pass it.
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni index 5429938..fc6c681 100644 --- a/build/config/ios/rules.gni +++ b/build/config/ios/rules.gni
@@ -1614,3 +1614,75 @@ set_defaults("ios_xctest_test") { configs = default_executable_configs } + +# Template to build a XCUITest that consists of two parts: the test runner +# application bundle and the xctest dynamic library. +# +# Arguments +# +# deps: +# list of labels to depends on, these values are used to create the +# xctest dynamic library. +# +# This template defines two targets, one named "${target_name}" is the xctest +# dynamic library, and the other named "${target_name}_runner" is the test +# runner application bundle. +# +template("ios_xcuitest_test") { + assert(false, + "ios_xcuitest_test is incomplete and should not be used, see " + + "crbug.com/709289 for tracking") + + _xcuitest_target = target_name + _xcuitest_runner_target = _xcuitest_target + "_runner" + _xctrunner_path = + "$ios_sdk_platform_path/Developer/Library/Xcode/Agents/XCTRunner.app" + + _xcuitest_runner_info_plist_merge_plist = + _xcuitest_runner_target + "_info_plist_merge_plist" + _xcuitest_runner_info_plist_target = _xcuitest_runner_target + "_info_plist" + _xcuitest_runner_info_plist_bundle = + _xcuitest_runner_target + "_info_plist_bundle" + + action(_xcuitest_runner_info_plist_merge_plist) { + testonly = true + script = "//build/config/mac/plist_util.py" + + sources = [ + "$_xctrunner_path/Info.plist", + + # NOTE: The XCTRunnerAddition+Info.plist must come after the Info.plist + # because it overrides the values under "CFBundleIdentifier" and + # "CFBundleName". + "//ios/chrome/app/resources/XCTRunnerAddition+Info.plist", + ] + + _output_name = "$target_gen_dir/${_xcuitest_runner_target}_merged.plist" + outputs = [ + _output_name, + ] + args = [ + "merge", + "-f=xml1", + "-o=" + rebase_path(_output_name, root_build_dir), + ] + rebase_path(sources, root_build_dir) + } + + ios_info_plist(_xcuitest_runner_info_plist_target) { + testonly = true + visibility = [ ":$_xcuitest_runner_info_plist_bundle" ] + + executable_name = _xcuitest_target + info_plist_target = ":$_xcuitest_runner_info_plist_merge_plist" + if (ios_automatically_manage_certs) { + # Use the same bundle identifier for XCUITest tests as for unit tests + # when managing certificates as the number of free certs is limited. + extra_substitutions = + [ "PRODUCT_NAME=${ios_generic_test_bundle_id_suffix}" ] + } + } +} + +set_defaults("ios_xcuitest_test") { + configs = default_executable_configs +}
diff --git a/build/mac/should_use_hermetic_xcode.py b/build/mac/should_use_hermetic_xcode.py index 68e288e..dc1b930 100755 --- a/build/mac/should_use_hermetic_xcode.py +++ b/build/mac/should_use_hermetic_xcode.py
@@ -3,8 +3,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Prints "1" if Chrome targets should be built with hermetic xcode. Otherwise -prints "0". +""" +Prints "1" if Chrome targets should be built with hermetic Xcode. +Prints "2" if Chrome targets should be built with hermetic Xcode, but the OS +version does not meet the minimum requirements of the hermetic version of Xcode. +Otherwise prints "0". Usage: python should_use_hermetic_xcode.py <target_os> @@ -13,6 +16,12 @@ import os import sys +_THIS_DIR_PATH = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) +_BUILD_PATH = os.path.join(_THIS_DIR_PATH, os.pardir) +sys.path.insert(0, _BUILD_PATH) + +import mac_toolchain + def _IsCorpMachine(): return os.path.isdir('/Library/GoogleCorpSupport/') @@ -21,6 +30,8 @@ def main(): allow_corp = sys.argv[1] == 'mac' and _IsCorpMachine() if os.environ.get('FORCE_MAC_TOOLCHAIN') or allow_corp: + if not mac_toolchain.PlatformMeetsHermeticXcodeRequirements(sys.argv[1]): + return "2" return "1" else: return "0"
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py index 123e5e0d3..534f9d198 100755 --- a/build/mac_toolchain.py +++ b/build/mac_toolchain.py
@@ -14,6 +14,7 @@ """ import os +import platform import plistlib import shutil import subprocess @@ -24,10 +25,14 @@ import urllib2 # This can be changed after running /build/package_mac_toolchain.py. -MAC_TOOLCHAIN_VERSION = '5B1008' +MAC_TOOLCHAIN_VERSION = '8E2002' MAC_TOOLCHAIN_SUB_REVISION = 3 MAC_TOOLCHAIN_VERSION = '%s-%s' % (MAC_TOOLCHAIN_VERSION, MAC_TOOLCHAIN_SUB_REVISION) +# The toolchain will not be downloaded if the minimum OS version is not met. +# 16 is the major version number for macOS 10.12. +MAC_MINIMUM_OS_VERSION = 16 + IOS_TOOLCHAIN_VERSION = '8C1002' IOS_TOOLCHAIN_SUB_REVISION = 1 IOS_TOOLCHAIN_VERSION = '%s-%s' % (IOS_TOOLCHAIN_VERSION, @@ -44,6 +49,13 @@ STAMP_FILE = os.path.join(BASE_DIR, '%s_files', 'toolchain_build_revision') TOOLCHAIN_URL = 'gs://chrome-mac-sdk/' + +def PlatformMeetsHermeticXcodeRequirements(target_os): + if target_os == 'ios': + return True + return int(platform.release().split('.')[0]) >= MAC_MINIMUM_OS_VERSION + + def GetPlatforms(): default_target_os = ["mac"] try: @@ -232,6 +244,10 @@ return 0 for target_os in GetPlatforms(): + if not PlatformMeetsHermeticXcodeRequirements(target_os): + print 'OS version does not support toolchain.' + continue + if target_os == 'ios': default_version = IOS_TOOLCHAIN_VERSION toolchain_filename = 'ios-toolchain-%s.tgz'
diff --git a/build_overrides/build.gni b/build_overrides/build.gni index 7b632bd..066298f 100644 --- a/build_overrides/build.gni +++ b/build_overrides/build.gni
@@ -58,5 +58,8 @@ _result = exec_script("//build/mac/should_use_hermetic_xcode.py", [ target_os ], "value") + assert(_result != 2, + "Do not allow building targets with the default" + + "hermetic toolchain if the minimum OS version is not met.") use_system_xcode = _result == 0 }
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc index d2c51d18..c89a657 100644 --- a/cc/blink/web_layer_impl.cc +++ b/cc/blink/web_layer_impl.cc
@@ -226,6 +226,10 @@ return layer_->HasTickingAnimationForTesting(); } +void WebLayerImpl::SetScrollable(const blink::WebSize& size) { + layer_->SetScrollable(size); +} + void WebLayerImpl::SetScrollPosition(blink::WebFloatPoint position) { layer_->SetScrollOffset(gfx::ScrollOffset(position.x, position.y)); } @@ -235,14 +239,6 @@ layer_->scroll_offset().y()); } -void WebLayerImpl::SetScrollClipLayer(WebLayer* clip_layer) { - if (!clip_layer) { - layer_->SetScrollClipLayerId(Layer::INVALID_ID); - return; - } - layer_->SetScrollClipLayerId(clip_layer->Id()); -} - bool WebLayerImpl::Scrollable() const { return layer_->scrollable(); }
diff --git a/cc/blink/web_layer_impl.h b/cc/blink/web_layer_impl.h index f85b1d9..8f831166 100644 --- a/cc/blink/web_layer_impl.h +++ b/cc/blink/web_layer_impl.h
@@ -91,9 +91,9 @@ void SetFiltersOrigin(const blink::WebFloatPoint& origin) override; void SetBackgroundFilters(const cc::FilterOperations& filters) override; bool HasTickingAnimationForTesting() override; + void SetScrollable(const blink::WebSize&) override; void SetScrollPosition(blink::WebFloatPoint position) override; blink::WebFloatPoint ScrollPosition() const override; - void SetScrollClipLayer(blink::WebLayer* clip_layer) override; bool Scrollable() const override; void SetUserScrollable(bool horizontal, bool vertical) override; bool UserScrollableHorizontal() const override;
diff --git a/cc/input/scrollbar_animation_controller_unittest.cc b/cc/input/scrollbar_animation_controller_unittest.cc index 6a891258..19fea25 100644 --- a/cc/input/scrollbar_animation_controller_unittest.cc +++ b/cc/input/scrollbar_animation_controller_unittest.cc
@@ -82,7 +82,6 @@ clip_layer_ = clip.get(); scroll_layer->SetElementId( LayerIdToElementIdForTesting(scroll_layer->id())); - scroll_layer->SetScrollClipLayer(clip_layer_->id()); LayerImpl* scroll_layer_ptr = scroll_layer.get(); const int kTrackStart = 0; @@ -119,6 +118,7 @@ h_scrollbar_layer_->test_properties()->opacity_can_animate = true; clip_layer_->SetBounds(gfx::Size(100, 100)); + scroll_layer_ptr->SetScrollable(gfx::Size(100, 100)); scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_.active_tree()->UpdateScrollbarGeometries(); @@ -185,12 +185,15 @@ // Make the Layer non-scrollable, scrollbar disappears. clip_layer_->SetBounds(gfx::Size(200, 200)); + LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); + scroll_layer->SetScrollable(gfx::Size(200, 200)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_->DidScrollUpdate(); ExpectScrollbarsOpacity(0); // Make the layer scrollable, scrollbar appears again. clip_layer_->SetBounds(gfx::Size(100, 100)); + scroll_layer->SetScrollable(gfx::Size(100, 100)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_->DidScrollUpdate(); ExpectScrollbarsOpacity(1); @@ -208,6 +211,7 @@ // Shrink along X axis, horizontal scrollbar should appear. clip_layer_->SetBounds(gfx::Size(100, 200)); EXPECT_EQ(gfx::Size(100, 200), clip_layer_->bounds()); + scroll_layer->SetScrollable(gfx::Size(100, 200)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_->DidScrollBegin(); @@ -221,6 +225,7 @@ // should disappear. clip_layer_->SetBounds(gfx::Size(200, 100)); EXPECT_EQ(gfx::Size(200, 100), clip_layer_->bounds()); + scroll_layer->SetScrollable(gfx::Size(200, 100)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_->DidScrollBegin(); @@ -1353,20 +1358,18 @@ scrollbar->test_properties()->opacity = 0.0f; scrollbar_layer_ = scrollbar.get(); scrollbar_layer_->test_properties()->opacity_can_animate = true; - std::unique_ptr<LayerImpl> clip = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 3); - clip_layer_ = clip.get(); + + scroll_layer->SetScrollable(gfx::Size(100, 100)); scroll_layer->SetElementId( LayerIdToElementIdForTesting(scroll_layer->id())); - - scroll_layer->SetScrollClipLayer(clip_layer_->id()); LayerImpl* scroll_layer_ptr = scroll_layer.get(); scroll_layer->test_properties()->AddChild(std::move(scrollbar)); - clip->test_properties()->AddChild(std::move(scroll_layer)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(clip)); + root->test_properties()->AddChild(std::move(scroll_layer)); + host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id()); - clip_layer_->SetBounds(gfx::Size(100, 100)); scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); DCHECK(host_impl_.active_tree()->ScrollbarGeometriesNeedUpdate()); @@ -1385,7 +1388,6 @@ TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; std::unique_ptr<ScrollbarAnimationController> scrollbar_controller_; - LayerImpl* clip_layer_; SolidColorScrollbarLayerImpl* scrollbar_layer_; base::Closure start_fade_; @@ -1451,21 +1453,17 @@ EXPECT_EQ(HORIZONTAL, scrollbar_layer_->orientation()); // Shrink along X axis, horizontal scrollbar should appear. - clip_layer_->SetBounds(gfx::Size(100, 200)); - EXPECT_EQ(gfx::Size(100, 200), clip_layer_->bounds()); + scroll_layer->SetScrollable(gfx::Size(100, 200)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - scrollbar_controller_->DidScrollEnd(); // Shrink along Y axis and expand along X, horizontal scrollbar // should disappear. - clip_layer_->SetBounds(gfx::Size(200, 100)); - EXPECT_EQ(gfx::Size(200, 100), clip_layer_->bounds()); + scroll_layer->SetScrollable(gfx::Size(200, 100)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_->DidScrollBegin(); @@ -1484,20 +1482,16 @@ EXPECT_EQ(VERTICAL, scrollbar_layer_->orientation()); // Shrink along X axis, vertical scrollbar should remain invisible. - clip_layer_->SetBounds(gfx::Size(100, 200)); - EXPECT_EQ(gfx::Size(100, 200), clip_layer_->bounds()); + scroll_layer->SetScrollable(gfx::Size(100, 200)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(); EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); - scrollbar_controller_->DidScrollEnd(); // Shrink along Y axis and expand along X, vertical scrollbar should appear. - clip_layer_->SetBounds(gfx::Size(200, 100)); - EXPECT_EQ(gfx::Size(200, 100), clip_layer_->bounds()); + scroll_layer->SetScrollable(gfx::Size(200, 100)); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_->DidScrollBegin();
diff --git a/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc b/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc index 8df33897..970afe6 100644 --- a/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc +++ b/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc
@@ -70,7 +70,6 @@ scroll_layer->SetElementId( LayerIdToElementIdForTesting(scroll_layer->id())); clip_layer_ = clip.get(); - scroll_layer->SetScrollClipLayer(clip_layer_->id()); LayerImpl* scroll_layer_ptr = scroll_layer.get(); const int kId = 2;
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 4740816bb..21f7f0d 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -54,7 +54,6 @@ sorting_context_id(0), use_parent_backface_visibility(false), background_color(0), - scroll_clip_layer_id(INVALID_ID), scrollable(false), user_scrollable_horizontal(true), user_scrollable_vertical(true), @@ -92,10 +91,8 @@ force_render_surface_for_testing_(false), subtree_property_changed_(false), may_contain_video_(false), - is_scroll_clip_layer_(false), needs_show_scrollbars_(false), has_transform_node_(false), - has_scroll_node_(false), subtree_has_copy_request_(false), safe_opaque_background_color_(0), num_unclipped_descendants_(0) {} @@ -298,16 +295,14 @@ SetPropertyTreesNeedRebuild(); } - if (scrollable() && has_scroll_node_) { - if (ScrollNode* node = layer_tree_host_->property_trees()->scroll_tree.Node( - scroll_tree_index())) { - node->bounds = inputs_.bounds; - } + if (scrollable()) { + auto& scroll_tree = layer_tree_host_->property_trees()->scroll_tree; + if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_)) + scroll_node->bounds = inputs_.bounds; + else + SetPropertyTreesNeedRebuild(); } - if (is_scroll_clip_layer_) - layer_tree_host_->property_trees()->scroll_tree.set_needs_update(true); - SetNeedsCommit(); } @@ -817,30 +812,24 @@ property_trees.transform_tree.set_needs_update(true); } -void Layer::SetScrollClipLayerId(int clip_layer_id) { +void Layer::SetScrollable(const gfx::Size& bounds) { DCHECK(IsPropertyChangeAllowed()); - if (inputs_.scroll_clip_layer_id == clip_layer_id) + if (inputs_.scrollable && inputs_.scroll_container_bounds == bounds) return; - inputs_.scroll_clip_layer_id = clip_layer_id; + bool was_scrollable = inputs_.scrollable; + inputs_.scrollable = true; + inputs_.scroll_container_bounds = bounds; - SetPropertyTreesNeedRebuild(); - - bool scrollable = clip_layer_id != Layer::INVALID_ID; - SetScrollable(scrollable); - - SetNeedsCommit(); -} - -Layer* Layer::scroll_clip_layer() const { - DCHECK(layer_tree_host_); - return layer_tree_host_->LayerById(inputs_.scroll_clip_layer_id); -} - -void Layer::SetScrollable(bool scrollable) { - DCHECK(IsPropertyChangeAllowed()); - if (inputs_.scrollable == scrollable) + if (!layer_tree_host_) return; - inputs_.scrollable = scrollable; + + auto& scroll_tree = layer_tree_host_->property_trees()->scroll_tree; + auto* scroll_node = scroll_tree.Node(scroll_tree_index_); + if (was_scrollable && scroll_node) + scroll_node->scroll_clip_layer_bounds = inputs_.scroll_container_bounds; + else + SetPropertyTreesNeedRebuild(); + SetNeedsCommit(); } @@ -854,13 +843,16 @@ if (!layer_tree_host_) return; - if (has_scroll_node_) { - if (ScrollNode* node = layer_tree_host_->property_trees()->scroll_tree.Node( - scroll_tree_index())) { - node->user_scrollable_horizontal = horizontal; - node->user_scrollable_vertical = vertical; + if (scrollable()) { + auto& scroll_tree = layer_tree_host_->property_trees()->scroll_tree; + if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_)) { + scroll_node->user_scrollable_horizontal = horizontal; + scroll_node->user_scrollable_vertical = vertical; + } else { + SetPropertyTreesNeedRebuild(); } } + SetNeedsCommit(); } @@ -944,6 +936,8 @@ DCHECK(IsPropertyChangeAllowed()); if (transform_tree_index_ == index) return; + if (index == TransformTree::kInvalidNodeId) + has_transform_node_ = false; transform_tree_index_ = index; SetNeedsPushProperties(); } @@ -1182,8 +1176,8 @@ layer->SetUseParentBackfaceVisibility(inputs_.use_parent_backface_visibility); layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility_); - layer->SetScrollClipLayer(inputs_.scroll_clip_layer_id); - layer->SetScrollable(inputs_.scrollable); + if (scrollable()) + layer->SetScrollable(inputs_.scroll_container_bounds); layer->SetMutableProperties(inputs_.mutable_properties); // The property trees must be safe to access because they will be used below
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index bbf9c0bbb..1dc0735e 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -217,14 +217,13 @@ gfx::ScrollOffset scroll_offset() const { return inputs_.scroll_offset; } void SetScrollOffsetFromImplSide(const gfx::ScrollOffset& scroll_offset); - // TODO(pdr): Remove scroll_clip_layer_id and store the scroll clip bounds - // directly instead of using scroll_clip_layer's bounds. - void SetScrollClipLayerId(int clip_layer_id); - Layer* scroll_clip_layer() const; - - // Marks this layer as being scrollable and needing an associated scroll node - // with bounds synced to this layer's bounds. - void SetScrollable(bool scrollable = true); + // Marks this layer as being scrollable and needing an associated scroll node. + // The scroll node's bounds and scroll_clip_layer_bounds will be kept in sync + // with this layer. Once scrollable, a Layer cannot become un-scrollable. + void SetScrollable(const gfx::Size& scroll_container_bounds); + gfx::Size scroll_container_bounds() const { + return inputs_.scroll_container_bounds; + } bool scrollable() const { return inputs_.scrollable; } void SetUserScrollable(bool horizontal, bool vertical); @@ -256,8 +255,8 @@ } void set_did_scroll_callback( - const base::Callback<void(const gfx::ScrollOffset&)>& callback) { - inputs_.did_scroll_callback = callback; + base::Callback<void(const gfx::ScrollOffset&)> callback) { + inputs_.did_scroll_callback = std::move(callback); } void SetForceRenderSurfaceForTesting(bool force_render_surface); @@ -418,8 +417,6 @@ void SetScrollbarsHiddenFromImplSide(bool hidden); - void set_is_scroll_clip_layer() { is_scroll_clip_layer_ = true; } - const gfx::Rect& update_rect() const { return inputs_.update_rect; } LayerTreeHost* layer_tree_host() const { return layer_tree_host_; } @@ -429,7 +426,6 @@ bool has_transform_node() { return has_transform_node_; } void SetHasTransformNode(bool val) { has_transform_node_ = val; } - void SetHasScrollNode(bool val) { has_scroll_node_ = val; } protected: friend class LayerImpl; @@ -573,14 +569,14 @@ gfx::ScrollOffset scroll_offset; - // This variable indicates which ancestor layer (if any) whose size, - // transformed relative to this layer, defines the maximum scroll offset - // for this layer. - int scroll_clip_layer_id; + // Size of the scroll container that this layer scrolls in. + gfx::Size scroll_container_bounds; // Indicates that this layer will need a scroll property node and that this - // layer's bounds correspond to the scroll node's bounds. + // layer's bounds correspond to the scroll node's bounds (both |bounds| and + // |scroll_container_bounds|). bool scrollable : 1; + bool user_scrollable_horizontal : 1; bool user_scrollable_vertical : 1; @@ -633,12 +629,10 @@ bool force_render_surface_for_testing_ : 1; bool subtree_property_changed_ : 1; bool may_contain_video_ : 1; - bool is_scroll_clip_layer_ : 1; bool needs_show_scrollbars_ : 1; // Whether the nodes referred to by *_tree_index_ // "belong" to this layer. Only applicable if use_layer_lists is false. bool has_transform_node_ : 1; - bool has_scroll_node_ : 1; // This value is valid only when LayerTreeHost::has_copy_request() is true bool subtree_has_copy_request_ : 1; SkColor safe_opaque_background_color_;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index e30b44d..6e45fd3 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -52,7 +52,6 @@ : layer_id_(id), layer_tree_impl_(tree_impl), test_properties_(nullptr), - scroll_clip_layer_id_(Layer::INVALID_ID), main_thread_scrolling_reasons_( MainThreadScrollingReason::kNotScrollingOnMain), scrollable_(false), @@ -271,30 +270,21 @@ return scroll_tree.ScrollBy(scroll_node, scroll, layer_tree_impl()); } -void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { - if (scroll_clip_layer_id_ == scroll_clip_layer_id) +void LayerImpl::SetScrollable(const gfx::Size& bounds) { + if (scrollable_ && scroll_container_bounds_ == bounds) return; - scroll_clip_layer_id_ = scroll_clip_layer_id; + scrollable_ = true; + scroll_container_bounds_ = bounds; - // The scrolling bounds are determined from the scroll clip layer's bounds. + // Scrollbar positions depend on the bounds. layer_tree_impl()->SetScrollbarGeometriesNeedUpdate(); - bool scrollable = scroll_clip_layer_id_ != Layer::INVALID_ID; - SetScrollable(scrollable); -} - -LayerImpl* LayerImpl::scroll_clip_layer() const { - return layer_tree_impl()->LayerById(scroll_clip_layer_id_); -} - -void LayerImpl::SetScrollable(bool scrollable) { - if (scrollable_ == scrollable) - return; - scrollable_ = scrollable; - if (scrollable && layer_tree_impl()->settings().scrollbar_animator == - LayerTreeSettings::AURA_OVERLAY) { + if (layer_tree_impl()->settings().scrollbar_animator == + LayerTreeSettings::AURA_OVERLAY) { set_needs_show_scrollbars(true); } + + NoteLayerPropertyChanged(); } std::unique_ptr<LayerImpl> LayerImpl::CreateLayerImpl( @@ -344,8 +334,8 @@ } layer->SetBounds(bounds_); - layer->SetScrollClipLayer(scroll_clip_layer_id_); - layer->SetScrollable(scrollable_); + if (scrollable_) + layer->SetScrollable(scroll_container_bounds_); layer->SetMutableProperties(mutable_properties_); // If the main thread commits multiple times before the impl thread actually @@ -511,8 +501,9 @@ bounds_ = bounds; - // Scrollbar positions depend on scrolling bounds and scroll clip bounds. - layer_tree_impl()->SetScrollbarGeometriesNeedUpdate(); + // Scrollbar positions depend on the scrolling layer bounds. + if (scrollable()) + layer_tree_impl()->SetScrollbarGeometriesNeedUpdate(); NoteLayerPropertyChanged(); }
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index c8e2610..65c190f2 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -295,14 +295,11 @@ // initial scroll gfx::Vector2dF ScrollBy(const gfx::Vector2dF& scroll); - // TODO(pdr): Remove scroll_clip_layer_id and use the scroll node's scroll - // clip bounds instead of the scroll_clip_layer bounds. - void SetScrollClipLayer(int scroll_clip_layer_id); - LayerImpl* scroll_clip_layer() const; - - // Marks this layer as being scrollable and having an associated scroll node - // with bounds synced to this layer's bounds. - void SetScrollable(bool scrollable = true); + // Marks this layer as being scrollable and needing an associated scroll node. + // The scroll node's bounds and scroll_clip_layer_bounds will be kept in sync + // with this layer. + void SetScrollable(const gfx::Size& bounds); + gfx::Size scroll_container_bounds() const { return scroll_container_bounds_; } bool scrollable() const { return scrollable_; } void set_main_thread_scrolling_reasons( @@ -476,13 +473,16 @@ // Properties synchronized from the associated Layer. gfx::Size bounds_; - int scroll_clip_layer_id_; gfx::Vector2dF offset_to_transform_parent_; uint32_t main_thread_scrolling_reasons_; - // Indicates that this layer is scrollable and has an associated scroll node - // with bounds synced to this layer's bounds. + // Size of the scroll container that this layer scrolls in. + gfx::Size scroll_container_bounds_; + + // Indicates that this layer will have a scroll property node and that this + // layer's bounds correspond to the scroll node's bounds (both |bounds| and + // |scroll_container_bounds|). bool scrollable_ : 1; bool should_flatten_transform_from_property_tree_ : 1;
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index 326ef45..9a5f4db7 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc
@@ -130,18 +130,13 @@ host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(layer_tree_frame_sink.get())); host_impl.CreatePendingTree(); - std::unique_ptr<LayerImpl> root_clip_ptr = - LayerImpl::Create(host_impl.pending_tree(), 1); - LayerImpl* root_clip = root_clip_ptr.get(); std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl.pending_tree(), 2); LayerImpl* root = root_ptr.get(); - root_clip_ptr->test_properties()->AddChild(std::move(root_ptr)); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root_clip_ptr)); + host_impl.pending_tree()->SetRootLayerForTesting(std::move(root_ptr)); root->test_properties()->force_render_surface = true; root->SetMasksToBounds(true); - root->SetScrollClipLayer(root_clip->id()); root->layer_tree_impl()->ResetAllChangeTracking(); root->test_properties()->AddChild( @@ -150,7 +145,6 @@ child->test_properties()->AddChild( LayerImpl::Create(host_impl.pending_tree(), 8)); LayerImpl* grand_child = child->test_properties()->children[0]; - root->SetScrollClipLayer(root_clip->id()); host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); // Adding children is an internal operation and should not mark layers as @@ -224,19 +218,15 @@ FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(layer_tree_frame_sink.get())); - std::unique_ptr<LayerImpl> root_clip_ptr = - LayerImpl::Create(host_impl.active_tree(), 1); - LayerImpl* root_clip = root_clip_ptr.get(); std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl.active_tree(), 2); LayerImpl* root = root_ptr.get(); - root_clip_ptr->test_properties()->AddChild(std::move(root_ptr)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root_clip_ptr)); + host_impl.active_tree()->SetRootLayerForTesting(std::move(root_ptr)); root->test_properties()->AddChild( LayerImpl::Create(host_impl.active_tree(), 7)); LayerImpl* child = root->test_properties()->children[0]; - root->SetScrollClipLayer(root_clip->id()); + root->SetScrollable(gfx::Size(100, 100)); host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); // Make root the inner viewport container layer. This ensures the later call @@ -306,7 +296,7 @@ LayerImpl::Create(host_impl.active_tree(), 2); LayerImpl* layer = layer_ptr.get(); root->test_properties()->AddChild(std::move(layer_ptr)); - layer->SetScrollClipLayer(root->id()); + layer->SetScrollable(gfx::Size(1, 1)); std::unique_ptr<LayerImpl> layer2_ptr = LayerImpl::Create(host_impl.active_tree(), 3); LayerImpl* layer2 = layer2_ptr.get(); @@ -493,12 +483,12 @@ ->root_layer_for_testing() ->test_properties() ->AddChild(LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1)); - layer()->SetScrollClipLayer(root_id_); // Set the max scroll offset by noting that the root layer has bounds (1,1), // thus whatever bounds are set for the layer will be the max scroll // offset plus 1 in each direction. host_impl_.active_tree()->root_layer_for_testing()->SetBounds( gfx::Size(1, 1)); + layer()->SetScrollable(gfx::Size(1, 1)); gfx::Vector2d max_scroll_offset(51, 81); layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y())); host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting();
diff --git a/cc/layers/layer_perftest.cc b/cc/layers/layer_perftest.cc index 61086a0d..a0bee52 100644 --- a/cc/layers/layer_perftest.cc +++ b/cc/layers/layer_perftest.cc
@@ -79,8 +79,6 @@ test_layer->SetDoubleSided(double_sided); test_layer->SetHideLayerAndSubtree(hide_layer_and_subtree); test_layer->SetMasksToBounds(masks_to_bounds); - test_layer->SetScrollClipLayerId(scrollable ? test_layer->id() - : Layer::INVALID_ID); test_layer->PushPropertiesTo(impl_layer.get()); transform_origin_z += 0.01f;
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc index 89fc3d0..ad31d96 100644 --- a/cc/layers/layer_position_constraint_unittest.cc +++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -124,15 +124,15 @@ inner_viewport_container_layer_->SetMasksToBounds(true); scroll_layer_->SetElementId( LayerIdToElementIdForTesting(scroll_layer_->id())); - scroll_layer_->SetScrollClipLayerId(inner_viewport_container_layer_->id()); + scroll_layer_->SetScrollable(clip_bounds); scroll_layer_->SetIsContainerForFixedPositionLayers(true); outer_viewport_container_layer_->SetMasksToBounds(true); child_->SetElementId(LayerIdToElementIdForTesting(child_->id())); - child_->SetScrollClipLayerId(outer_viewport_container_layer_->id()); + child_->SetScrollable(clip_bounds); grand_child_->SetElementId( LayerIdToElementIdForTesting(grand_child_->id())); - grand_child_->SetScrollClipLayerId(outer_viewport_container_layer_->id()); + grand_child_->SetScrollable(clip_bounds); grand_child_->AddChild(great_grand_child_); child_->AddChild(grand_child_); @@ -1071,7 +1071,7 @@ great_grand_child_->SetIsContainerForFixedPositionLayers(true); great_grand_child_->SetElementId( LayerIdToElementIdForTesting(great_grand_child_->id())); - great_grand_child_->SetScrollClipLayerId(root_->id()); + great_grand_child_->SetScrollable(gfx::Size(100, 100)); great_great_grand_child->SetPositionConstraint(fixed_to_top_left_); CommitAndUpdateImplPointers();
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index b1808b9..6355412b 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -913,8 +913,7 @@ EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetContentsOpaque(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f))); // We can use any layer pointer here since we aren't syncing for real. - EXPECT_SET_NEEDS_COMMIT(2, - test_layer->SetScrollClipLayerId(test_layer->id())); + EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(gfx::Size(1, 1))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset( gfx::ScrollOffset(10, 10)));
diff --git a/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/cc/layers/painted_scrollbar_layer_impl_unittest.cc index 3932b0e..2dd6d0b7 100644 --- a/cc/layers/painted_scrollbar_layer_impl_unittest.cc +++ b/cc/layers/painted_scrollbar_layer_impl_unittest.cc
@@ -57,9 +57,6 @@ scrollbar_layer_impl->set_thumb_ui_resource_id(thumb_uid); scrollbar_layer_impl->set_thumb_opacity(thumb_opacity); - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); - impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - impl.CalcDrawProps(viewport_size); gfx::Rect thumb_rect = scrollbar_layer_impl->ComputeThumbQuadRect();
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index fcd74017..32c0f39 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -297,9 +297,9 @@ // Choose bounds to give max_scroll_offset = (30, 50). layer_tree_root->SetBounds(gfx::Size(70, 150)); - scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20)); scroll_layer->SetBounds(gfx::Size(100, 200)); + scroll_layer->SetScrollable(gfx::Size(70, 150)); content_layer->SetBounds(gfx::Size(100, 200)); layer_tree_host_->SetRootLayer(layer_tree_root); @@ -322,6 +322,7 @@ cc_scrollbar_layer->clip_layer_length()); layer_tree_root->SetBounds(gfx::Size(700, 1500)); + scroll_layer->SetScrollable(gfx::Size(700, 1500)); scroll_layer->SetBounds(gfx::Size(1000, 2000)); scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 200)); content_layer->SetBounds(gfx::Size(1000, 2000)); @@ -344,32 +345,28 @@ cc_scrollbar_layer->clip_layer_length()); } -#define UPDATE_AND_EXTRACT_LAYER_POINTERS() \ - do { \ - scrollbar_layer->UpdateInternalContentScale(); \ - scrollbar_layer->UpdateThumbAndTrackGeometry(); \ - root_clip_layer_impl = layer_tree_host_->CommitAndCreateLayerImplTree(); \ - root_clip_layer_impl->layer_tree_impl()->UpdateScrollbarGeometries(); \ - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( \ - root_clip_layer_impl->layer_tree_impl()->LayerById( \ - scrollbar_layer->id())); \ +#define UPDATE_AND_EXTRACT_LAYER_POINTERS() \ + do { \ + scrollbar_layer->UpdateInternalContentScale(); \ + scrollbar_layer->UpdateThumbAndTrackGeometry(); \ + root_layer_impl = layer_tree_host_->CommitAndCreateLayerImplTree(); \ + root_layer_impl->layer_tree_impl()->UpdateScrollbarGeometries(); \ + scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( \ + root_layer_impl->layer_tree_impl()->LayerById(scrollbar_layer->id())); \ } while (false) TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) { - scoped_refptr<Layer> root_clip_layer = Layer::Create(); scoped_refptr<Layer> root_layer = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer = FakePaintedScrollbarLayer::Create(false, true, root_layer->element_id()); - root_layer->SetScrollClipLayerId(root_clip_layer->id()); - // Give the root-clip a size that will result in MaxScrollOffset = (80, 0). - root_clip_layer->SetBounds(gfx::Size(20, 50)); + // Give the root layer a size that will result in MaxScrollOffset = (80, 0). + root_layer->SetScrollable(gfx::Size(20, 50)); root_layer->SetBounds(gfx::Size(100, 50)); content_layer->SetBounds(gfx::Size(100, 50)); - layer_tree_host_->SetRootLayer(root_clip_layer); - root_clip_layer->AddChild(root_layer); + layer_tree_host_->SetRootLayer(root_layer); root_layer->AddChild(content_layer); root_layer->AddChild(scrollbar_layer); @@ -380,7 +377,7 @@ scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10)); scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); scrollbar_layer->fake_scrollbar()->set_thumb_length(4); - LayerImpl* root_clip_layer_impl = nullptr; + LayerImpl* root_layer_impl = nullptr; PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr; layer_tree_host_->BuildPropertyTreesForTesting(); @@ -396,21 +393,18 @@ } TEST_F(ScrollbarLayerTest, ThumbRect) { - scoped_refptr<Layer> root_clip_layer = Layer::Create(); scoped_refptr<Layer> root_layer = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer = FakePaintedScrollbarLayer::Create(false, true, root_layer->element_id()); root_layer->SetElementId(LayerIdToElementIdForTesting(root_layer->id())); - root_layer->SetScrollClipLayerId(root_clip_layer->id()); - // Give the root-clip a size that will result in MaxScrollOffset = (80, 0). - root_clip_layer->SetBounds(gfx::Size(20, 50)); + // Give the root layer a size that will result in MaxScrollOffset = (80, 0). + root_layer->SetScrollable(gfx::Size(20, 50)); root_layer->SetBounds(gfx::Size(100, 50)); content_layer->SetBounds(gfx::Size(100, 50)); - layer_tree_host_->SetRootLayer(root_clip_layer); - root_clip_layer->AddChild(root_layer); + layer_tree_host_->SetRootLayer(root_layer); root_layer->AddChild(content_layer); root_layer->AddChild(scrollbar_layer); @@ -422,7 +416,7 @@ scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); scrollbar_layer->fake_scrollbar()->set_thumb_length(4); layer_tree_host_->UpdateLayers(); - LayerImpl* root_clip_layer_impl = nullptr; + LayerImpl* root_layer_impl = nullptr; PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr; // Thumb is at the edge of the scrollbar (should be inset to @@ -475,18 +469,15 @@ } TEST_F(ScrollbarLayerTest, ThumbRectForOverlayLeftSideVerticalScrollbar) { - scoped_refptr<Layer> root_clip_layer = Layer::Create(); scoped_refptr<Layer> root_layer = Layer::Create(); // Create an overlay left side vertical scrollbar. scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer = FakePaintedScrollbarLayer::Create(false, true, VERTICAL, true, true, root_layer->element_id()); - root_layer->SetScrollClipLayerId(root_clip_layer->id()); - root_clip_layer->SetBounds(gfx::Size(50, 20)); + root_layer->SetScrollable(gfx::Size(20, 50)); root_layer->SetBounds(gfx::Size(50, 100)); - layer_tree_host_->SetRootLayer(root_clip_layer); - root_clip_layer->AddChild(root_layer); + layer_tree_host_->SetRootLayer(root_layer); root_layer->AddChild(scrollbar_layer); root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0)); @@ -496,7 +487,7 @@ scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); scrollbar_layer->fake_scrollbar()->set_thumb_length(4); layer_tree_host_->UpdateLayers(); - LayerImpl* root_clip_layer_impl = nullptr; + LayerImpl* root_layer_impl = nullptr; PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr; // Thumb is at the edge of the scrollbar (should be inset to @@ -542,9 +533,6 @@ scrollbar_layer_impl->SetClipLayerLength(200 / 3.f); scrollbar_layer_impl->SetScrollLayerLength(100 + 200 / 3.f); - DCHECK(layer_tree_host_->active_tree()->ScrollbarGeometriesNeedUpdate()); - layer_tree_host_->active_tree()->UpdateScrollbarGeometries(); - // Thickness should be overridden to 3. { std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); @@ -598,7 +586,6 @@ scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); - scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> child2; const bool kIsLeftSideVerticalScrollbar = false; @@ -612,6 +599,7 @@ // Choose layer bounds to give max_scroll_offset = (8, 8). layer_tree_root->SetBounds(gfx::Size(2, 2)); + scroll_layer->SetScrollable(gfx::Size(2, 2)); scroll_layer->SetBounds(gfx::Size(10, 10)); layer_tree_host_->UpdateLayers(); @@ -653,7 +641,6 @@ scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); - scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); scroll_layer->SetElementId(ElementId(200)); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<SolidColorScrollbarLayer> scrollbar_layer; @@ -732,7 +719,6 @@ scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); - scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> scrollbar_layer; const bool kIsLeftSideVerticalScrollbar = false; @@ -746,6 +732,7 @@ layer_tree_root->SetBounds(gfx::Size(2, 2)); scroll_layer->SetBounds(gfx::Size(10, 10)); + scroll_layer->SetScrollable(layer_tree_root->bounds()); layer_tree_host_->UpdateLayers(); LayerTreeHostImpl* host_impl = layer_tree_host_->host_impl(); host_impl->CreatePendingTree(); @@ -772,10 +759,7 @@ LayerTestCommon::LayerImplTest impl; - LayerImpl* clip_layer = impl.AddChildToRoot<LayerImpl>(); - LayerImpl* scroll_layer = impl.AddChild<LayerImpl>(clip_layer); - - scroll_layer->SetScrollClipLayer(clip_layer->id()); + LayerImpl* scroll_layer = impl.AddChildToRoot<LayerImpl>(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); const int kTrackStart = 0; @@ -789,7 +773,7 @@ kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); - clip_layer->SetBounds(gfx::Size(980, 980)); + scroll_layer->SetScrollable(gfx::Size(980, 980)); scroll_layer->SetBounds(gfx::Size(980, 980)); impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); @@ -835,32 +819,41 @@ scroll_layer, HORIZONTAL, kThumbThickness, kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - scroll_layer->SetScrollClipLayer(clip_layer->id()); - scroll_layer->SetScrollable(); - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + scroll_layer->SetBounds(gfx::Size(900, 900)); + // If the scroll layer is not scrollable, the bounds do not affect scrollbar + // geometries. + EXPECT_FALSE( + impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + + scroll_layer->SetScrollable(gfx::Size(900, 900)); + EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); clip_layer->SetBounds(gfx::Size(900, 900)); - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); - impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); + // The clip layer for scrolling is managed independently of the scroll + // container bounds so changing the clip does not require an update. + EXPECT_FALSE( + impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); scroll_layer->SetBounds(gfx::Size(980, 980)); - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + // Changes to the bounds should also require an update. + EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); clip_layer->SetViewportBoundsDelta(gfx::Vector2dF(1, 2)); - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); // Not changing the current value should not require an update. - scroll_layer->SetScrollClipLayer(clip_layer->id()); + scroll_layer->SetScrollable(gfx::Size(900, 900)); clip_layer->SetBounds(gfx::Size(900, 900)); scroll_layer->SetBounds(gfx::Size(980, 980)); clip_layer->SetViewportBoundsDelta(gfx::Vector2dF(1, 2)); - DCHECK(!impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + EXPECT_TRUE( + !impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); } class ScrollbarLayerSolidColorThumbTest : public testing::Test { @@ -909,8 +902,6 @@ horizontal_scrollbar_layer_->SetClipLayerLength(5.f); horizontal_scrollbar_layer_->SetScrollLayerLength(15.f); horizontal_scrollbar_layer_->SetBounds(gfx::Size(100, 3)); - DCHECK(host_impl_->active_tree()->ScrollbarGeometriesNeedUpdate()); - host_impl_->active_tree()->UpdateScrollbarGeometries(); EXPECT_EQ(33, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); // The thumb's length should never be less than its thickness. @@ -922,9 +913,6 @@ TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbPosition) { horizontal_scrollbar_layer_->SetBounds(gfx::Size(100, 3)); - DCHECK(host_impl_->active_tree()->ScrollbarGeometriesNeedUpdate()); - host_impl_->active_tree()->UpdateScrollbarGeometries(); - horizontal_scrollbar_layer_->SetCurrentPos(0.f); horizontal_scrollbar_layer_->SetClipLayerLength(12.f); horizontal_scrollbar_layer_->SetScrollLayerLength(112.f); @@ -953,9 +941,6 @@ layers[0]->SetBounds(gfx::Size(100, 3)); layers[1]->SetBounds(gfx::Size(3, 100)); - DCHECK(host_impl_->active_tree()->ScrollbarGeometriesNeedUpdate()); - host_impl_->active_tree()->UpdateScrollbarGeometries(); - EXPECT_EQ(gfx::Rect(20, 0, 20, 3), horizontal_scrollbar_layer_->ComputeThumbQuadRect()); EXPECT_EQ(gfx::Rect(0, 20, 3, 20), @@ -982,7 +967,6 @@ int expected_deleted, bool use_solid_color_scrollbar) { std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false)); - scoped_refptr<Layer> root_clip_layer = Layer::Create(); scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<Layer> scrollbar_layer; @@ -1004,7 +988,7 @@ scrollbar_layer->SetIsDrawable(true); scrollbar_layer->SetBounds(gfx::Size(100, 100)); - layer_tree_root->SetScrollClipLayerId(root_clip_layer->id()); + layer_tree_root->SetScrollable(gfx::Size(100, 200)); layer_tree_root->SetScrollOffset(gfx::ScrollOffset(10, 20)); layer_tree_root->SetBounds(gfx::Size(100, 200)); content_layer->SetBounds(gfx::Size(100, 200));
diff --git a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc index 4cff576..a2b24303 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc +++ b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
@@ -39,9 +39,6 @@ // SolidColorScrollbarLayers construct with opacity = 0.f, so override. scrollbar_layer_impl->test_properties()->opacity = 1.f; - DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); - impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - impl.CalcDrawProps(viewport_size); gfx::Rect thumb_rect = scrollbar_layer_impl->ComputeThumbQuadRect();
diff --git a/cc/test/layer_tree_json_parser.cc b/cc/test/layer_tree_json_parser.cc index 426bc6fe..8987791 100644 --- a/cc/test/layer_tree_json_parser.cc +++ b/cc/test/layer_tree_json_parser.cc
@@ -98,29 +98,6 @@ if (dict->GetBoolean("ContentsOpaque", &contents_opaque)) new_layer->SetContentsOpaque(contents_opaque); - bool scrollable; - // TODO(wjmaclean) At some time in the future we may wish to test that a - // reconstructed layer tree contains the correct linkage for the scroll - // clip layer. This is complicated by the fact that the json output doesn't - // (currently) re-construct the tree with the same layer IDs as the original. - // But, since a clip layer is always an ancestor of the scrollable layer, we - // can just count the number of upwards hops to the clip layer and write that - // into the json file (with 0 hops implying no clip layer, i.e. not - // scrollable). Reconstructing the tree can then be accomplished by passing - // the parent pointer to this function and traversing the same number of - // ancestors to determine the pointer to the clip layer. The LayerTreesMatch() - // function should then check that both original and reconstructed layers - // have the same positioning with respect to their clip layers. - // - // For now, we can safely indicate a layer is scrollable by giving it a - // pointer to itself, something not normally allowed in a working tree. - // - // https://code.google.com/p/chromium/issues/detail?id=330622 - // - if (dict->GetBoolean("Scrollable", &scrollable)) - new_layer->SetScrollClipLayerId(scrollable ? new_layer->id() - : Layer::INVALID_ID); - bool is_3d_sorted; if (dict->GetBoolean("Is3DSorted", &is_3d_sorted)) { // A non-zero context ID will put the layer into a 3D sorting context
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 14666f6..c3b179f 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -57,18 +57,16 @@ inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer); outer_viewport_container_layer->AddChild(outer_scroll_layer); - inner_viewport_scroll_layer->SetScrollClipLayerId( - inner_viewport_container_layer->id()); inner_viewport_scroll_layer->SetElementId( LayerIdToElementIdForTesting(inner_viewport_scroll_layer->id())); - outer_scroll_layer->SetScrollClipLayerId( - outer_viewport_container_layer->id()); outer_scroll_layer->SetElementId( LayerIdToElementIdForTesting(outer_scroll_layer->id())); inner_viewport_container_layer->SetBounds(inner_bounds); + inner_viewport_scroll_layer->SetScrollable(inner_bounds); inner_viewport_scroll_layer->SetBounds(outer_bounds); outer_viewport_container_layer->SetBounds(outer_bounds); + outer_scroll_layer->SetScrollable(outer_bounds); inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); outer_scroll_layer->SetIsContainerForFixedPositionLayers(true);
diff --git a/cc/test/test_layer_tree_host_base.cc b/cc/test/test_layer_tree_host_base.cc index a252a59..76aa612 100644 --- a/cc/test/test_layer_tree_host_base.cc +++ b/cc/test/test_layer_tree_host_base.cc
@@ -115,7 +115,7 @@ if (!tile_size.IsEmpty()) pending_layer->set_fixed_tile_size(tile_size); pending_layer->SetDrawsContent(true); - pending_layer->SetScrollClipLayer(new_pending_root->id()); + pending_layer->SetScrollable(gfx::Size(1, 1)); pending_root = new_pending_root.get(); pending_tree->SetRootLayerForTesting(std::move(new_pending_root)); } else {
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 7578582..d9de4290f 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -735,23 +735,6 @@ } } -static void UpdateScrollTree(ScrollTree* scroll_tree, - const LayerTreeHost* layer_tree_host) { - if (!scroll_tree->needs_update()) - return; - - for (int i = ScrollTree::kRootNodeId; - i < static_cast<int>(scroll_tree->size()); ++i) { - ScrollNode* scroll_node = scroll_tree->Node(i); - if (Layer* scroll_layer = - layer_tree_host->LayerById(scroll_node->owning_layer_id)) { - if (Layer* scroll_clip_layer = scroll_layer->scroll_clip_layer()) { - scroll_node->scroll_clip_layer_bounds = scroll_clip_layer->bounds(); - } - } - } -} - static void ComputeClips(PropertyTrees* property_trees) { DCHECK(!property_trees->transform_tree.needs_update()); ClipTree* clip_tree = &property_trees->clip_tree; @@ -886,7 +869,6 @@ property_trees->clip_tree.set_needs_update(true); property_trees->effect_tree.set_needs_update(true); } - UpdateScrollTree(&property_trees->scroll_tree, layer_tree_host); ComputeTransforms(&property_trees->transform_tree); ComputeEffects(&property_trees->effect_tree); // Computation of clips uses ToScreen which is updated while computing
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 1fe36ba..f7210f02 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -537,30 +537,23 @@ LayerImpl::Create(host_impl.active_tree(), 2)); LayerImpl* scroll_layer = scroll_layer_scoped_ptr.get(); scroll_layer->SetBounds(gfx::Size(10, 20)); - std::unique_ptr<LayerImpl> clip_layer_scoped_ptr( - LayerImpl::Create(host_impl.active_tree(), 4)); - LayerImpl* clip_layer = clip_layer_scoped_ptr.get(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); - scroll_layer->SetScrollClipLayer(clip_layer->id()); - clip_layer->SetBounds( + scroll_layer->SetScrollable( gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(), scroll_layer->bounds().height() + kMaxScrollOffset.y())); - scroll_layer->SetScrollClipLayer(clip_layer->id()); SetScrollOffsetDelta(scroll_layer, kScrollDelta); gfx::Transform impl_transform; scroll_layer->test_properties()->AddChild(std::move(sublayer_scoped_ptr)); - LayerImpl* scroll_layer_raw_ptr = scroll_layer_scoped_ptr.get(); - clip_layer->test_properties()->AddChild(std::move(scroll_layer_scoped_ptr)); - scroll_layer_raw_ptr->layer_tree_impl() + scroll_layer_scoped_ptr->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer_raw_ptr->element_id(), kScrollOffset); + scroll_layer_scoped_ptr->element_id(), kScrollOffset); std::unique_ptr<LayerImpl> root( LayerImpl::Create(host_impl.active_tree(), 3)); root->SetBounds(gfx::Size(3, 4)); - root->test_properties()->AddChild(std::move(clip_layer_scoped_ptr)); + root->test_properties()->AddChild(std::move(scroll_layer_scoped_ptr)); LayerImpl* root_layer = root.get(); host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); @@ -1169,7 +1162,6 @@ root->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); child->SetDrawsContent(true); - child->SetScrollClipLayer(root->id()); child->SetBounds(gfx::Size(100, 100)); child->SetMasksToBounds(true); @@ -5322,7 +5314,7 @@ intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); - intervening->SetScrollClipLayer(clip_parent->id()); + intervening->SetScrollable(gfx::Size(1, 1)); intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id())); intervening->SetCurrentScrollOffset(gfx::ScrollOffset(3, 3)); @@ -6108,7 +6100,6 @@ fixed->test_properties()->position_constraint = constraint; scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayer(container->id()); gfx::Transform container_transform; container_transform.Translate3d(10.0, 20.0, 0.0); @@ -6119,6 +6110,7 @@ container->SetBounds(gfx::Size(40, 40)); container->SetDrawsContent(true); scroller->SetBounds(gfx::Size(30, 30)); + scroller->SetScrollable(container->bounds()); scroller->SetDrawsContent(true); fixed->SetBounds(gfx::Size(50, 50)); fixed->SetDrawsContent(true); @@ -6232,7 +6224,7 @@ container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(100, 100)); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayer(container->id()); + scroller->SetScrollable(container->bounds()); scroller->SetDrawsContent(true); gfx::Transform end_scale; @@ -6275,7 +6267,6 @@ host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); scroll_child->SetScrollParent(scroller.get()); gfx::Transform rotate; @@ -6283,6 +6274,7 @@ root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(container->bounds()); scroller->SetPosition(gfx::PointF(10.3f, 10.3f)); scroll_child->SetBounds(gfx::Size(10, 10)); scroll_child->SetTransform(rotate); @@ -6323,7 +6315,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6338,6 +6329,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(10, 20)); @@ -6396,7 +6388,6 @@ sticky_pos->SetScrollParent(scroller.get()); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); // The sticky layer has already been scrolled on the main thread side, and has // stuck. This test then checks that further changes from cc-only scrolling @@ -6415,6 +6406,7 @@ container->SetBounds(gfx::Size(100, 100)); container->SetPosition(gfx::PointF(50, 50)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(60, 70)); @@ -6472,7 +6464,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6487,6 +6478,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 200)); @@ -6518,7 +6510,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6533,6 +6524,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 150)); @@ -6586,7 +6578,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(root->id()); LayerTreeHost::ViewportLayers viewport_layers; viewport_layers.page_scale = root; viewport_layers.inner_viewport_container = root; @@ -6604,6 +6595,7 @@ sticky_pos->SetStickyPositionConstraint(sticky_position); root->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 70)); @@ -6662,8 +6654,6 @@ outer_viewport->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(root->id()); - outer_viewport->SetScrollClipLayerId(outer_clip->id()); LayerTreeHost::ViewportLayers viewport_layers; viewport_layers.page_scale = root; viewport_layers.inner_viewport_container = root; @@ -6683,8 +6673,10 @@ sticky_pos->SetStickyPositionConstraint(sticky_position); root->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); outer_clip->SetBounds(gfx::Size(100, 100)); + outer_viewport->SetScrollable(gfx::Size(100, 100)); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 70)); @@ -6745,7 +6737,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6762,6 +6753,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(145, 0)); @@ -6850,7 +6842,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6865,6 +6856,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(10, 20)); @@ -6943,7 +6935,6 @@ sticky_container->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6958,6 +6949,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_container->SetPosition(gfx::PointF(20, 20)); sticky_container->SetBounds(gfx::Size(30, 30)); sticky_pos->SetBounds(gfx::Size(10, 10)); @@ -7041,7 +7033,6 @@ scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); gfx::Transform t; t.Scale(2, 2); sticky_pos->SetTransform(t); @@ -7059,6 +7050,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 20)); @@ -7120,7 +7112,6 @@ sticky_container->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); gfx::Transform t; t.Scale(2, 2); sticky_container->SetTransform(t); @@ -7138,6 +7129,7 @@ root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_container->SetBounds(gfx::Size(50, 50)); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 20)); @@ -7199,11 +7191,11 @@ outer_sticky->AddChild(inner_sticky); host()->SetRootLayer(root); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); + scroller->SetScrollable(container->bounds()); outer_sticky->SetBounds(gfx::Size(10, 50)); outer_sticky->SetPosition(gfx::PointF(0, 50)); inner_sticky->SetBounds(gfx::Size(10, 10)); @@ -7300,12 +7292,12 @@ LayerPositionConstraint fixed_position; fixed_position.set_is_fixed_position(true); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); fixed_pos->SetPositionConstraint(fixed_position); root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(50, 50)); + scroller->SetScrollable(container->bounds()); fixed_pos->SetBounds(gfx::Size(50, 50)); gfx::Transform rotate; @@ -7345,12 +7337,12 @@ LayerPositionConstraint fixed_position; fixed_position.set_is_fixed_position(true); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayerId(container->id()); fixed_pos->SetPositionConstraint(fixed_position); root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(container->bounds()); scroller->SetPosition(gfx::PointF(10.3f, 10.3f)); fixed_pos->SetBounds(gfx::Size(10, 10)); @@ -8212,11 +8204,6 @@ inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer); outer_viewport_container_layer->AddChild(outer_viewport_scroll_layer); - inner_viewport_scroll_layer->SetScrollClipLayerId( - inner_viewport_container_layer->id()); - outer_viewport_scroll_layer->SetScrollClipLayerId( - outer_viewport_container_layer->id()); - inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); @@ -8592,7 +8579,7 @@ scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); scroller->SetCurrentScrollOffset(gfx::ScrollOffset(100, 100)); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollClipLayer(frame_clip->id()); + scroller->SetScrollable(frame_clip->bounds()); scroller->SetDrawsContent(true); fixed->SetPosition(gfx::PointF(100, 100)); fixed->SetBounds(gfx::Size(50, 50)); @@ -8943,7 +8930,6 @@ player.get()); player->AddAnimation(std::move(transform_animation)); grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - child_ptr->SetScrollClipLayer(root_ptr->id()); root_ptr->test_properties()->transform = singular; child_ptr->test_properties()->transform = singular; root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; @@ -9749,7 +9735,6 @@ scroll_parent->test_properties()->scroll_children = base::MakeUnique<std::set<LayerImpl*>>(); scroll_parent->test_properties()->scroll_children->insert(scroll_child); - scroll_parent->SetScrollClipLayer(scroll_clip->id()); scroll_parent->SetDrawsContent(true); scroll_child->SetDrawsContent(true); @@ -10037,22 +10022,25 @@ child9->AddChild(grand_child12); host()->SetRootLayer(root1); + root1->SetBounds(gfx::Size(1, 1)); parent2->AddMainThreadScrollingReasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); parent2->AddMainThreadScrollingReasons( MainThreadScrollingReason::kScrollbarScrolling); parent2->SetElementId(LayerIdToElementIdForTesting(parent2->id())); - parent2->SetScrollClipLayerId(root1->id()); + parent2->SetScrollable(root1->bounds()); child6->AddMainThreadScrollingReasons( MainThreadScrollingReason::kScrollbarScrolling); grand_child10->AddMainThreadScrollingReasons( MainThreadScrollingReason::kScrollbarScrolling); - child7->SetScrollClipLayerId(parent3->id()); + parent3->SetBounds(gfx::Size(2, 2)); + child7->SetScrollable(parent3->bounds()); child7->SetElementId(LayerIdToElementIdForTesting(child7->id())); child8->SetScrollParent(child7.get()); - grand_child11->SetScrollClipLayerId(parent3->id()); + child8->SetBounds(gfx::Size(3, 3)); + grand_child11->SetScrollable(child8->bounds()); grand_child11->SetElementId( LayerIdToElementIdForTesting(grand_child11->id())); @@ -10087,6 +10075,7 @@ // The node owned by root1 ScrollNode scroll_root1; scroll_root1.id = 1; + scroll_root1.bounds = root1->bounds(); scroll_root1.owning_layer_id = root1->id(); scroll_root1.user_scrollable_horizontal = true; scroll_root1.user_scrollable_vertical = true; @@ -10141,6 +10130,7 @@ scroll_grand_child11.owning_layer_id = grand_child11->id(); scroll_grand_child11.element_id = grand_child11->element_id(); scroll_grand_child11.scrollable = true; + scroll_grand_child11.scroll_clip_layer_bounds = child8->bounds(); scroll_grand_child11.user_scrollable_horizontal = true; scroll_grand_child11.user_scrollable_vertical = true; scroll_grand_child11.transform_id = grand_child11->transform_tree_index();
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 1aa17af9..3e781b3 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -2017,6 +2017,10 @@ return !!InnerViewportScrollLayer(); } +LayerImpl* LayerTreeHostImpl::InnerViewportContainerLayer() const { + return active_tree_->InnerViewportContainerLayer(); +} + LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { return active_tree_->InnerViewportScrollLayer(); } @@ -2029,6 +2033,10 @@ return scroll_tree.Node(inner_viewport_scroll_layer->scroll_tree_index()); } +LayerImpl* LayerTreeHostImpl::OuterViewportContainerLayer() const { + return active_tree_->OuterViewportContainerLayer(); +} + LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { return active_tree_->OuterViewportScrollLayer(); }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 8c765ef..b5510a6 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -439,8 +439,10 @@ virtual void ActivateSyncTree(); // Shortcuts to layers/nodes on the active tree. + LayerImpl* InnerViewportContainerLayer() const; LayerImpl* InnerViewportScrollLayer() const; ScrollNode* InnerViewportScrollNode() const; + LayerImpl* OuterViewportContainerLayer() const; LayerImpl* OuterViewportScrollLayer() const; ScrollNode* OuterViewportScrollNode() const; ScrollNode* CurrentlyScrollingNode();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index f37061a..9f362a34 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -339,13 +339,14 @@ std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); - inner_clip->SetBounds( - gfx::Size(content_size.width() / 2, content_size.height() / 2)); + gfx::Size viewport_scroll_bounds = + gfx::Size(content_size.width() / 2, content_size.height() / 2); + inner_clip->SetBounds(viewport_scroll_bounds); std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - inner_scroll->SetScrollClipLayer(inner_clip->id()); + inner_scroll->SetScrollable(viewport_scroll_bounds); inner_scroll->SetElementId( LayerIdToElementIdForTesting(inner_scroll->id())); inner_scroll->SetBounds(content_size); @@ -359,7 +360,7 @@ std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetScrollable(content_size); outer_scroll->SetElementId( LayerIdToElementIdForTesting(outer_scroll->id())); outer_scroll->layer_tree_impl() @@ -414,13 +415,9 @@ root->SetBounds(content_size); root->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); scroll->SetBounds(scroll_content_size); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); @@ -451,10 +448,9 @@ squash2->SetDrawsContent(true); scroll->test_properties()->AddChild(std::move(squash2)); - clip->test_properties()->AddChild(std::move(scroll)); - clip->test_properties()->AddChild(std::move(scrollbar)); - clip->test_properties()->AddChild(std::move(squash1)); - root->test_properties()->AddChild(std::move(clip)); + root->test_properties()->AddChild(std::move(scroll)); + root->test_properties()->AddChild(std::move(scrollbar)); + root->test_properties()->AddChild(std::move(squash1)); layer_tree_impl->SetRootLayerForTesting(std::move(root)); layer_tree_impl->BuildPropertyTreesForTesting(); @@ -496,6 +492,7 @@ ->children.back(); content_layer->SetBounds(content_size); host_impl_->OuterViewportScrollLayer()->SetBounds(content_size); + host_impl_->OuterViewportScrollLayer()->SetScrollable(viewport_size); LayerImpl* outer_clip = host_impl_->OuterViewportScrollLayer()->test_properties()->parent; @@ -507,6 +504,7 @@ ->parent; inner_clip_layer->SetBounds(viewport_size); host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size); + host_impl_->InnerViewportScrollLayer()->SetScrollable(viewport_size); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -517,17 +515,15 @@ } std::unique_ptr<LayerImpl> CreateScrollableLayer(int id, - const gfx::Size& size, - LayerImpl* clip_layer) { - DCHECK(clip_layer); - DCHECK(id != clip_layer->id()); + const gfx::Size& size) { std::unique_ptr<LayerImpl> layer = LayerImpl::Create(host_impl_->active_tree(), id); - layer->SetScrollClipLayer(clip_layer->id()); layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); layer->SetDrawsContent(true); layer->SetBounds(size); - clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2)); + gfx::Size scroll_container_bounds = + gfx::Size(size.width() / 2, size.height() / 2); + layer->SetScrollable(scroll_container_bounds); return layer; } @@ -809,21 +805,17 @@ gfx::ScrollOffset scroll_offset(20, 30); gfx::Vector2d scroll_delta(11, -15); - auto root_clip_owned = LayerImpl::Create(host_impl_->active_tree(), 2); - auto* root_clip = root_clip_owned.get(); auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); auto* root = root_owned.get(); - root_clip->SetBounds(gfx::Size(10, 10)); - root_clip->test_properties()->AddChild(std::move(root_owned)); root->SetBounds(gfx::Size(110, 110)); - root->SetScrollClipLayer(root_clip->id()); + root->SetScrollable(gfx::Size(10, 10)); root->SetElementId(LayerIdToElementIdForTesting(root->id())); root->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->element_id(), scroll_offset); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip_owned)); + host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -857,20 +849,14 @@ int id = outer_viewport_scroll_layer->id(); std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), id + 2); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), id + 3); - child_clip->SetBounds(gfx::Size(100, 100)); - - child->SetScrollClipLayer(child_clip->id()); + child->SetScrollable(gfx::Size(100, 100)); child->SetElementId(LayerIdToElementIdForTesting(child->id())); child->SetBounds(gfx::Size(100, 400)); child->SetPosition(gfx::PointF()); child->SetDrawsContent(true); - child_clip->test_properties()->AddChild(std::move(child)); - outer_viewport_scroll_layer->test_properties()->AddChild( - std::move(child_clip)); + outer_viewport_scroll_layer->test_properties()->AddChild(std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); base::HistogramTester histogram_tester; @@ -1196,13 +1182,9 @@ root->SetBounds(content_size); root->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); scroll->SetBounds(scroll_content_size); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); @@ -1222,8 +1204,7 @@ scroll->test_properties()->AddChild(std::move(drawn_scrollbar)); scroll->test_properties()->AddChild(std::move(squash)); - clip->test_properties()->AddChild(std::move(scroll)); - root->test_properties()->AddChild(std::move(clip)); + root->test_properties()->AddChild(std::move(scroll)); layer_tree_impl->SetRootLayerForTesting(std::move(root)); layer_tree_impl->BuildPropertyTreesForTesting(); @@ -1446,8 +1427,7 @@ ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); LayerImpl* overflow = scroll_layer->test_properties()->children[0]; overflow->SetBounds(overflow_size); - overflow->SetScrollClipLayer( - scroll_layer->test_properties()->parent->test_properties()->parent->id()); + overflow->SetScrollable(gfx::Size(100, 100)); overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); overflow->layer_tree_impl() ->property_trees() @@ -1763,7 +1743,7 @@ DrawFrame(); EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); - LayerImpl* container_layer = scroll_layer->scroll_clip_layer(); + LayerImpl* container_layer = host_impl_->InnerViewportContainerLayer(); EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); float min_page_scale = 1.f, max_page_scale = 4.f; @@ -2165,19 +2145,15 @@ LayerImpl* child; LayerImpl* child_clip; - std::unique_ptr<LayerImpl> scroll_parent_clip = - LayerImpl::Create(host_impl_->active_tree(), 6); std::unique_ptr<LayerImpl> scroll_parent = - CreateScrollableLayer(7, gfx::Size(10, 10), scroll_parent_clip.get()); + CreateScrollableLayer(7, gfx::Size(10, 10)); parent = scroll_parent.get(); - scroll_parent_clip->test_properties()->AddChild(std::move(scroll_parent)); - - viewport_scroll->test_properties()->AddChild(std::move(scroll_parent_clip)); + viewport_scroll->test_properties()->AddChild(std::move(scroll_parent)); std::unique_ptr<LayerImpl> scroll_child_clip = LayerImpl::Create(host_impl_->active_tree(), 8); std::unique_ptr<LayerImpl> scroll_child = - CreateScrollableLayer(9, gfx::Size(10, 10), scroll_child_clip.get()); + CreateScrollableLayer(9, gfx::Size(10, 10)); child = scroll_child.get(); scroll_child->SetPosition(gfx::PointF(20.f, 20.f)); scroll_child_clip->test_properties()->AddChild(std::move(scroll_child)); @@ -2791,7 +2767,7 @@ DrawFrame(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - LayerImpl* inner_container = inner_scroll->scroll_clip_layer(); + LayerImpl* inner_container = host_impl_->InnerViewportContainerLayer(); DCHECK(inner_scroll); DCHECK(inner_container); EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset()); @@ -3232,14 +3208,17 @@ gfx::Size content_size(1000, 1000); const int horiz_id = 11; - const int child_clip_id = 14; const int child_scroll_id = 15; CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( inner_viewport_size); + host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( + inner_viewport_size); host_impl_->active_tree()->OuterViewportContainerLayer()->SetBounds( outer_viewport_size); + host_impl_->active_tree()->OuterViewportScrollLayer()->SetScrollable( + outer_viewport_size); LayerImpl* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar = @@ -3248,8 +3227,6 @@ std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); child->SetBounds(content_size); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(inner_viewport_size); horiz_scrollbar->SetScrollElementId(root_scroll->element_id()); @@ -3274,7 +3251,6 @@ const int horiz_1_id = 11; const int vert_2_id = 12; const int horiz_2_id = 13; - const int child_clip_id = 14; const int child_scroll_id = 15; CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); @@ -3306,12 +3282,8 @@ std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->SetBounds(content_size); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(viewport_size); LayerImpl* child_ptr = child.get(); - LayerImpl* child_clip_ptr = child_clip.get(); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -3337,11 +3309,10 @@ animation_task_ = base::Closure(); // Check scrollbar registration on a sublayer. - child->SetScrollClipLayer(child_clip->id()); + child->SetScrollable(viewport_size); child->SetElementId(LayerIdToElementIdForTesting(child->id())); ElementId child_scroll_element_id = child->element_id(); - child_clip->test_properties()->AddChild(std::move(child)); - root_scroll->test_properties()->AddChild(std::move(child_clip)); + root_scroll->test_properties()->AddChild(std::move(child)); EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( child_scroll_element_id)); @@ -3357,7 +3328,7 @@ // Changing one of the child layers should result in a scrollbar animation // update. animation_task_ = base::Closure(); - child_clip_ptr->SetBounds(gfx::Size(200, 200)); + child_ptr->SetBounds(gfx::Size(200, 200)); child_ptr->set_needs_show_scrollbars(true); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); @@ -4229,7 +4200,6 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetScrollClipLayer(Layer::INVALID_ID); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -4325,7 +4295,7 @@ std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5); root_clip->SetBounds(inner_viewport_size); - root->SetScrollClipLayer(root_clip->id()); + root->SetScrollable(inner_viewport_size); root->SetElementId(LayerIdToElementIdForTesting(root->id())); root->SetBounds(outer_viewport_size); root->SetPosition(gfx::PointF()); @@ -4333,7 +4303,7 @@ root_clip->test_properties()->force_render_surface = true; root->test_properties()->is_container_for_fixed_position_layers = true; outer_clip->SetBounds(outer_viewport_size); - outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetScrollable(outer_viewport_size); outer_scroll->SetElementId( LayerIdToElementIdForTesting(outer_scroll->id())); outer_scroll->SetBounds(scroll_layer_size); @@ -4778,14 +4748,10 @@ LayerImpl* outer_viewport_scroll_layer = host_impl_->active_tree()->OuterViewportScrollLayer(); int id = outer_viewport_scroll_layer->id(); - std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), id + 2); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), id + 3); - child_clip->SetBounds(sub_content_layer_size); - child->SetScrollClipLayer(child_clip->id()); + child->SetScrollable(sub_content_layer_size); child->SetElementId(LayerIdToElementIdForTesting(child->id())); child->SetBounds(sub_content_size); child->SetPosition(gfx::PointF()); @@ -4794,9 +4760,7 @@ // scroll child to limit SetScrollOffsetDelta(child.get(), gfx::Vector2dF(0, 100.f)); - child_clip->test_properties()->AddChild(std::move(child)); - outer_viewport_scroll_layer->test_properties()->AddChild( - std::move(child_clip)); + outer_viewport_scroll_layer->test_properties()->AddChild(std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); // Scroll 25px to hide browser controls @@ -5329,19 +5293,19 @@ content_layer->SetPosition(gfx::PointF()); content_layer->SetBounds(contents_size); - LayerImpl* scroll_clip_layer = + LayerImpl* scroll_container_layer = CreateBasicVirtualViewportLayers(surface_size, surface_size); std::unique_ptr<LayerImpl> scroll_layer = LayerImpl::Create(host_impl_->active_tree(), 12); - scroll_layer->SetScrollClipLayer(scroll_clip_layer->id()); + scroll_layer->SetScrollable(surface_size); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); scroll_layer->SetBounds(contents_size); scroll_layer->SetPosition(gfx::PointF()); scroll_layer->test_properties()->AddChild(std::move(content_layer)); - scroll_clip_layer->test_properties()->AddChild(std::move(scroll_layer)); + scroll_container_layer->test_properties()->AddChild(std::move(scroll_layer)); - scroll_clip_layer->test_properties()->force_render_surface = true; + scroll_container_layer->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(surface_size); @@ -5365,8 +5329,7 @@ LayerImpl* root = CreateBasicVirtualViewportLayers(surface_size, surface_size); - root->test_properties()->AddChild( - CreateScrollableLayer(12, contents_size, root)); + root->test_properties()->AddChild(CreateScrollableLayer(12, contents_size)); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -5388,8 +5351,7 @@ gfx::Size surface_size(10, 10); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->AddChild( - CreateScrollableLayer(2, surface_size, root.get())); + root->test_properties()->AddChild(CreateScrollableLayer(2, surface_size)); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -5414,8 +5376,7 @@ std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, surface_size, root.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); gfx::Transform matrix; matrix.RotateAboutXAxis(180.0); @@ -5443,23 +5404,17 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> clip_layer = - LayerImpl::Create(host_impl_->active_tree(), 3); std::unique_ptr<LayerImpl> content_layer = - CreateScrollableLayer(1, surface_size, clip_layer.get()); + CreateScrollableLayer(1, surface_size); content_layer->set_main_thread_scrolling_reasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); - content_layer->SetScrollClipLayer(Layer::INVALID_ID); // Note: we can use the same clip layer for both since both calls to // CreateScrollableLayer() use the same surface size. std::unique_ptr<LayerImpl> scroll_layer = - CreateScrollableLayer(2, surface_size, clip_layer.get()); + CreateScrollableLayer(2, surface_size); scroll_layer->test_properties()->AddChild(std::move(content_layer)); - clip_layer->test_properties()->AddChild(std::move(scroll_layer)); - clip_layer->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(clip_layer)); + host_impl_->active_tree()->SetRootLayerForTesting(std::move(scroll_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(surface_size); @@ -5481,23 +5436,18 @@ SetupScrollAndContentsLayers(viewport_size); // Setup the layers so that the outer viewport is scrollable. - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->parent->SetBounds(viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds( - gfx::Size(40, 40)); + host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( + viewport_size); + host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); DrawFrame(); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); - EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds()); + LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); + EXPECT_EQ(viewport_size, root_container->bounds()); gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; + LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -5512,6 +5462,7 @@ std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); @@ -5530,25 +5481,20 @@ SetupScrollAndContentsLayers(viewport_size); // Setup the layers so that the outer viewport is scrollable. - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->parent->SetBounds(viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds( - gfx::Size(40, 40)); + host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( + viewport_size); + host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); - EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds()); + LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); + EXPECT_EQ(viewport_size, root_container->bounds()); gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; + LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -5571,6 +5517,7 @@ // The scroll delta is not scaled because the main thread did not scale. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); @@ -5602,7 +5549,7 @@ std::unique_ptr<LayerImpl> scrollable_child_clip = LayerImpl::Create(host_impl_->active_tree(), 6); std::unique_ptr<LayerImpl> scrollable_child = - CreateScrollableLayer(7, surface_size, scrollable_child_clip.get()); + CreateScrollableLayer(7, surface_size); scrollable_child_clip->test_properties()->AddChild( std::move(scrollable_child)); child->test_properties()->AddChild(std::move(scrollable_child_clip)); @@ -5692,10 +5639,9 @@ root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size, root); + CreateScrollableLayer(13, content_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(12, content_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -5758,10 +5704,9 @@ root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size, root); + CreateScrollableLayer(13, content_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(12, content_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -5856,23 +5801,21 @@ std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), kViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scrolling = CreateScrollableLayer( - kViewportScrollLayerId, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scrolling = + CreateScrollableLayer(kViewportScrollLayerId, surface_size); root_scrolling->test_properties()->is_container_for_fixed_position_layers = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(5, surface_size, root_clip.get()); + CreateScrollableLayer(5, surface_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(4, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(4, surface_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); LayerImpl* child_layer = child.get(); root_scrolling->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scrolling)); - EXPECT_EQ(viewport_size, root_clip->bounds()); root_ptr->test_properties()->AddChild(std::move(root_clip)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -6007,14 +5950,15 @@ std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer( - kViewportClipLayerId, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scroll = + CreateScrollableLayer(kViewportClipLayerId, content_size); // Make 'root' the clip layer for child: since they have the same sizes the // child will have zero max_scroll_offset and scrolls will bubble. - std::unique_ptr<LayerImpl> child = CreateScrollableLayer( - kViewportScrollLayerId, content_size, root_scroll.get()); + std::unique_ptr<LayerImpl> child = + CreateScrollableLayer(kViewportScrollLayerId, content_size); child->test_properties()->is_container_for_fixed_position_layers = true; root_scroll->SetBounds(content_size); + child->SetScrollable(content_size); ElementId root_scroll_id = root_scroll->element_id(); root_scroll->test_properties()->AddChild(std::move(child)); @@ -6063,12 +6007,12 @@ LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); - std::unique_ptr<LayerImpl> inner_scroll = CreateScrollableLayer( - kInnerViewportScrollLayerId, surface_size, inner_clip.get()); + std::unique_ptr<LayerImpl> inner_scroll = + CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId); - std::unique_ptr<LayerImpl> outer_scroll = CreateScrollableLayer( - kOuterViewportScrollLayerId, surface_size, outer_clip.get()); + std::unique_ptr<LayerImpl> outer_scroll = + CreateScrollableLayer(kOuterViewportScrollLayerId, surface_size); inner_clip->test_properties()->force_render_surface = true; inner_scroll->test_properties()->is_container_for_fixed_position_layers = true; @@ -6105,12 +6049,12 @@ LayerImpl::Create(host_impl_->active_tree(), 4); std::unique_ptr<LayerImpl> inner_clip2 = LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId2); - std::unique_ptr<LayerImpl> inner_scroll2 = CreateScrollableLayer( - kInnerViewportScrollLayerId2, surface_size, inner_clip2.get()); + std::unique_ptr<LayerImpl> inner_scroll2 = + CreateScrollableLayer(kInnerViewportScrollLayerId2, surface_size); std::unique_ptr<LayerImpl> outer_clip2 = LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId2); - std::unique_ptr<LayerImpl> outer_scroll2 = CreateScrollableLayer( - kOuterViewportScrollLayerId2, surface_size, outer_clip2.get()); + std::unique_ptr<LayerImpl> outer_scroll2 = + CreateScrollableLayer(kOuterViewportScrollLayerId2, surface_size); inner_scroll2->test_properties()->is_container_for_fixed_position_layers = true; outer_scroll2->test_properties()->is_container_for_fixed_position_layers = @@ -6198,8 +6142,8 @@ // Create a child layer that is rotated to a non-axis-aligned angle. std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer( - child_layer_id, scroll_layer->bounds(), clip_layer.get()); + std::unique_ptr<LayerImpl> child = + CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); gfx::Transform rotate_transform; rotate_transform.Translate(-50.0, -50.0); rotate_transform.Rotate(child_layer_angle); @@ -6207,8 +6151,10 @@ clip_layer->test_properties()->transform = rotate_transform; // Only allow vertical scrolling. - clip_layer->SetBounds( - gfx::Size(child->bounds().width(), child->bounds().height() / 2)); + gfx::Size scroll_container_bounds = + gfx::Size(child->bounds().width(), child->bounds().height() / 2); + clip_layer->SetBounds(scroll_container_bounds); + child->SetScrollable(scroll_container_bounds); // The rotation depends on the layer's transform origin, and the child layer // is a different size than the clip, so make sure the clip layer's origin // lines up over the child. @@ -6216,6 +6162,7 @@ clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f); LayerImpl* child_ptr = child.get(); clip_layer->test_properties()->AddChild(std::move(child)); + // TODO(pdr): Shouldn't clip_layer be scroll_layer's parent? scroll_layer->test_properties()->AddChild(std::move(clip_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -6286,8 +6233,8 @@ // Create a child layer that is rotated on its x axis, with perspective. std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer( - child_layer_id, scroll_layer->bounds(), clip_layer.get()); + std::unique_ptr<LayerImpl> child = + CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); LayerImpl* child_ptr = child.get(); gfx::Transform perspective_transform; perspective_transform.Translate(-50.0, -50.0); @@ -6411,8 +6358,11 @@ int height = 20; int scale = 3; SetupScrollAndContentsLayers(gfx::Size(width, height)); + gfx::Size container_bounds = gfx::Size(width * scale - 1, height * scale); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - gfx::Size(width * scale - 1, height * scale)); + container_bounds); + host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( + container_bounds); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetDeviceScaleFactor(scale); @@ -6431,6 +6381,7 @@ LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; clip_layer->SetBounds(gfx::Size(10, 20)); + scroll_layer->SetScrollable(gfx::Size(10, 20)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->BindToClient(&scroll_watcher, false); @@ -6543,6 +6494,7 @@ LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; clip_layer->SetBounds(gfx::Size(10, 20)); + scroll_layer->SetScrollable(gfx::Size(10, 20)); scroll_layer->SetDrawsContent(true); // Draw first frame to clear any pending draws and check scroll. @@ -6705,14 +6657,13 @@ LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root = CreateScrollableLayer( - kInnerViewportScrollLayerId, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> root = + CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(3, surface_size, root_clip.get()); + CreateScrollableLayer(3, surface_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -6845,6 +6796,7 @@ scroll_layer->test_properties()->parent->test_properties()->parent; clip_layer->SetBounds(gfx::Size(50, 50)); + scroll_layer->SetScrollable(gfx::Size(50, 50)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(gfx::Size(50, 50)); @@ -7002,20 +6954,15 @@ // passing through the outer viewport still scroll correctly and affect // browser controls. { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(viewport_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(viewport_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); scroll_layer = scroll.get(); - clip->test_properties()->AddChild(std::move(scroll)); - inner_scroll_layer->test_properties()->AddChild(std::move(clip)); + inner_scroll_layer->test_properties()->AddChild(std::move(scroll)); // Move the outer viewport layer away so that scrolls won't target it. host_impl_->active_tree()->OuterViewportContainerLayer()->SetPosition( @@ -7093,35 +7040,23 @@ // with another scrolling div inside it. Set the outer "div" to be the outer // viewport. { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); - std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 12); - clip2->SetBounds(gfx::Size(300, 300)); - clip2->SetPosition(gfx::PointF()); - clip2->SetDrawsContent(true); - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13); scroll2->SetBounds(gfx::Size(500, 500)); - scroll2->SetScrollClipLayer(clip2->id()); + scroll2->SetScrollable(gfx::Size(300, 300)); scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); scroll2->SetDrawsContent(true); scroll_layer = scroll.get(); child_scroll_layer = scroll2.get(); - clip2->test_properties()->AddChild(std::move(scroll2)); - scroll->test_properties()->AddChild(std::move(clip2)); - - clip->test_properties()->AddChild(std::move(scroll)); - content_layer->test_properties()->AddChild(std::move(clip)); + scroll->test_properties()->AddChild(std::move(scroll2)); + content_layer->test_properties()->AddChild(std::move(scroll)); LayerTreeImpl::ViewportLayerIds viewport_ids; viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); viewport_ids.inner_viewport_scroll = inner_scroll_layer->id(); @@ -7228,36 +7163,26 @@ // set as the outer viewport. Add a sibling scrolling layer that isn't a child // of the outer viewport scroll layer. { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF(100, 100)); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(gfx::Size(1200, 1200)); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); outer_scroll_layer = scroll.get(); - clip->test_properties()->AddChild(std::move(scroll)); - content_layer->test_properties()->AddChild(std::move(clip)); + content_layer->test_properties()->AddChild(std::move(scroll)); // Create the non-descendant. - std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 14); - clip2->SetBounds(gfx::Size(600, 600)); - clip2->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 15); scroll2->SetBounds(gfx::Size(1200, 1200)); - scroll2->SetScrollClipLayer(clip2->id()); + scroll2->SetScrollable(gfx::Size(600, 600)); scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); scroll2->SetDrawsContent(true); sibling_scroll_layer = scroll2.get(); - clip2->test_properties()->AddChild(std::move(scroll2)); - content_layer->test_properties()->AddChild(std::move(clip2)); + content_layer->test_properties()->AddChild(std::move(scroll2)); LayerImpl* inner_container = host_impl_->active_tree()->InnerViewportContainerLayer(); @@ -8468,7 +8393,7 @@ root->SetBounds(root_size); gfx::ScrollOffset scroll_offset(100000, 0); - scrolling_layer->SetScrollClipLayer(root->id()); + scrolling_layer->SetScrollable(content_layer_bounds); scrolling_layer->SetElementId( LayerIdToElementIdForTesting(scrolling_layer->id())); host_impl_->pending_tree()->BuildPropertyTreesForTesting(); @@ -8927,11 +8852,10 @@ LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer( - kInnerViewportScrollLayerId, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scroll = + CreateScrollableLayer(kInnerViewportScrollLayerId, content_size); root_scroll->test_properties()->is_container_for_fixed_position_layers = true; - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size); root_scroll->test_properties()->AddChild(std::move(child)); ElementId root_id = root_scroll->element_id(); @@ -8982,17 +8906,17 @@ root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> root_scrolling_owned = - CreateScrollableLayer(12, surface_size, root); + CreateScrollableLayer(12, surface_size); auto* root_scrolling = root_scrolling_owned.get(); root->test_properties()->AddChild(std::move(root_scrolling_owned)); std::unique_ptr<LayerImpl> child_owned = - CreateScrollableLayer(13, surface_size, root); + CreateScrollableLayer(13, surface_size); auto* child = child_owned.get(); root_scrolling->test_properties()->AddChild(std::move(child_owned)); std::unique_ptr<LayerImpl> grand_child_owned = - CreateScrollableLayer(14, surface_size, root); + CreateScrollableLayer(14, surface_size); auto* grand_child = grand_child_owned.get(); child->test_properties()->AddChild(std::move(grand_child_owned)); @@ -9078,10 +9002,9 @@ CreateBasicVirtualViewportLayers(surface_size, surface_size); root_clip->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> root_scroll = - CreateScrollableLayer(11, content_size, root_clip); + CreateScrollableLayer(11, content_size); ElementId root_scroll_id = root_scroll->element_id(); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(12, content_size, root_clip); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); root_scroll->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scroll)); @@ -9175,8 +9098,8 @@ LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id); int child_scroll_layer_id = 8; - std::unique_ptr<LayerImpl> child_scroll = CreateScrollableLayer( - child_scroll_layer_id, content_size, child_scroll_clip.get()); + std::unique_ptr<LayerImpl> child_scroll = + CreateScrollableLayer(child_scroll_layer_id, content_size); child_scroll->SetPosition(gfx::PointF(10.f, 10.f)); @@ -9198,15 +9121,13 @@ gfx::Size content_size(100, 100); SetupScrollAndContentsLayers(content_size); - LayerImpl* root = host_impl_->active_tree()->LayerById(1); - int scroll_layer_id = 2; LayerImpl* scroll_layer = host_impl_->active_tree()->LayerById(scroll_layer_id); int child_scroll_layer_id = 7; std::unique_ptr<LayerImpl> child_scroll = - CreateScrollableLayer(child_scroll_layer_id, content_size, root); + CreateScrollableLayer(child_scroll_layer_id, content_size); child_scroll->SetDrawsContent(false); scroll_layer->test_properties()->AddChild(std::move(child_scroll)); @@ -9966,7 +9887,7 @@ std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(scroll_content_size); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(root_layer_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); @@ -10034,7 +9955,7 @@ std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - inner_scroll->SetScrollClipLayer(inner_clip->id()); + inner_scroll->SetScrollable(inner_viewport); inner_scroll->SetElementId( LayerIdToElementIdForTesting(inner_scroll->id())); inner_scroll->SetBounds(outer_viewport); @@ -10048,7 +9969,7 @@ std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetScrollable(outer_viewport); outer_scroll->SetElementId( LayerIdToElementIdForTesting(outer_scroll->id())); outer_scroll->layer_tree_impl() @@ -10260,8 +10181,7 @@ LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(10, outer_viewport, outer_scroll); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport); LayerImpl* child_scroll = child.get(); outer_scroll->test_properties()->children[0]->test_properties()->AddChild( std::move(child)); @@ -10333,8 +10253,7 @@ LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(10, outer_viewport, outer_scroll); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport); LayerImpl* child_scroll = child.get(); outer_scroll->test_properties()->children[0]->test_properties()->AddChild( std::move(child)); @@ -10510,14 +10429,13 @@ root->test_properties()->force_render_surface = true; // A div layer which has an event handler. - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(26, surface_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(26, surface_size); LayerImpl* child_layer = child.get(); // The layer tree should create a layer for the div layer, which is the // actual scrolling layer. std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(27, content_size, root); + CreateScrollableLayer(27, content_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -10571,19 +10489,18 @@ root->test_properties()->force_render_surface = true; // A div layer which has an event handler. - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(26, surface_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(26, surface_size); LayerImpl* child_layer = child.get(); // The layer tree should create a layer for the div layer, which is the // actual scrolling layer. std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(27, content_size, root); + CreateScrollableLayer(27, content_size); LayerImpl* grand_child_layer = grand_child.get(); // A child scrollable layer inside grand_child_layer. std::unique_ptr<LayerImpl> great_grand_child = - CreateScrollableLayer(28, inner_size, root); + CreateScrollableLayer(28, inner_size); LayerImpl* great_grand_child_layer = great_grand_child.get(); grand_child->test_properties()->AddChild(std::move(great_grand_child)); @@ -12223,7 +12140,6 @@ const int scrollbar_1_id = 10; const int scrollbar_2_id = 11; - const int child_clip_id = 12; const int child_scroll_id = 13; CreateHostImpl(settings, CreateLayerTreeFrameSink()); @@ -12341,14 +12257,12 @@ SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), scrollbar_2_id, VERTICAL, 15, 0, true, true); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), child_clip_id); std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); child->SetPosition(gfx::PointF(50, 50)); child->SetBounds(child_layer_size); child->SetDrawsContent(true); - child->SetScrollClipLayer(child_clip_id); + child->SetScrollable(gfx::Size(100, 100)); child->SetElementId(LayerIdToElementIdForTesting(child->id())); ElementId child_element_id = child->element_id(); @@ -12364,8 +12278,7 @@ scrollbar_2->SetPosition(gfx::PointF(0, 0)); child->test_properties()->AddChild(std::move(scrollbar_2)); - child_clip->test_properties()->AddChild(std::move(child)); - root_scroll->test_properties()->AddChild(std::move(child_clip)); + root_scroll->test_properties()->AddChild(std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries();
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index cd297d7f..46bf072 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -813,17 +813,18 @@ break; case 2: // child_ should create a scroll node. - child_->SetScrollClipLayerId(root_->id()); + child_->SetScrollable(gfx::Size(1, 1)); break; case 3: // child_ should create a clip node. child_->SetMasksToBounds(true); break; case 4: - // child_ should not create any property tree node. + // child_ should only create the scroll-related nodes. child_->SetMasksToBounds(false); child_->SetForceRenderSurfaceForTesting(false); - child_->SetScrollClipLayerId(Layer::INVALID_ID); + // Should have no effect because empty bounds do not prevent scrolling. + child_->SetScrollable(gfx::Size(0, 0)); } } @@ -877,11 +878,11 @@ EXPECT_NE(root_clip_node, child_clip_node); break; case 4: - // child_ should not create any property tree nodes. - EXPECT_EQ(child_transform_node, root_transform_node); + // child_ should only create the scroll-related nodes. + EXPECT_EQ(child_transform_node->id, child_scroll_node->transform_id); EXPECT_EQ(child_effect_node, root_effect_node); EXPECT_EQ(root_clip_node, child_clip_node); - EXPECT_EQ(root_scroll_node, child_scroll_node); + EXPECT_NE(root_scroll_node, child_scroll_node); EndTest(); break; } @@ -2742,7 +2743,7 @@ scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollClipLayerId(root_clip->id()); + pinch->SetScrollable(gfx::Size(200, 200)); pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -4766,8 +4767,8 @@ scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); scoped_refptr<Layer> page_scale_layer = Layer::Create(); scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - inner_viewport_scroll_layer->SetScrollClipLayerId( - inner_viewport_container_layer->id()); + inner_viewport_scroll_layer->SetScrollable( + inner_viewport_container_layer->bounds()); inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); root_layer_->AddChild(inner_viewport_container_layer); @@ -6191,7 +6192,7 @@ scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollClipLayerId(root_clip->id()); + pinch->SetScrollable(gfx::Size(500, 500)); pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -6498,7 +6499,7 @@ scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollClipLayerId(root_clip->id()); + pinch->SetScrollable(gfx::Size(500, 500)); pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -6904,7 +6905,7 @@ CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer, gfx::Size(50, 50), gfx::Size(50, 50), layer_tree_host()); - outer_viewport_scroll_layer->scroll_clip_layer()->SetMasksToBounds(true); + layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true); outer_viewport_scroll_layer->AddChild(content_layer); client_.set_bounds(root->bounds());
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index b9fa010f..1574fb2 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -724,7 +724,7 @@ LayerTreeHostAnimationTest::SetupTree(); scroll_layer_ = FakePictureLayer::Create(&client_); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); scroll_layer_->SetBounds(gfx::Size(1000, 1000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); @@ -785,7 +785,7 @@ scroll_layer_->SetBounds(gfx::Size(10000, 10000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(10, 10)); layer_tree_host()->root_layer()->AddChild(scroll_layer_); AttachPlayersToTimeline(); @@ -845,7 +845,7 @@ scroll_layer_->SetBounds(gfx::Size(10000, 10000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(10, 10)); layer_tree_host()->root_layer()->AddChild(scroll_layer_); AttachPlayersToTimeline(); @@ -951,7 +951,7 @@ LayerTreeHostAnimationTest::SetupTree(); scroll_layer_ = FakePictureLayer::Create(&client_); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); scroll_layer_->SetBounds(gfx::Size(10000, 10000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc index 578324f..34950c6e 100644 --- a/cc/trees/layer_tree_host_unittest_damage.cc +++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -339,19 +339,14 @@ root_layer->SetMasksToBounds(true); layer_tree_host()->SetRootLayer(root_layer); - scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); content_layer_ = FakePictureLayer::Create(&client_); content_layer_->SetElementId( LayerIdToElementIdForTesting(content_layer_->id())); - content_layer_->SetScrollClipLayerId(scroll_clip_layer->id()); + content_layer_->SetScrollable(root_layer->bounds()); content_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); content_layer_->SetBounds(gfx::Size(100, 200)); content_layer_->SetIsDrawable(true); - scroll_clip_layer->SetBounds( - gfx::Size(content_layer_->bounds().width() - 30, - content_layer_->bounds().height() - 50)); - scroll_clip_layer->AddChild(content_layer_); - root_layer->AddChild(scroll_clip_layer); + root_layer->AddChild(content_layer_); scoped_refptr<Layer> scrollbar_layer = FakePaintedScrollbarLayer::Create( false, true, content_layer_->element_id());
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc index e4fefef..6579662 100644 --- a/cc/trees/layer_tree_host_unittest_picture.cc +++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -224,7 +224,7 @@ // picture_'s transform is going to be changing on the compositor thread, so // force it to have a transform node by making it scrollable. - picture_->SetScrollClipLayerId(root->id()); + picture_->SetScrollable(root->bounds()); layer_tree_host()->SetRootLayer(root); LayerTreeHostPictureTest::SetupTree(); @@ -412,7 +412,7 @@ pinch_ = Layer::Create(); pinch_->SetBounds(gfx::Size(500, 500)); - pinch_->SetScrollClipLayerId(root_clip->id()); + pinch_->SetScrollable(root_clip->bounds()); pinch_->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch_); root_clip->AddChild(page_scale_layer);
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index d3ac199..767c4e2 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -94,10 +94,8 @@ num_scrolls_(0) {} void BeginTest() override { - outer_viewport_container_layer_id_ = layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->id(); + outer_viewport_container_layer_id_ = + layer_tree_host()->outer_viewport_container_layer()->id(); layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( initial_scroll_); layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( @@ -125,7 +123,6 @@ LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); - scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); scroll_layer->ScrollBy(scroll_amount_); @@ -505,15 +502,12 @@ void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() + ->outer_viewport_container_layer() ->SetForceRenderSurfaceForTesting(true); gfx::Transform translate; translate.Translate(0.25f, 0.f); - layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->SetTransform(translate); + layer_tree_host()->outer_viewport_container_layer()->SetTransform( + translate); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f); } @@ -598,11 +592,8 @@ child_layer_->SetPosition(gfx::PointF(60.f, 5.f)); } - scoped_refptr<Layer> outer_container_layer = - layer_tree_host()->outer_viewport_scroll_layer()->parent(); - child_layer_->SetIsDrawable(true); - child_layer_->SetScrollClipLayerId(outer_container_layer->id()); + child_layer_->SetScrollable(root_layer->bounds()); child_layer_->SetElementId( LayerIdToElementIdForTesting(child_layer_->id())); child_layer_->SetBounds(root_scroll_layer_->bounds()); @@ -1102,10 +1093,8 @@ LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {} void BeginTest() override { - outer_viewport_container_layer_id_ = layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->id(); + outer_viewport_container_layer_id_ = + layer_tree_host()->outer_viewport_container_layer()->id(); PostSetNeedsCommitToMainThread(); } @@ -1114,7 +1103,7 @@ Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); switch (layer_tree_host()->SourceFrameNumber()) { case 0: - scroll_layer->SetScrollClipLayerId(outer_viewport_container_layer_id_); + scroll_layer->SetScrollable(root->bounds()); // Set max_scroll_offset = (100, 100). scroll_layer->SetBounds(gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); @@ -1442,10 +1431,9 @@ Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { scoped_refptr<PictureLayer> scroll_layer = PictureLayer::Create(&fake_content_layer_client_); - scroll_layer->SetBounds(gfx::Size(110, 110)); scroll_layer->SetPosition(gfx::PointF()); scroll_layer->SetIsDrawable(true); - scroll_layer->SetScrollClipLayerId(parent->id()); + scroll_layer->SetScrollable(parent->bounds()); scroll_layer->SetElementId( LayerIdToElementIdForTesting(scroll_layer->id())); scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100, @@ -1504,10 +1492,8 @@ } void BeginTest() override { - outer_viewport_container_layer_id_ = layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->id(); + outer_viewport_container_layer_id_ = + layer_tree_host()->outer_viewport_container_layer()->id(); layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( initial_scroll_); layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( @@ -1599,7 +1585,6 @@ LayerImpl* root = impl->active_tree()->root_layer_for_testing(); LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); - scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); scroll_layer->ScrollBy(scroll_amount_);
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index 6f2fcdd..b4a4222 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc
@@ -1248,9 +1248,6 @@ scale_factor = transform_tree.page_scale_factor(); gfx::SizeF scaled_scroll_bounds = gfx::ScaleSize(scroll_bounds, scale_factor); - scaled_scroll_bounds.SetSize(std::floor(scaled_scroll_bounds.width()), - std::floor(scaled_scroll_bounds.height())); - gfx::Size clip_layer_bounds = scroll_clip_layer_bounds(scroll_node->id); gfx::ScrollOffset max_offset(
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 2f287ca..af37d72 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -140,12 +140,6 @@ return layer->test_properties()->transform; } -static void SetIsScrollClipLayer(Layer* layer) { - layer->set_is_scroll_clip_layer(); -} - -static void SetIsScrollClipLayer(LayerImpl* layer) {} - // Methods to query state from the AnimationHost ---------------------- template <typename LayerType> bool OpacityIsAnimating(LayerType* layer) { @@ -394,7 +388,6 @@ data_for_children->affected_by_outer_viewport_bounds_delta = layer == data_from_ancestor.outer_viewport_scroll_layer; if (is_scrollable) { - DCHECK(!is_root); DCHECK(Transform(layer).IsIdentity()); data_for_children->transform_fixed_parent = Parent(layer); } else { @@ -1001,11 +994,6 @@ layer->SetHasTransformNode(val); } -void SetHasScrollNode(LayerImpl* layer, bool val) {} -void SetHasScrollNode(Layer* layer, bool val) { - layer->SetHasScrollNode(val); -} - template <typename LayerType> void AddScrollNodeIfNeeded( const DataForRecursion<LayerType>& data_from_ancestor, @@ -1037,14 +1025,12 @@ if (!requires_node) { node_id = parent_id; data_for_children->scroll_tree_parent = node_id; - SetHasScrollNode(layer, false); } else { ScrollNode node; node.owning_layer_id = layer->id(); node.scrollable = scrollable; node.main_thread_scrolling_reasons = main_thread_scrolling_reasons; node.non_fast_scrollable_region = layer->non_fast_scrollable_region(); - node.scrolls_inner_viewport = layer == data_from_ancestor.inner_viewport_scroll_layer; node.scrolls_outer_viewport = @@ -1055,12 +1041,8 @@ node.max_scroll_offset_affected_by_page_scale = true; } - if (LayerType* scroll_clip_layer = layer->scroll_clip_layer()) { - SetIsScrollClipLayer(scroll_clip_layer); - node.scroll_clip_layer_bounds = scroll_clip_layer->bounds(); - } - node.bounds = layer->bounds(); + node.scroll_clip_layer_bounds = layer->scroll_container_bounds(); node.offset_to_transform_parent = layer->offset_to_transform_parent(); node.should_flatten = layer->should_flatten_transform_from_property_tree(); node.user_scrollable_horizontal = UserScrollableHorizontal(layer); @@ -1087,7 +1069,6 @@ data_for_children->property_trees->scroll_tree.SetBaseScrollOffset( layer->element_id(), layer->CurrentScrollOffset()); } - SetHasScrollNode(layer, true); } layer->SetScrollTreeIndex(node_id);
diff --git a/cc/trees/scroll_node.h b/cc/trees/scroll_node.h index 43841bf..60b3293 100644 --- a/cc/trees/scroll_node.h +++ b/cc/trees/scroll_node.h
@@ -30,6 +30,7 @@ // The layer id that corresponds to the layer contents that are scrolled. // Unlike |id|, this id is stable across frames that don't change the // composited layer list. + // TODO(pdr): This is no longer used and can be removed. int owning_layer_id; uint32_t main_thread_scrolling_reasons; @@ -38,6 +39,7 @@ // Size of the clipped area, not including non-overlay scrollbars. Overlay // scrollbars do not affect the clipped area. + // TODO(pdr): Rename this to scroll_container_bounds. gfx::Size scroll_clip_layer_bounds; // Bounds of the overflow scrolling area.
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc index 18ab0a7..daf58880 100644 --- a/cc/trees/tree_synchronizer_unittest.cc +++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -494,22 +494,17 @@ host_impl->CreatePendingTree(); scoped_refptr<Layer> layer_tree_root = Layer::Create(); - scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); - scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> transient_scroll_layer = Layer::Create(); - layer_tree_root->AddChild(transient_scroll_clip_layer); - transient_scroll_clip_layer->AddChild(transient_scroll_layer); - transient_scroll_layer->AddChild(scroll_clip_layer); - scroll_clip_layer->AddChild(scroll_layer); + layer_tree_root->AddChild(transient_scroll_layer); + transient_scroll_layer->AddChild(scroll_layer); ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); - transient_scroll_layer->SetScrollClipLayerId( - transient_scroll_clip_layer->id()); - scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id()); + transient_scroll_layer->SetScrollable(gfx::Size(1, 1)); + scroll_layer->SetScrollable(gfx::Size(1, 1)); host_->SetRootLayer(layer_tree_root); host_->BuildPropertyTreesForTesting(); host_->CommitAndCreatePendingTree(); @@ -523,7 +518,7 @@ host_impl->active_tree()->property_trees()->scroll_tree.Node( scroll_layer->scroll_tree_index()); host_impl->active_tree()->SetCurrentlyScrollingNode(scroll_node); - transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID); + transient_scroll_layer->SetScrollable(gfx::Size(0, 0)); host_->BuildPropertyTreesForTesting(); host_impl->CreatePendingTree(); @@ -546,25 +541,20 @@ host_impl->CreatePendingTree(); scoped_refptr<Layer> layer_tree_root = Layer::Create(); - scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); - scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> transient_scroll_layer = Layer::Create(); ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); - layer_tree_root->AddChild(transient_scroll_clip_layer); - transient_scroll_clip_layer->AddChild(transient_scroll_layer); - transient_scroll_layer->AddChild(scroll_clip_layer); - scroll_clip_layer->AddChild(scroll_layer); + layer_tree_root->AddChild(transient_scroll_layer); + transient_scroll_layer->AddChild(scroll_layer); ElementId transient_scroll_element_id = ElementId(7); transient_scroll_layer->SetElementId(transient_scroll_element_id); - transient_scroll_layer->SetScrollClipLayerId( - transient_scroll_clip_layer->id()); - scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id()); + transient_scroll_layer->SetScrollable(gfx::Size(1, 1)); + scroll_layer->SetScrollable(gfx::Size(1, 1)); transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2)); scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20)); @@ -624,8 +614,9 @@ host_impl->active_tree()->SetCurrentlyScrollingNode( scroll_tree.Node(scroll_layer_impl->scroll_tree_index())); - // Make one layer unscrollable so that scroll tree topology changes - transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID); + // Change the scroll tree topology by removing transient_scroll_layer. + transient_scroll_layer->RemoveFromParent(); + layer_tree_root->AddChild(scroll_layer); host_->BuildPropertyTreesForTesting(); host_impl->CreatePendingTree();
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 36b77b5..d8fe989 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -391,7 +391,6 @@ "//chrome/common:features", "//chrome/install_static:install_static_util", "//chrome/install_static:secondary_module", - "//chrome/profiling", "//chrome_elf", "//components/crash/content/app", "//components/policy:generated", @@ -1415,6 +1414,7 @@ public_deps = [ "//chrome/browser", "//chrome/common", + "//chrome/profiling", "//components/sync", ] if (enable_plugins) {
diff --git a/chrome/android/java/res/layout/account_signin_view.xml b/chrome/android/java/res/layout/account_signin_view.xml index 09c3565..9139aad 100644 --- a/chrome/android/java/res/layout/account_signin_view.xml +++ b/chrome/android/java/res/layout/account_signin_view.xml
@@ -117,6 +117,7 @@ <View style="@style/Divider"/> <TextView + style="@style/RobotoMediumStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" @@ -126,7 +127,6 @@ android:text="@string/sync_confirmation_chrome_sync_title" android:textColor="@color/default_text_color" android:textSize="@dimen/fre_normal_text_size" - android:fontFamily="sans-serif-medium" android:drawableStart="@drawable/chrome_sync_logo" android:drawablePadding="16dp"/> @@ -147,6 +147,7 @@ android:layout_marginEnd="16dp"/> <TextView + style="@style/RobotoMediumStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" @@ -156,7 +157,6 @@ android:text="@string/sync_confirmation_personalize_services_title" android:textColor="@color/default_text_color" android:textSize="@dimen/fre_normal_text_size" - android:fontFamily="sans-serif-medium" android:drawableStart="@drawable/googleg" android:drawablePadding="16dp"/>
diff --git a/chrome/android/java/res/layout/contextual_search_peek_promo_text_view.xml b/chrome/android/java/res/layout/contextual_search_peek_promo_text_view.xml index 97fcef5..df0772b 100644 --- a/chrome/android/java/res/layout/contextual_search_peek_promo_text_view.xml +++ b/chrome/android/java/res/layout/contextual_search_peek_promo_text_view.xml
@@ -14,12 +14,12 @@ android:paddingEnd="@dimen/contextual_search_peek_promo_padding" android:visibility="invisible"> <TextView + style="@style/RobotoMediumStyle" android:id="@+id/contextual_search_peek_promo_new" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/contextual_search_peek_promo_padding" android:background="@drawable/contextual_search_peek_promo_new_background" - android:fontFamily="sans-serif-medium" android:text="@string/contextual_search_peek_promo_new" android:textAllCaps="true" android:textColor="@color/light_active_color"
diff --git a/chrome/android/java/res/layout/contextual_search_promo_view.xml b/chrome/android/java/res/layout/contextual_search_promo_view.xml index e262beb6..18712fc 100644 --- a/chrome/android/java/res/layout/contextual_search_promo_view.xml +++ b/chrome/android/java/res/layout/contextual_search_promo_view.xml
@@ -39,7 +39,6 @@ android:layout_gravity="end" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" - android:fontFamily="sans-serif-medium" android:paddingStart="8dp" android:paddingEnd="8dp" android:text="@string/contextual_search_allow_button" @@ -57,7 +56,6 @@ android:layout_gravity="end" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" - android:fontFamily="sans-serif-medium" android:paddingStart="8dp" android:paddingEnd="8dp" android:text="@string/contextual_search_no_thanks_button"
diff --git a/chrome/android/java/res/layout/dialog_with_titlebar.xml b/chrome/android/java/res/layout/dialog_with_titlebar.xml deleted file mode 100644 index 3a4dd68e..0000000 --- a/chrome/android/java/res/layout/dialog_with_titlebar.xml +++ /dev/null
@@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="@dimen/toolbar_height_no_shadow" - android:background="@color/default_primary_color" > - - <TextView - android:id="@+id/title" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:fontFamily="sans-serif-medium" - android:gravity="center_vertical" - android:paddingStart="16dp" - android:paddingEnd="16dp" - android:textColor="#333333" - android:textSize="20sp" /> - - <ImageButton - android:id="@+id/close_button" - style="@style/ToolbarButton" - android:layout_width="52dp" - android:layout_height="match_parent" - android:layout_gravity="top" - android:contentDescription="@string/close" - android:src="@drawable/btn_close" /> - </LinearLayout> - - <ImageView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/toolbar_height_no_shadow" - android:contentDescription="@null" - android:scaleType="fitXY" - android:src="@drawable/toolbar_shadow" /> - - <!-- Dialog content will be inserted here from Java code --> - -</FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/fre_data_reduction_proxy.xml b/chrome/android/java/res/layout/fre_data_reduction_proxy.xml index 08c7356..1be505b 100644 --- a/chrome/android/java/res/layout/fre_data_reduction_proxy.xml +++ b/chrome/android/java/res/layout/fre_data_reduction_proxy.xml
@@ -66,6 +66,7 @@ android:textSize="@dimen/fre_normal_text_size" /> <android.support.v7.widget.SwitchCompat + style="@style/RobotoMediumStyle" android:id="@+id/enable_data_saver_switch" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -73,8 +74,7 @@ android:showText="false" android:text="@string/data_reduction_enabled_switch" android:textColor="@color/fre_text_color" - android:textSize="@dimen/fre_normal_text_size" - android:fontFamily="sans-serif-medium" /> + android:textSize="@dimen/fre_normal_text_size" /> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res/layout/new_tab_page_incognito.xml b/chrome/android/java/res/layout/new_tab_page_incognito.xml index 84f44dcf..f6be0ba3 100644 --- a/chrome/android/java/res/layout/new_tab_page_incognito.xml +++ b/chrome/android/java/res/layout/new_tab_page_incognito.xml
@@ -64,7 +64,6 @@ style="@style/IncognitoNewTabLearnMoreLink" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:fontFamily="sans-serif-medium" android:text="@string/learn_more" android:textColor="#03a9f4" />
diff --git a/chrome/android/java/res/layout/new_tab_page_incognito_md.xml b/chrome/android/java/res/layout/new_tab_page_incognito_md.xml index 2e1a7708..146fd29 100644 --- a/chrome/android/java/res/layout/new_tab_page_incognito_md.xml +++ b/chrome/android/java/res/layout/new_tab_page_incognito_md.xml
@@ -78,10 +78,10 @@ android:background="?attr/listChoiceBackgroundIndicator" android:clickable="true" android:focusable="true" - android:fontFamily="sans-serif-medium" android:text="@string/learn_more" android:textColor="@color/google_blue_300" - android:lineSpacingExtra="6sp" /> + android:lineSpacingExtra="6sp" + style="@style/RobotoMediumStyle" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/photo_picker_bitmap_view.xml b/chrome/android/java/res/layout/photo_picker_bitmap_view.xml index e84c8c3..22c50cc 100644 --- a/chrome/android/java/res/layout/photo_picker_bitmap_view.xml +++ b/chrome/android/java/res/layout/photo_picker_bitmap_view.xml
@@ -77,11 +77,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/photo_picker_label_gap" - android:fontFamily="sans-serif-medium" android:gravity="center" - android:textStyle="bold" android:textSize="14sp" android:textAllCaps="true" - android:textColor="@color/photo_picker_special_tile_color" /> + android:textColor="@color/photo_picker_special_tile_color" + style="@style/RobotoMediumStyle" /> </LinearLayout> </view>
diff --git a/chrome/android/java/res/layout/snackbar.xml b/chrome/android/java/res/layout/snackbar.xml index d9ba185..d466784 100644 --- a/chrome/android/java/res/layout/snackbar.xml +++ b/chrome/android/java/res/layout/snackbar.xml
@@ -41,7 +41,6 @@ android:layout_gravity="center_vertical" android:paddingEnd="24dp" android:paddingStart="24dp" - android:fontFamily="sans-serif-medium" android:textAllCaps="true" android:textColor="@color/snackbar_button_color" android:textSize="14sp"
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 80b0593e..09c67660 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -130,10 +130,9 @@ <item name="android:paddingTop">16dp</item> <item name="android:layout_marginBottom">16dp</item> </style> - <style name="PreferenceCategoryTextStyle"> + <style name="PreferenceCategoryTextStyle" parent="RobotoMediumStyle"> <item name="android:textColor">@color/pref_accent_color</item> <item name="android:textSize">12sp</item> - <item name="android:textStyle">bold</item> </style> <style name="PreferenceTitle"> <item name="android:ellipsize">end</item> @@ -720,7 +719,7 @@ <item name="android:textSize">14sp</item> <item name="android:lineSpacingMultiplier">1.2</item> </style> - <style name="IncognitoNewTabLearnMoreLink"> + <style name="IncognitoNewTabLearnMoreLink" parent="RobotoMediumStyle"> <item name="android:background">?attr/listChoiceBackgroundIndicator</item> <item name="android:clickable">true</item> <item name="android:focusable">true</item>
diff --git a/chrome/android/java/res/values-v21/styles.xml b/chrome/android/java/res/values-v21/styles.xml index 51ade34..725a6828d 100644 --- a/chrome/android/java/res/values-v21/styles.xml +++ b/chrome/android/java/res/values-v21/styles.xml
@@ -25,8 +25,7 @@ <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item> <item name="android:paddingEnd">4dp</item> </style> - <style name="PreferenceCategoryTextStyle"> - <item name="android:fontFamily">sans-serif-medium</item> + <style name="PreferenceCategoryTextStyle" parent="RobotoMediumStyle"> <item name="android:textColor">@color/pref_accent_color</item> <item name="android:textSize">12sp</item> </style>
diff --git a/chrome/android/java/res/values-v21/values.xml b/chrome/android/java/res/values-v21/values.xml deleted file mode 100644 index d903908..0000000 --- a/chrome/android/java/res/values-v21/values.xml +++ /dev/null
@@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<resources xmlns:android="http://schemas.android.com/apk/res/android"> - <!-- Font to use when a spec asks for "Roboto Medium". --> - <string name="roboto_medium_typeface">sans-serif-medium</string> - <integer name="roboto_medium_textstyle">0</integer> -</resources>
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml index ae55468..ab3adfd 100644 --- a/chrome/android/java/res/values/ids.xml +++ b/chrome/android/java/res/values/ids.xml
@@ -22,6 +22,7 @@ <!-- InfoBar constants --> <item type="id" name="button_primary" /> <item type="id" name="button_secondary" /> + <item type="id" name="infobar_icon" /> <item type="id" name="infobar_close_button" /> <item type="id" name="infobar_extra_check" /> <item type="id" name="infobar_message" />
diff --git a/chrome/android/java/res/values/values.xml b/chrome/android/java/res/values/values.xml index ef5aa31..8ea6bc2 100644 --- a/chrome/android/java/res/values/values.xml +++ b/chrome/android/java/res/values/values.xml
@@ -8,12 +8,6 @@ xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation"> - <!-- Font to use when a spec asks for "Roboto Medium". - Bolding the text makes it look almost, but not quite, entirely unlike Roboto Medium, - which doesn't exist pre-L. --> - <string name="roboto_medium_typeface">sans-serif</string> - <integer name="roboto_medium_textstyle">1</integer> - <!-- Menu Animation Constants --> <item type="fraction" format="fraction" name="menu_animation_pivot_x">95%</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java index ec47df7..312102d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java
@@ -8,7 +8,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; -import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; import android.text.SpannableString; @@ -26,6 +25,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.DualControlLayout; +import org.chromium.ui.UiUtils; import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.widget.ButtonCompat; @@ -259,10 +259,8 @@ lp.endMargin = mBigIconMargin; Resources res = getContext().getResources(); - String typeface = res.getString(R.string.roboto_medium_typeface); - int textStyle = res.getInteger(R.integer.roboto_medium_textstyle); float textSize = res.getDimension(R.dimen.infobar_big_icon_message_size); - mMessageTextView.setTypeface(Typeface.create(typeface, textStyle)); + mMessageTextView.setTypeface(UiUtils.createRobotoMediumTypeface()); mMessageTextView.setMaxLines(1); mMessageTextView.setEllipsize(TextUtils.TruncateAt.END); mMessageTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); @@ -529,6 +527,7 @@ iconView.setImageBitmap(iconBitmap); } iconView.setFocusable(false); + iconView.setId(R.id.infobar_icon); iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); } return iconView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/ReaderModeInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/ReaderModeInfoBar.java index 2eca9f3..14948a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/ReaderModeInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/ReaderModeInfoBar.java
@@ -23,6 +23,16 @@ */ public class ReaderModeInfoBar extends InfoBar { /** + * Navigate to Reader Mode when the icon or the message text is clicked. + */ + private View.OnClickListener mNavigateListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getReaderModeManager() != null) getReaderModeManager().navigateToReaderMode(); + } + }; + + /** * Default constructor. */ private ReaderModeInfoBar() { @@ -44,14 +54,9 @@ prompt.setTextColor( ApiCompatibilityUtils.getColor(layout.getResources(), R.color.default_text_color)); prompt.setGravity(Gravity.CENTER_VERTICAL); + prompt.setOnClickListener(mNavigateListener); - prompt.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getReaderModeManager() != null) getReaderModeManager().navigateToReaderMode(); - } - }); - + layout.findViewById(R.id.infobar_icon).setOnClickListener(mNavigateListener); layout.addContent(prompt, 1f); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java index 2219914c..5cccb6c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
@@ -11,6 +11,7 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.blink_public.platform.modules.remoteplayback.WebRemotePlaybackAvailability; import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; /** * Acts as a proxy between the remotely playing video and the HTMLMediaElement. @@ -202,6 +203,11 @@ @CalledByNative private void requestRemotePlayback(long startPositionMillis) { Log.d(TAG, "requestRemotePlayback at t=%d", startPositionMillis); + // TODO(crbug.com/736568): Re-enable dialog in VR. + if (VrShellDelegate.isInVr()) { + mMediaStateListener.onRouteDialogCancelled(); + return; + } if (mRouteController == null) return; // Clear out the state mPauseRequested = false; @@ -217,6 +223,11 @@ @CalledByNative private void requestRemotePlaybackControl() { Log.d(TAG, "requestRemotePlaybackControl"); + // TODO(crbug.com/736568): Re-enable dialog in VR. + if (VrShellDelegate.isInVr()) { + mMediaStateListener.onRouteDialogCancelled(); + return; + } RemoteMediaPlayerController.instance().requestRemotePlaybackControl(mMediaStateListener); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageDialog.java deleted file mode 100644 index 63f0935..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageDialog.java +++ /dev/null
@@ -1,61 +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. - -package org.chromium.chrome.browser.ntp; - -import android.app.Activity; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; -import android.widget.FrameLayout; -import android.widget.ImageButton; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.NativePage; -import org.chromium.chrome.browser.widget.AlwaysDismissedDialog; - -/** - * Displays a NativePage in a full screen dialog instead of like a regular Chrome page. - */ -public class NativePageDialog extends AlwaysDismissedDialog { - private final NativePage mPage; - - public NativePageDialog(Activity ownerActivity, NativePage page) { - super(ownerActivity, R.style.DialogWhenLarge); - mPage = page; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - FrameLayout view = (FrameLayout) LayoutInflater.from(getContext()).inflate( - R.layout.dialog_with_titlebar, null); - view.addView(mPage.getView(), 0); - setContentView(view); - - getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); - - TextView title = (TextView) view.findViewById(R.id.title); - title.setText(mPage.getTitle()); - - ImageButton closeButton = (ImageButton) view.findViewById(R.id.close_button); - closeButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - } - - @Override - public void dismiss() { - super.dismiss(); - if (mPage != null) mPage.destroy(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java index 3d1741b3..62996a22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java
@@ -7,23 +7,17 @@ import android.content.Context; import org.chromium.base.ContextUtils; -import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.SuppressFBWarnings; -import org.chromium.base.library_loader.LibraryProcessType; -import org.chromium.base.library_loader.ProcessInitException; -import org.chromium.chrome.browser.init.ChromeBrowserInitializer; +import org.chromium.chrome.browser.background_task_scheduler.NativeBackgroundTask; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.components.background_task_scheduler.BackgroundTask; import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFinishedCallback; import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; import org.chromium.components.background_task_scheduler.TaskIds; import org.chromium.components.background_task_scheduler.TaskInfo; import org.chromium.components.background_task_scheduler.TaskParameters; -import org.chromium.content.browser.BrowserStartupController; import java.util.concurrent.TimeUnit; @@ -34,7 +28,7 @@ * happens when a task fires. */ @JNINamespace("offline_pages::prefetch") -public class PrefetchBackgroundTask implements BackgroundTask { +public class PrefetchBackgroundTask extends NativeBackgroundTask { public static final long DEFAULT_START_DELAY_SECONDS = 15 * 60; private static final String TAG = "OPPrefetchBGTask"; @@ -43,16 +37,9 @@ private long mNativeTask = 0; private TaskFinishedCallback mTaskFinishedCallback = null; + private Profile mProfile = null; - private Profile mProfile; - - public PrefetchBackgroundTask() { - mProfile = Profile.getLastUsedProfile(); - } - - public PrefetchBackgroundTask(Profile profile) { - mProfile = profile; - } + public PrefetchBackgroundTask() {} static BackgroundTaskScheduler getScheduler() { if (sSchedulerInstance != null) { @@ -61,6 +48,11 @@ return BackgroundTaskSchedulerFactory.getScheduler(); } + protected Profile getProfile() { + if (mProfile == null) mProfile = Profile.getLastUsedProfile(); + return mProfile; + } + /** * Schedules the default 'NWake' task for the prefetching service. * @@ -94,39 +86,47 @@ ContextUtils.getApplicationContext(), TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID); } - /** - * Initializer that runs when the task wakes up Chrome. - * - * Loads the native library and then calls into the PrefetchService, which then manages the - * lifetime of this task. - */ @Override - public boolean onStartTask( + public int onStartTaskBeforeNativeLoaded( Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { - assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID; - if (mNativeTask != 0) return false; - // TODO(dewittj): Ensure that the conditions are right to do work. If the maximum time to // wait is reached, it is possible the task will fire even if network conditions are - // incorrect. - - // Ensures that native potion of the browser is launched. - launchBrowserIfNecessary(context); - - mTaskFinishedCallback = callback; - return nativeStartPrefetchTask(mProfile); + // incorrect. We want: + // * Unmetered WiFi connection + // * >50% battery + // * Preferences enabled. + return NativeBackgroundTask.LOAD_NATIVE; } @Override - public boolean onStopTask(Context context, TaskParameters taskParameters) { + protected void onStartTaskWithNative( + Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID; - if (mNativeTask == 0) return false; + if (mNativeTask != 0) return; + + mTaskFinishedCallback = callback; + nativeStartPrefetchTask(getProfile()); + } + + @Override + protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParameters taskParameters) { + // TODO(dewittj): Implement this properly. + return true; + } + + @Override + protected boolean onStopTaskWithNative(Context context, TaskParameters taskParameters) { + assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID; + assert mNativeTask != 0; return nativeOnStopTask(mNativeTask); } @Override - public void reschedule(Context context) {} + public void reschedule(Context context) { + // TODO(dewittj): Set the backoff time appropriately. + scheduleTask(0); + } /** * Called during construction of the native task. @@ -151,26 +151,6 @@ } @VisibleForTesting - @SuppressFBWarnings("DM_EXIT") - void launchBrowserIfNecessary(Context context) { - if (BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) - .isStartupSuccessfullyCompleted()) { - return; - } - - // TODO(https://crbug.com/717251): Remove when BackgroundTaskScheduler supports loading the - // native library. - try { - ChromeBrowserInitializer.getInstance(context).handleSynchronousStartup(); - } catch (ProcessInitException e) { - Log.e(TAG, "ProcessInitException while starting the browser process."); - // Since the library failed to initialize nothing in the application can work, so kill - // the whole application not just the activity. - System.exit(-1); - } - } - - @VisibleForTesting static void setSchedulerForTesting(BackgroundTaskScheduler scheduler) { sSchedulerInstance = scheduler; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPlaceholderFieldTrial.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPlaceholderFieldTrial.java index 99a70d5..08eddf5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPlaceholderFieldTrial.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPlaceholderFieldTrial.java
@@ -17,12 +17,9 @@ public class OmniboxPlaceholderFieldTrial { private static final String FIELD_TRIAL_NAME = "OmniboxPlaceholderExperiment"; private static final String GROUP_SEARCH_OR_TYPE_URL = "SearchOrTypeUrl"; - private static final String GROUP_SEARCH_OR_TYPE_WEBSITE_NAME = "SearchOrTypeWebsiteName"; - private static final String GROUP_SEARCH_THE_WEB = "SearchTheWeb"; - private static final String GROUP_ENTER_A_SEARCH_OR_WEBSITE = "EnterASearchOrWebsite"; - private static final String GROUP_SEARCH_NEWS = "SearchNews"; - private static final String GROUP_SEARCH_RECIPES = "SearchRecipes"; - private static final String GROUP_SEARCH_WEATHER = "SearchWeather"; + private static final String GROUP_SEARCH_OR_TYPE_WEB_ADDRESS = "SearchOrTypeWebAddress"; + private static final String GROUP_TYPE_WHAT_YOU_ARE_LOOKING_FOR = "TypeWhatYouAreLookingFor"; + private static final String GROUP_FIND_NEWS_RECIPES_WEATHER = "FindNewsRecipesWeather"; private static final String GROUP_BLANK = "Blank"; private static String sCachedHint; @@ -50,23 +47,14 @@ case GROUP_SEARCH_OR_TYPE_URL: sCachedHint = resources.getString(R.string.search_or_type_url); break; - case GROUP_SEARCH_OR_TYPE_WEBSITE_NAME: - sCachedHint = resources.getString(R.string.search_or_type_website_name); + case GROUP_SEARCH_OR_TYPE_WEB_ADDRESS: + sCachedHint = resources.getString(R.string.search_or_type_web_address); break; - case GROUP_SEARCH_THE_WEB: - sCachedHint = resources.getString(R.string.search_the_web); + case GROUP_TYPE_WHAT_YOU_ARE_LOOKING_FOR: + sCachedHint = resources.getString(R.string.type_what_you_are_looking_for); break; - case GROUP_ENTER_A_SEARCH_OR_WEBSITE: - sCachedHint = resources.getString(R.string.enter_a_search_or_website); - break; - case GROUP_SEARCH_NEWS: - sCachedHint = resources.getString(R.string.search_news); - break; - case GROUP_SEARCH_RECIPES: - sCachedHint = resources.getString(R.string.search_recipes); - break; - case GROUP_SEARCH_WEATHER: - sCachedHint = resources.getString(R.string.search_weather); + case GROUP_FIND_NEWS_RECIPES_WEATHER: + sCachedHint = resources.getString(R.string.find_news_recipes_weather); break; case GROUP_BLANK: sCachedHint = "";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java index 8b1352d..d117f6ca7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationSnackbarController.java
@@ -9,7 +9,7 @@ import android.net.Uri; import android.os.Build; import android.text.SpannableString; -import android.text.style.TypefaceSpan; +import android.text.style.StyleSpan; import android.view.View; import org.chromium.base.ContextUtils; @@ -74,7 +74,7 @@ } Uri searchUri = Uri.parse(TemplateUrlService.getInstance().getUrlForSearchQuery("foo")); - TypefaceSpan robotoMediumSpan = new TypefaceSpan("sans-serif-medium"); + StyleSpan robotoMediumSpan = new StyleSpan(R.style.RobotoMediumStyle); String messageWithoutSpans = context.getResources().getString( R.string.omnibox_geolocation_disclosure, "<b>" + searchUri.getHost() + "</b>"); SpannableString message = SpanApplier.applySpans(messageWithoutSpans,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java index 51c340d..880cb980 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.content.res.Resources; -import android.graphics.Typeface; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -14,6 +13,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.ui.UiUtils; import java.util.List; @@ -116,9 +116,7 @@ // Set the correct appearance, face and style for the text. ApiCompatibilityUtils.setTextAppearance( textView, R.style.PaymentsUiSectionAddButtonLabel); - textView.setTypeface( - Typeface.create(resources.getString(R.string.roboto_medium_typeface), - R.integer.roboto_medium_textstyle)); + textView.setTypeface(UiUtils.createRobotoMediumTypeface()); // Padding at the bottom of the dropdown. ApiCompatibilityUtils.setPaddingRelative(convertView,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java index 8d5c0f97..834d19b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
@@ -7,7 +7,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Color; -import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Handler; import android.support.v4.view.animation.LinearOutSlowInInterpolator; @@ -37,6 +36,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.DualControlLayout; import org.chromium.chrome.browser.widget.TintedDrawable; +import org.chromium.ui.UiUtils; import java.util.ArrayList; import java.util.List; @@ -942,8 +942,6 @@ labelView.setEnabled(isEnabled); } else if (mRowType == OPTION_ROW_TYPE_ADD) { // Shows string saying that the user can add a new option, e.g. credit card no. - String typeface = resources.getString(R.string.roboto_medium_typeface); - int textStyle = resources.getInteger(R.integer.roboto_medium_textstyle); int buttonHeight = resources.getDimensionPixelSize( R.dimen.payments_section_add_button_height); @@ -951,7 +949,7 @@ labelView, R.style.PaymentsUiSectionAddButtonLabel); labelView.setMinimumHeight(buttonHeight); labelView.setGravity(Gravity.CENTER_VERTICAL); - labelView.setTypeface(Typeface.create(typeface, textStyle)); + labelView.setTypeface(UiUtils.createRobotoMediumTypeface()); } else if (mRowType == OPTION_ROW_TYPE_DESCRIPTION) { // The description spans all the columns. columnStart = 0;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java index f709b697..49df02c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java
@@ -6,13 +6,11 @@ import android.content.Context; import android.graphics.drawable.Drawable; -import android.os.Build; import android.preference.PreferenceGroup; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; -import android.text.style.TypefaceSpan; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; @@ -47,18 +45,8 @@ new SpannableStringBuilder(getContext().getResources().getString(resourceId)); String prefCount = String.format(Locale.getDefault(), " - %d", count); spannable.append(prefCount); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - spannable.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), - 0, - spannable.length() - prefCount.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } else { - spannable.setSpan(new TypefaceSpan("sans-serif-medium"), - 0, - spannable.length() - prefCount.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } + spannable.setSpan(new StyleSpan(R.style.RobotoMediumStyle), 0, + spannable.length() - prefCount.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Color the first part of the title blue. ForegroundColorSpan blueSpan = new ForegroundColorSpan(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java index 399fb26..a1c2350 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.preferences; import android.content.Context; -import android.graphics.Typeface; import android.preference.Preference; import android.util.AttributeSet; import android.util.TypedValue; @@ -15,6 +14,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; +import org.chromium.ui.UiUtils; /** * A preference that displays hint message to resolve sync error. Click of it navigates user to @@ -33,7 +33,7 @@ View view = super.onCreateView(parent); TextView title = (TextView) view.findViewById(android.R.id.title); title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); - title.setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL)); + title.setTypeface(UiUtils.createRobotoMediumTypeface()); title.setTextColor(ApiCompatibilityUtils.getColor( getContext().getResources(), R.color.input_underline_error_color)); return view;
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 94f2e2b..d56817e 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1773,7 +1773,7 @@ <message name="IDS_BROWSER_ACTIONS_SINGLE_LINK_OPEN_NOTIFICATION_TITLE" desc="Content title displayed in the notification when one link is opened in the background from Browser Actions. [CHAR-LIMIT=30]"> Link opened in Chrome </message> - <message name="IDS_BROWSER_ACTIONS_MULTI_LINKS_OPEN_NOTIFICATION_TITLE" desc="Content title displayed in the notification when multiple links are opened in the background from Browser Actions. [CHAR-LIMIT=30]"> + <message name="IDS_BROWSER_ACTIONS_MULTI_LINKS_OPEN_NOTIFICATION_TITLE" desc="Content title displayed in the notification when multiple links are opened in the background from Browser Actions. [CHAR-LIMIT=41]"> Multiple links opened in Chrome </message> <message name="IDS_BROWSER_ACTIONS_NOTIFICATION_TEXT" desc="Context text displayed in the notification when links are opened in the background from Browser Actions. [CHAR-LIMIT=30]"> @@ -2541,31 +2541,19 @@ </message> <!-- Omnibox --> - <message name="IDS_SEARCH_OR_TYPE_URL" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL. [CHAR-LIMIT=38]"> - Search or type URL - </message> <message name="IDS_LOCATION_BAR_VERBOSE_STATUS_OFFLINE" desc="Verbose indication of offline status in the location bar. [CHAR-LIMIT=20]"> Offline </message> <!-- Omnibox Placeholder Experiment --> - <message name="IDS_SEARCH_OR_TYPE_WEBSITE_NAME" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL. [CHAR-LIMIT=38]"> - Search or type website name + <message name="IDS_SEARCH_OR_TYPE_WEB_ADDRESS" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a website. [CHAR-LIMIT=38]"> + Search or type web address </message> - <message name="IDS_SEARCH_THE_WEB" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL. [CHAR-LIMIT=38]"> - Search the web + <message name="IDS_TYPE_WHAT_YOU_ARE_LOOKING_FOR" desc="Prompt to enter what user is looking for into the text field that will either perform web searches or navigate to a website. [CHAR-LIMIT=38]"> + Type what you’re looking for </message> - <message name="IDS_ENTER_A_SEARCH_OR_WEBSITE" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL. [CHAR-LIMIT=38]"> - Enter a search or website - </message> - <message name="IDS_SEARCH_NEWS" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL, with a suggestion of searching news. [CHAR-LIMIT=38]"> - Search… news - </message> - <message name="IDS_SEARCH_RECIPES" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL, with a suggestion of searching recipes. [CHAR-LIMIT=38]"> - Search… recipes - </message> - <message name="IDS_SEARCH_WEATHER" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL, with a suggestion of searching weather. [CHAR-LIMIT=38]"> - Search… weather + <message name="IDS_FIND_NEWS_RECIPES_WEATHER" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a website, with suggestions of finding news, recipes or weather. [CHAR-LIMIT=38]"> + Find news, recipes, weather... </message> <!-- Voice search -->
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index a72e0ac..158ce1e 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -621,7 +621,6 @@ "java/src/org/chromium/chrome/browser/ntp/LogoDelegateImpl.java", "java/src/org/chromium/chrome/browser/ntp/LogoView.java", "java/src/org/chromium/chrome/browser/ntp/NativePageAssassin.java", - "java/src/org/chromium/chrome/browser/ntp/NativePageDialog.java", "java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java", "java/src/org/chromium/chrome/browser/ntp/NativePageRootFrameLayout.java", "java/src/org/chromium/chrome/browser/ntp/NewTabPage.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java index 1dd80a0..84b1de4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
@@ -101,25 +101,11 @@ } /** - * Verify that WebShare is missing by default (without a flag). - * @throws Exception - */ - @Test - @MediumTest - @Feature({"WebShare"}) - public void testWebShareMissingWithoutFlag() throws Exception { - mActivityTestRule.loadUrl(mUrl); - mActivityTestRule.runJavaScriptCodeInCurrentTab("initiate_share()"); - Assert.assertEquals("Fail: navigator.share === undefined", mUpdateWaiter.waitForUpdate()); - } - - /** * Verify that WebShare fails if called without a user gesture. * @throws Exception */ @Test @MediumTest - @CommandLineFlags.Add("enable-blink-features=WebShare") @Feature({"WebShare"}) public void testWebShareNoUserGesture() throws Exception { mActivityTestRule.loadUrl(mUrl); @@ -130,28 +116,11 @@ } /** - * Verify that WebShare fails if the origin trial is disabled. - * @throws Exception - */ - @Test - @MediumTest - @CommandLineFlags.Add({"enable-blink-features=WebShare", - "origin-trial-disabled-features=WebShare"}) - @Feature({"WebShare"}) - public void testWebShareOriginTrialDisabled() throws Exception { - mActivityTestRule.loadUrl(mUrl); - TouchCommon.singleClickView(mTab.getView()); - Assert.assertEquals( - "Fail: SecurityError: WebShare is disabled.", mUpdateWaiter.waitForUpdate()); - } - - /** * Verify WebShare fails if share is called from a user gesture, and canceled. * @throws Exception */ @Test @MediumTest - @CommandLineFlags.Add("enable-blink-features=WebShare") @Feature({"WebShare"}) public void testWebShareCancel() throws Exception { // This test tests functionality that is only available post Lollipop MR1. @@ -184,7 +153,6 @@ */ @Test @MediumTest - @CommandLineFlags.Add("enable-blink-features=WebShare") @Feature({"WebShare"}) public void testWebShareSuccess() throws Exception { // This test tests functionality that is only available post Lollipop MR1. @@ -240,7 +208,6 @@ */ @Test @MediumTest - @CommandLineFlags.Add("enable-blink-features=WebShare") @Feature({"WebShare"}) public void testWebShareCancelPreLMR1() throws Exception { ShareHelper.setFakeIntentReceiverForTesting(new ShareHelper.FakeIntentReceiver() { @@ -271,7 +238,6 @@ */ @Test @MediumTest - @CommandLineFlags.Add("enable-blink-features=WebShare") @Feature({"WebShare"}) public void testWebShareSuccessPreLMR1() throws Exception { ShareHelper.setFakeIntentReceiverForTesting(new ShareHelper.FakeIntentReceiver() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskTest.java index 437bdd5..ef62836 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskTest.java
@@ -22,7 +22,6 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFinishedCallback; @@ -56,7 +55,6 @@ private Semaphore mStopSemaphore = new Semaphore(0); public TestPrefetchBackgroundTask(TaskInfo taskInfo) { - super(Profile.getLastUsedProfile()); mTaskInfo = taskInfo; }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java index 3c84028..06c1f88a 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskUnitTest.java
@@ -9,10 +9,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -20,6 +22,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; import org.mockito.invocation.InvocationOnMock; @@ -30,6 +35,9 @@ import org.robolectric.internal.ShadowExtractor; import org.robolectric.shadows.multidex.ShadowMultiDex; +import org.chromium.base.library_loader.ProcessInitException; +import org.chromium.chrome.browser.init.BrowserParts; +import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFinishedCallback; import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; @@ -76,12 +84,33 @@ } @Spy - private PrefetchBackgroundTask mPrefetchBackgroundTask = new PrefetchBackgroundTask(null); + private PrefetchBackgroundTask mPrefetchBackgroundTask = new PrefetchBackgroundTask(); + @Mock + private ChromeBrowserInitializer mChromeBrowserInitializer; + @Captor + ArgumentCaptor<BrowserParts> mBrowserParts; private ShadowBackgroundTaskScheduler mShadowTaskScheduler; @Before public void setUp() { MockitoAnnotations.initMocks(this); + doNothing().when(mChromeBrowserInitializer).handlePreNativeStartup(any(BrowserParts.class)); + try { + doAnswer(new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) { + mBrowserParts.getValue().finishNativeInitialization(); + return null; + } + }) + .when(mChromeBrowserInitializer) + .handlePostNativeStartup(eq(true), mBrowserParts.capture()); + } catch (ProcessInitException ex) { + fail("Unexpected exception while initializing mock of ChromeBrowserInitializer."); + } + + ChromeBrowserInitializer.setForTesting(mChromeBrowserInitializer); + doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) { mPrefetchBackgroundTask.setNativeTask(1); @@ -91,7 +120,7 @@ .when(mPrefetchBackgroundTask) .nativeStartPrefetchTask(any()); doReturn(true).when(mPrefetchBackgroundTask).nativeOnStopTask(1); - doNothing().when(mPrefetchBackgroundTask).launchBrowserIfNecessary(any()); + doReturn(null).when(mPrefetchBackgroundTask).getProfile(); mShadowTaskScheduler = (ShadowBackgroundTaskScheduler) ShadowExtractor.extract( BackgroundTaskSchedulerFactory.getScheduler());
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc index 25b891f3..234c16c 100644 --- a/chrome/app/chrome_main.cc +++ b/chrome/app/chrome_main.cc
@@ -4,6 +4,7 @@ #include <stdint.h> +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/time/time.h" #include "build/build_config.h" @@ -68,7 +69,11 @@ content::ContentMainParams params(&chrome_main_delegate); #if defined(OS_WIN) - // The process should crash when going through abnormal termination. + // The process should crash when going through abnormal termination, but we + // must be sure to reset this setting when ChromeMain returns normally. + auto crash_on_detach_resetter = base::ScopedClosureRunner( + base::Bind(&base::win::SetShouldCrashOnProcessDetach, + base::win::ShouldCrashOnProcessDetach())); base::win::SetShouldCrashOnProcessDetach(true); base::win::SetAbortBehaviorForCrashReporting(); params.instance = instance; @@ -124,9 +129,5 @@ int rv = content::ContentMain(params); -#if defined(OS_WIN) - base::win::SetShouldCrashOnProcessDetach(false); -#endif - return rv; }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index dcc4e4d..f7bd9cc 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5406,6 +5406,11 @@ <message name="IDS_OMNIBOX_CLEAR_ALL" desc="Accessibility text for the button that deletes all text input from the omnibox on touch devices."> Clear input </message> + <if expr="is_android"> + <message name="IDS_SEARCH_OR_TYPE_URL" desc="Prompt to enter text into the text field that will either perform web searches or navigate to a URL. [CHAR-LIMIT=38]" formatter_data="android_java"> + Search or type URL + </message> + </if> <!--Tooltip strings--> <message name="IDS_TOOLTIP_BACK" desc="The tooltip for back button">
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 03df9c6b..028cdb3b 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3176,20 +3176,14 @@ <message name="IDS_SETTINGS_POWER_IDLE_OTHER" desc="In Device Settings > Power, menu item for custom idle behavior."> Other </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_LABEL" desc="In Device Settings > Power, label for behavior when lid is closed."> - When lid is closed + <message name="IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL" desc="In Device Settings > Power, label for suspending when lid is closed."> + Sleep when lid is closed </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_SLEEP" desc="In Device Settings > Power, menu item for lid-closed behavior that puts the device to sleep."> - Sleep + <message name="IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL" desc="In Device Settings > Power, label for signing out when lid is closed."> + Sign out when lid is closed </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_STAY_AWAKE" desc="In Device Settings > Power, menu item for lid-closed behavior that prevents the device from sleeping."> - Stay awake - </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT" desc="In Device Settings > Power, menu item for lid-closed behavior that signs the user out."> - Sign out - </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN" desc="In Device Settings > Power, menu item for lid-closed behavior that shuts the system down."> - Shut down + <message name="IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL" desc="In Device Settings > Power, label for shutting down when lid is closed."> + Shut down when lid is closed </message> </if>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 72df3d62..4616e29 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2181,6 +2181,8 @@ "offline_pages/offliner_user_data.h", "offline_pages/prefetch/offline_metrics_collector_impl.cc", "offline_pages/prefetch/offline_metrics_collector_impl.h", + "offline_pages/prefetch/offline_prefetch_download_client.cc", + "offline_pages/prefetch/offline_prefetch_download_client.h", "offline_pages/prefetch/prefetch_instance_id_proxy.cc", "offline_pages/prefetch/prefetch_instance_id_proxy.h", "offline_pages/prefetch/prefetch_service_factory.cc",
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index c3bd542..608c851 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -186,10 +186,10 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kSearchEnginePromoExistingDevice{ - "SearchEnginePromo.ExistingDevice", base::FEATURE_DISABLED_BY_DEFAULT}; + "SearchEnginePromo.ExistingDevice", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kSearchEnginePromoNewDevice{ - "SearchEnginePromo.NewDevice", base::FEATURE_DISABLED_BY_DEFAULT}; + "SearchEnginePromo.NewDevice", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kNewPhotoPicker{"NewPhotoPicker", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn index c58ac362..89c566d 100644 --- a/chrome/browser/android/vr_shell/BUILD.gn +++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -34,6 +34,8 @@ "textures/button_texture.h", "textures/close_button_texture.cc", "textures/close_button_texture.h", + "textures/exclusive_screen_toast_texture.cc", + "textures/exclusive_screen_toast_texture.h", "textures/exit_prompt_texture.cc", "textures/exit_prompt_texture.h", "textures/exit_warning_texture.cc", @@ -44,8 +46,6 @@ "textures/insecure_content_transient_texture.h", "textures/loading_indicator_texture.cc", "textures/loading_indicator_texture.h", - "textures/presentation_toast_texture.cc", - "textures/presentation_toast_texture.h", "textures/render_text_wrapper.cc", "textures/render_text_wrapper.h", "textures/splash_screen_icon_texture.cc",
diff --git a/chrome/browser/android/vr_shell/color_scheme.cc b/chrome/browser/android/vr_shell/color_scheme.cc index 5545ecd..178fe5b1 100644 --- a/chrome/browser/android/vr_shell/color_scheme.cc +++ b/chrome/browser/android/vr_shell/color_scheme.cc
@@ -40,9 +40,9 @@ normal_scheme.exit_warning_foreground; normal_scheme.transient_warning_background = normal_scheme.exit_warning_background; - normal_scheme.presentation_toast_foreground = + normal_scheme.exclusive_screen_toast_foreground = normal_scheme.exit_warning_foreground; - normal_scheme.presentation_toast_background = + normal_scheme.exclusive_screen_toast_background = normal_scheme.exit_warning_background; normal_scheme.permanent_warning_foreground = 0xFF444444;
diff --git a/chrome/browser/android/vr_shell/color_scheme.h b/chrome/browser/android/vr_shell/color_scheme.h index b6516343..ccefb8bb 100644 --- a/chrome/browser/android/vr_shell/color_scheme.h +++ b/chrome/browser/android/vr_shell/color_scheme.h
@@ -45,8 +45,8 @@ SkColor exit_warning_background; SkColor transient_warning_foreground; SkColor transient_warning_background; - SkColor presentation_toast_foreground; - SkColor presentation_toast_background; + SkColor exclusive_screen_toast_foreground; + SkColor exclusive_screen_toast_background; SkColor permanent_warning_foreground; SkColor permanent_warning_background; SkColor system_indicator_foreground;
diff --git a/chrome/browser/android/vr_shell/textures/presentation_toast_texture.cc b/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc similarity index 75% rename from chrome/browser/android/vr_shell/textures/presentation_toast_texture.cc rename to chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc index 2729b85..62cb453b 100644 --- a/chrome/browser/android/vr_shell/textures/presentation_toast_texture.cc +++ b/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/vr_shell/textures/presentation_toast_texture.h" +#include "chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.h" #include "cc/paint/skia_paint_canvas.h" #include "chrome/grit/generated_resources.h" @@ -23,12 +23,12 @@ } // namespace -PresentationToastTexture::PresentationToastTexture() = default; +ExclusiveScreenToastTexture::ExclusiveScreenToastTexture() = default; -PresentationToastTexture::~PresentationToastTexture() = default; +ExclusiveScreenToastTexture::~ExclusiveScreenToastTexture() = default; -void PresentationToastTexture::Draw(SkCanvas* sk_canvas, - const gfx::Size& texture_size) { +void ExclusiveScreenToastTexture::Draw(SkCanvas* sk_canvas, + const gfx::Size& texture_size) { cc::SkiaPaintCanvas paint_canvas(sk_canvas); gfx::Canvas gfx_canvas(&paint_canvas, 1.0f); gfx::Canvas* canvas = &gfx_canvas; @@ -36,14 +36,14 @@ size_.set_width(texture_size.width()); SkPaint paint; - paint.setColor(color_scheme().presentation_toast_background); + paint.setColor(color_scheme().exclusive_screen_toast_background); auto text = l10n_util::GetStringUTF16(IDS_PRESS_APP_TO_EXIT); gfx::FontList fonts; GetFontList(size_.width() * kFontSizeFactor, text, &fonts); gfx::Rect text_size(size_.width() * kTextWidthFactor, 0); std::vector<std::unique_ptr<gfx::RenderText>> lines = PrepareDrawStringRect( - text, fonts, color_scheme().presentation_toast_foreground, &text_size, + text, fonts, color_scheme().exclusive_screen_toast_foreground, &text_size, kTextAlignmentCenter, kWrappingBehaviorWrap); DCHECK_LE(text_size.height(), @@ -61,12 +61,12 @@ canvas->Restore(); } -gfx::Size PresentationToastTexture::GetPreferredTextureSize( +gfx::Size ExclusiveScreenToastTexture::GetPreferredTextureSize( int maximum_width) const { return gfx::Size(maximum_width, maximum_width); } -gfx::SizeF PresentationToastTexture::GetDrawnSize() const { +gfx::SizeF ExclusiveScreenToastTexture::GetDrawnSize() const { return size_; }
diff --git a/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.h b/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.h new file mode 100644 index 0000000..6f7a49cc --- /dev/null +++ b/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.h
@@ -0,0 +1,30 @@ +// Copyright 2017 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_ANDROID_VR_SHELL_TEXTURES_EXCLUSIVE_SCREEN_TOAST_TEXTURE_H_ +#define CHROME_BROWSER_ANDROID_VR_SHELL_TEXTURES_EXCLUSIVE_SCREEN_TOAST_TEXTURE_H_ + +#include "base/macros.h" +#include "chrome/browser/android/vr_shell/textures/ui_texture.h" + +namespace vr_shell { + +class ExclusiveScreenToastTexture : public UiTexture { + public: + ExclusiveScreenToastTexture(); + ~ExclusiveScreenToastTexture() override; + gfx::Size GetPreferredTextureSize(int width) const override; + gfx::SizeF GetDrawnSize() const override; + + private: + void Draw(SkCanvas* canvas, const gfx::Size& texture_size) override; + + gfx::SizeF size_; + + DISALLOW_COPY_AND_ASSIGN(ExclusiveScreenToastTexture); +}; + +} // namespace vr_shell + +#endif // CHROME_BROWSER_ANDROID_VR_SHELL_TEXTURES_EXCLUSIVE_SCREEN_TOAST_TEXTURE_H_
diff --git a/chrome/browser/android/vr_shell/textures/presentation_toast_texture.h b/chrome/browser/android/vr_shell/textures/presentation_toast_texture.h deleted file mode 100644 index 649b1e6..0000000 --- a/chrome/browser/android/vr_shell/textures/presentation_toast_texture.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2017 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_ANDROID_VR_SHELL_TEXTURES_PRESENTATION_TOAST_TEXTURE_H_ -#define CHROME_BROWSER_ANDROID_VR_SHELL_TEXTURES_PRESENTATION_TOAST_TEXTURE_H_ - -#include "base/macros.h" -#include "chrome/browser/android/vr_shell/textures/ui_texture.h" - -namespace vr_shell { - -class PresentationToastTexture : public UiTexture { - public: - PresentationToastTexture(); - ~PresentationToastTexture() override; - gfx::Size GetPreferredTextureSize(int width) const override; - gfx::SizeF GetDrawnSize() const override; - - private: - void Draw(SkCanvas* canvas, const gfx::Size& texture_size) override; - - gfx::SizeF size_; - - DISALLOW_COPY_AND_ASSIGN(PresentationToastTexture); -}; - -} // namespace vr_shell - -#endif // CHROME_BROWSER_ANDROID_VR_SHELL_TEXTURES_PRESENTATION_TOAST_TEXTURE_H_
diff --git a/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h b/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h index f170fab4..4494bbc 100644 --- a/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h +++ b/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h
@@ -9,10 +9,10 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.h" #include "chrome/browser/android/vr_shell/textures/exit_warning_texture.h" #include "chrome/browser/android/vr_shell/textures/insecure_content_permanent_texture.h" #include "chrome/browser/android/vr_shell/textures/insecure_content_transient_texture.h" -#include "chrome/browser/android/vr_shell/textures/presentation_toast_texture.h" #include "chrome/browser/android/vr_shell/textures/splash_screen_icon_texture.h" #include "chrome/browser/android/vr_shell/textures/ui_texture.h" #include "chrome/browser/android/vr_shell/ui_elements/textured_element.h" @@ -42,7 +42,7 @@ PermanentSecurityWarning; typedef SimpleTexturedElement<InsecureContentTransientTexture> TransientSecurityWarning; -typedef SimpleTexturedElement<PresentationToastTexture> PresentationToast; +typedef SimpleTexturedElement<ExclusiveScreenToastTexture> ExclusiveScreenToast; typedef SimpleTexturedElement<SplashScreenIconTexture> SplashScreenIcon; } // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_elements/ui_element_debug_id.h b/chrome/browser/android/vr_shell/ui_elements/ui_element_debug_id.h index 26c2f6a7..91e82c4 100644 --- a/chrome/browser/android/vr_shell/ui_elements/ui_element_debug_id.h +++ b/chrome/browser/android/vr_shell/ui_elements/ui_element_debug_id.h
@@ -29,7 +29,7 @@ kExitPromptBackplane, kTransientUrlBar, kLocationAccessIndicator, - kPresentationToast, + kExclusiveScreenToast, kSplashScreenIcon, };
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc index 1596a3c..a0507a63 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager.cc +++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -425,8 +425,9 @@ } void UiSceneManager::CreateToasts() { - std::unique_ptr<UiElement> element = base::MakeUnique<PresentationToast>(512); - element->set_debug_id(kPresentationToast); + std::unique_ptr<UiElement> element = + base::MakeUnique<ExclusiveScreenToast>(512); + element->set_debug_id(kExclusiveScreenToast); element->set_id(AllocateId()); element->set_fill(vr_shell::Fill::NONE); element->set_size({kToastWidth, kToastHeight, 1}); @@ -434,7 +435,7 @@ element->set_visible(false); element->set_hit_testable(false); element->set_lock_to_fov(true); - presentation_toast_ = element.get(); + exclusive_screen_toast_ = element.get(); scene_->AddUiElement(std::move(element)); } @@ -454,7 +455,7 @@ toast_state_ = SET_FOR_WEB_VR; ConfigureScene(); ConfigureSecurityWarnings(); - ConfigurePresentationToast(); + ConfigureExclusiveScreenToast(); } void UiSceneManager::ConfigureScene() { @@ -601,7 +602,7 @@ fullscreen_ = fullscreen; toast_state_ = SET_FOR_FULLSCREEN; ConfigureScene(); - ConfigurePresentationToast(); + ConfigureExclusiveScreenToast(); } void UiSceneManager::ConfigureSecurityWarnings() { @@ -649,7 +650,7 @@ } } -void UiSceneManager::ConfigurePresentationToast() { +void UiSceneManager::ConfigureExclusiveScreenToast() { bool toast_visible = false; switch (toast_state_) { case SET_FOR_WEB_VR: @@ -661,13 +662,13 @@ case UNCHANGED: return; } - presentation_toast_->set_visible(toast_visible); + exclusive_screen_toast_->set_visible(toast_visible); if (toast_visible) { - presentation_toast_timer_.Start( + exclusive_screen_toast_timer_.Start( FROM_HERE, base::TimeDelta::FromSeconds(kToastTimeoutSeconds), this, - &UiSceneManager::OnPresentationToastTimer); + &UiSceneManager::OnExclusiveScreenToastTimer); } else { - presentation_toast_timer_.Stop(); + exclusive_screen_toast_timer_.Stop(); } toast_state_ = UNCHANGED; } @@ -692,8 +693,8 @@ transient_url_bar_->set_visible(false); } -void UiSceneManager::OnPresentationToastTimer() { - presentation_toast_->set_visible(false); +void UiSceneManager::OnExclusiveScreenToastTimer() { + exclusive_screen_toast_->set_visible(false); } void UiSceneManager::OnBackButtonClicked() {
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.h b/chrome/browser/android/vr_shell/ui_scene_manager.h index 7901ad99..e57883c 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager.h +++ b/chrome/browser/android/vr_shell/ui_scene_manager.h
@@ -83,12 +83,12 @@ void ConfigureSecurityWarnings(); void ConfigureTransientUrlBar(); void ConfigureIndicators(); - void ConfigurePresentationToast(); + void ConfigureExclusiveScreenToast(); void UpdateBackgroundColor(); void CloseExitPrompt(); void OnSecurityWarningTimer(); void OnTransientUrlBarTimer(); - void OnPresentationToastTimer(); + void OnExclusiveScreenToastTimer(); void OnBackButtonClicked(); void OnSecurityIconClicked(); void OnExitPromptPrimaryButtonClicked(); @@ -106,7 +106,7 @@ // UI element pointers (not owned by the scene manager). UiElement* permanent_security_warning_ = nullptr; UiElement* transient_security_warning_ = nullptr; - UiElement* presentation_toast_ = nullptr; + UiElement* exclusive_screen_toast_ = nullptr; UiElement* exit_prompt_ = nullptr; UiElement* exit_prompt_backplane_ = nullptr; UiElement* exit_warning_ = nullptr; @@ -147,7 +147,7 @@ base::OneShotTimer security_warning_timer_; base::OneShotTimer transient_url_bar_timer_; - base::OneShotTimer presentation_toast_timer_; + base::OneShotTimer exclusive_screen_toast_timer_; base::WeakPtrFactory<UiSceneManager> weak_ptr_factory_;
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc b/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc index 93d6988c..5e2efd9 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc +++ b/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc
@@ -167,28 +167,28 @@ // Tests toast not showing when directly entering VR though WebVR // presentation. MakeManager(kNotInCct, kInWebVr); - EXPECT_FALSE(IsVisible(kPresentationToast)); + EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); MakeManager(kNotInCct, kNotInWebVr); - EXPECT_FALSE(IsVisible(kPresentationToast)); + EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); manager_->SetFullscreen(true); - EXPECT_TRUE(IsVisible(kPresentationToast)); + EXPECT_TRUE(IsVisible(kExclusiveScreenToast)); manager_->SetWebVrMode(true, true); - EXPECT_TRUE(IsVisible(kPresentationToast)); + EXPECT_TRUE(IsVisible(kExclusiveScreenToast)); manager_->SetWebVrMode(false, false); - EXPECT_FALSE(IsVisible(kPresentationToast)); + EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); manager_->SetFullscreen(false); - EXPECT_FALSE(IsVisible(kPresentationToast)); + EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); manager_->SetWebVrMode(true, false); - EXPECT_FALSE(IsVisible(kPresentationToast)); + EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); manager_->SetWebVrMode(false, true); - EXPECT_TRUE(IsVisible(kPresentationToast)); + EXPECT_TRUE(IsVisible(kExclusiveScreenToast)); } TEST_F(UiSceneManagerTest, CloseButtonVisibleInCctFullscreen) { @@ -295,7 +295,7 @@ TEST_F(UiSceneManagerTest, UiUpdatesForFullscreenChanges) { std::set<UiElementDebugId> visible_in_fullscreen = { kContentQuad, kCloseButton, kBackplane, - kCeiling, kFloor, kPresentationToast, + kCeiling, kFloor, kExclusiveScreenToast, }; MakeManager(kNotInCct, kNotInWebVr);
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index efc1b8e..1d0f415 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -1466,8 +1466,7 @@ parsed_command_line_); } - ui::SelectFileDialog::SetFactory(new ChromeSelectFileDialogFactory( - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); + ui::SelectFileDialog::SetFactory(new ChromeSelectFileDialogFactory()); #endif // defined(OS_WIN) if (parsed_command_line().HasSwitch(switches::kMakeDefaultBrowser)) {
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 7e747d52..c5ec45e 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -56,7 +56,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/conflicts/module_watcher_win.h" #include "chrome/common/crash_keys.h" #include "chrome/common/env_vars.h" @@ -70,8 +69,6 @@ #include "chrome/installer/util/l10n_string_util.h" #include "chrome/installer/util/shell_util.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/utility_process_host.h" -#include "content/public/browser/utility_process_host_client.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "ui/base/cursor/cursor_loader_win.h"
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 1b93edb..a6280f1 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -112,7 +112,6 @@ #include "chrome/common/env_vars.h" #include "chrome/common/features.h" #include "chrome/common/logging_chrome.h" -#include "chrome/common/origin_trials/chrome_origin_trial_policy.h" #include "chrome/common/pepper_permission_util.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" @@ -3353,14 +3352,12 @@ } #endif - if (!ChromeOriginTrialPolicy().IsFeatureDisabled("WebShare")) { #if defined(OS_ANDROID) - frame_interfaces_parameterized_->AddInterface(base::Bind( - &ForwardToJavaWebContentsRegistry<blink::mojom::ShareService>)); + frame_interfaces_parameterized_->AddInterface(base::Bind( + &ForwardToJavaWebContentsRegistry<blink::mojom::ShareService>)); #elif defined(OS_LINUX) || defined(OS_WIN) - frame_interfaces_->AddInterface(base::Bind(&ShareServiceImpl::Create)); + frame_interfaces_->AddInterface(base::Bind(&ShareServiceImpl::Create)); #endif - } } #if BUILDFLAG(ENABLE_WEBRTC)
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc index 26322dc..a5e991a 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -413,6 +413,8 @@ // Do not expect that SetProfile() is called for various Profile instances. // At the moment, it is used for testing purposes. DCHECK(profile != profile_); + // TODO(yusukes): Once Shutdown() is removed, always call RequestStop() with + // |true|. We can actually remove the boolean parameter then. Shutdown(); profile_ = profile; @@ -470,7 +472,7 @@ playstore_launcher_.reset(); terms_of_service_negotiator_.reset(); android_management_checker_.reset(); - arc_session_runner_->RequestStop(); + arc_session_runner_->RequestStop(false); // TODO(hidehiko): The ARC instance's stopping is asynchronous, so it might // still be running when we return from this function. Do not set the // STOPPED state immediately here. @@ -624,7 +626,9 @@ DCHECK(profile_); if (!enable_requested_) { - VLOG(1) << "ARC is already disabled. Do nothing."; + VLOG(1) << "ARC is already disabled. " + << "Killing an instance for login screen (if any)."; + arc_session_runner_->RequestStop(true); return; } enable_requested_ = false;
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc index 6541abb..4ffc5b6 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -638,10 +638,6 @@ ASSERT_FALSE(registry()->IsHandledProtocol("test")); } -// TODO(smckay): This is much more appropriately an integration -// test. Make that so, then update the -// ShellIntegretion{Delegate,Callback,Worker} test classes we use to fully -// isolate this test from the FILE thread. TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) { ProtocolHandler ph_do1 = CreateProtocolHandler("do", "test1"); ProtocolHandler ph_do2 = CreateProtocolHandler("do", "test2"); @@ -671,10 +667,6 @@ #define MAYBE_TestOSRegistrationFailure TestOSRegistrationFailure #endif -// TODO(smckay): This is much more appropriately an integration -// test. Make that so, then update the -// ShellIntegretion{Delegate,Callback,Worker} test classes we use to fully -// isolate this test from the FILE thread. TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestOSRegistrationFailure) { ProtocolHandler ph_do = CreateProtocolHandler("do", "test1"); ProtocolHandler ph_dont = CreateProtocolHandler("dont", "test");
diff --git a/chrome/browser/download/download_service_factory.cc b/chrome/browser/download/download_service_factory.cc index 05a415bc..c37af5b 100644 --- a/chrome/browser/download/download_service_factory.cc +++ b/chrome/browser/download/download_service_factory.cc
@@ -19,12 +19,17 @@ #include "components/download/public/download_service.h" #include "components/download/public/task_scheduler.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/offline_pages/features/features.h" #include "content/public/browser/browser_context.h" #if defined(OS_ANDROID) #include "chrome/browser/android/download/service/download_task_scheduler.h" #endif +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +#include "chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h" +#endif + // static DownloadServiceFactory* DownloadServiceFactory::GetInstance() { return base::Singleton<DownloadServiceFactory>::get(); @@ -48,7 +53,11 @@ content::BrowserContext* context) const { auto clients = base::MakeUnique<download::DownloadClientMap>(); - // TODO(dtrainor): Register all clients here. +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + clients->insert(std::make_pair( + download::DownloadClient::OFFLINE_PAGE_PREFETCH, + base::MakeUnique<offline_pages::OfflinePrefetchDownloadClient>(context))); +#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) auto* download_manager = content::BrowserContext::GetDownloadManager(context);
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc index 796f1f37..1001d5bf 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
@@ -61,6 +61,30 @@ std::vector<std::unique_ptr<DesktopMediaList>> source_lists, bool request_audio, const DoneCallback& done_callback) override { + bool show_screens = false; + bool show_windows = false; + bool show_tabs = false; + + for (auto& source_list : source_lists) { + switch (source_list->GetMediaListType()) { + case DesktopMediaID::TYPE_NONE: + break; + case DesktopMediaID::TYPE_SCREEN: + show_screens = true; + break; + case DesktopMediaID::TYPE_WINDOW: + show_windows = true; + break; + case DesktopMediaID::TYPE_WEB_CONTENTS: + show_tabs = true; + break; + } + } + EXPECT_EQ(expectation_->expect_screens, show_screens); + EXPECT_EQ(expectation_->expect_windows, show_windows); + EXPECT_EQ(expectation_->expect_tabs, show_tabs); + EXPECT_EQ(expectation_->expect_audio, request_audio); + if (!expectation_->cancelled) { // Post a task to call the callback asynchronously. base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -98,34 +122,6 @@ current_test_ = 0; } - // DesktopCaptureChooseDesktopMediaFunction::PickerFactory interface. - MediaListArray CreateModel( - bool show_screens, - bool show_windows, - bool show_tabs, - bool show_audio) override { - EXPECT_LE(current_test_, tests_count_); - MediaListArray media_lists; - if (current_test_ >= tests_count_) { - return media_lists; - } - EXPECT_EQ(test_flags_[current_test_].expect_screens, show_screens); - EXPECT_EQ(test_flags_[current_test_].expect_windows, show_windows); - EXPECT_EQ(test_flags_[current_test_].expect_tabs, show_tabs); - EXPECT_EQ(test_flags_[current_test_].expect_audio, show_audio); - - media_lists[0] = std::unique_ptr<DesktopMediaList>( - show_screens ? new FakeDesktopMediaList(DesktopMediaID::TYPE_SCREEN) - : nullptr); - media_lists[1] = std::unique_ptr<DesktopMediaList>( - show_windows ? new FakeDesktopMediaList(DesktopMediaID::TYPE_WINDOW) - : nullptr); - media_lists[2] = std::unique_ptr<DesktopMediaList>( - show_tabs ? new FakeDesktopMediaList(DesktopMediaID::TYPE_WEB_CONTENTS) - : nullptr); - return media_lists; - } - std::unique_ptr<DesktopMediaPicker> CreatePicker() override { EXPECT_LE(current_test_, tests_count_); if (current_test_ >= tests_count_) @@ -135,6 +131,12 @@ new FakeDesktopMediaPicker(test_flags_ + current_test_ - 1)); } + std::unique_ptr<DesktopMediaList> CreateMediaList( + DesktopMediaID::Type type) override { + EXPECT_LE(current_test_, tests_count_); + return std::unique_ptr<DesktopMediaList>(new FakeDesktopMediaList(type)); + } + private: TestFlags* test_flags_; int tests_count_;
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index 29763ff..05ca164 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -82,56 +82,6 @@ // Register to be notified when the tab is closed. Observe(web_contents); - bool show_screens = false; - bool show_windows = false; - bool show_tabs = false; - bool request_audio = false; - - std::vector<DesktopMediaID::Type> source_types; - - for (auto source_type : sources) { - // Avoid duplicates in the input |sources|. - if (std::find(source_types.begin(), source_types.end(), source_type) != - source_types.end()) { - continue; - } - - switch (source_type) { - case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_NONE: - error_ = kInvalidSourceNameError; - return false; - - case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_SCREEN: - source_types.push_back(DesktopMediaID::TYPE_SCREEN); - show_screens = true; - break; - - case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_WINDOW: - source_types.push_back(DesktopMediaID::TYPE_WINDOW); - show_windows = true; - break; - - case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_TAB: - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - extensions::switches::kDisableTabForDesktopShare)) { - source_types.push_back(DesktopMediaID::TYPE_WEB_CONTENTS); - show_tabs = true; - } - break; - - case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_AUDIO: - bool has_flag = base::CommandLine::ForCurrentProcess()->HasSwitch( - extensions::switches::kDisableDesktopCaptureAudio); - request_audio = !has_flag; - break; - } - } - - if (!show_screens && !show_windows && !show_tabs) { - error_ = kEmptySourcesListError; - return false; - } - gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow(); // In case of coming from background extension page, |parent_window| will // be null. We are going to make the picker modal to the current browser @@ -143,59 +93,110 @@ if (target_browser) parent_window = target_browser->window()->GetNativeWindow(); } - std::unique_ptr<DesktopMediaList> screen_list; - std::unique_ptr<DesktopMediaList> window_list; - std::unique_ptr<DesktopMediaList> tab_list; + + // Keep same order as the input |sources| and avoid duplicates. + std::vector<std::unique_ptr<DesktopMediaList>> source_lists; + bool have_screen_list = false; + bool have_window_list = false; + bool have_tab_list = false; + bool request_audio = false; + for (auto source_type : sources) { + switch (source_type) { + case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_NONE: { + error_ = kInvalidSourceNameError; + return false; + } + case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_SCREEN: { + if (have_screen_list) { + continue; + } + std::unique_ptr<DesktopMediaList> screen_list; + if (g_picker_factory) { + screen_list = + g_picker_factory->CreateMediaList(DesktopMediaID::TYPE_SCREEN); + } else { +#if defined(USE_ASH) + screen_list = base::MakeUnique<DesktopMediaListAsh>( + DesktopMediaID::TYPE_SCREEN); +#else // !defined(USE_ASH) + webrtc::DesktopCaptureOptions capture_options = + webrtc::DesktopCaptureOptions::CreateDefault(); + capture_options.set_disable_effects(false); + screen_list = base::MakeUnique<NativeDesktopMediaList>( + DesktopMediaID::TYPE_SCREEN, + webrtc::DesktopCapturer::CreateScreenCapturer(capture_options)); +#endif // !defined(USE_ASH) + } + have_screen_list = true; + source_lists.push_back(std::move(screen_list)); + break; + } + case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_WINDOW: { + if (have_window_list) { + continue; + } + std::unique_ptr<DesktopMediaList> window_list; + if (g_picker_factory) { + window_list = + g_picker_factory->CreateMediaList(DesktopMediaID::TYPE_WINDOW); + } else { +#if defined(USE_ASH) + window_list = base::MakeUnique<DesktopMediaListAsh>( + DesktopMediaID::TYPE_WINDOW); +#else // !defined(USE_ASH) + // NativeDesktopMediaList calls the capturers on a background thread. + // This means that the two DesktopCapturer instances (for screens and + // windows) created here cannot share the same DesktopCaptureOptions + // instance. DesktopCaptureOptions owns X connection, which cannot be + // used on multiple threads concurrently. + webrtc::DesktopCaptureOptions capture_options = + webrtc::DesktopCaptureOptions::CreateDefault(); + capture_options.set_disable_effects(false); + window_list = base::MakeUnique<NativeDesktopMediaList>( + DesktopMediaID::TYPE_WINDOW, + webrtc::DesktopCapturer::CreateWindowCapturer(capture_options)); +#endif // !defined(USE_ASH) + } + have_window_list = true; + source_lists.push_back(std::move(window_list)); + break; + } + case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_TAB: { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + extensions::switches::kDisableTabForDesktopShare) || + have_tab_list) { + continue; + } + std::unique_ptr<DesktopMediaList> tab_list; + if (g_picker_factory) { + tab_list = g_picker_factory->CreateMediaList( + DesktopMediaID::TYPE_WEB_CONTENTS); + } else { + tab_list = base::MakeUnique<TabDesktopMediaList>(); + } + have_tab_list = true; + source_lists.push_back(std::move(tab_list)); + break; + } + case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_AUDIO: { + bool audio_capture_disabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + extensions::switches::kDisableDesktopCaptureAudio); + if (!audio_capture_disabled) { + request_audio = true; + } + break; + } + } + } + if (source_lists.empty()) { + error_ = kEmptySourcesListError; + return false; + } + if (g_picker_factory) { - PickerFactory::MediaListArray media_lists = - g_picker_factory->CreateModel(show_screens, show_windows, show_tabs, - request_audio); - screen_list = std::move(media_lists[0]); - window_list = std::move(media_lists[1]); - tab_list = std::move(media_lists[2]); picker_ = g_picker_factory->CreatePicker(); } else { - // Create a screens list. - if (show_screens) { -#if defined(USE_ASH) - screen_list = - base::MakeUnique<DesktopMediaListAsh>(DesktopMediaID::TYPE_SCREEN); -#else // !defined(USE_ASH) - webrtc::DesktopCaptureOptions capture_options = - webrtc::DesktopCaptureOptions::CreateDefault(); - capture_options.set_disable_effects(false); - screen_list = base::MakeUnique<NativeDesktopMediaList>( - DesktopMediaID::TYPE_SCREEN, - webrtc::DesktopCapturer::CreateScreenCapturer(capture_options)); -#endif // !defined(USE_ASH) - } - - // Create a windows list. - if (show_windows) { -#if defined(USE_ASH) - window_list = - base::MakeUnique<DesktopMediaListAsh>(DesktopMediaID::TYPE_WINDOW); -#else // !defined(USE_ASH) - // NativeDesktopMediaList calls the capturers on a background - // thread. This means that the two DesktopCapturer instances (for screens - // and windows) created here cannot share the same DesktopCaptureOptions - // instance. DesktopCaptureOptions owns X connection, which cannot be used - // on multiple threads concurrently. - webrtc::DesktopCaptureOptions capture_options = - webrtc::DesktopCaptureOptions::CreateDefault(); - capture_options.set_disable_effects(false); - window_list = base::MakeUnique<NativeDesktopMediaList>( - DesktopMediaID::TYPE_WINDOW, - webrtc::DesktopCapturer::CreateWindowCapturer(capture_options)); -#endif // !defined(USE_ASH) - } - - if (show_tabs) - tab_list = base::MakeUnique<TabDesktopMediaList>(); - - DCHECK(screen_list || window_list || tab_list); - DCHECK(!source_types.empty()); - // DesktopMediaPicker is implemented only for Windows, OSX and // Aura Linux builds. #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) @@ -206,28 +207,6 @@ #endif } - // Keep same order as the input |sources|. - std::vector<std::unique_ptr<DesktopMediaList>> source_lists; - for (auto source_type : source_types) { - switch (source_type) { - case DesktopMediaID::TYPE_NONE: - NOTREACHED(); - break; - case DesktopMediaID::TYPE_SCREEN: - if (screen_list) - source_lists.push_back(std::move(screen_list)); - break; - case DesktopMediaID::TYPE_WINDOW: - if (window_list) - source_lists.push_back(std::move(window_list)); - break; - case DesktopMediaID::TYPE_WEB_CONTENTS: - if (tab_list) - source_lists.push_back(std::move(tab_list)); - break; - } - } - DesktopMediaPicker::DoneCallback callback = base::Bind( &DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults, this);
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h index f4f03f04..a5643287 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h
@@ -28,13 +28,9 @@ // Used for tests to supply fake picker. class PickerFactory { public: - typedef std::array<std::unique_ptr<DesktopMediaList>, 3> MediaListArray; - virtual MediaListArray CreateModel( - bool show_screens, - bool show_windows, - bool show_tabs, - bool show_audio) = 0; virtual std::unique_ptr<DesktopMediaPicker> CreatePicker() = 0; + virtual std::unique_ptr<DesktopMediaList> CreateMediaList( + content::DesktopMediaID::Type type) = 0; protected: PickerFactory() = default;
diff --git a/chrome/browser/extensions/api/socket/socket_api_unittest.cc b/chrome/browser/extensions/api/socket/socket_api_unittest.cc index c174cc6..34e18a1 100644 --- a/chrome/browser/extensions/api/socket/socket_api_unittest.cc +++ b/chrome/browser/extensions/api/socket/socket_api_unittest.cc
@@ -5,6 +5,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/extensions/extension_api_unittest.h" @@ -35,13 +36,9 @@ }; TEST_F(SocketUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketCreateFunction* function = new SocketCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(
diff --git a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc index 7801b0d..dbcdc6a2 100644 --- a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc +++ b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc
@@ -5,6 +5,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/extensions/extension_api_unittest.h" @@ -48,14 +49,10 @@ }; TEST_F(SocketsTcpServerUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketsTcpServerCreateFunction* function = new SocketsTcpServerCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc index 9e9dd82..dd6db4ce 100644 --- a/chrome/browser/extensions/bookmark_app_helper.cc +++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -9,6 +9,7 @@ #include <cctype> #include <string> +#include "base/command_line.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -40,6 +41,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/image_loader.h" @@ -67,7 +69,6 @@ #include "ui/gfx/image/image_family.h" #if defined(OS_MACOSX) -#include "base/command_line.h" #include "chrome/browser/web_applications/web_app_mac.h" #include "chrome/common/chrome_switches.h" #endif @@ -590,8 +591,12 @@ UpdateWebAppInfoFromManifest(manifest, &web_app_info_); - if (!ChromeOriginTrialPolicy().IsFeatureDisabled("WebShare")) + // TODO(mgiuca): Web Share Target should have its own flag, rather than using + // the experimental-web-platform-features flag. https://crbug.com/736178. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExperimentalWebPlatformFeatures)) { UpdateShareTargetInPrefs(manifest_url, manifest, profile_->GetPrefs()); + } // Add urls from the WebApplicationInfo. std::vector<GURL> web_app_info_icon_urls;
diff --git a/chrome/browser/history/top_sites_factory.cc b/chrome/browser/history/top_sites_factory.cc index 97a0ac9a..dc0163a 100644 --- a/chrome/browser/history/top_sites_factory.cc +++ b/chrome/browser/history/top_sites_factory.cc
@@ -103,9 +103,7 @@ profile->GetPrefs(), HistoryServiceFactory::GetForProfile( profile, ServiceAccessType::EXPLICIT_ACCESS), prepopulated_page_list, base::Bind(CanAddURLToHistory))); - top_sites->Init(context->GetPath().Append(history::kTopSitesFilename), - content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::DB)); + top_sites->Init(context->GetPath().Append(history::kTopSitesFilename)); return top_sites; }
diff --git a/chrome/browser/media/android/router/media_router_dialog_controller_android.cc b/chrome/browser/media/android/router/media_router_dialog_controller_android.cc index ca4ef76..08983f6 100644 --- a/chrome/browser/media/android/router/media_router_dialog_controller_android.cc +++ b/chrome/browser/media/android/router/media_router_dialog_controller_android.cc
@@ -18,8 +18,13 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" +#include "device/vr/features/features.h" #include "jni/ChromeMediaRouterDialogController_jni.h" +#if BUILDFLAG(ENABLE_VR) +#include "chrome/browser/android/vr_shell/vr_tab_helper.h" +#endif // BUILDFLAG(ENABLE_VR) + DEFINE_WEB_CONTENTS_USER_DATA_KEY( media_router::MediaRouterDialogControllerAndroid); @@ -143,6 +148,14 @@ } void MediaRouterDialogControllerAndroid::CreateMediaRouterDialog() { +#if BUILDFLAG(ENABLE_VR) + // TODO(crbug.com/736568): Re-enable dialog in VR. + if (vr_shell::VrTabHelper::IsInVr(initiator())) { + CancelPresentationRequest(); + return; + } +#endif // BUILDFLAG(ENABLE_VR) + JNIEnv* env = base::android::AttachCurrentThread(); const std::vector<MediaSource> sources =
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc new file mode 100644 index 0000000..a2d49a9 --- /dev/null +++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc
@@ -0,0 +1,67 @@ +// Copyright 2017 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/offline_pages/prefetch/offline_prefetch_download_client.h" + +#include "base/logging.h" +#include "chrome/browser/download/download_service_factory.h" +#include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" +#include "components/offline_pages/core/prefetch/prefetch_downloader.h" +#include "components/offline_pages/core/prefetch/prefetch_service.h" + +namespace offline_pages { + +OfflinePrefetchDownloadClient::OfflinePrefetchDownloadClient( + content::BrowserContext* context) + : context_(context) {} + +OfflinePrefetchDownloadClient::~OfflinePrefetchDownloadClient() = default; + +void OfflinePrefetchDownloadClient::OnServiceInitialized( + const std::vector<std::string>& outstanding_download_guids) { + // TODO(jianli): Remove orphaned downloads. + PrefetchDownloader* downloader = GetPrefetchDownloader(); + if (downloader) + downloader->OnDownloadServiceReady(); +} + +download::Client::ShouldDownload +OfflinePrefetchDownloadClient::OnDownloadStarted( + const std::string& guid, + const std::vector<GURL>& url_chain, + const scoped_refptr<const net::HttpResponseHeaders>& headers) { + return download::Client::ShouldDownload::CONTINUE; +} + +void OfflinePrefetchDownloadClient::OnDownloadUpdated( + const std::string& guid, + uint64_t bytes_downloaded) {} + +void OfflinePrefetchDownloadClient::OnDownloadFailed( + const std::string& guid, + download::Client::FailureReason reason) { + PrefetchDownloader* downloader = GetPrefetchDownloader(); + if (downloader) + downloader->OnDownloadFailed(guid); +} + +void OfflinePrefetchDownloadClient::OnDownloadSucceeded( + const std::string& guid, + const base::FilePath& path, + uint64_t size) { + PrefetchDownloader* downloader = GetPrefetchDownloader(); + if (downloader) + downloader->OnDownloadSucceeded(guid, path, size); +} + +PrefetchDownloader* OfflinePrefetchDownloadClient::GetPrefetchDownloader() + const { + PrefetchService* prefetch_service = + PrefetchServiceFactory::GetForBrowserContext(context_); + if (!prefetch_service) + return nullptr; + return prefetch_service->GetPrefetchDownloader(); +} + +} // namespace offline_pages
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h new file mode 100644 index 0000000..3a258ff --- /dev/null +++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h
@@ -0,0 +1,49 @@ +// Copyright 2017 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_OFFLINE_PAGES_PREFETCH_OFFLINE_PREFETCH_DOWNLOAD_CLIENT_H_ +#define CHROME_BROWSER_OFFLINE_PAGES_PREFETCH_OFFLINE_PREFETCH_DOWNLOAD_CLIENT_H_ + +#include "base/macros.h" +#include "components/download/public/client.h" + +namespace content { +class BrowserContext; +} + +namespace offline_pages { + +class PrefetchDownloader; + +class OfflinePrefetchDownloadClient : public download::Client { + public: + explicit OfflinePrefetchDownloadClient(content::BrowserContext* context); + ~OfflinePrefetchDownloadClient() override; + + private: + // Overridden from Client: + void OnServiceInitialized( + const std::vector<std::string>& outstanding_download_guids) override; + download::Client::ShouldDownload OnDownloadStarted( + const std::string& guid, + const std::vector<GURL>& url_chain, + const scoped_refptr<const net::HttpResponseHeaders>& headers) override; + void OnDownloadUpdated(const std::string& guid, + uint64_t bytes_downloaded) override; + void OnDownloadFailed(const std::string& guid, + download::Client::FailureReason reason) override; + void OnDownloadSucceeded(const std::string& guid, + const base::FilePath& path, + uint64_t size) override; + + PrefetchDownloader* GetPrefetchDownloader() const; + + content::BrowserContext* context_; + + DISALLOW_COPY_AND_ASSIGN(OfflinePrefetchDownloadClient); +}; + +} // namespace offline_pages + +#endif // CHROME_BROWSER_OFFLINE_PAGES_PREFETCH_OFFLINE_PREFETCH_DOWNLOAD_CLIENT_H_
diff --git a/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc b/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc index 34eaf11..12dbcc3 100644 --- a/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc +++ b/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/singleton.h" +#include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/offline_pages/prefetch/offline_metrics_collector_impl.h" #include "chrome/browser/offline_pages/prefetch/prefetch_instance_id_proxy.h" #include "chrome/browser/profiles/profile.h" @@ -16,6 +17,7 @@ #include "chrome/common/chrome_content_client.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h" +#include "components/offline_pages/core/prefetch/prefetch_downloader.h" #include "components/offline_pages/core/prefetch/prefetch_gcm_app_handler.h" #include "components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.h" #include "components/offline_pages/core/prefetch/prefetch_service_impl.h" @@ -27,7 +29,10 @@ PrefetchServiceFactory::PrefetchServiceFactory() : BrowserContextKeyedServiceFactory( "OfflinePagePrefetchService", - BrowserContextDependencyManager::GetInstance()) {} + BrowserContextDependencyManager::GetInstance()) { + DependsOn(DownloadServiceFactory::GetInstance()); +} + // static PrefetchServiceFactory* PrefetchServiceFactory::GetInstance() { return base::Singleton<PrefetchServiceFactory>::get(); @@ -55,11 +60,15 @@ auto suggested_articles_observer = base::MakeUnique<SuggestedArticlesObserver>(); - return new PrefetchServiceImpl(std::move(offline_metrics_collector), - std::move(prefetch_dispatcher), - std::move(prefetch_gcm_app_handler), - std::move(prefetch_network_request_factory), - std::move(suggested_articles_observer)); + auto prefetch_downloader = base::MakeUnique<PrefetchDownloader>( + DownloadServiceFactory::GetForBrowserContext(context), + chrome::GetChannel()); + + return new PrefetchServiceImpl( + std::move(offline_metrics_collector), std::move(prefetch_dispatcher), + std::move(prefetch_gcm_app_handler), + std::move(prefetch_network_request_factory), + std::move(suggested_articles_observer), std::move(prefetch_downloader)); } } // namespace offline_pages
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index abab796..f04aef7 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -199,21 +199,6 @@ net::URLRequestContextStorage* main_context_storage = main_request_context_storage(); - IOThread* const io_thread = profile_params->io_thread; - IOThread::Globals* const io_thread_globals = io_thread->globals(); - - ApplyProfileParamsToContext(main_context); - - main_context->set_transport_security_state(transport_security_state()); - main_context->set_ct_policy_enforcer( - io_thread_globals->system_request_context->ct_policy_enforcer()); - - main_context->set_net_log(io_thread->net_log()); - - main_context->set_http_auth_handler_factory( - io_thread_globals->system_request_context->http_auth_handler_factory()); - main_context->set_proxy_service(proxy_service()); - // For incognito, we use the default non-persistent HttpServerPropertiesImpl. main_context_storage->set_http_server_properties( base::MakeUnique<net::HttpServerPropertiesImpl>());
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 81a5cbf2..f35c5a4 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -469,24 +469,12 @@ IOThread* const io_thread = profile_params->io_thread; IOThread::Globals* const io_thread_globals = io_thread->globals(); - ApplyProfileParamsToContext(main_context); - if (lazy_params_->http_server_properties_manager) { lazy_params_->http_server_properties_manager->InitializeOnNetworkSequence(); main_context_storage->set_http_server_properties( std::move(lazy_params_->http_server_properties_manager)); } - main_context->set_transport_security_state(transport_security_state()); - main_context->set_ct_policy_enforcer( - io_thread_globals->system_request_context->ct_policy_enforcer()); - - main_context->set_net_log(io_thread->net_log()); - - main_context->set_http_auth_handler_factory( - io_thread_globals->system_request_context->http_auth_handler_factory()); - - main_context->set_proxy_service(proxy_service()); main_context->set_network_quality_estimator( io_thread_globals->network_quality_estimator.get()); @@ -796,9 +784,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(initialized()); - DCHECK(transport_security_state()); // Completes synchronously. - transport_security_state()->DeleteAllDynamicDataSince(time); + main_request_context()->transport_security_state()->DeleteAllDynamicDataSince( + time); DCHECK(http_server_properties_manager_); http_server_properties_manager_->Clear(completion); }
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 128b17e..824002c 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -658,39 +658,33 @@ static_cast<void*>(it->second), sizeof(void*)); } - // Prevent the TreeStateTracker from getting any more notifications by - // severing the link between it and the CTVerifier and unregistering it from - // new STH notifications. - // - // Only do this if the |cert_transparency_verifier_| is not null. - if (cert_transparency_verifier_) { - cert_transparency_verifier_->SetObserver(nullptr); + if (main_request_context_) { + // Prevent the TreeStateTracker from getting any more notifications by + // severing the link between it and the CTVerifier and unregistering it from + // new STH notifications. + main_request_context_->cert_transparency_verifier()->SetObserver(nullptr); ct_tree_tracker_unregistration_.Run(); - } - // Destroy certificate_report_sender_ before main_request_context_, - // since the former has a reference to the latter. - if (transport_security_state_) - transport_security_state_->SetReportSender(nullptr); - certificate_report_sender_.reset(); + // Destroy certificate_report_sender_ before main_request_context_, + // since the former has a reference to the latter. + main_request_context_->transport_security_state()->SetReportSender(nullptr); + certificate_report_sender_.reset(); - if (transport_security_state_) - transport_security_state_->SetExpectCTReporter(nullptr); - expect_ct_reporter_.reset(); + main_request_context_->transport_security_state()->SetExpectCTReporter( + nullptr); + expect_ct_reporter_.reset(); - if (transport_security_state_) - transport_security_state_->SetRequireCTDelegate(nullptr); + main_request_context_->transport_security_state()->SetRequireCTDelegate( + nullptr); - // And the same for the ReportingService. - if (main_request_context_storage()) { + // And the same for the ReportingService. main_request_context_storage()->set_reporting_service( std::unique_ptr<net::ReportingService>()); - } - // This should be shut down last, as any other requests may initiate more - // activity when the ProxyService aborts lookups. - if (proxy_service_) - proxy_service_->OnShutdown(); + // This should be shut down last, as any other requests may initiate more + // activity when the ProxyService aborts lookups. + main_request_context_->proxy_service()->OnShutdown(); + } // TODO(ajwong): These AssertNoURLRequests() calls are unnecessary since they // are already done in the URLRequestContext destructor. @@ -1004,13 +998,18 @@ const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); - // Create the common request contexts. + // Create extension request context. Only used for cookies. + extensions_request_context_.reset(new net::URLRequestContext()); + extensions_request_context_->set_name("extensions"); + + // Create the main request context. main_request_context_.reset(new net::URLRequestContext()); main_request_context_storage_.reset( new net::URLRequestContextStorage(main_request_context_.get())); - extensions_request_context_.reset(new net::URLRequestContext()); main_request_context_->set_name("main"); - extensions_request_context_->set_name("extensions"); + + ApplyProfileParamsToContext(main_request_context_.get()); + main_request_context_->set_net_log(io_thread->net_log()); main_request_context_->set_enable_brotli(io_thread_globals->enable_brotli); @@ -1053,20 +1052,24 @@ main_request_context_->set_host_resolver( io_thread_globals->system_request_context->host_resolver()); - // NOTE: Proxy service uses the default io thread network delegate, not the - // delegate just created. - proxy_service_ = ProxyServiceFactory::CreateProxyService( - io_thread->net_log(), main_request_context_.get(), network_delegate.get(), - std::move(profile_params_->proxy_config_service), command_line, - io_thread->WpadQuickCheckEnabled(), - io_thread->PacHttpsUrlStrippingEnabled()); + main_request_context_->set_http_auth_handler_factory( + io_thread_globals->system_request_context->http_auth_handler_factory()); + + main_request_context_storage_->set_proxy_service( + ProxyServiceFactory::CreateProxyService( + io_thread->net_log(), main_request_context_.get(), + network_delegate.get(), + std::move(profile_params_->proxy_config_service), command_line, + io_thread->WpadQuickCheckEnabled(), + io_thread->PacHttpsUrlStrippingEnabled())); main_request_context_storage_->set_network_delegate( std::move(network_delegate)); - transport_security_state_.reset(new net::TransportSecurityState()); + std::unique_ptr<net::TransportSecurityState> transport_security_state( + base::MakeUnique<net::TransportSecurityState>()); transport_security_persister_.reset(new net::TransportSecurityPersister( - transport_security_state_.get(), profile_params_->path, + transport_security_state.get(), profile_params_->path, base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}), @@ -1102,14 +1105,16 @@ })"); certificate_report_sender_.reset( new net::ReportSender(main_request_context_.get(), traffic_annotation)); - transport_security_state_->SetReportSender(certificate_report_sender_.get()); + transport_security_state->SetReportSender(certificate_report_sender_.get()); expect_ct_reporter_.reset( new ChromeExpectCTReporter(main_request_context_.get())); - transport_security_state_->SetExpectCTReporter(expect_ct_reporter_.get()); + transport_security_state->SetExpectCTReporter(expect_ct_reporter_.get()); - transport_security_state_->SetRequireCTDelegate( + transport_security_state->SetRequireCTDelegate( ct_policy_manager_->GetDelegate()); + main_request_context_storage_->set_transport_security_state( + std::move(transport_security_state)); // Take ownership over these parameters. cookie_settings_ = profile_params_->cookie_settings; @@ -1169,18 +1174,22 @@ std::unique_ptr<net::MultiLogCTVerifier> ct_verifier( new net::MultiLogCTVerifier()); ct_verifier->AddLogs(io_thread_globals->ct_logs); - main_request_context_->set_cert_transparency_verifier(ct_verifier.get()); ct_tree_tracker_.reset(new certificate_transparency::TreeStateTracker( io_thread_globals->ct_logs, io_thread->net_log())); ct_verifier->SetObserver(ct_tree_tracker_.get()); - cert_transparency_verifier_ = std::move(ct_verifier); + main_request_context_storage_->set_cert_transparency_verifier( + std::move(ct_verifier)); + io_thread->RegisterSTHObserver(ct_tree_tracker_.get()); ct_tree_tracker_unregistration_ = base::Bind(&IOThread::UnregisterSTHObserver, base::Unretained(io_thread), ct_tree_tracker_.get()); + main_request_context_->set_ct_policy_enforcer( + io_thread_globals->system_request_context->ct_policy_enforcer()); + InitializeInternal(profile_params_.get(), protocol_handlers, std::move(request_interceptors));
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index a25e88d..d626a45 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h
@@ -77,15 +77,12 @@ class ChannelIDService; class ClientCertStore; class CookieStore; -class CTVerifier; class HttpTransactionFactory; class ProxyConfigService; -class ProxyService; class ReportingService; class ReportSender; class SSLConfigService; class TransportSecurityPersister; -class TransportSecurityState; class URLRequestContextStorage; class URLRequestJobFactoryImpl; } // namespace net @@ -187,10 +184,6 @@ return &network_controller_handle_; } - net::TransportSecurityState* transport_security_state() const { - return transport_security_state_.get(); - } - #if defined(OS_CHROMEOS) std::string username_hash() const { return username_hash_; @@ -383,10 +376,6 @@ void set_previews_io_data( std::unique_ptr<previews::PreviewsIOData> previews_io_data) const; - net::ProxyService* proxy_service() const { - return proxy_service_.get(); - } - net::URLRequestContext* main_request_context() const { return main_request_context_.get(); } @@ -564,10 +553,6 @@ mutable std::unique_ptr<data_reduction_proxy::DataReductionProxyIOData> data_reduction_proxy_io_data_; - mutable std::unique_ptr<net::ProxyService> proxy_service_; - mutable std::unique_ptr<net::TransportSecurityState> - transport_security_state_; - mutable std::unique_ptr<net::CTVerifier> cert_transparency_verifier_; mutable std::unique_ptr<ChromeExpectCTReporter> expect_ct_reporter_; #if defined(OS_CHROMEOS) // Set to |cert_verifier_| if it references a PolicyCertVerifier. In that @@ -579,13 +564,6 @@ mutable std::unique_ptr<chromeos::CertificateProvider> certificate_provider_; #endif - // Pointed to by the TransportSecurityState. - mutable std::unique_ptr<net::TransportSecurityPersister> - transport_security_persister_; - mutable std::unique_ptr<net::ReportSender> certificate_report_sender_; - mutable std::unique_ptr<certificate_transparency::CTPolicyManager> - ct_policy_manager_; - // Owns the subset of URLRequestContext's elements that are created by // subclasses of ProfileImplIOData, to ensure proper destruction ordering. // TODO(mmenke): Move ownship of net objects owned by the ProfileIOData @@ -594,6 +572,15 @@ main_request_context_storage_; mutable std::unique_ptr<net::URLRequestContext> main_request_context_; + // Pointed to by the TransportSecurityState (owned by + // URLRequestContextStorage), and must be disconnected from it before it's + // destroyed. + mutable std::unique_ptr<net::TransportSecurityPersister> + transport_security_persister_; + mutable std::unique_ptr<net::ReportSender> certificate_report_sender_; + mutable std::unique_ptr<certificate_transparency::CTPolicyManager> + ct_policy_manager_; + mutable std::unique_ptr<net::URLRequestContext> extensions_request_context_; // One URLRequestContext per isolated app for main and media requests. mutable URLRequestContextMap app_request_context_map_;
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 034d12c..3351f16 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -354,10 +354,10 @@ const size_t kMappingSize = arraysize(kUmaEnumToControlId); for (size_t i = 0; i < kMappingSize; ++i) { if (kUmaEnumToControlId[i].control_id == id) { - if (enum_lookup_type == GENERAL_ENUM_ID) { + if (enum_lookup_type == GENERAL_ENUM_ID) return kUmaEnumToControlId[i].enum_id; - } else if (enum_lookup_type == CONTEXT_SPECIFIC_ENUM_ID && - kUmaEnumToControlId[i].context_specific_enum_id > -1) { + if (enum_lookup_type == CONTEXT_SPECIFIC_ENUM_ID && + kUmaEnumToControlId[i].context_specific_enum_id > -1) { return kUmaEnumToControlId[i].context_specific_enum_id; } } @@ -514,9 +514,8 @@ // static bool RenderViewContextMenu::IsInternalResourcesURL(const GURL& url) { - if (!url.SchemeIs(content::kChromeUIScheme)) - return false; - return url.host_piece() == chrome::kChromeUISyncResourcesHost; + return url.SchemeIs(content::kChromeUIScheme) && + url.host_piece() == chrome::kChromeUISyncResourcesHost; } // static @@ -677,14 +676,14 @@ sorted_menu_titles.end()); int index = 0; - for (size_t i = 0; i < sorted_menu_titles.size(); ++i) { - std::vector<const Extension*>& extensions = - title_to_extensions_map[sorted_menu_titles[i]]; - for (auto* extension : extensions) { + for (const auto& title : sorted_menu_titles) { + const std::vector<const Extension*>& extensions = + title_to_extensions_map[title]; + for (const Extension* extension : extensions) { MenuItem::ExtensionKey extension_key(extension->id()); extension_items_.AppendExtensionItems(extension_key, printable_selection_text, &index, - false); // is_action_menu + /*is_action_menu=*/false); } } } @@ -712,7 +711,7 @@ // Only add extension items from this extension. int index = 0; extension_items_.AppendExtensionItems(key, PrintableSelectionText(), &index, - false /* is_action_menu */); + /*is_action_menu=*/false); } #endif // BUILDFLAG(ENABLE_EXTENSIONS) @@ -733,10 +732,10 @@ menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); } - if (content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_MEDIA_IMAGE)) { + bool media_image = content_type_->SupportsGroup( + ContextMenuContentType::ITEM_GROUP_MEDIA_IMAGE); + if (media_image) AppendImageItems(); - } if (content_type_->SupportsGroup( ContextMenuContentType::ITEM_GROUP_SEARCHWEBFORIMAGE)) { @@ -765,12 +764,13 @@ // ITEM_GROUP_MEDIA_FILE has no specific items. - if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_EDITABLE)) + bool editable = + content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_EDITABLE); + if (editable) AppendEditableItems(); if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_COPY)) { - DCHECK(!content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_EDITABLE)); + DCHECK(!editable); AppendCopyItem(); } @@ -780,15 +780,12 @@ AppendSearchProvider(); } - if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PRINT) && - !content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_MEDIA_IMAGE)) { + if (!media_image && + content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PRINT)) { AppendPrintItem(); } - if (content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_EDITABLE) && - params_.misspelled_word.empty()) { + if (editable && params_.misspelled_word.empty()) { menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); AppendLanguageSettings(); AppendPlatformEditableItems(); @@ -829,10 +826,10 @@ } // Remove any redundant trailing separator. - if (menu_model_.GetItemCount() > 0 && - menu_model_.GetTypeAt(menu_model_.GetItemCount() - 1) == - ui::MenuModel::TYPE_SEPARATOR) { - menu_model_.RemoveItemAt(menu_model_.GetItemCount() - 1); + int index = menu_model_.GetItemCount() - 1; + if (index >= 0 && + menu_model_.GetTypeAt(index) == ui::MenuModel::TYPE_SEPARATOR) { + menu_model_.RemoveItemAt(index); } } @@ -842,38 +839,37 @@ void RenderViewContextMenu::RecordUsedItem(int id) { int enum_id = FindUMAEnumValueForCommand(id, GENERAL_ENUM_ID); - if (enum_id != -1) { - const size_t kMappingSize = arraysize(kUmaEnumToControlId); - UMA_HISTOGRAM_EXACT_LINEAR("RenderViewContextMenu.Used", enum_id, - kUmaEnumToControlId[kMappingSize - 1].enum_id); - // Record to additional context specific histograms. - enum_id = FindUMAEnumValueForCommand(id, CONTEXT_SPECIFIC_ENUM_ID); - - // Linked image context. - if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_LINK) && - content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_MEDIA_IMAGE)) { - UMA_HISTOGRAM_EXACT_LINEAR("ContextMenu.SelectedOption.ImageLink", - enum_id, - kUmaEnumToControlId[kMappingSize - 1].enum_id); - } - // Selected text context. - if (content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_SEARCH_PROVIDER) && - content_type_->SupportsGroup( - ContextMenuContentType::ITEM_GROUP_PRINT)) { - UMA_HISTOGRAM_EXACT_LINEAR("ContextMenu.SelectedOption.SelectedText", - enum_id, - kUmaEnumToControlId[kMappingSize - 1].enum_id); - } - // Misspelled word context. - if (!params_.misspelled_word.empty()) { - UMA_HISTOGRAM_EXACT_LINEAR("ContextMenu.SelectedOption.MisspelledWord", - enum_id, - kUmaEnumToControlId[kMappingSize - 1].enum_id); - } - } else { + if (enum_id == -1) { NOTREACHED() << "Update kUmaEnumToControlId. Unhanded IDC: " << id; + return; + } + + const size_t kMappingSize = arraysize(kUmaEnumToControlId); + UMA_HISTOGRAM_EXACT_LINEAR("RenderViewContextMenu.Used", enum_id, + kUmaEnumToControlId[kMappingSize - 1].enum_id); + // Record to additional context specific histograms. + enum_id = FindUMAEnumValueForCommand(id, CONTEXT_SPECIFIC_ENUM_ID); + + // Linked image context. + if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_LINK) && + content_type_->SupportsGroup( + ContextMenuContentType::ITEM_GROUP_MEDIA_IMAGE)) { + UMA_HISTOGRAM_EXACT_LINEAR("ContextMenu.SelectedOption.ImageLink", enum_id, + kUmaEnumToControlId[kMappingSize - 1].enum_id); + } + // Selected text context. + if (content_type_->SupportsGroup( + ContextMenuContentType::ITEM_GROUP_SEARCH_PROVIDER) && + content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PRINT)) { + UMA_HISTOGRAM_EXACT_LINEAR("ContextMenu.SelectedOption.SelectedText", + enum_id, + kUmaEnumToControlId[kMappingSize - 1].enum_id); + } + // Misspelled word context. + if (!params_.misspelled_word.empty()) { + UMA_HISTOGRAM_EXACT_LINEAR("ContextMenu.SelectedOption.MisspelledWord", + enum_id, + kUmaEnumToControlId[kMappingSize - 1].enum_id); } } @@ -909,9 +905,9 @@ void RenderViewContextMenu::AppendPrintPreviewItems() { #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - if (!print_preview_menu_observer_.get()) { - print_preview_menu_observer_.reset( - new PrintPreviewContextMenuObserver(source_web_contents_)); + if (!print_preview_menu_observer_) { + print_preview_menu_observer_ = + base::MakeUnique<PrintPreviewContextMenuObserver>(source_web_contents_); } observers_.AddObserver(print_preview_menu_observer_.get()); @@ -1114,22 +1110,23 @@ } void RenderViewContextMenu::AppendSearchWebForImageItems() { + if (!params_.has_image_contents) + return; + TemplateURLService* service = TemplateURLServiceFactory::GetForProfile(GetProfile()); - const TemplateURL* const default_provider = - service->GetDefaultSearchProvider(); - if (params_.has_image_contents && default_provider && - !default_provider->image_url().empty() && - default_provider->image_url_ref().IsValid(service->search_terms_data())) { - menu_model_.AddItem( - IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE, - l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_SEARCHWEBFORIMAGE, - default_provider->short_name())); - if (default_provider->image_url_ref().HasGoogleBaseURLs( - service->search_terms_data())) { - AddGoogleIconToLastMenuItem(&menu_model_); - } + const TemplateURL* const provider = service->GetDefaultSearchProvider(); + if (!provider || provider->image_url().empty() || + !provider->image_url_ref().IsValid(service->search_terms_data())) { + return; } + + menu_model_.AddItem( + IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE, + l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_SEARCHWEBFORIMAGE, + provider->short_name())); + if (provider->image_url_ref().HasGoogleBaseURLs(service->search_terms_data())) + AddGoogleIconToLastMenuItem(&menu_model_); } void RenderViewContextMenu::AppendAudioItems() { @@ -1382,8 +1379,9 @@ #else if (!spelling_options_submenu_observer_) { const int kLanguageRadioGroup = 1; - spelling_options_submenu_observer_.reset( - new SpellingOptionsSubMenuObserver(this, this, kLanguageRadioGroup)); + spelling_options_submenu_observer_ = + base::MakeUnique<SpellingOptionsSubMenuObserver>(this, this, + kLanguageRadioGroup); } spelling_options_submenu_observer_->InitMenu(params_); @@ -1392,8 +1390,10 @@ } void RenderViewContextMenu::AppendSpellingSuggestionItems() { - if (!spelling_suggestions_menu_observer_) - spelling_suggestions_menu_observer_.reset(new SpellingMenuObserver(this)); + if (!spelling_suggestions_menu_observer_) { + spelling_suggestions_menu_observer_ = + base::MakeUnique<SpellingMenuObserver>(this); + } observers_.AddObserver(spelling_suggestions_menu_observer_.get()); spelling_suggestions_menu_observer_->InitMenu(params_); } @@ -1954,13 +1954,13 @@ bool RenderViewContextMenu::IsDevCommandEnabled(int id) const { if (id == IDC_CONTENT_CONTEXT_INSPECTELEMENT || id == IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE) { - if (!GetPrefs(browser_context_) - ->GetBoolean(prefs::kWebKitJavascriptEnabled)) + PrefService* prefs = GetPrefs(browser_context_); + if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled)) return false; // Don't enable the web inspector if the developer tools are disabled via // the preference dev-tools-disabled. - if (GetPrefs(browser_context_)->GetBoolean(prefs::kDevToolsDisabled)) + if (prefs->GetBoolean(prefs::kDevToolsDisabled)) return false; } @@ -2033,7 +2033,7 @@ url.is_valid() && ProfileIOData::IsHandledProtocol(url.scheme()); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Do not save the preview PDF on the print preview page. + // Do not save the preview PDF on the print preview page. can_save = can_save && !(printing::PrintPreviewDialogController::IsPrintPreviewURL(url)); #endif @@ -2211,11 +2211,11 @@ source_web_contents_->GetBrowserContext(), render_frame_host->GetSiteInstance()); - std::unique_ptr<DownloadUrlParameters> dl_params(new DownloadUrlParameters( + auto dl_params = base::MakeUnique<DownloadUrlParameters>( url, render_frame_host->GetProcess()->GetID(), render_frame_host->GetRenderViewHost()->GetRoutingID(), render_frame_host->GetRoutingID(), - storage_partition->GetURLRequestContext(), NO_TRAFFIC_ANNOTATION_YET)); + storage_partition->GetURLRequestContext(), NO_TRAFFIC_ANNOTATION_YET); dl_params->set_referrer(CreateReferrer(url, params_)); dl_params->set_referrer_encoding(params_.frame_charset); dl_params->set_suggested_name(params_.suggested_filename);
diff --git a/chrome/browser/resources/offline_pages/offline_internals.html b/chrome/browser/resources/offline_pages/offline_internals.html index a90859c..7220e63a 100644 --- a/chrome/browser/resources/offline_pages/offline_internals.html +++ b/chrome/browser/resources/offline_pages/offline_internals.html
@@ -100,6 +100,10 @@ placeholder="operations/1234-5678"> <button id="get-operation">Get Operation</button> </div> + <div> + <input id="download-name" type="text" placeholder="us/page/1234-5678"> + <button id="download-archive">Download</button> + </div> </div> <div id="prefetch-actions-info" class="dump"></div> </body>
diff --git a/chrome/browser/resources/offline_pages/offline_internals.js b/chrome/browser/resources/offline_pages/offline_internals.js index 705eb4ac..5acddb5 100644 --- a/chrome/browser/resources/offline_pages/offline_internals.js +++ b/chrome/browser/resources/offline_pages/offline_internals.js
@@ -335,6 +335,9 @@ browserProxy.getOperation($('operation-name').value) .then(setPrefetchResult); }; + $('download-archive').onclick = function() { + browserProxy.downloadArchive($('download-name').value); + }; if (!incognito) refreshAll(); }
diff --git a/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js b/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js index 4066134..81d58c11 100644 --- a/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js +++ b/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js
@@ -145,6 +145,12 @@ * @return {!Promise<string>} A string describing the result. */ getOperation: function(name) {}, + + /** + * Downloads an archive. + * @param {string} name Name of archive to download. + */ + downloadArchive: function(name) {}, }; /** @@ -229,6 +235,11 @@ getOperation: function(name) { return cr.sendWithPromise('getOperation', name); }, + + /** @override */ + downloadArchive: function(name) { + chrome.send('downloadArchive', [name]); + }, }; return {
diff --git a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js index 52f3ced..beb4b67 100644 --- a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js +++ b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
@@ -130,35 +130,34 @@ } /** @interface */ - function AboutPageBrowserProxy() {} - - AboutPageBrowserProxy.prototype = { + class AboutPageBrowserProxy { /** * Indicates to the browser that the page is ready. */ - pageReady: function() {}, + pageReady() {} /** * Request update status from the browser. It results in one or more * 'update-status-changed' WebUI events. */ - refreshUpdateStatus: function() {}, + refreshUpdateStatus() {} /** Opens the help page. */ - openHelpPage: function() {}, + openHelpPage() {} // <if expr="_google_chrome"> /** * Opens the feedback dialog. */ - openFeedbackDialog: function() {}, + openFeedbackDialog() {} + // </if> // <if expr="chromeos"> /** * Checks for available update and applies if it exists. */ - requestUpdate: function() {}, + requestUpdate() {} /** * Checks for the update with specified version and size and applies over @@ -170,101 +169,102 @@ * @param {string} target_version * @param {string} target_size */ - requestUpdateOverCellular: function(target_version, target_size) {}, + requestUpdateOverCellular(target_version, target_size) {} /** * @param {!BrowserChannel} channel * @param {boolean} isPowerwashAllowed */ - setChannel: function(channel, isPowerwashAllowed) {}, + setChannel(channel, isPowerwashAllowed) {} /** @return {!Promise<!ChannelInfo>} */ - getChannelInfo: function() {}, + getChannelInfo() {} /** @return {!Promise<!VersionInfo>} */ - getVersionInfo: function() {}, + getVersionInfo() {} /** @return {!Promise<?RegulatoryInfo>} */ - getRegulatoryInfo: function() {}, + getRegulatoryInfo() {} + // </if> // <if expr="_google_chrome and is_macosx"> /** * Triggers setting up auto-updates for all users. */ - promoteUpdater: function() {}, + promoteUpdater() {} // </if> - }; + } /** * @implements {settings.AboutPageBrowserProxy} - * @constructor */ - function AboutPageBrowserProxyImpl() {} - cr.addSingletonGetter(AboutPageBrowserProxyImpl); - - AboutPageBrowserProxyImpl.prototype = { + class AboutPageBrowserProxyImpl { /** @override */ - pageReady: function() { + pageReady() { chrome.send('aboutPageReady'); - }, + } /** @override */ - refreshUpdateStatus: function() { + refreshUpdateStatus() { chrome.send('refreshUpdateStatus'); - }, + } // <if expr="_google_chrome and is_macosx"> /** @override */ - promoteUpdater: function() { + promoteUpdater() { chrome.send('promoteUpdater'); - }, + } + // </if> /** @override */ - openHelpPage: function() { + openHelpPage() { chrome.send('openHelpPage'); - }, + } // <if expr="_google_chrome"> /** @override */ - openFeedbackDialog: function() { + openFeedbackDialog() { chrome.send('openFeedbackDialog'); - }, + } + // </if> // <if expr="chromeos"> /** @override */ - requestUpdate: function() { + requestUpdate() { chrome.send('requestUpdate'); - }, + } /** @override */ - requestUpdateOverCellular: function(target_version, target_size) { + requestUpdateOverCellular(target_version, target_size) { chrome.send('requestUpdateOverCellular', [target_version, target_size]); - }, + } /** @override */ - setChannel: function(channel, isPowerwashAllowed) { + setChannel(channel, isPowerwashAllowed) { chrome.send('setChannel', [channel, isPowerwashAllowed]); - }, + } /** @override */ - getChannelInfo: function() { + getChannelInfo() { return cr.sendWithPromise('getChannelInfo'); - }, + } /** @override */ - getVersionInfo: function() { + getVersionInfo() { return cr.sendWithPromise('getVersionInfo'); - }, + } /** @override */ - getRegulatoryInfo: function() { + getRegulatoryInfo() { return cr.sendWithPromise('getRegulatoryInfo'); } // </if> - }; + } + + cr.addSingletonGetter(AboutPageBrowserProxyImpl); return { AboutPageBrowserProxy: AboutPageBrowserProxy,
diff --git a/chrome/browser/resources/settings/android_apps_page/android_apps_browser_proxy.js b/chrome/browser/resources/settings/android_apps_page/android_apps_browser_proxy.js index c5b32bd..6cb17f5f 100644 --- a/chrome/browser/resources/settings/android_apps_page/android_apps_browser_proxy.js +++ b/chrome/browser/resources/settings/android_apps_page/android_apps_browser_proxy.js
@@ -21,40 +21,35 @@ cr.define('settings', function() { /** @interface */ - function AndroidAppsBrowserProxy() {} - - AndroidAppsBrowserProxy.prototype = { - requestAndroidAppsInfo: function() {}, + class AndroidAppsBrowserProxy { + requestAndroidAppsInfo() {} /** * @param {boolean} keyboardAction True if the app was opened using a * keyboard action. */ - showAndroidAppsSettings: function(keyboardAction) {}, - }; + showAndroidAppsSettings(keyboardAction) {} + } /** - * @constructor * @implements {settings.AndroidAppsBrowserProxy} */ - function AndroidAppsBrowserProxyImpl() {} + class AndroidAppsBrowserProxyImpl { + /** @override */ + requestAndroidAppsInfo() { + chrome.send('requestAndroidAppsInfo'); + } + + /** @override */ + showAndroidAppsSettings(keyboardAction) { + chrome.send('showAndroidAppsSettings', [keyboardAction]); + } + } // The singleton instance_ can be replaced with a test version of this wrapper // during testing. cr.addSingletonGetter(AndroidAppsBrowserProxyImpl); - AndroidAppsBrowserProxyImpl.prototype = { - /** @override */ - requestAndroidAppsInfo: function() { - chrome.send('requestAndroidAppsInfo'); - }, - - /** @override */ - showAndroidAppsSettings: function(keyboardAction) { - chrome.send('showAndroidAppsSettings', [keyboardAction]); - }, - }; - return { AndroidAppsBrowserProxy: AndroidAppsBrowserProxy, AndroidAppsBrowserProxyImpl: AndroidAppsBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js b/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js index 5006a3f..779818bd 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js +++ b/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js
@@ -4,90 +4,89 @@ cr.define('settings', function() { /** @interface */ - function AppearanceBrowserProxy() {} - - AppearanceBrowserProxy.prototype = { + class AppearanceBrowserProxy { /** @return {!Promise<number>} */ - getDefaultZoom: assertNotReached, + getDefaultZoom() {} /** * @param {string} themeId * @return {!Promise<!chrome.management.ExtensionInfo>} Theme info. */ - getThemeInfo: assertNotReached, + getThemeInfo(themeId) {} /** @return {boolean} Whether the current profile is supervised. */ - isSupervised: assertNotReached, + isSupervised() {} // <if expr="chromeos"> - openWallpaperManager: assertNotReached, + openWallpaperManager() {} + // </if> - useDefaultTheme: assertNotReached, + useDefaultTheme() {} // <if expr="is_linux and not chromeos"> - useSystemTheme: assertNotReached, + useSystemTheme() {} + // </if> /** * @param {string} url The url of which to check validity. * @return {!Promise<boolean>} */ - validateStartupPage: assertNotReached, - }; + validateStartupPage(url) {} + } /** * @implements {settings.AppearanceBrowserProxy} - * @constructor */ - function AppearanceBrowserProxyImpl() {} - - cr.addSingletonGetter(AppearanceBrowserProxyImpl); - - AppearanceBrowserProxyImpl.prototype = { + class AppearanceBrowserProxyImpl { /** @override */ - getDefaultZoom: function() { + getDefaultZoom() { return new Promise(function(resolve) { chrome.settingsPrivate.getDefaultZoom(resolve); }); - }, + } /** @override */ - getThemeInfo: function(themeId) { + getThemeInfo(themeId) { return new Promise(function(resolve) { chrome.management.get(themeId, resolve); }); - }, + } /** @override */ - isSupervised: function() { + isSupervised() { return loadTimeData.getBoolean('isSupervised'); - }, + } // <if expr="chromeos"> /** @override */ - openWallpaperManager: function() { + openWallpaperManager() { chrome.send('openWallpaperManager'); - }, + } + // </if> /** @override */ - useDefaultTheme: function() { + useDefaultTheme() { chrome.send('useDefaultTheme'); - }, + } // <if expr="is_linux and not chromeos"> /** @override */ - useSystemTheme: function() { + useSystemTheme() { chrome.send('useSystemTheme'); - }, + } + // </if> /** @override */ - validateStartupPage: function(url) { + validateStartupPage(url) { return cr.sendWithPromise('validateStartupPage', url); - }, - }; + } + } + + cr.addSingletonGetter(AppearanceBrowserProxyImpl); return { AppearanceBrowserProxy: AppearanceBrowserProxy,
diff --git a/chrome/browser/resources/settings/appearance_page/fonts_browser_proxy.js b/chrome/browser/resources/settings/appearance_page/fonts_browser_proxy.js index b8b1263..d513b3ad 100644 --- a/chrome/browser/resources/settings/appearance_page/fonts_browser_proxy.js +++ b/chrome/browser/resources/settings/appearance_page/fonts_browser_proxy.js
@@ -12,44 +12,39 @@ cr.define('settings', function() { /** @interface */ - function FontsBrowserProxy() {} - - FontsBrowserProxy.prototype = { + class FontsBrowserProxy { /** * @return {!Promise<!FontsData>} Fonts and the advanced font settings * extension URL. */ - fetchFontsData: assertNotReached, + fetchFontsData() {} - observeAdvancedFontExtensionAvailable: assertNotReached, + observeAdvancedFontExtensionAvailable() {} - openAdvancedFontSettings: assertNotReached, - }; + openAdvancedFontSettings() {} + } /** * @implements {settings.FontsBrowserProxy} - * @constructor */ - function FontsBrowserProxyImpl() {} - - cr.addSingletonGetter(FontsBrowserProxyImpl); - - FontsBrowserProxyImpl.prototype = { + class FontsBrowserProxyImpl { /** @override */ - fetchFontsData: function() { + fetchFontsData() { return cr.sendWithPromise('fetchFontsData'); - }, + } /** @override */ - observeAdvancedFontExtensionAvailable: function() { + observeAdvancedFontExtensionAvailable() { chrome.send('observeAdvancedFontExtensionAvailable'); - }, + } /** @override */ - openAdvancedFontSettings: function() { + openAdvancedFontSettings() { chrome.send('openAdvancedFontSettings'); } - }; + } + + cr.addSingletonGetter(FontsBrowserProxyImpl); return { FontsBrowserProxy: FontsBrowserProxy,
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 index eb89020..3501b77 100644 --- a/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js +++ b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js
@@ -83,36 +83,33 @@ var CertificatesImportError; cr.define('settings', function() { - /** @interface */ - function CertificatesBrowserProxy() {} - - CertificatesBrowserProxy.prototype = { + class CertificatesBrowserProxy { /** * Triggers 5 events in the following order * 1x 'certificates-model-ready' event. * 4x 'certificates-changed' event, one for each certificate category. */ - refreshCertificates: function() {}, + refreshCertificates() {} /** @param {string} id */ - viewCertificate: function(id) {}, + viewCertificate(id) {} /** @param {string} id */ - exportCertificate: function(id) {}, + exportCertificate(id) {} /** * @param {string} id * @return {!Promise} A promise resolved when the certificate has been * deleted successfully or rejected with a CertificatesError. */ - deleteCertificate: function(id) {}, + deleteCertificate(id) {} /** * @param {string} id * @return {!Promise<!CaTrustInfo>} */ - getCaCertificateTrust: function(id) {}, + getCaCertificateTrust(id) {} /** * @param {string} id @@ -121,9 +118,9 @@ * @param {boolean} objSign * @return {!Promise} */ - editCaCertificateTrust: function(id, ssl, email, objSign) {}, + editCaCertificateTrust(id, ssl, email, objSign) {} - cancelImportExportCertificate: function() {}, + cancelImportExportCertificate() {} /** * @param {string} id @@ -133,13 +130,13 @@ * passed back via a call to * exportPersonalCertificatePasswordSelected(). */ - exportPersonalCertificate: function(id) {}, + exportPersonalCertificate(id) {} /** * @param {string} password * @return {!Promise} */ - exportPersonalCertificatePasswordSelected: function(password) {}, + exportPersonalCertificatePasswordSelected(password) {} /** * @param {boolean} useHardwareBacked @@ -148,13 +145,13 @@ * the user, and the password should be passed back via a call to * importPersonalCertificatePasswordSelected(). */ - importPersonalCertificate: function(useHardwareBacked) {}, + importPersonalCertificate(useHardwareBacked) {} /** * @param {string} password * @return {!Promise} */ - importPersonalCertificatePasswordSelected: function(password) {}, + importPersonalCertificatePasswordSelected(password) {} /** * @return {!Promise} A promise firing once the user has selected @@ -163,7 +160,7 @@ * trust levels, and that information should be passed back via a call * to importCaCertificateTrustSelected(). */ - importCaCertificate: function() {}, + importCaCertificate() {} /** * @param {boolean} ssl @@ -174,101 +171,99 @@ * error occurred with either a CertificatesError or * CertificatesImportError. */ - importCaCertificateTrustSelected: function(ssl, email, objSign) {}, + importCaCertificateTrustSelected(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() {}, - }; + importServerCertificate() {} + } /** - * @constructor * @implements {settings.CertificatesBrowserProxy} */ - function CertificatesBrowserProxyImpl() {} + class CertificatesBrowserProxyImpl { + /** @override */ + refreshCertificates() { + chrome.send('refreshCertificates'); + } + + /** @override */ + viewCertificate(id) { + chrome.send('viewCertificate', [id]); + } + + /** @override */ + exportCertificate(id) { + chrome.send('exportCertificate', [id]); + } + + /** @override */ + deleteCertificate(id) { + return cr.sendWithPromise('deleteCertificate', id); + } + + /** @override */ + exportPersonalCertificate(id) { + return cr.sendWithPromise('exportPersonalCertificate', id); + } + + /** @override */ + exportPersonalCertificatePasswordSelected(password) { + return cr.sendWithPromise( + 'exportPersonalCertificatePasswordSelected', password); + } + + /** @override */ + importPersonalCertificate(useHardwareBacked) { + return cr.sendWithPromise('importPersonalCertificate', useHardwareBacked); + } + + /** @override */ + importPersonalCertificatePasswordSelected(password) { + return cr.sendWithPromise( + 'importPersonalCertificatePasswordSelected', password); + } + + /** @override */ + getCaCertificateTrust(id) { + return cr.sendWithPromise('getCaCertificateTrust', id); + } + + /** @override */ + editCaCertificateTrust(id, ssl, email, objSign) { + return cr.sendWithPromise( + 'editCaCertificateTrust', id, ssl, email, objSign); + } + + /** @override */ + importCaCertificateTrustSelected(ssl, email, objSign) { + return cr.sendWithPromise( + 'importCaCertificateTrustSelected', ssl, email, objSign); + } + + /** @override */ + cancelImportExportCertificate() { + chrome.send('cancelImportExportCertificate'); + } + + /** @override */ + importCaCertificate() { + return cr.sendWithPromise('importCaCertificate'); + } + + /** @override */ + importServerCertificate() { + return cr.sendWithPromise('importServerCertificate'); + } + } + // 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 { CertificatesBrowserProxy: CertificatesBrowserProxy, CertificatesBrowserProxyImpl: CertificatesBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js index 7edbab00..b032a5cd 100644 --- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js +++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js
@@ -4,61 +4,56 @@ cr.define('settings', function() { /** @interface */ - function ChromeCleanupProxy() {} - - ChromeCleanupProxy.prototype = { + class ChromeCleanupProxy { /** * Registers the current ChromeCleanupHandler as an observer of * ChromeCleanerController events. */ - registerChromeCleanerObserver: assertNotReached, + registerChromeCleanerObserver() {} /** * Starts a cleanup on the user's computer. */ - startCleanup: assertNotReached, + startCleanup() {} /** * Restarts the user's computer. */ - restartComputer: assertNotReached, + restartComputer() {} /** * Hides the Cleanup page from the settings menu. */ - dismissCleanupPage: assertNotReached, - }; + dismissCleanupPage() {} + } /** * @implements {settings.ChromeCleanupProxy} - * @constructor */ - function ChromeCleanupProxyImpl() {} + class ChromeCleanupProxyImpl { + /** @override */ + registerChromeCleanerObserver() { + chrome.send('registerChromeCleanerObserver'); + } + + /** @override */ + startCleanup() { + chrome.send('startCleanup'); + } + + /** @override */ + restartComputer() { + chrome.send('restartComputer'); + } + + /** @override */ + dismissCleanupPage() { + chrome.send('dismissCleanupPage'); + } + } cr.addSingletonGetter(ChromeCleanupProxyImpl); - ChromeCleanupProxyImpl.prototype = { - /** @override */ - registerChromeCleanerObserver: function() { - chrome.send('registerChromeCleanerObserver'); - }, - - /** @override */ - startCleanup: function() { - chrome.send('startCleanup'); - }, - - /** @override */ - restartComputer: function() { - chrome.send('restartComputer'); - }, - - /** @override */ - dismissCleanupPage: function() { - chrome.send('dismissCleanupPage'); - }, - }; - return { ChromeCleanupProxy: ChromeCleanupProxy, ChromeCleanupProxyImpl: ChromeCleanupProxyImpl,
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_browser_proxy.js b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_browser_proxy.js index 20e2ffe8..24bdd364 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_browser_proxy.js +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_browser_proxy.js
@@ -26,52 +26,48 @@ cr.define('settings', function() { /** @interface */ - function ClearBrowsingDataBrowserProxy() {} - - ClearBrowsingDataBrowserProxy.prototype = { + class ClearBrowsingDataBrowserProxy { /** * @param {!Array<!ImportantSite>} importantSites * @return {!Promise<void>} * A promise resolved when data clearing has completed. */ - clearBrowsingData: function(importantSites) {}, + clearBrowsingData(importantSites) {} /** * @return {!Promise<!Array<!ImportantSite>>} * A promise resolved when imporant sites are retrieved. */ - getImportantSites: function() {}, + getImportantSites() {} /** * Kick off counter updates and return initial state. * @return {!Promise<void>} Signal when the setup is complete. */ - initialize: function() {}, - }; + initialize() {} + } /** - * @constructor * @implements {settings.ClearBrowsingDataBrowserProxy} */ - function ClearBrowsingDataBrowserProxyImpl() {} - cr.addSingletonGetter(ClearBrowsingDataBrowserProxyImpl); - - ClearBrowsingDataBrowserProxyImpl.prototype = { + class ClearBrowsingDataBrowserProxyImpl { /** @override */ - clearBrowsingData: function(importantSites) { + clearBrowsingData(importantSites) { return cr.sendWithPromise('clearBrowsingData', importantSites); - }, + } /** @override */ - getImportantSites: function() { + getImportantSites() { return cr.sendWithPromise('getImportantSites'); - }, + } /** @override */ - initialize: function() { + initialize() { return cr.sendWithPromise('initializeClearBrowsingData'); - }, - }; + } + } + + cr.addSingletonGetter(ClearBrowsingDataBrowserProxyImpl); return { ClearBrowsingDataBrowserProxy: ClearBrowsingDataBrowserProxy,
diff --git a/chrome/browser/resources/settings/default_browser_page/default_browser_browser_proxy.js b/chrome/browser/resources/settings/default_browser_page/default_browser_browser_proxy.js index e4f34da..bb8703a 100644 --- a/chrome/browser/resources/settings/default_browser_page/default_browser_browser_proxy.js +++ b/chrome/browser/resources/settings/default_browser_page/default_browser_browser_proxy.js
@@ -19,42 +19,38 @@ cr.define('settings', function() { /** @interface */ - function DefaultBrowserBrowserProxy() {} - - DefaultBrowserBrowserProxy.prototype = { + class DefaultBrowserBrowserProxy { /** * Get the initial DefaultBrowserInfo and begin sending updates to * 'settings.updateDefaultBrowserState'. * @return {!Promise<DefaultBrowserInfo>} */ - requestDefaultBrowserState: function() {}, + requestDefaultBrowserState() {} /* * Try to set the current browser as the default browser. The new status of * the settings will be sent to 'settings.updateDefaultBrowserState'. */ - setAsDefaultBrowser: function() {}, - }; + setAsDefaultBrowser() {} + } /** - * @constructor * @implements {settings.DefaultBrowserBrowserProxy} */ - function DefaultBrowserBrowserProxyImpl() {} - cr.addSingletonGetter(DefaultBrowserBrowserProxyImpl); - - DefaultBrowserBrowserProxyImpl.prototype = { + class DefaultBrowserBrowserProxyImpl { /** @override */ - requestDefaultBrowserState: function() { + requestDefaultBrowserState() { return cr.sendWithPromise( 'SettingsDefaultBrowser.requestDefaultBrowserState'); - }, + } /** @override */ - setAsDefaultBrowser: function() { + setAsDefaultBrowser() { chrome.send('SettingsDefaultBrowser.setAsDefaultBrowser'); - }, - }; + } + } + + cr.addSingletonGetter(DefaultBrowserBrowserProxyImpl); return { DefaultBrowserBrowserProxy: DefaultBrowserBrowserProxy,
diff --git a/chrome/browser/resources/settings/device_page/compiled_resources2.gyp b/chrome/browser/resources/settings/device_page/compiled_resources2.gyp index f93da31..97ba452 100644 --- a/chrome/browser/resources/settings/device_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/device_page/compiled_resources2.gyp
@@ -118,6 +118,7 @@ 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', + '<(EXTERNS_GYP):settings_private', '../compiled_resources2.gyp:route', '../prefs/compiled_resources2.gyp:prefs_types', 'device_page_browser_proxy'
diff --git a/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js b/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js index 5e63b92..d84e6c06 100644 --- a/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js +++ b/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js
@@ -76,161 +76,157 @@ cr.define('settings', function() { /** @interface */ - function DevicePageBrowserProxy() {} - - DevicePageBrowserProxy.prototype = { + class DevicePageBrowserProxy { /** Initializes the mouse and touchpad handler. */ - initializePointers: function() {}, + initializePointers() {} /** Initializes the stylus handler. */ - initializeStylus: function() {}, + initializeStylus() {} /** * Override to interact with the on-tap/on-keydown event on the Learn More * link. * @param {!Event} e */ - handleLinkEvent: function(e) {}, + handleLinkEvent(e) {} /** Initializes the keyboard WebUI handler. */ - initializeKeyboard: function() {}, + initializeKeyboard() {} /** Shows the Ash keyboard shortcuts overlay. */ - showKeyboardShortcutsOverlay: function() {}, + showKeyboardShortcutsOverlay() {} /** Requests a power status update. */ - updatePowerStatus: function() {}, + updatePowerStatus() {} /** * Sets the ID of the power source to use. * @param {string} powerSourceId ID of the power source. '' denotes the * battery (no external power source). */ - setPowerSource: function(powerSourceId) {}, + setPowerSource(powerSourceId) {} /** Requests the current power management settings. */ - requestPowerManagementSettings: function() {}, + requestPowerManagementSettings() {} /** * Sets the idle power management behavior. * @param {settings.IdleBehavior} behavior Idle behavior. */ - setIdleBehavior: function(behavior) {}, + setIdleBehavior(behavior) {} /** * Sets the lid-closed power management behavior. * @param {settings.LidClosedBehavior} behavior Lid-closed behavior. */ - setLidClosedBehavior: function(behavior) {}, + setLidClosedBehavior(behavior) {} /** * |callback| is run when there is new note-taking app information * available or after |requestNoteTakingApps| has been called. * @param {function(Array<settings.NoteAppInfo>, boolean):void} callback */ - setNoteTakingAppsUpdatedCallback: function(callback) {}, + setNoteTakingAppsUpdatedCallback(callback) {} /** * Open up the play store with the given URL. * @param {string} url */ - showPlayStore: function(url) {}, + showPlayStore(url) {} /** * Request current note-taking app info. Invokes any callback registered in * |onNoteTakingAppsUpdated|. */ - requestNoteTakingApps: function() {}, + requestNoteTakingApps() {} /** * Changes the preferred note taking app. * @param {string} appId The app id. This should be a value retrieved from a * |onNoteTakingAppsUpdated| callback. */ - setPreferredNoteTakingApp: function(appId) {}, - }; + setPreferredNoteTakingApp(appId) {} + } /** - * @constructor * @implements {settings.DevicePageBrowserProxy} */ - function DevicePageBrowserProxyImpl() {} - cr.addSingletonGetter(DevicePageBrowserProxyImpl); - - DevicePageBrowserProxyImpl.prototype = { + class DevicePageBrowserProxyImpl { /** @override */ - initializePointers: function() { + initializePointers() { chrome.send('initializePointerSettings'); - }, + } /** @override */ - initializeStylus: function() { + initializeStylus() { chrome.send('initializeStylusSettings'); - }, + } /** override */ - handleLinkEvent: function(e) { + handleLinkEvent(e) { // Prevent the link from activating its parent element when tapped or // when Enter is pressed. if (e.type != 'keydown' || e.keyCode == 13) e.stopPropagation(); - }, + } /** @override */ - initializeKeyboard: function() { + initializeKeyboard() { chrome.send('initializeKeyboardSettings'); - }, + } /** @override */ - showKeyboardShortcutsOverlay: function() { + showKeyboardShortcutsOverlay() { chrome.send('showKeyboardShortcutsOverlay'); - }, + } /** @override */ - updatePowerStatus: function() { + updatePowerStatus() { chrome.send('updatePowerStatus'); - }, + } /** @override */ - setPowerSource: function(powerSourceId) { + setPowerSource(powerSourceId) { chrome.send('setPowerSource', [powerSourceId]); - }, + } /** @override */ - requestPowerManagementSettings: function() { + requestPowerManagementSettings() { chrome.send('requestPowerManagementSettings'); - }, + } /** @override */ - setIdleBehavior: function(behavior) { + setIdleBehavior(behavior) { chrome.send('setIdleBehavior', [behavior]); - }, + } /** @override */ - setLidClosedBehavior: function(behavior) { + setLidClosedBehavior(behavior) { chrome.send('setLidClosedBehavior', [behavior]); - }, + } /** @override */ - setNoteTakingAppsUpdatedCallback: function(callback) { + setNoteTakingAppsUpdatedCallback(callback) { cr.addWebUIListener('onNoteTakingAppsUpdated', callback); - }, + } /** @override */ - showPlayStore: function(url) { + showPlayStore(url) { chrome.send('showPlayStoreApps', [url]); - }, + } /** @override */ - requestNoteTakingApps: function() { + requestNoteTakingApps() { chrome.send('requestNoteTakingApps'); - }, + } /** @override */ - setPreferredNoteTakingApp: function(appId) { + setPreferredNoteTakingApp(appId) { chrome.send('setPreferredNoteTakingApp', [appId]); - }, - }; + } + } + + cr.addSingletonGetter(DevicePageBrowserProxyImpl); return { DevicePageBrowserProxy: DevicePageBrowserProxy,
diff --git a/chrome/browser/resources/settings/device_page/power.html b/chrome/browser/resources/settings/device_page/power.html index f007de7e..f0ee3e45 100644 --- a/chrome/browser/resources/settings/device_page/power.html +++ b/chrome/browser/resources/settings/device_page/power.html
@@ -5,6 +5,7 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_shared_css.html"> @@ -59,24 +60,11 @@ <div id="lidClosedRow" class="settings-box continuation" hidden$="[[!hasLid_]]"> - <div class="start">$i18n{powerLidClosedLabel}</div> - <template is="dom-if" if="[[lidClosedControlled_]]" restamp> - <cr-policy-indicator id="lidClosedControlledIndicator" - indicator-type="devicePolicy" - icon-aria-label="$i18n{powerLidClosedLabel}"> - </cr-policy-indicator> - </template> - <div class="md-select-wrapper"> - <select id="lidClosedSelect" class="md-select" - on-change="onLidClosedSelectChange_" - disabled="[[lidClosedControlled_]]" - aria-label="$i18n{powerLidClosedLabel}"> - <template is="dom-repeat" items="[[lidClosedOptions_]]"> - <option value="[[item.value]]">[[item.name]]</option> - </template> - </select> - <span class="md-select-underline"></span> - </div> + <settings-toggle-button class="start" id="lidClosedToggle" + pref="[[lidClosedPref_]]" label="[[lidClosedLabel_]]" + on-settings-boolean-control-change="onLidClosedToggleChange_" + no-set-pref> + </settings-toggle-button> </div> </template> <script src="power.js"></script>
diff --git a/chrome/browser/resources/settings/device_page/power.js b/chrome/browser/resources/settings/device_page/power.js index 61532061..842ab2dc 100644 --- a/chrome/browser/resources/settings/device_page/power.js +++ b/chrome/browser/resources/settings/device_page/power.js
@@ -30,10 +30,8 @@ /** @private {boolean} Whether the idle behavior is controlled by policy. */ idleControlled_: Boolean, - /** @private {boolean} Whether the lid-closed behavior is controlled by - * policy. - */ - lidClosedControlled_: Boolean, + /** @private {string} Text for label describing the lid-closed behavior. */ + lidClosedLabel_: String, /** @private {boolean} Whether the system posesses a lid. */ hasLid_: Boolean, @@ -73,10 +71,12 @@ computed: 'computeIdleOptions_(idleControlled_)', }, - /** @private */ - lidClosedOptions_: { - type: Array, - computed: 'computeLidClosedOptions_(lidClosedControlled_)', + /** @private {!chrome.settingsPrivate.PrefObject} */ + lidClosedPref_: { + type: Object, + value: function() { + return /** @type {!chrome.settingsPrivate.PrefObject} */ ({}); + }, }, }, @@ -172,36 +172,6 @@ return options; }, - /** - * @param {boolean} lidClosedControlled - * @return {!Array<!{value: settings.LidClosedBehavior, name: string}>} - * Options to display in lid-closed-behavior select. - * @private - */ - computeLidClosedOptions_: function(lidClosedControlled) { - var options = [ - { - value: settings.LidClosedBehavior.SUSPEND, - name: loadTimeData.getString('powerLidClosedSleep'), - }, - { - value: settings.LidClosedBehavior.DO_NOTHING, - name: loadTimeData.getString('powerLidClosedStayAwake'), - }, - ]; - if (lidClosedControlled) { - // Some options are only settable via policy. - options.push({ - value: settings.LidClosedBehavior.STOP_SESSION, - name: loadTimeData.getString('powerLidClosedSignOut'), - }, { - value: settings.LidClosedBehavior.SHUT_DOWN, - name: loadTimeData.getString('powerLidClosedShutDown'), - }); - } - return options; - }, - /** @private */ onPowerSourceChange_: function() { settings.DevicePageBrowserProxyImpl.getInstance().setPowerSource( @@ -216,11 +186,12 @@ }, /** @private */ - onLidClosedSelectChange_: function() { - var behavior = /** @type {settings.LidClosedBehavior} */ - (parseInt(this.$.lidClosedSelect.value, 10)); + onLidClosedToggleChange_: function() { + // Other behaviors are only displayed when the setting is controlled, in + // which case the toggle can't be changed by the user. settings.DevicePageBrowserProxyImpl.getInstance().setLidClosedBehavior( - behavior); + this.$.lidClosedToggle.checked ? settings.LidClosedBehavior.SUSPEND : + settings.LidClosedBehavior.DO_NOTHING); }, /** @@ -237,21 +208,58 @@ }, /** - * @param {!settings.PowerManagementSettings} settings Current power + * @param {settings.LidClosedBehavior} behavior Current behavior. + * @param {boolean} isControlled Whether the underlying pref is controlled. + * @private + */ + updateLidClosedLabelAndPref_: function(behavior, isControlled) { + var pref = { + key: '', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + // Most behaviors get a dedicated label and appear as checked. + value: true, + }; + + switch (behavior) { + case settings.LidClosedBehavior.SUSPEND: + case settings.LidClosedBehavior.DO_NOTHING: + // "Suspend" and "do nothing" share the "sleep" label and communicate + // their state via the toggle state. + this.lidClosedLabel_ = loadTimeData.getString('powerLidSleepLabel'); + pref.value = behavior == settings.LidClosedBehavior.SUSPEND; + break; + case settings.LidClosedBehavior.STOP_SESSION: + this.lidClosedLabel_ = loadTimeData.getString('powerLidSignOutLabel'); + break; + case settings.LidClosedBehavior.SHUT_DOWN: + this.lidClosedLabel_ = loadTimeData.getString('powerLidShutDownLabel'); + break; + } + + if (isControlled) { + pref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED; + pref.controlledBy = chrome.settingsPrivate.ControlledBy.USER_POLICY; + } + + this.lidClosedPref_ = pref; + }, + + /** + * @param {!settings.PowerManagementSettings} browserSettings Current power * management settings. * @private */ - powerManagementSettingsChanged_: function(settings) { - this.idleControlled_ = settings.idleControlled; - this.lidClosedControlled_ = settings.lidClosedControlled; - this.hasLid_ = settings.hasLid; + powerManagementSettingsChanged_: function(browserSettings) { + this.idleControlled_ = browserSettings.idleControlled; + this.hasLid_ = browserSettings.hasLid; + this.updateLidClosedLabelAndPref_( + browserSettings.lidClosedBehavior, browserSettings.lidClosedControlled); - // The select elements include "Other" options when controlled but omit them - // otherwise. Make sure that the options are there before we potentially try - // to select them. + // The idle behavior select element includes an "Other" option when + // controlled but omits it otherwise. Make sure that the option is there + // before we potentially try to select it. this.async(function() { - this.$.idleSelect.value = settings.idleBehavior; - this.$.lidClosedSelect.value = settings.lidClosedBehavior; + this.$.idleSelect.value = browserSettings.idleBehavior; }); },
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_browser_proxy.js b/chrome/browser/resources/settings/downloads_page/downloads_browser_proxy.js index 2f510a1..88c41db 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_browser_proxy.js +++ b/chrome/browser/resources/settings/downloads_page/downloads_browser_proxy.js
@@ -4,41 +4,34 @@ cr.define('settings', function() { /** @interface */ - function DownloadsBrowserProxy() {} - - DownloadsBrowserProxy.prototype = { - initializeDownloads: assertNotReached, - - selectDownloadLocation: assertNotReached, - - resetAutoOpenFileTypes: assertNotReached, - }; + class DownloadsBrowserProxy { + initializeDownloads() {} + selectDownloadLocation() {} + resetAutoOpenFileTypes() {} + } /** * @implements {settings.DownloadsBrowserProxy} - * @constructor */ - function DownloadsBrowserProxyImpl() {} + class DownloadsBrowserProxyImpl { + /** @override */ + initializeDownloads() { + chrome.send('initializeDownloads'); + } + + /** @override */ + selectDownloadLocation() { + chrome.send('selectDownloadLocation'); + } + + /** @override */ + resetAutoOpenFileTypes() { + chrome.send('resetAutoOpenFileTypes'); + } + } cr.addSingletonGetter(DownloadsBrowserProxyImpl); - DownloadsBrowserProxyImpl.prototype = { - /** @override */ - initializeDownloads: function() { - chrome.send('initializeDownloads'); - }, - - /** @override */ - selectDownloadLocation: function() { - chrome.send('selectDownloadLocation'); - }, - - /** @override */ - resetAutoOpenFileTypes: function() { - chrome.send('resetAutoOpenFileTypes'); - }, - }; - return { DownloadsBrowserProxy: DownloadsBrowserProxy, DownloadsBrowserProxyImpl: DownloadsBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/extension_control_browser_proxy.js b/chrome/browser/resources/settings/extension_control_browser_proxy.js index adbbd79..84b350e 100644 --- a/chrome/browser/resources/settings/extension_control_browser_proxy.js +++ b/chrome/browser/resources/settings/extension_control_browser_proxy.js
@@ -4,36 +4,32 @@ cr.define('settings', function() { /** @interface */ - function ExtensionControlBrowserProxy() {} - - ExtensionControlBrowserProxy.prototype = { + class ExtensionControlBrowserProxy { // TODO(dbeam): should be be returning !Promise<boolean> to indicate whether // it succeeded? /** @param {string} extensionId */ - disableExtension: assertNotReached, + disableExtension(extensionId) {} /** @param {string} extensionId */ - manageExtension: assertNotReached, - }; + manageExtension(extensionId) {} + } /** * @implements {settings.ExtensionControlBrowserProxy} - * @constructor */ - function ExtensionControlBrowserProxyImpl() {} - cr.addSingletonGetter(ExtensionControlBrowserProxyImpl); - - ExtensionControlBrowserProxyImpl.prototype = { + class ExtensionControlBrowserProxyImpl { /** @override */ - disableExtension: function(extensionId) { + disableExtension(extensionId) { chrome.send('disableExtension', [extensionId]); - }, + } /** @override */ - manageExtension: function(extensionId) { + manageExtension(extensionId) { window.open('chrome://extensions?id=' + extensionId); - }, - }; + } + } + + cr.addSingletonGetter(ExtensionControlBrowserProxyImpl); return { ExtensionControlBrowserProxy: ExtensionControlBrowserProxy,
diff --git a/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js b/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js index 5edc03f..e23dd250 100644 --- a/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js +++ b/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js
@@ -9,65 +9,63 @@ cr.define('settings', function() { /** @interface */ - function LanguagesBrowserProxy() {} - - LanguagesBrowserProxy.prototype = { + class LanguagesBrowserProxy { // <if expr="chromeos or is_win"> /** * Sets the prospective UI language to the chosen language. This won't * affect the actual UI language until a restart. * @param {string} languageCode */ - setProspectiveUILanguage: function(languageCode) {}, + setProspectiveUILanguage(languageCode) {} /** @return {!Promise<string>} */ - getProspectiveUILanguage: function() {}, + getProspectiveUILanguage() {} + // </if> /** @return {!LanguageSettingsPrivate} */ - getLanguageSettingsPrivate: function() {}, + getLanguageSettingsPrivate() {} // <if expr="chromeos"> /** @return {!InputMethodPrivate} */ - getInputMethodPrivate: function() {}, + getInputMethodPrivate() {} // </if> - }; + } /** - * @constructor * @implements {settings.LanguagesBrowserProxy} */ - function LanguagesBrowserProxyImpl() {} - // The singleton instance_ is replaced with a test version of this wrapper - // during testing. - cr.addSingletonGetter(LanguagesBrowserProxyImpl); - - LanguagesBrowserProxyImpl.prototype = { + class LanguagesBrowserProxyImpl { // <if expr="chromeos or is_win"> /** @override */ - setProspectiveUILanguage: function(languageCode) { + setProspectiveUILanguage(languageCode) { chrome.send('setProspectiveUILanguage', [languageCode]); - }, + } /** @override */ - getProspectiveUILanguage: function() { + getProspectiveUILanguage() { return cr.sendWithPromise('getProspectiveUILanguage'); - }, + } + // </if> /** @override */ - getLanguageSettingsPrivate: function() { + getLanguageSettingsPrivate() { return /** @type {!LanguageSettingsPrivate} */ ( chrome.languageSettingsPrivate); - }, + } // <if expr="chromeos"> /** @override */ - getInputMethodPrivate: function() { + getInputMethodPrivate() { return /** @type {!InputMethodPrivate} */ (chrome.inputMethodPrivate); - }, + } // </if> - }; + } + + // The singleton instance_ is replaced with a test version of this wrapper + // during testing. + cr.addSingletonGetter(LanguagesBrowserProxyImpl); return { LanguagesBrowserProxy: LanguagesBrowserProxy,
diff --git a/chrome/browser/resources/settings/lifetime_browser_proxy.js b/chrome/browser/resources/settings/lifetime_browser_proxy.js index b9915c0..d97ac2d 100644 --- a/chrome/browser/resources/settings/lifetime_browser_proxy.js +++ b/chrome/browser/resources/settings/lifetime_browser_proxy.js
@@ -4,54 +4,50 @@ cr.define('settings', function() { /** @interface */ - function LifetimeBrowserProxy() {} - - LifetimeBrowserProxy.prototype = { + class LifetimeBrowserProxy { // Triggers a browser restart. - restart: function() {}, + restart() {} // Triggers a browser relaunch. - relaunch: function() {}, + relaunch() {} // <if expr="chromeos"> // First signs out current user and then performs a restart. - signOutAndRestart: function() {}, + signOutAndRestart() {} // Triggers a factory reset. - factoryReset: function() {}, + factoryReset() {} // </if> - }; + } /** - * @constructor * @implements {settings.LifetimeBrowserProxy} */ - function LifetimeBrowserProxyImpl() {} - cr.addSingletonGetter(LifetimeBrowserProxyImpl); - - LifetimeBrowserProxyImpl.prototype = { + class LifetimeBrowserProxyImpl { /** @override */ - restart: function() { + restart() { chrome.send('restart'); - }, + } /** @override */ - relaunch: function() { + relaunch() { chrome.send('relaunch'); - }, + } // <if expr="chromeos"> /** @override */ - signOutAndRestart: function() { + signOutAndRestart() { chrome.send('signOutAndRestart'); - }, + } /** @override */ - factoryReset: function() { + factoryReset() { chrome.send('factoryReset'); - }, + } // </if> - }; + } + + cr.addSingletonGetter(LifetimeBrowserProxyImpl); return { LifetimeBrowserProxy: LifetimeBrowserProxy,
diff --git a/chrome/browser/resources/settings/on_startup_page/on_startup_browser_proxy.js b/chrome/browser/resources/settings/on_startup_page/on_startup_browser_proxy.js index a99f618..917029b 100644 --- a/chrome/browser/resources/settings/on_startup_page/on_startup_browser_proxy.js +++ b/chrome/browser/resources/settings/on_startup_page/on_startup_browser_proxy.js
@@ -7,26 +7,22 @@ cr.define('settings', function() { /** @interface */ - function OnStartupBrowserProxy() {} - - OnStartupBrowserProxy.prototype = { + class OnStartupBrowserProxy { /** @return {!Promise<?NtpExtension>} */ - getNtpExtension: assertNotReached, - }; + getNtpExtension() {} + } /** - * @constructor * @implements {settings.OnStartupBrowserProxy} */ - function OnStartupBrowserProxyImpl() {} - cr.addSingletonGetter(OnStartupBrowserProxyImpl); - - OnStartupBrowserProxyImpl.prototype = { + class OnStartupBrowserProxyImpl { /** @override */ - getNtpExtension: function() { + getNtpExtension() { return cr.sendWithPromise('getNtpExtension'); - }, - }; + } + } + + cr.addSingletonGetter(OnStartupBrowserProxyImpl); return { OnStartupBrowserProxy: OnStartupBrowserProxy,
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page_browser_proxy.js b/chrome/browser/resources/settings/on_startup_page/startup_urls_page_browser_proxy.js index b33e31a..ff13b19 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page_browser_proxy.js +++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page_browser_proxy.js
@@ -14,25 +14,22 @@ cr.define('settings', function() { /** @interface */ - function StartupUrlsPageBrowserProxy() {} - - StartupUrlsPageBrowserProxy.prototype = { - loadStartupPages: assertNotReached, - - useCurrentPages: assertNotReached, + class StartupUrlsPageBrowserProxy { + loadStartupPages() {} + useCurrentPages() {} /** * @param {string} url * @return {!Promise<boolean>} Whether the URL is valid. */ - validateStartupPage: assertNotReached, + validateStartupPage(url) {} /** * @param {string} url * @return {!Promise<boolean>} Whether the URL was actually added, or * ignored because it was invalid. */ - addStartupPage: assertNotReached, + addStartupPage(url) {} /** * @param {number} modelIndex @@ -40,52 +37,49 @@ * @return {!Promise<boolean>} Whether the URL was actually edited, or * ignored because it was invalid. */ - editStartupPage: assertNotReached, + editStartupPage(modelIndex, url) {} /** @param {number} index */ - removeStartupPage: assertNotReached, - }; + removeStartupPage(index) {} + } /** * @implements {settings.StartupUrlsPageBrowserProxy} - * @constructor */ - function StartupUrlsPageBrowserProxyImpl() {} + class StartupUrlsPageBrowserProxyImpl { + /** @override */ + loadStartupPages() { + chrome.send('onStartupPrefsPageLoad'); + } + + /** @override */ + useCurrentPages() { + chrome.send('setStartupPagesToCurrentPages'); + } + + /** @override */ + validateStartupPage(url) { + return cr.sendWithPromise('validateStartupPage', url); + } + + /** @override */ + addStartupPage(url) { + return cr.sendWithPromise('addStartupPage', url); + } + + /** @override */ + editStartupPage(modelIndex, url) { + return cr.sendWithPromise('editStartupPage', modelIndex, url); + } + + /** @override */ + removeStartupPage(index) { + chrome.send('removeStartupPage', [index]); + } + } cr.addSingletonGetter(StartupUrlsPageBrowserProxyImpl); - StartupUrlsPageBrowserProxyImpl.prototype = { - /** @override */ - loadStartupPages: function() { - chrome.send('onStartupPrefsPageLoad'); - }, - - /** @override */ - useCurrentPages: function() { - chrome.send('setStartupPagesToCurrentPages'); - }, - - /** @override */ - validateStartupPage: function(url) { - return cr.sendWithPromise('validateStartupPage', url); - }, - - /** @override */ - addStartupPage: function(url) { - return cr.sendWithPromise('addStartupPage', url); - }, - - /** @override */ - editStartupPage: function(modelIndex, url) { - return cr.sendWithPromise('editStartupPage', modelIndex, url); - }, - - /** @override */ - removeStartupPage: function(index) { - chrome.send('removeStartupPage', [index]); - }, - }; - return { StartupUrlsPageBrowserProxy: StartupUrlsPageBrowserProxy, StartupUrlsPageBrowserProxyImpl: StartupUrlsPageBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js b/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js index 05e3dc6..d6dc9b9 100644 --- a/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/change_picture_browser_proxy.js
@@ -21,91 +21,87 @@ cr.define('settings', function() { /** @interface */ - function ChangePictureBrowserProxy() {} - - ChangePictureBrowserProxy.prototype = { + class ChangePictureBrowserProxy { /** * Retrieves the initial set of default images, profile image, etc. As a * response, the C++ sends these WebUIListener events: * 'default-images-changed', 'profile-image-changed', 'old-image-changed', * and 'selected-image-changed' */ - initialize: function() {}, + initialize() {} /** * Sets the user image to one of the default images. As a response, the C++ * sends the 'default-images-changed' WebUIListener event. * @param {string} imageUrl */ - selectDefaultImage: function(imageUrl) {}, + selectDefaultImage(imageUrl) {} /** * Sets the user image to the 'old' image. As a response, the C++ sends the * 'old-image-changed' WebUIListener event. */ - selectOldImage: function() {}, + selectOldImage() {} /** * Sets the user image to the profile image. As a response, the C++ sends * the 'profile-image-changed' WebUIListener event. */ - selectProfileImage: function() {}, + selectProfileImage() {} /** * Provides the taken photo as a data URL to the C++. No response is * expected. * @param {string} photoDataUrl */ - photoTaken: function(photoDataUrl) {}, + photoTaken(photoDataUrl) {} /** * Requests a file chooser to select a new user image. No response is * expected. */ - chooseFile: function() {}, - }; + chooseFile() {} + } /** - * @constructor * @implements {settings.ChangePictureBrowserProxy} */ - function ChangePictureBrowserProxyImpl() {} + class ChangePictureBrowserProxyImpl { + /** @override */ + initialize() { + chrome.send('onChangePicturePageInitialized'); + } + + /** @override */ + selectDefaultImage(imageUrl) { + chrome.send('selectImage', [imageUrl, 'default']); + } + + /** @override */ + selectOldImage() { + chrome.send('selectImage', ['', 'old']); + } + + /** @override */ + selectProfileImage() { + chrome.send('selectImage', ['', 'profile']); + } + + /** @override */ + photoTaken(photoDataUrl) { + chrome.send('photoTaken', [photoDataUrl]); + } + + /** @override */ + chooseFile() { + chrome.send('chooseFile'); + } + } + // The singleton instance_ is replaced with a test version of this wrapper // during testing. cr.addSingletonGetter(ChangePictureBrowserProxyImpl); - ChangePictureBrowserProxyImpl.prototype = { - /** @override */ - initialize: function() { - chrome.send('onChangePicturePageInitialized'); - }, - - /** @override */ - selectDefaultImage: function(imageUrl) { - chrome.send('selectImage', [imageUrl, 'default']); - }, - - /** @override */ - selectOldImage: function() { - chrome.send('selectImage', ['', 'old']); - }, - - /** @override */ - selectProfileImage: function() { - chrome.send('selectImage', ['', 'profile']); - }, - - /** @override */ - photoTaken: function(photoDataUrl) { - chrome.send('photoTaken', [photoDataUrl]); - }, - - /** @override */ - chooseFile: function() { - chrome.send('chooseFile'); - }, - }; - return { ChangePictureBrowserProxy: ChangePictureBrowserProxy, ChangePictureBrowserProxyImpl: ChangePictureBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js b/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js index f43dfb6..008e6c94 100644 --- a/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js
@@ -10,73 +10,69 @@ cr.define('settings', function() { /** @interface */ - function EasyUnlockBrowserProxy() {} - - EasyUnlockBrowserProxy.prototype = { + class EasyUnlockBrowserProxy { /** * Returns a true promise if Easy Unlock is already enabled on the device. * @return {!Promise<boolean>} */ - getEnabledStatus: function() {}, + getEnabledStatus() {} /** * Starts the Easy Unlock setup flow. */ - startTurnOnFlow: function() {}, + startTurnOnFlow() {} /** * Returns the Easy Unlock turn off flow status. * @return {!Promise<string>} */ - getTurnOffFlowStatus: function() {}, + getTurnOffFlowStatus() {} /** * Begins the Easy Unlock turn off flow. */ - startTurnOffFlow: function() {}, + startTurnOffFlow() {} /** * Cancels any in-progress Easy Unlock turn-off flows. */ - cancelTurnOffFlow: function() {}, - }; + cancelTurnOffFlow() {} + } /** - * @constructor * @implements {settings.EasyUnlockBrowserProxy} */ - function EasyUnlockBrowserProxyImpl() {} + class EasyUnlockBrowserProxyImpl { + /** @override */ + getEnabledStatus() { + return cr.sendWithPromise('easyUnlockGetEnabledStatus'); + } + + /** @override */ + startTurnOnFlow() { + chrome.send('easyUnlockStartTurnOnFlow'); + } + + /** @override */ + getTurnOffFlowStatus() { + return cr.sendWithPromise('easyUnlockGetTurnOffFlowStatus'); + } + + /** @override */ + startTurnOffFlow() { + chrome.send('easyUnlockStartTurnOffFlow'); + } + + /** @override */ + cancelTurnOffFlow() { + chrome.send('easyUnlockCancelTurnOffFlow'); + } + } + // The singleton instance_ is replaced with a test version of this wrapper // during testing. cr.addSingletonGetter(EasyUnlockBrowserProxyImpl); - EasyUnlockBrowserProxyImpl.prototype = { - /** @override */ - getEnabledStatus: function() { - return cr.sendWithPromise('easyUnlockGetEnabledStatus'); - }, - - /** @override */ - startTurnOnFlow: function() { - chrome.send('easyUnlockStartTurnOnFlow'); - }, - - /** @override */ - getTurnOffFlowStatus: function() { - return cr.sendWithPromise('easyUnlockGetTurnOffFlowStatus'); - }, - - /** @override */ - startTurnOffFlow: function() { - chrome.send('easyUnlockStartTurnOffFlow'); - }, - - /** @override */ - cancelTurnOffFlow: function() { - chrome.send('easyUnlockCancelTurnOffFlow'); - }, - }; - return { EasyUnlockBrowserProxy: EasyUnlockBrowserProxy, EasyUnlockBrowserProxyImpl: EasyUnlockBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/people_page/fingerprint_browser_proxy.js b/chrome/browser/resources/settings/people_page/fingerprint_browser_proxy.js index 09e2f8c0..71941a3a 100644 --- a/chrome/browser/resources/settings/people_page/fingerprint_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/fingerprint_browser_proxy.js
@@ -52,112 +52,106 @@ cr.define('settings', function() { /** @interface */ - function FingerprintBrowserProxy() {} - - FingerprintBrowserProxy.prototype = { + class FingerprintBrowserProxy { /** * @return {!Promise<!settings.FingerprintInfo>} */ - getFingerprintsList: function() {}, + getFingerprintsList() {} /** * @return {!Promise<number>} */ - getNumFingerprints: function() {}, + getNumFingerprints() {} - startEnroll: function() {}, - - cancelCurrentEnroll: function() {}, + startEnroll() {} + cancelCurrentEnroll() {} /** * @param {number} index * @return {!Promise<string>} */ - getEnrollmentLabel: function(index) {}, + getEnrollmentLabel(index) {} /** * @param {number} index * @return {!Promise<boolean>} */ - removeEnrollment: function(index) {}, + removeEnrollment(index) {} /** * @param {number} index * @param {string} newLabel * @return {!Promise<boolean>} */ - changeEnrollmentLabel: function(index, newLabel) {}, + changeEnrollmentLabel(index, newLabel) {} - startAuthentication: function() {}, - - endCurrentAuthentication: function() {}, + startAuthentication() {} + endCurrentAuthentication() {} /** * TODO(sammiequon): Temporary function to let the handler know when a * completed scan has been sent via click on the setup fingerprint dialog. * Remove this when real scans are implemented. */ - fakeScanComplete: function() {}, - }; + fakeScanComplete() {} + } /** - * @constructor * @implements {settings.FingerprintBrowserProxy} */ - function FingerprintBrowserProxyImpl() {} - cr.addSingletonGetter(FingerprintBrowserProxyImpl); - - FingerprintBrowserProxyImpl.prototype = { + class FingerprintBrowserProxyImpl { /** @override */ - getFingerprintsList: function() { + getFingerprintsList() { return cr.sendWithPromise('getFingerprintsList'); - }, + } /** @override */ - getNumFingerprints: function() { + getNumFingerprints() { return cr.sendWithPromise('getNumFingerprints'); - }, + } /** @override */ - startEnroll: function() { + startEnroll() { chrome.send('startEnroll'); - }, + } /** @override */ - cancelCurrentEnroll: function() { + cancelCurrentEnroll() { chrome.send('cancelCurrentEnroll'); - }, + } /** @override */ - getEnrollmentLabel: function(index) { + getEnrollmentLabel(index) { return cr.sendWithPromise('getEnrollmentLabel'); - }, + } /** @override */ - removeEnrollment: function(index) { + removeEnrollment(index) { return cr.sendWithPromise('removeEnrollment', index); - }, + } /** @override */ - changeEnrollmentLabel: function(index, newLabel) { + changeEnrollmentLabel(index, newLabel) { return cr.sendWithPromise('changeEnrollmentLabel', index, newLabel); - }, + } /** @override */ - startAuthentication: function() { + startAuthentication() { chrome.send('startAuthentication'); - }, + } /** @override */ - endCurrentAuthentication: function() { + endCurrentAuthentication() { chrome.send('endCurrentAuthentication'); - }, + } /** @override */ - fakeScanComplete: function() { + fakeScanComplete() { chrome.send('fakeScanComplete'); - }, - }; + } + } + + cr.addSingletonGetter(FingerprintBrowserProxyImpl); return { FingerprintBrowserProxy: FingerprintBrowserProxy,
diff --git a/chrome/browser/resources/settings/people_page/import_data_browser_proxy.js b/chrome/browser/resources/settings/people_page/import_data_browser_proxy.js index 24c108ec..5458bab 100644 --- a/chrome/browser/resources/settings/people_page/import_data_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/import_data_browser_proxy.js
@@ -36,54 +36,50 @@ cr.define('settings', function() { /** @interface */ - function ImportDataBrowserProxy() {} - - ImportDataBrowserProxy.prototype = { + class ImportDataBrowserProxy { /** * Returns the source profiles available for importing from other browsers. * @return {!Promise<!Array<!settings.BrowserProfile>>} */ - initializeImportDialog: function() {}, + initializeImportDialog() {} /** * Starts importing data for the specificed source browser profile. The C++ * responds with the 'import-data-status-changed' WebUIListener event. * @param {number} sourceBrowserProfileIndex */ - importData: function(sourceBrowserProfileIndex) {}, + importData(sourceBrowserProfileIndex) {} /** * Prompts the user to choose a bookmarks file to import bookmarks from. */ - importFromBookmarksFile: function() {}, - }; + importFromBookmarksFile() {} + } /** - * @constructor * @implements {settings.ImportDataBrowserProxy} */ - function ImportDataBrowserProxyImpl() {} + class ImportDataBrowserProxyImpl { + /** @override */ + initializeImportDialog() { + return cr.sendWithPromise('initializeImportDialog'); + } + + /** @override */ + importData(sourceBrowserProfileIndex) { + chrome.send('importData', [sourceBrowserProfileIndex]); + } + + /** @override */ + importFromBookmarksFile() { + chrome.send('importFromBookmarksFile'); + } + } + // The singleton instance_ is replaced with a test version of this wrapper // during testing. cr.addSingletonGetter(ImportDataBrowserProxyImpl); - ImportDataBrowserProxyImpl.prototype = { - /** @override */ - initializeImportDialog: function() { - return cr.sendWithPromise('initializeImportDialog'); - }, - - /** @override */ - importData: function(sourceBrowserProfileIndex) { - chrome.send('importData', [sourceBrowserProfileIndex]); - }, - - /** @override */ - importFromBookmarksFile: function() { - chrome.send('importFromBookmarksFile'); - }, - }; - return { ImportDataBrowserProxy: ImportDataBrowserProxy, ImportDataBrowserProxyImpl: ImportDataBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/people_page/manage_profile_browser_proxy.js b/chrome/browser/resources/settings/people_page/manage_profile_browser_proxy.js index 34e2d341..85a7259 100644 --- a/chrome/browser/resources/settings/people_page/manage_profile_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/manage_profile_browser_proxy.js
@@ -20,95 +20,91 @@ cr.define('settings', function() { /** @interface */ - function ManageProfileBrowserProxy() {} - - ManageProfileBrowserProxy.prototype = { + class ManageProfileBrowserProxy { /** * Gets the available profile icons to choose from. * @return {!Promise<!Array<!AvatarIcon>>} */ - getAvailableIcons: function() {}, + getAvailableIcons() {} /** * Sets the profile's icon to the GAIA avatar. */ - setProfileIconToGaiaAvatar: function() {}, + setProfileIconToGaiaAvatar() {} /** * Sets the profile's icon to one of the default avatars. * @param {string} iconUrl The new profile URL. */ - setProfileIconToDefaultAvatar: function(iconUrl) {}, + setProfileIconToDefaultAvatar(iconUrl) {} /** * Sets the profile's name. * @param {string} name The new profile name. */ - setProfileName: function(name) {}, + setProfileName(name) {} /** * Returns whether the current profile has a shortcut. * @return {!Promise<ProfileShortcutStatus>} */ - getProfileShortcutStatus: function() {}, + getProfileShortcutStatus() {} /** * Adds a shortcut for the current profile. */ - addProfileShortcut: function() {}, + addProfileShortcut() {} /** * Removes the shortcut of the current profile. */ - removeProfileShortcut: function() {}, - }; + removeProfileShortcut() {} + } /** - * @constructor * @implements {settings.ManageProfileBrowserProxy} */ - function ManageProfileBrowserProxyImpl() {} + class ManageProfileBrowserProxyImpl { + /** @override */ + getAvailableIcons() { + return cr.sendWithPromise('getAvailableIcons'); + } + + /** @override */ + setProfileIconToGaiaAvatar() { + chrome.send('setProfileIconToGaiaAvatar'); + } + + /** @override */ + setProfileIconToDefaultAvatar(iconUrl) { + chrome.send('setProfileIconToDefaultAvatar', [iconUrl]); + } + + /** @override */ + setProfileName(name) { + chrome.send('setProfileName', [name]); + } + + /** @override */ + getProfileShortcutStatus() { + return cr.sendWithPromise('requestProfileShortcutStatus'); + } + + /** @override */ + addProfileShortcut() { + chrome.send('addProfileShortcut'); + } + + /** @override */ + removeProfileShortcut() { + chrome.send('removeProfileShortcut'); + } + } + // The singleton instance_ is replaced with a test version of this wrapper // during testing. cr.addSingletonGetter(ManageProfileBrowserProxyImpl); - ManageProfileBrowserProxyImpl.prototype = { - /** @override */ - getAvailableIcons: function() { - return cr.sendWithPromise('getAvailableIcons'); - }, - - /** @override */ - setProfileIconToGaiaAvatar: function() { - chrome.send('setProfileIconToGaiaAvatar'); - }, - - /** @override */ - setProfileIconToDefaultAvatar: function(iconUrl) { - chrome.send('setProfileIconToDefaultAvatar', [iconUrl]); - }, - - /** @override */ - setProfileName: function(name) { - chrome.send('setProfileName', [name]); - }, - - /** @override */ - getProfileShortcutStatus: function() { - return cr.sendWithPromise('requestProfileShortcutStatus'); - }, - - /** @override */ - addProfileShortcut: function() { - chrome.send('addProfileShortcut'); - }, - - /** @override */ - removeProfileShortcut: function() { - chrome.send('removeProfileShortcut'); - }, - }; - return { ManageProfileBrowserProxy: ManageProfileBrowserProxy, ManageProfileBrowserProxyImpl: ManageProfileBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/people_page/profile_info_browser_proxy.js b/chrome/browser/resources/settings/people_page/profile_info_browser_proxy.js index 81eb71a..31f4824 100644 --- a/chrome/browser/resources/settings/people_page/profile_info_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/profile_info_browser_proxy.js
@@ -20,51 +20,47 @@ cr.define('settings', function() { /** @interface */ - function ProfileInfoBrowserProxy() {} - - ProfileInfoBrowserProxy.prototype = { + class ProfileInfoBrowserProxy { /** * Returns a Promise for the profile info. * @return {!Promise<!settings.ProfileInfo>} */ - getProfileInfo: function() {}, + getProfileInfo() {} /** * Requests the profile stats count. The result is returned by the * 'profile-stats-count-ready' WebUI listener event. */ - getProfileStatsCount: function() {}, + getProfileStatsCount() {} /** * Returns a Promise that's true if the profile manages supervised users. * @return {!Promise<boolean>} */ - getProfileManagesSupervisedUsers: function() {}, - }; + getProfileManagesSupervisedUsers() {} + } /** - * @constructor * @implements {ProfileInfoBrowserProxy} */ - function ProfileInfoBrowserProxyImpl() {} - cr.addSingletonGetter(ProfileInfoBrowserProxyImpl); - - ProfileInfoBrowserProxyImpl.prototype = { + class ProfileInfoBrowserProxyImpl { /** @override */ - getProfileInfo: function() { + getProfileInfo() { return cr.sendWithPromise('getProfileInfo'); - }, + } /** @override */ - getProfileStatsCount: function() { + getProfileStatsCount() { chrome.send('getProfileStatsCount'); - }, + } /** @override */ - getProfileManagesSupervisedUsers: function() { + getProfileManagesSupervisedUsers() { return cr.sendWithPromise('getProfileManagesSupervisedUsers'); - }, - }; + } + } + + cr.addSingletonGetter(ProfileInfoBrowserProxyImpl); return { ProfileInfoBrowserProxyImpl: ProfileInfoBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js index 648d22f..05f345f3 100644 --- a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
@@ -105,138 +105,138 @@ cr.define('settings', function() { /** @interface */ - function SyncBrowserProxy() {} - - SyncBrowserProxy.prototype = { + class SyncBrowserProxy { // <if expr="not chromeos"> /** * Starts the signin process for the user. Does nothing if the user is * already signed in. */ - startSignIn: function() {}, + startSignIn() {} /** * Signs out the signed-in user. * @param {boolean} deleteProfile */ - signOut: function(deleteProfile) {}, + signOut(deleteProfile) {} /** * Opens the multi-profile user manager. */ - manageOtherPeople: function() {}, + manageOtherPeople() {} + // </if> // <if expr="chromeos"> /** * Signs the user out. */ - attemptUserExit: function() {}, + attemptUserExit() {} + // </if> /** * Gets the current sync status. * @return {!Promise<!settings.SyncStatus>} */ - getSyncStatus: function() {}, + getSyncStatus() {} /** * Function to invoke when the sync page has been navigated to. This * registers the UI as the "active" sync UI so that if the user tries to * open another sync UI, this one will be shown instead. */ - didNavigateToSyncPage: function() {}, + didNavigateToSyncPage() {} /** * Function to invoke when leaving the sync page so that the C++ layer can * be notified that the sync UI is no longer open. */ - didNavigateAwayFromSyncPage: function() {}, + didNavigateAwayFromSyncPage() {} /** * Sets which types of data to sync. * @param {!settings.SyncPrefs} syncPrefs * @return {!Promise<!settings.PageStatus>} */ - setSyncDatatypes: function(syncPrefs) {}, + setSyncDatatypes(syncPrefs) {} /** * Sets the sync encryption options. * @param {!settings.SyncPrefs} syncPrefs * @return {!Promise<!settings.PageStatus>} */ - setSyncEncryption: function(syncPrefs) {}, + setSyncEncryption(syncPrefs) {} /** * Opens the Google Activity Controls url in a new tab. */ - openActivityControlsUrl: function() {}, - }; + openActivityControlsUrl() {} + } /** - * @constructor * @implements {settings.SyncBrowserProxy} */ - function SyncBrowserProxyImpl() {} - cr.addSingletonGetter(SyncBrowserProxyImpl); - - SyncBrowserProxyImpl.prototype = { + class SyncBrowserProxyImpl { // <if expr="not chromeos"> /** @override */ - startSignIn: function() { + startSignIn() { chrome.send('SyncSetupStartSignIn'); - }, + } /** @override */ - signOut: function(deleteProfile) { + signOut(deleteProfile) { chrome.send('SyncSetupStopSyncing', [deleteProfile]); - }, + } /** @override */ - manageOtherPeople: function() { + manageOtherPeople() { chrome.send('SyncSetupManageOtherPeople'); - }, + } + // </if> // <if expr="chromeos"> /** @override */ - attemptUserExit: function() { + attemptUserExit() { return chrome.send('AttemptUserExit'); - }, + } + // </if> /** @override */ - getSyncStatus: function() { + getSyncStatus() { return cr.sendWithPromise('SyncSetupGetSyncStatus'); - }, + } /** @override */ - didNavigateToSyncPage: function() { + didNavigateToSyncPage() { chrome.send('SyncSetupShowSetupUI'); - }, + } /** @override */ - didNavigateAwayFromSyncPage: function() { + didNavigateAwayFromSyncPage() { chrome.send('SyncSetupDidClosePage'); - }, + } /** @override */ - setSyncDatatypes: function(syncPrefs) { + setSyncDatatypes(syncPrefs) { return cr.sendWithPromise( 'SyncSetupSetDatatypes', JSON.stringify(syncPrefs)); - }, + } /** @override */ - setSyncEncryption: function(syncPrefs) { + setSyncEncryption(syncPrefs) { return cr.sendWithPromise( 'SyncSetupSetEncryption', JSON.stringify(syncPrefs)); - }, + } /** @override */ - openActivityControlsUrl: function() { + openActivityControlsUrl() { chrome.metricsPrivate.recordUserAction( 'Signin_AccountSettings_GoogleActivityControlsClicked'); } - }; + } + + cr.addSingletonGetter(SyncBrowserProxyImpl); return { SyncBrowserProxy: SyncBrowserProxy,
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js b/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js index 3af40d9..2a5eb45 100644 --- a/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js +++ b/chrome/browser/resources/settings/printing_page/cups_printers_browser_proxy.js
@@ -65,117 +65,111 @@ cr.define('settings', function() { /** @interface */ - function CupsPrintersBrowserProxy() {} - - CupsPrintersBrowserProxy.prototype = { - + class CupsPrintersBrowserProxy { /** * @return {!Promise<!CupsPrintersList>} */ - getCupsPrintersList: function() {}, + getCupsPrintersList() {} /** * @param {string} printerId * @param {string} printerName */ - updateCupsPrinter: function(printerId, printerName) {}, + updateCupsPrinter(printerId, printerName) {} /** * @param {string} printerId * @param {string} printerName */ - removeCupsPrinter: function(printerId, printerName) {}, + removeCupsPrinter(printerId, printerName) {} /** * @return {!Promise<string>} The full path of the printer PPD file. */ - getCupsPrinterPPDPath: function() {}, + getCupsPrinterPPDPath() {} /** * @param {!CupsPrinterInfo} newPrinter */ - addCupsPrinter: function(newPrinter) {}, + addCupsPrinter(newPrinter) {} - startDiscoveringPrinters: function() {}, - - stopDiscoveringPrinters: function() {}, + startDiscoveringPrinters() {} + stopDiscoveringPrinters() {} /** * @return {!Promise<!ManufacturersInfo>} */ - getCupsPrinterManufacturersList: function() {}, + getCupsPrinterManufacturersList() {} /** * @param {string} manufacturer * @return {!Promise<!ModelsInfo>} */ - getCupsPrinterModelsList: function(manufacturer) {}, + getCupsPrinterModelsList(manufacturer) {} /** * @param {!CupsPrinterInfo} newPrinter * @return {!Promise<!PrinterMakeModel>} */ - getPrinterInfo: function(newPrinter) {}, - }; + getPrinterInfo(newPrinter) {} + } /** - * @constructor * @implements {settings.CupsPrintersBrowserProxy} */ - function CupsPrintersBrowserProxyImpl() {} - cr.addSingletonGetter(CupsPrintersBrowserProxyImpl); - - CupsPrintersBrowserProxyImpl.prototype = { + class CupsPrintersBrowserProxyImpl { /** @override */ - getCupsPrintersList: function() { + getCupsPrintersList() { return cr.sendWithPromise('getCupsPrintersList'); - }, + } /** @override */ - updateCupsPrinter: function(printerId, printerName) { + updateCupsPrinter(printerId, printerName) { chrome.send('updateCupsPrinter', [printerId, printerName]); - }, + } /** @override */ - removeCupsPrinter: function(printerId, printerName) { + removeCupsPrinter(printerId, printerName) { chrome.send('removeCupsPrinter', [printerId, printerName]); - }, + } /** @override */ - addCupsPrinter: function(newPrinter) { + addCupsPrinter(newPrinter) { chrome.send('addCupsPrinter', [newPrinter]); - }, + } /** @override */ - getCupsPrinterPPDPath: function() { + getCupsPrinterPPDPath() { return cr.sendWithPromise('selectPPDFile'); - }, + } /** @override */ - startDiscoveringPrinters: function() { + startDiscoveringPrinters() { chrome.send('startDiscoveringPrinters'); - }, + } /** @override */ - stopDiscoveringPrinters: function() { + stopDiscoveringPrinters() { chrome.send('stopDiscoveringPrinters'); - }, + } /** @override */ - getCupsPrinterManufacturersList: function() { + getCupsPrinterManufacturersList() { return cr.sendWithPromise('getCupsPrinterManufacturersList'); - }, + } /** @override */ - getCupsPrinterModelsList: function(manufacturer) { + getCupsPrinterModelsList(manufacturer) { return cr.sendWithPromise('getCupsPrinterModelsList', manufacturer); - }, + } /** @override */ - getPrinterInfo: function(newPrinter) { + getPrinterInfo(newPrinter) { return cr.sendWithPromise('getPrinterInfo', newPrinter); - }, - }; + } + } + + cr.addSingletonGetter(CupsPrintersBrowserProxyImpl); return { CupsPrintersBrowserProxy: CupsPrintersBrowserProxy,
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js b/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js index 38f544d..9d384a2 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js
@@ -9,66 +9,65 @@ cr.define('settings', function() { /** @interface */ - function PrivacyPageBrowserProxy() {} - - PrivacyPageBrowserProxy.prototype = { + class PrivacyPageBrowserProxy { // <if expr="_google_chrome and not chromeos"> /** @return {!Promise<!MetricsReporting>} */ - getMetricsReporting: assertNotReached, + getMetricsReporting() {} /** @param {boolean} enabled */ - setMetricsReportingEnabled: assertNotReached, + setMetricsReportingEnabled(enabled) {} + // </if> // <if expr="is_win or is_macosx"> /** Invokes the native certificate manager (used by win and mac). */ - showManageSSLCertificates: function() {}, + showManageSSLCertificates() {} + // </if> /** @return {!Promise<boolean>} */ - getSafeBrowsingExtendedReporting: assertNotReached, + getSafeBrowsingExtendedReporting() {} /** @param {boolean} enabled */ - setSafeBrowsingExtendedReportingEnabled: assertNotReached, - }; + setSafeBrowsingExtendedReportingEnabled(enabled) {} + } /** - * @constructor * @implements {settings.PrivacyPageBrowserProxy} */ - function PrivacyPageBrowserProxyImpl() {} - cr.addSingletonGetter(PrivacyPageBrowserProxyImpl); - - PrivacyPageBrowserProxyImpl.prototype = { + class PrivacyPageBrowserProxyImpl { // <if expr="_google_chrome and not chromeos"> /** @override */ - getMetricsReporting: function() { + getMetricsReporting() { return cr.sendWithPromise('getMetricsReporting'); - }, + } /** @override */ - setMetricsReportingEnabled: function(enabled) { + setMetricsReportingEnabled(enabled) { chrome.send('setMetricsReportingEnabled', [enabled]); - }, + } + // </if> /** @override */ - getSafeBrowsingExtendedReporting: function() { + getSafeBrowsingExtendedReporting() { return cr.sendWithPromise('getSafeBrowsingExtendedReporting'); - }, + } /** @override */ - setSafeBrowsingExtendedReportingEnabled: function(enabled) { + setSafeBrowsingExtendedReportingEnabled(enabled) { chrome.send('setSafeBrowsingExtendedReportingEnabled', [enabled]); - }, + } // <if expr="is_win or is_macosx"> /** @override */ - showManageSSLCertificates: function() { + showManageSSLCertificates() { chrome.send('showManageSSLCertificates'); - }, + } // </if> - }; + } + + cr.addSingletonGetter(PrivacyPageBrowserProxyImpl); return { PrivacyPageBrowserProxy: PrivacyPageBrowserProxy,
diff --git a/chrome/browser/resources/settings/reset_page/reset_browser_proxy.js b/chrome/browser/resources/settings/reset_page/reset_browser_proxy.js index ef80889..f43c9a0 100644 --- a/chrome/browser/resources/settings/reset_page/reset_browser_proxy.js +++ b/chrome/browser/resources/settings/reset_page/reset_browser_proxy.js
@@ -4,89 +4,83 @@ cr.define('settings', function() { /** @interface */ - function ResetBrowserProxy() {} - - ResetBrowserProxy.prototype = { + class ResetBrowserProxy { /** * @param {boolean} sendSettings Whether the user gave consent to upload * broken settings to Google for analysis. * @param {string} requestOrigin The origin of the reset request. * @return {!Promise} A promise firing once resetting has completed. */ - performResetProfileSettings: function(sendSettings, requestOrigin) {}, + performResetProfileSettings(sendSettings, requestOrigin) {} /** * A method to be called when the reset profile dialog is hidden. */ - onHideResetProfileDialog: function() {}, + onHideResetProfileDialog() {} /** * A method to be called when the reset profile banner is hidden. */ - onHideResetProfileBanner: function() {}, + onHideResetProfileBanner() {} /** * A method to be called when the reset profile dialog is shown. */ - onShowResetProfileDialog: function() {}, + onShowResetProfileDialog() {} /** * Shows the settings that are about to be reset and which will be reported * to Google for analysis, in a new tab. */ - showReportedSettings: function() {}, + showReportedSettings() {} /** * Retrieves the triggered reset tool name. * @return {!Promise<string>} A promise firing with the tool name, once it * has been retrieved. */ - getTriggeredResetToolName: function() {}, + getTriggeredResetToolName() {} // <if expr="chromeos"> /** * A method to be called when the reset powerwash dialog is shown. */ - onPowerwashDialogShow: function() {}, + onPowerwashDialogShow() {} /** * Initiates a factory reset and restarts ChromeOS. */ - requestFactoryResetRestart: function() {}, + requestFactoryResetRestart() {} // </if> - }; + } /** - * @constructor * @implements {settings.ResetBrowserProxy} */ - function ResetBrowserProxyImpl() {} - cr.addSingletonGetter(ResetBrowserProxyImpl); - - ResetBrowserProxyImpl.prototype = { + class ResetBrowserProxyImpl { /** @override */ - performResetProfileSettings: function(sendSettings, requestOrigin) { + performResetProfileSettings(sendSettings, requestOrigin) { return cr.sendWithPromise( 'performResetProfileSettings', sendSettings, requestOrigin); - }, + } /** @override */ - onHideResetProfileDialog: function() { + onHideResetProfileDialog() { chrome.send('onHideResetProfileDialog'); - }, + } /** @override */ - onHideResetProfileBanner: function() { + onHideResetProfileBanner() { chrome.send('onHideResetProfileBanner'); - }, + } /** @override */ - onShowResetProfileDialog: function() { + onShowResetProfileDialog() { chrome.send('onShowResetProfileDialog'); - }, + } /** @override */ - showReportedSettings: function() { + showReportedSettings() { cr.sendWithPromise('getReportedSettings').then(function(settings) { var output = settings.map(function(entry) { return entry.key + ': ' + entry.value.replace(/\n/g, ', '); @@ -97,25 +91,27 @@ div.style.whiteSpace = 'pre'; win.document.body.appendChild(div); }); - }, + } /** @override */ - getTriggeredResetToolName: function() { + getTriggeredResetToolName() { return cr.sendWithPromise('getTriggeredResetToolName'); - }, + } // <if expr="chromeos"> /** @override */ - onPowerwashDialogShow: function() { + onPowerwashDialogShow() { chrome.send('onPowerwashDialogShow'); - }, + } /** @override */ - requestFactoryResetRestart: function() { + requestFactoryResetRestart() { chrome.send('requestFactoryResetRestart'); - }, + } // </if> - }; + } + + cr.addSingletonGetter(ResetBrowserProxyImpl); return { ResetBrowserProxyImpl: ResetBrowserProxyImpl,
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.js b/chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.js index 5423903..76642485 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.js +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.js
@@ -51,112 +51,108 @@ cr.define('settings', function() { /** @interface */ - function SearchEnginesBrowserProxy() {} - - SearchEnginesBrowserProxy.prototype = { + class SearchEnginesBrowserProxy { /** @param {number} modelIndex */ - setDefaultSearchEngine: function(modelIndex) {}, + setDefaultSearchEngine(modelIndex) {} /** @param {number} modelIndex */ - removeSearchEngine: function(modelIndex) {}, + removeSearchEngine(modelIndex) {} /** @param {number} modelIndex */ - searchEngineEditStarted: function(modelIndex) {}, + searchEngineEditStarted(modelIndex) {} - searchEngineEditCancelled: function() {}, + searchEngineEditCancelled() {} /** * @param {string} searchEngine * @param {string} keyword * @param {string} queryUrl */ - searchEngineEditCompleted: function(searchEngine, keyword, queryUrl) {}, + searchEngineEditCompleted(searchEngine, keyword, queryUrl) {} /** @return {!Promise<!SearchEnginesInfo>} */ - getSearchEnginesList: function() {}, + getSearchEnginesList() {} /** * @param {string} fieldName * @param {string} fieldValue * @return {!Promise<boolean>} */ - validateSearchEngineInput: function(fieldName, fieldValue) {}, + validateSearchEngineInput(fieldName, fieldValue) {} /** @return {!Promise<!SearchPageHotwordInfo>} */ - getHotwordInfo: function() {}, + getHotwordInfo() {} /** @param {boolean} enabled */ - setHotwordSearchEnabled: function(enabled) {}, + setHotwordSearchEnabled(enabled) {} /** @return {!Promise<boolean>} */ - getGoogleNowAvailability: function() {}, - }; + getGoogleNowAvailability() {} + } /** - * @constructor * @implements {settings.SearchEnginesBrowserProxy} */ - function SearchEnginesBrowserProxyImpl() {} - // The singleton instance_ is replaced with a test version of this wrapper - // during testing. - cr.addSingletonGetter(SearchEnginesBrowserProxyImpl); - - SearchEnginesBrowserProxyImpl.prototype = { + class SearchEnginesBrowserProxyImpl { /** @override */ - setDefaultSearchEngine: function(modelIndex) { + setDefaultSearchEngine(modelIndex) { chrome.send('setDefaultSearchEngine', [modelIndex]); - }, + } /** @override */ - removeSearchEngine: function(modelIndex) { + removeSearchEngine(modelIndex) { chrome.send('removeSearchEngine', [modelIndex]); - }, + } /** @override */ - searchEngineEditStarted: function(modelIndex) { + searchEngineEditStarted(modelIndex) { chrome.send('searchEngineEditStarted', [modelIndex]); - }, + } /** @override */ - searchEngineEditCancelled: function() { + searchEngineEditCancelled() { chrome.send('searchEngineEditCancelled'); - }, + } /** @override */ - searchEngineEditCompleted: function(searchEngine, keyword, queryUrl) { + searchEngineEditCompleted(searchEngine, keyword, queryUrl) { chrome.send('searchEngineEditCompleted', [ searchEngine, keyword, queryUrl, ]); - }, + } /** @override */ - getSearchEnginesList: function() { + getSearchEnginesList() { return cr.sendWithPromise('getSearchEnginesList'); - }, + } /** @override */ - validateSearchEngineInput: function(fieldName, fieldValue) { + validateSearchEngineInput(fieldName, fieldValue) { return cr.sendWithPromise( 'validateSearchEngineInput', fieldName, fieldValue); - }, + } /** @override */ - getHotwordInfo: function() { + getHotwordInfo() { return cr.sendWithPromise('getHotwordInfo'); - }, + } /** @override */ - setHotwordSearchEnabled: function(enabled) { + setHotwordSearchEnabled(enabled) { chrome.send('setHotwordSearchEnabled', [enabled]); - }, + } /** @override */ - getGoogleNowAvailability: function() { + getGoogleNowAvailability() { return cr.sendWithPromise('getGoogleNowAvailability'); - }, - }; + } + } + + // The singleton instance_ is replaced with a test version of this wrapper + // during testing. + cr.addSingletonGetter(SearchEnginesBrowserProxyImpl); return { SearchEnginesBrowserProxy: SearchEnginesBrowserProxy,
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index e2b6b6cc..395a62c 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -6,6 +6,12 @@ <dom-module id="settings-shared"> <template> <style include="settings-icons cr-shared-style"> + /* Prevent action-links from being selected to avoid accidental + * selection when trying to click it. */ + a[is=action-link] { + -webkit-user-select: none; + } + /* Use <h2> as the "sub-header" mentioned in the UX design docs. */ h2 { align-items: center;
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js index ecbd1c1..e335cdf 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
@@ -98,43 +98,41 @@ cr.define('settings', function() { /** @interface */ - function SiteSettingsPrefsBrowserProxy() {} - - SiteSettingsPrefsBrowserProxy.prototype = { + class SiteSettingsPrefsBrowserProxy { /** * Sets the default value for a site settings category. * @param {string} contentType The name of the category to change. * @param {string} defaultValue The name of the value to set as default. */ - setDefaultValueForContentType: function(contentType, defaultValue) {}, + setDefaultValueForContentType(contentType, defaultValue) {} /** * Gets the cookie details for a particular site. * @param {string} site The name of the site. * @return {!Promise<!CookieList>} */ - getCookieDetails: function(site) {}, + getCookieDetails(site) {} /** * Gets the default value for a site settings category. * @param {string} contentType The name of the category to query. * @return {!Promise<!DefaultContentSetting>} */ - getDefaultValueForContentType: function(contentType) {}, + getDefaultValueForContentType(contentType) {} /** * Gets the exceptions (site list) for a particular category. * @param {string} contentType The name of the category to query. * @return {!Promise<!Array<!RawSiteException>>} */ - getExceptionList: function(contentType) {}, + getExceptionList(contentType) {} /** * Gets the exception details for a particular site. * @param {string} site The name of the site. * @return {!Promise<!RawSiteException>} */ - getSiteDetails: function(site) {}, + getSiteDetails(site) {} /** * Resets the category permission for a given origin (expressed as primary @@ -146,8 +144,8 @@ * @param {boolean} incognito Whether this applies only to a current * incognito session exception. */ - resetCategoryPermissionForOrigin: function( - primaryPattern, secondaryPattern, contentType, incognito) {}, + resetCategoryPermissionForOrigin( + primaryPattern, secondaryPattern, contentType, incognito) {} /** * Sets the category permission for a given origin (expressed as primary @@ -160,36 +158,36 @@ * @param {boolean} incognito Whether this rule applies only to the current * incognito session. */ - setCategoryPermissionForOrigin: function( - primaryPattern, secondaryPattern, contentType, value, incognito) {}, + setCategoryPermissionForOrigin( + primaryPattern, secondaryPattern, contentType, value, incognito) {} /** * Checks whether a pattern is valid. * @param {string} pattern The pattern to check * @return {!Promise<boolean>} True if the pattern is valid. */ - isPatternValid: function(pattern) {}, + isPatternValid(pattern) {} /** * Gets the list of default capture devices for a given type of media. List * is returned through a JS call to updateDevicesMenu. * @param {string} type The type to look up. */ - getDefaultCaptureDevices: function(type) {}, + getDefaultCaptureDevices(type) {} /** * Sets a default devices for a given type of media. * @param {string} type The type of media to configure. * @param {string} defaultValue The id of the media device to set. */ - setDefaultCaptureDevice: function(type, defaultValue) {}, + setDefaultCaptureDevice(type, defaultValue) {} /** * Reloads all cookies. * @return {!Promise<!CookieList>} Returns the full cookie * list. */ - reloadCookies: function() {}, + reloadCookies() {} /** * Fetches all children of a given cookie. @@ -197,20 +195,20 @@ * @return {!Promise<!Array<!CookieDataSummaryItem>>} Returns a cookie list * for the given path. */ - loadCookieChildren: function(path) {}, + loadCookieChildren(path) {} /** * Removes a given cookie. * @param {string} path The path to the parent cookie. */ - removeCookie: function(path) {}, + removeCookie(path) {} /** * Removes all cookies. * @return {!Promise<!CookieList>} Returns the up to date * cookie list once deletion is complete (empty list). */ - removeAllCookies: function() {}, + removeAllCookies() {} /** * observes _all_ of the the protocol handler state, which includes a list @@ -218,7 +216,7 @@ * other state sent with the messages 'setIgnoredProtocolHandler' and * 'setHandlersEnabled'. */ - observeProtocolHandlers: function() {}, + observeProtocolHandlers() {} /** * Observes one aspect of the protocol handler so that updates to the @@ -229,34 +227,34 @@ * If |observeProtocolHandlers| is called, there's no need to call this * observe as well. */ - observeProtocolHandlersEnabledState: function() {}, + observeProtocolHandlersEnabledState() {} /** * Enables or disables the ability for sites to ask to become the default * protocol handlers. * @param {boolean} enabled Whether sites can ask to become default. */ - setProtocolHandlerDefault: function(enabled) {}, + setProtocolHandlerDefault(enabled) {} /** * Sets a certain url as default for a given protocol handler. * @param {string} protocol The protocol to set a default for. * @param {string} url The url to use as the default. */ - setProtocolDefault: function(protocol, url) {}, + setProtocolDefault(protocol, url) {} /** * Deletes a certain protocol handler by url. * @param {string} protocol The protocol to delete the url from. * @param {string} url The url to delete. */ - removeProtocolHandler: function(protocol, url) {}, + removeProtocolHandler(protocol, url) {} /** * Fetches a list of all USB devices and the sites permitted to use them. * @return {!Promise<!Array<!UsbDeviceEntry>>} The list of USB devices. */ - fetchUsbDevices: function() {}, + fetchUsbDevices() {} /** * Removes a particular USB device object permission by origin and embedding @@ -266,73 +264,66 @@ * @param {!UsbDeviceDetails} usbDevice The USB device to revoke permission * for. */ - removeUsbDevice: function(origin, embeddingOrigin, usbDevice) {}, + removeUsbDevice(origin, embeddingOrigin, usbDevice) {} /** * Fetches the incognito status of the current profile (whether an icognito * profile exists). Returns the results via onIncognitoStatusChanged. */ - updateIncognitoStatus: function() {}, + updateIncognitoStatus() {} /** * Fetches the currently defined zoom levels for sites. Returns the results * via onZoomLevelsChanged. */ - fetchZoomLevels: function() {}, + fetchZoomLevels() {} /** * Removes a zoom levels for a given host. * @param {string} host The host to remove zoom levels for. */ - removeZoomLevel: function(host) {}, - }; + removeZoomLevel(host) {} + } /** - * @constructor * @implements {settings.SiteSettingsPrefsBrowserProxy} */ - function SiteSettingsPrefsBrowserProxyImpl() {} - - // The singleton instance_ is replaced with a test version of this wrapper - // during testing. - cr.addSingletonGetter(SiteSettingsPrefsBrowserProxyImpl); - - SiteSettingsPrefsBrowserProxyImpl.prototype = { + class SiteSettingsPrefsBrowserProxyImpl { /** @override */ - setDefaultValueForContentType: function(contentType, defaultValue) { + setDefaultValueForContentType(contentType, defaultValue) { chrome.send('setDefaultValueForContentType', [contentType, defaultValue]); - }, + } /** @override */ - getCookieDetails: function(site) { + getCookieDetails(site) { return cr.sendWithPromise('getCookieDetails', site); - }, + } /** @override */ - getDefaultValueForContentType: function(contentType) { + getDefaultValueForContentType(contentType) { return cr.sendWithPromise('getDefaultValueForContentType', contentType); - }, + } /** @override */ - getExceptionList: function(contentType) { + getExceptionList(contentType) { return cr.sendWithPromise('getExceptionList', contentType); - }, + } /** @override */ - getSiteDetails: function(site) { + getSiteDetails(site) { return cr.sendWithPromise('getSiteDetails', site); - }, + } /** @override */ - resetCategoryPermissionForOrigin: function( + resetCategoryPermissionForOrigin( primaryPattern, secondaryPattern, contentType, incognito) { chrome.send( 'resetCategoryPermissionForOrigin', [primaryPattern, secondaryPattern, contentType, incognito]); - }, + } /** @override */ - setCategoryPermissionForOrigin: function( + setCategoryPermissionForOrigin( primaryPattern, secondaryPattern, contentType, value, incognito) { // TODO(dschuyler): It may be incorrect for JS to send the embeddingOrigin // pattern. Look into removing this parameter from site_settings_handler. @@ -340,93 +331,97 @@ chrome.send( 'setCategoryPermissionForOrigin', [primaryPattern, '', contentType, value, incognito]); - }, + } /** @override */ - isPatternValid: function(pattern) { + isPatternValid(pattern) { return cr.sendWithPromise('isPatternValid', pattern); - }, + } /** @override */ - getDefaultCaptureDevices: function(type) { + getDefaultCaptureDevices(type) { chrome.send('getDefaultCaptureDevices', [type]); - }, + } /** @override */ - setDefaultCaptureDevice: function(type, defaultValue) { + setDefaultCaptureDevice(type, defaultValue) { chrome.send('setDefaultCaptureDevice', [type, defaultValue]); - }, + } /** @override */ - reloadCookies: function() { + reloadCookies() { return cr.sendWithPromise('reloadCookies'); - }, + } /** @override */ - loadCookieChildren: function(path) { + loadCookieChildren(path) { return cr.sendWithPromise('loadCookie', path); - }, + } /** @override */ - removeCookie: function(path) { + removeCookie(path) { chrome.send('removeCookie', [path]); - }, + } /** @override */ - removeAllCookies: function() { + removeAllCookies() { return cr.sendWithPromise('removeAllCookies'); - }, + } /** @override */ - observeProtocolHandlers: function() { + observeProtocolHandlers() { chrome.send('observeProtocolHandlers'); - }, + } /** @override */ - observeProtocolHandlersEnabledState: function() { + observeProtocolHandlersEnabledState() { chrome.send('observeProtocolHandlersEnabledState'); - }, + } /** @override */ - setProtocolHandlerDefault: function(enabled) { + setProtocolHandlerDefault(enabled) { chrome.send('setHandlersEnabled', [enabled]); - }, + } /** @override */ - setProtocolDefault: function(protocol, url) { + setProtocolDefault(protocol, url) { chrome.send('setDefault', [[protocol, url]]); - }, + } /** @override */ - removeProtocolHandler: function(protocol, url) { + removeProtocolHandler(protocol, url) { chrome.send('removeHandler', [[protocol, url]]); - }, + } /** @override */ - fetchUsbDevices: function() { + fetchUsbDevices() { return cr.sendWithPromise('fetchUsbDevices'); - }, + } /** @override */ - removeUsbDevice: function(origin, embeddingOrigin, usbDevice) { + removeUsbDevice(origin, embeddingOrigin, usbDevice) { chrome.send('removeUsbDevice', [origin, embeddingOrigin, usbDevice]); - }, + } /** @override */ - updateIncognitoStatus: function() { + updateIncognitoStatus() { chrome.send('updateIncognitoStatus'); - }, + } /** @override */ - fetchZoomLevels: function() { + fetchZoomLevels() { chrome.send('fetchZoomLevels'); - }, + } /** @override */ - removeZoomLevel: function(host) { + removeZoomLevel(host) { chrome.send('removeZoomLevel', [host]); - }, - }; + } + } + + // The singleton instance_ is replaced with a test version of this wrapper + // during testing. + cr.addSingletonGetter(SiteSettingsPrefsBrowserProxyImpl); return { SiteSettingsPrefsBrowserProxy: SiteSettingsPrefsBrowserProxy,
diff --git a/chrome/browser/resources/settings/system_page/system_page_browser_proxy.js b/chrome/browser/resources/settings/system_page/system_page_browser_proxy.js index b9ac51b3..3b4d509 100644 --- a/chrome/browser/resources/settings/system_page/system_page_browser_proxy.js +++ b/chrome/browser/resources/settings/system_page/system_page_browser_proxy.js
@@ -6,39 +6,34 @@ cr.define('settings', function() { /** @interface */ - function SystemPageBrowserProxy() {} - - SystemPageBrowserProxy.prototype = { + class SystemPageBrowserProxy { /** Shows the native system proxy settings. */ - showProxySettings: function() {}, + showProxySettings() {} /** * @return {boolean} Whether hardware acceleration was enabled when the user * started Chrome. */ - wasHardwareAccelerationEnabledAtStartup: function() {}, - }; + wasHardwareAccelerationEnabledAtStartup() {} + } /** - * @constructor * @implements {settings.SystemPageBrowserProxy} */ - function SystemPageBrowserProxyImpl() {} + class SystemPageBrowserProxyImpl { + /** @override */ + showProxySettings() { + chrome.send('showProxySettings'); + } + + /** @override */ + wasHardwareAccelerationEnabledAtStartup() { + return loadTimeData.getBoolean('hardwareAccelerationEnabledAtStartup'); + } + } cr.addSingletonGetter(SystemPageBrowserProxyImpl); - SystemPageBrowserProxyImpl.prototype = { - /** @override */ - showProxySettings: function() { - chrome.send('showProxySettings'); - }, - - /** @override */ - wasHardwareAccelerationEnabledAtStartup: function() { - return loadTimeData.getBoolean('hardwareAccelerationEnabledAtStartup'); - }, - }; - return { SystemPageBrowserProxy: SystemPageBrowserProxy, SystemPageBrowserProxyImpl: SystemPageBrowserProxyImpl,
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index f4123b4..7605395c 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -137,8 +137,9 @@ if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { - if (GURL(url_param).is_valid()) + if (GURL(url_param).is_valid()) { request_url = GURL(url_param); + } } std::string overridable_param; if (net::GetValueForKeyInQuery(web_contents->GetURL(), @@ -152,6 +153,12 @@ &strict_enforcement_param)) { strict_enforcement = strict_enforcement_param == "1"; } + std::string type_param; + if (net::GetValueForKeyInQuery(web_contents->GetURL(), "type", &type_param)) { + if (type_param == "hpkp_failure") { + cert_error = net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; + } + } net::SSLInfo ssl_info; ssl_info.cert = ssl_info.unverified_cert = CreateFakeCert(); // This delegate doesn't create an interstitial. @@ -224,8 +231,9 @@ if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { - if (GURL(url_param).is_valid()) + if (GURL(url_param).is_valid()) { request_url = GURL(url_param); + } } GURL main_frame_url(request_url); // TODO(mattm): add flag to change main_frame_url or add dedicated flag to
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc index 87e4fcd4..9147c8d 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
@@ -52,6 +52,11 @@ "Privacy error"); } +IN_PROC_BROWSER_TEST_F(InterstitialUITest, PinnedCertInterstitial) { + TestInterstitial(GURL("chrome://interstitials/ssl?type=hpkp_failure"), + "Privacy error"); +} + IN_PROC_BROWSER_TEST_F(InterstitialUITest, MalwareInterstitial) { TestInterstitial( GURL("chrome://interstitials/safebrowsing?type=malware"),
diff --git a/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc b/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc index ab599f61..de7fec70 100644 --- a/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc +++ b/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc
@@ -29,6 +29,7 @@ #include "components/offline_pages/core/offline_page_feature.h" #include "components/offline_pages/core/prefetch/generate_page_bundle_request.h" #include "components/offline_pages/core/prefetch/get_operation_request.h" +#include "components/offline_pages/core/prefetch/prefetch_downloader.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" #include "content/public/browser/web_ui.h" #include "net/base/network_change_notifier.h" @@ -348,6 +349,19 @@ weak_ptr_factory_.GetWeakPtr(), callback_id))); } +void OfflineInternalsUIMessageHandler::HandleDownloadArchive( + const base::ListValue* args) { + AllowJavascript(); + std::string name; + CHECK(args->GetString(0, &name)); + base::TrimWhitespaceASCII(name, base::TRIM_ALL, &name); + + if (prefetch_service_) { + prefetch_service_->GetPrefetchDownloader()->StartDownload( + base::GenerateGUID(), name); + } +} + void OfflineInternalsUIMessageHandler::HandlePrefetchRequestCallback( std::string callback_id, offline_pages::PrefetchRequestStatus status, @@ -510,6 +524,10 @@ "getOperation", base::Bind(&OfflineInternalsUIMessageHandler::HandleGetOperation, weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "downloadArchive", + base::Bind(&OfflineInternalsUIMessageHandler::HandleDownloadArchive, + weak_ptr_factory_.GetWeakPtr())); // Get the offline page model associated with this web ui. Profile* profile = Profile::FromWebUI(web_ui());
diff --git a/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h b/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h index 61da1724..00a595de 100644 --- a/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h +++ b/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h
@@ -82,6 +82,9 @@ // Sends and processes a request to get the info about an operation. void HandleGetOperation(const base::ListValue* args); + // Downloads an archive. + void HandleDownloadArchive(const base::ListValue* args); + // Callback for async GetAllPages calls. void HandleStoredPagesCallback( std::string callback_id, @@ -109,12 +112,6 @@ const std::string& operation_name, const std::vector<offline_pages::RenderPageInfo>& pages); - // Callback for GetOperation calls. - void HandleGetOperationCallback( - std::string callback_id, - offline_pages::PrefetchRequestStatus status, - const std::vector<offline_pages::RenderPageInfo>& pages); - // Offline page model to call methods on. offline_pages::OfflinePageModel* offline_page_model_;
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 928d1b9..c6fe9e83 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -754,11 +754,9 @@ {"powerIdleDisplayOff", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF}, {"powerIdleDisplayOn", IDS_SETTINGS_POWER_IDLE_DISPLAY_ON}, {"powerIdleOther", IDS_SETTINGS_POWER_IDLE_OTHER}, - {"powerLidClosedLabel", IDS_SETTINGS_POWER_LID_CLOSED_LABEL}, - {"powerLidClosedSleep", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP}, - {"powerLidClosedStayAwake", IDS_SETTINGS_POWER_LID_CLOSED_STAY_AWAKE}, - {"powerLidClosedSignOut", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT}, - {"powerLidClosedShutDown", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN}, + {"powerLidSleepLabel", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL}, + {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL}, + {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL}, }; AddLocalizedStringsBulk(html_source, power_strings, arraysize(power_strings));
diff --git a/chrome/browser/win/chrome_select_file_dialog_factory.cc b/chrome/browser/win/chrome_select_file_dialog_factory.cc index 87338fe..a0ea71c2 100644 --- a/chrome/browser/win/chrome_select_file_dialog_factory.cc +++ b/chrome/browser/win/chrome_select_file_dialog_factory.cc
@@ -4,319 +4,113 @@ #include "chrome/browser/win/chrome_select_file_dialog_factory.h" -#include <Windows.h> -#include <commdlg.h> +#include <utility> +#include <vector> #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/metrics/field_trial.h" +#include "base/feature_list.h" +#include "base/memory/ptr_util.h" #include "base/strings/string16.h" -#include "base/synchronization/waitable_event.h" -#include "chrome/common/chrome_utility_messages.h" +#include "base/strings/string_util.h" +#include "base/win/win_util.h" +#include "chrome/common/shell_handler_win.mojom.h" #include "chrome/grit/generated_resources.h" -#include "content/public/browser/utility_process_host.h" -#include "content/public/browser/utility_process_host_client.h" -#include "ipc/ipc_message_macros.h" +#include "content/public/browser/utility_process_mojo_client.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/win/open_file_name_win.h" #include "ui/shell_dialogs/select_file_dialog_win.h" namespace { -bool ShouldIsolateShellOperations() { - return base::FieldTrialList::FindFullName("IsolateShellOperations") == - "Enabled"; -} +constexpr base::Feature kIsolateShellOperations{ + "IsolateShellOperations", base::FEATURE_DISABLED_BY_DEFAULT}; -// Receives the GetOpenFileName result from the utility process. -class GetOpenFileNameClient : public content::UtilityProcessHostClient { - public: - GetOpenFileNameClient(); +using UtilityProcessClient = + content::UtilityProcessMojoClient<chrome::mojom::ShellHandler>; - // Blocks until the GetOpenFileName result is received (including failure to - // launch or a crash of the utility process). - void WaitForCompletion(); +std::unique_ptr<UtilityProcessClient> StartUtilityProcess() { + auto utility_process_client = base::MakeUnique<UtilityProcessClient>( + l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_FILE_DIALOG_NAME)); - // Returns the selected directory. - const base::FilePath& directory() const { return directory_; } + // TODO(crbug.com/618459): should we change the mojo utility client + // to allow an empty error callback? Currently, the client DCHECKs + // if no error callback is set when Start() is called. + utility_process_client->set_error_callback(base::Bind(&base::DoNothing)); - // Returns the list of selected filenames. Each should be interpreted as a - // child of directory(). - const std::vector<base::FilePath>& filenames() const { return filenames_; } + utility_process_client->set_disable_sandbox(); - // UtilityProcessHostClient implementation - void OnProcessCrashed(int exit_code) override; - void OnProcessLaunchFailed(int error_code) override; - bool OnMessageReceived(const IPC::Message& message) override; + utility_process_client->Start(); - protected: - ~GetOpenFileNameClient() override; - - private: - void OnResult(const base::FilePath& directory, - const std::vector<base::FilePath>& filenames); - void OnFailure(); - - base::FilePath directory_; - std::vector<base::FilePath> filenames_; - base::WaitableEvent event_; - - DISALLOW_COPY_AND_ASSIGN(GetOpenFileNameClient); -}; - -GetOpenFileNameClient::GetOpenFileNameClient() - : event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED) {} - -void GetOpenFileNameClient::WaitForCompletion() { - event_.Wait(); -} - -void GetOpenFileNameClient::OnProcessCrashed(int exit_code) { - event_.Signal(); -} - -void GetOpenFileNameClient::OnProcessLaunchFailed(int error_code) { - event_.Signal(); -} - -bool GetOpenFileNameClient::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GetOpenFileNameClient, message) - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetOpenFileName_Failed, - OnFailure) - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetOpenFileName_Result, - OnResult) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -GetOpenFileNameClient::~GetOpenFileNameClient() {} - -void GetOpenFileNameClient::OnResult( - const base::FilePath& directory, - const std::vector<base::FilePath>& filenames) { - directory_ = directory; - filenames_ = filenames; - event_.Signal(); -} - -void GetOpenFileNameClient::OnFailure() { - event_.Signal(); -} - -// Initiates IPC with a new utility process using |client|. Instructs the -// utility process to call GetOpenFileName with |ofn|. |current_task_runner| -// must be the currently executing task runner. -void DoInvokeGetOpenFileName( - OPENFILENAME* ofn, - scoped_refptr<GetOpenFileNameClient> client, - const scoped_refptr<base::SequencedTaskRunner>& current_task_runner) { - DCHECK(current_task_runner->RunsTasksInCurrentSequence()); - - base::WeakPtr<content::UtilityProcessHost> utility_process_host( - content::UtilityProcessHost::Create(client, current_task_runner) - ->AsWeakPtr()); - utility_process_host->SetName(l10n_util::GetStringUTF16( - IDS_UTILITY_PROCESS_FILE_DIALOG_NAME)); - utility_process_host->DisableSandbox(); - utility_process_host->Send(new ChromeUtilityMsg_GetOpenFileName( - ofn->hwndOwner, - ofn->Flags & ~OFN_ENABLEHOOK, // We can't send a hook function over IPC. - ui::win::OpenFileName::GetFilters(ofn), - base::FilePath(ofn->lpstrInitialDir ? ofn->lpstrInitialDir - : base::string16()), - base::FilePath(ofn->lpstrFile))); -} - -// Invokes GetOpenFileName in a utility process. Blocks until the result is -// received. Uses |blocking_task_runner| for IPC. -bool GetOpenFileNameInUtilityProcess( - const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, - OPENFILENAME* ofn) { - scoped_refptr<GetOpenFileNameClient> client(new GetOpenFileNameClient); - blocking_task_runner->PostTask( - FROM_HERE, - base::Bind(&DoInvokeGetOpenFileName, - base::Unretained(ofn), client, blocking_task_runner)); - client->WaitForCompletion(); - - if (client->filenames().empty()) - return false; - - ui::win::OpenFileName::SetResult( - client->directory(), client->filenames(), ofn); - return true; -} - -// Implements GetOpenFileName for CreateWinSelectFileDialog by delegating to a -// utility process. -bool GetOpenFileNameImpl( - const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, - OPENFILENAME* ofn) { - if (ShouldIsolateShellOperations()) - return GetOpenFileNameInUtilityProcess(blocking_task_runner, ofn); - - return ::GetOpenFileName(ofn) == TRUE; -} - -class GetSaveFileNameClient : public content::UtilityProcessHostClient { - public: - GetSaveFileNameClient(); - - // Blocks until the GetSaveFileName result is received (including failure to - // launch or a crash of the utility process). - void WaitForCompletion(); - - // Returns the selected path. - const base::FilePath& path() const { return path_; } - - // Returns the index of the user-selected filter. - int one_based_filter_index() const { return one_based_filter_index_; } - - // UtilityProcessHostClient implementation - void OnProcessCrashed(int exit_code) override; - void OnProcessLaunchFailed(int error_code) override; - bool OnMessageReceived(const IPC::Message& message) override; - - protected: - ~GetSaveFileNameClient() override; - - private: - void OnResult(const base::FilePath& path, int one_based_filter_index); - void OnFailure(); - - base::FilePath path_; - int one_based_filter_index_; - base::WaitableEvent event_; - - DISALLOW_COPY_AND_ASSIGN(GetSaveFileNameClient); -}; - -GetSaveFileNameClient::GetSaveFileNameClient() - : one_based_filter_index_(0), - event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED) {} - -void GetSaveFileNameClient::WaitForCompletion() { - event_.Wait(); -} - -void GetSaveFileNameClient::OnProcessCrashed(int exit_code) { - event_.Signal(); -} - -void GetSaveFileNameClient::OnProcessLaunchFailed(int error_code) { - event_.Signal(); -} - -bool GetSaveFileNameClient::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GetSaveFileNameClient, message) - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetSaveFileName_Failed, - OnFailure) - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetSaveFileName_Result, - OnResult) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -GetSaveFileNameClient::~GetSaveFileNameClient() {} - -void GetSaveFileNameClient::OnResult(const base::FilePath& path, - int one_based_filter_index) { - path_ = path; - one_based_filter_index_ = one_based_filter_index; - event_.Signal(); -} - -void GetSaveFileNameClient::OnFailure() { - event_.Signal(); -} - -// Initiates IPC with a new utility process using |client|. Instructs the -// utility process to call GetSaveFileName with |ofn|. |current_task_runner| -// must be the currently executing task runner. -void DoInvokeGetSaveFileName( - OPENFILENAME* ofn, - scoped_refptr<GetSaveFileNameClient> client, - const scoped_refptr<base::SequencedTaskRunner>& current_task_runner) { - DCHECK(current_task_runner->RunsTasksInCurrentSequence()); - - base::WeakPtr<content::UtilityProcessHost> utility_process_host( - content::UtilityProcessHost::Create(client, current_task_runner) - ->AsWeakPtr()); - utility_process_host->SetName(l10n_util::GetStringUTF16( - IDS_UTILITY_PROCESS_FILE_DIALOG_NAME)); - utility_process_host->DisableSandbox(); - ChromeUtilityMsg_GetSaveFileName_Params params; - params.owner = ofn->hwndOwner; - // We can't pass the hook function over IPC. - params.flags = ofn->Flags & ~OFN_ENABLEHOOK; - params.filters = ui::win::OpenFileName::GetFilters(ofn); - params.one_based_filter_index = ofn->nFilterIndex; - params.suggested_filename = base::FilePath(ofn->lpstrFile); - params.initial_directory = base::FilePath( - ofn->lpstrInitialDir ? ofn->lpstrInitialDir : base::string16()); - params.default_extension = - ofn->lpstrDefExt ? base::string16(ofn->lpstrDefExt) : base::string16(); - - utility_process_host->Send(new ChromeUtilityMsg_GetSaveFileName(params)); -} - -// Invokes GetSaveFileName in a utility process. Blocks until the result is -// received. Uses |blocking_task_runner| for IPC. -bool GetSaveFileNameInUtilityProcess( - const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, - OPENFILENAME* ofn) { - scoped_refptr<GetSaveFileNameClient> client(new GetSaveFileNameClient); - blocking_task_runner->PostTask( - FROM_HERE, - base::Bind(&DoInvokeGetSaveFileName, - base::Unretained(ofn), client, blocking_task_runner)); - client->WaitForCompletion(); - - if (client->path().empty()) - return false; - - base::wcslcpy(ofn->lpstrFile, client->path().value().c_str(), ofn->nMaxFile); - ofn->nFilterIndex = client->one_based_filter_index(); - - return true; -} - -// Implements GetSaveFileName for CreateWinSelectFileDialog by delegating to a -// utility process. -bool GetSaveFileNameImpl( - const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, - OPENFILENAME* ofn) { - if (ShouldIsolateShellOperations()) - return GetSaveFileNameInUtilityProcess(blocking_task_runner, ofn); - - return ::GetSaveFileName(ofn) == TRUE; + return utility_process_client; } } // namespace -ChromeSelectFileDialogFactory::ChromeSelectFileDialogFactory( - const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) - : blocking_task_runner_(blocking_task_runner) { -} +ChromeSelectFileDialogFactory::ChromeSelectFileDialogFactory() = default; -ChromeSelectFileDialogFactory::~ChromeSelectFileDialogFactory() {} +ChromeSelectFileDialogFactory::~ChromeSelectFileDialogFactory() = default; ui::SelectFileDialog* ChromeSelectFileDialogFactory::Create( ui::SelectFileDialog::Listener* listener, ui::SelectFilePolicy* policy) { return ui::CreateWinSelectFileDialog( - listener, - policy, - base::Bind(GetOpenFileNameImpl, blocking_task_runner_), - base::Bind(GetSaveFileNameImpl, blocking_task_runner_)); + listener, policy, + base::Bind(&ChromeSelectFileDialogFactory::BlockingGetOpenFileName), + base::Bind(&ChromeSelectFileDialogFactory::BlockingGetSaveFileName)); +} + +// static +bool ChromeSelectFileDialogFactory::BlockingGetOpenFileName(OPENFILENAME* ofn) { + if (!base::FeatureList::IsEnabled(kIsolateShellOperations)) + return ::GetOpenFileName(ofn) == TRUE; + + auto utility_process_client = StartUtilityProcess(); + + mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; + std::vector<base::FilePath> files; + base::FilePath directory; + + utility_process_client->service()->CallGetOpenFileName( + base::win::HandleToUint32(ofn->hwndOwner), + static_cast<uint32_t>(ofn->Flags & ~OFN_ENABLEHOOK), + ui::win::OpenFileName::GetFilters(ofn), + ofn->lpstrInitialDir ? base::FilePath(ofn->lpstrInitialDir) + : base::FilePath(), + base::FilePath(ofn->lpstrFile), &directory, &files); + + if (files.empty()) + return false; + + ui::win::OpenFileName::SetResult(directory, files, ofn); + return true; +} + +// static +bool ChromeSelectFileDialogFactory::BlockingGetSaveFileName(OPENFILENAME* ofn) { + if (!base::FeatureList::IsEnabled(kIsolateShellOperations)) + return ::GetSaveFileName(ofn) == TRUE; + + auto utility_process_client = StartUtilityProcess(); + + mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; + uint32_t filter_index = 0; + base::FilePath path; + + utility_process_client->service()->CallGetSaveFileName( + base::win::HandleToUint32(ofn->hwndOwner), + static_cast<uint32_t>(ofn->Flags & ~OFN_ENABLEHOOK), + ui::win::OpenFileName::GetFilters(ofn), ofn->nFilterIndex, + ofn->lpstrInitialDir ? base::FilePath(ofn->lpstrInitialDir) + : base::FilePath(), + base::FilePath(ofn->lpstrFile), + ofn->lpstrDefExt ? base::string16(ofn->lpstrDefExt) : base::string16(), + &path, &filter_index); + + if (path.empty()) + return false; + + base::wcslcpy(ofn->lpstrFile, path.value().c_str(), ofn->nMaxFile); + ofn->nFilterIndex = static_cast<DWORD>(filter_index); + return true; }
diff --git a/chrome/browser/win/chrome_select_file_dialog_factory.h b/chrome/browser/win/chrome_select_file_dialog_factory.h index b1d8745f..6c0f1c0 100644 --- a/chrome/browser/win/chrome_select_file_dialog_factory.h +++ b/chrome/browser/win/chrome_select_file_dialog_factory.h
@@ -5,32 +5,27 @@ #ifndef CHROME_BROWSER_WIN_CHROME_SELECT_FILE_DIALOG_FACTORY_H_ #define CHROME_BROWSER_WIN_CHROME_SELECT_FILE_DIALOG_FACTORY_H_ -#include "base/compiler_specific.h" +#include <Windows.h> +#include <commdlg.h> + #include "base/macros.h" -#include "base/memory/ref_counted.h" #include "ui/shell_dialogs/select_file_dialog_factory.h" -namespace base { -class SequencedTaskRunner; -} // namespace base - -// Implements a Select File dialog that delegates to a Metro file picker on -// Metro and to a utility process otherwise. The utility process is used in -// order to isolate the Chrome browser process from potential instability -// caused by Shell extension modules loaded by GetOpenFileName. +// Implements a file Open / Save dialog in a utility process. The utility +// process is used to isolate the Chrome browser process from potential +// instability caused by Shell extension modules loaded by ::GetOpenFileName +// and ::GetSaveFileName. class ChromeSelectFileDialogFactory : public ui::SelectFileDialogFactory { public: - // Uses |blocking_task_runner| to perform IPC with the utility process. - explicit ChromeSelectFileDialogFactory( - const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner); + ChromeSelectFileDialogFactory(); ~ChromeSelectFileDialogFactory() override; - // ui::SelectFileDialogFactory implementation + // ui::SelectFileDialogFactory: ui::SelectFileDialog* Create(ui::SelectFileDialog::Listener* listener, ui::SelectFilePolicy* policy) override; - private: - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; + static bool BlockingGetOpenFileName(OPENFILENAME* ofn); + static bool BlockingGetSaveFileName(OPENFILENAME* ofn); DISALLOW_COPY_AND_ASSIGN(ChromeSelectFileDialogFactory); };
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 5a5cd912..be73029 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -659,7 +659,6 @@ mojom("mojo_bindings") { sources = [ "cache_stats_recorder.mojom", - "conflicts/module_event_sink_win.mojom", "file_patcher.mojom", "image_context_menu_renderer.mojom", "insecure_content_renderer.mojom", @@ -669,10 +668,16 @@ "prerender.mojom", "renderer_configuration.mojom", "resource_usage_reporter.mojom", - "shell_handler_win.mojom", "thumbnail_capturer.mojom", ] + if (is_win) { + sources += [ + "conflicts/module_event_sink_win.mojom", + "shell_handler_win.mojom", + ] + } + if (is_chromeos) { sources += [ "zip_file_creator.mojom" ] }
diff --git a/chrome/common/chrome_utility_messages.h b/chrome/common/chrome_utility_messages.h index 045a338..a60c443 100644 --- a/chrome/common/chrome_utility_messages.h +++ b/chrome/common/chrome_utility_messages.h
@@ -4,17 +4,9 @@ // Multiply-included message file, so no include guard. -#if defined(OS_WIN) -#include <Windows.h> -#endif // defined(OS_WIN) +// TODO(noel): rename this file to a param traits variant for the full safe +// browsing feature, and remove all remaining #include of this file. -#include <string> -#include <tuple> -#include <vector> - -#include "base/files/file_path.h" -#include "base/strings/string16.h" -#include "base/values.h" #include "build/build_config.h" #include "ipc/ipc_message_macros.h" @@ -24,21 +16,6 @@ #include "chrome/common/safe_browsing/protobuf_message_param_traits.h" #endif -// Singly-included section for typedefs. -#ifndef CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_ -#define CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_ - -#if defined(OS_WIN) -// A vector of filters, each being a tuple containing a display string (i.e. -// "Text Files") and a filter pattern (i.e. "*.txt"). -typedef std::vector<std::tuple<base::string16, base::string16>> - GetOpenFileNameFilter; -#endif // OS_WIN - -#endif // CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_ - -#define IPC_MESSAGE_START ChromeUtilityMsgStart - #if defined(FULL_SAFE_BROWSING) IPC_ENUM_TRAITS_VALIDATE( safe_browsing::ClientDownloadRequest_DownloadType, @@ -120,53 +97,3 @@ IPC_STRUCT_TRAITS_MEMBER(archived_archive_filenames) IPC_STRUCT_TRAITS_END() #endif // FULL_SAFE_BROWSING - -#if defined(OS_WIN) -IPC_STRUCT_BEGIN(ChromeUtilityMsg_GetSaveFileName_Params) - IPC_STRUCT_MEMBER(HWND, owner) - IPC_STRUCT_MEMBER(DWORD, flags) - IPC_STRUCT_MEMBER(GetOpenFileNameFilter, filters) - IPC_STRUCT_MEMBER(int, one_based_filter_index) - IPC_STRUCT_MEMBER(base::FilePath, suggested_filename) - IPC_STRUCT_MEMBER(base::FilePath, initial_directory) - IPC_STRUCT_MEMBER(base::string16, default_extension) -IPC_STRUCT_END() -#endif // OS_WIN - -//------------------------------------------------------------------------------ -// Utility process messages: -// These are messages from the browser to the utility process. - -#if defined(OS_WIN) -// Instructs the utility process to invoke GetOpenFileName. |owner| is the -// parent of the modal dialog, |flags| are OFN_* flags. |filter| constrains the -// user's file choices. |initial_directory| and |filename| select the directory -// to be displayed and the file to be initially selected. -// -// Either ChromeUtilityHostMsg_GetOpenFileName_Failed or -// ChromeUtilityHostMsg_GetOpenFileName_Result will be returned when the -// operation completes whether due to error or user action. -IPC_MESSAGE_CONTROL5(ChromeUtilityMsg_GetOpenFileName, - HWND /* owner */, - DWORD /* flags */, - GetOpenFileNameFilter /* filter */, - base::FilePath /* initial_directory */, - base::FilePath /* filename */) -IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_GetSaveFileName, - ChromeUtilityMsg_GetSaveFileName_Params /* params */) -#endif // defined(OS_WIN) - -//------------------------------------------------------------------------------ -// Utility process host messages: -// These are messages from the utility process to the browser. - -#if defined(OS_WIN) -IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetOpenFileName_Failed) -IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetOpenFileName_Result, - base::FilePath /* directory */, - std::vector<base::FilePath> /* filenames */) -IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetSaveFileName_Failed) -IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetSaveFileName_Result, - base::FilePath /* path */, - int /* one_based_filter_index */) -#endif // defined(OS_WIN)
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index efd6292..fc7203d 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -57,6 +57,12 @@ // A preference that indicates that user accepted Assistant Value Prop. const char kArcVoiceInteractionValuePropAccepted[] = "arc.voice_interaction_value_prop.accepted"; +// A preference that indicates the user has enabled voice interaction services. +const char kVoiceInteractionEnabled[] = "settings.voice_interaction.enabled"; +// A preference that indicates the user has enabled providing context to +// voice interaction services. +const char kVoiceInteractionContextEnabled[] = + "settings.voice_interaction.context.enabled"; #endif // A bool pref that keeps whether the child status for this profile was already
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 184079a..a788216a 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -34,6 +34,8 @@ extern const char kArcSignedIn[]; extern const char kArcCompatibleFilesystemChosen[]; extern const char kArcVoiceInteractionValuePropAccepted[]; +extern const char kVoiceInteractionEnabled[]; +extern const char kVoiceInteractionContextEnabled[]; #endif extern const char kChildAccountStatusKnown[]; extern const char kDefaultApps[];
diff --git a/chrome/common/profiling/BUILD.gn b/chrome/common/profiling/BUILD.gn index 16464eea..b455adbb 100644 --- a/chrome/common/profiling/BUILD.gn +++ b/chrome/common/profiling/BUILD.gn
@@ -12,6 +12,8 @@ "memlog_sender.cc", "memlog_sender.h", "memlog_sender_pipe.h", + "memlog_sender_pipe_posix.cc", + "memlog_sender_pipe_posix.h", "memlog_sender_pipe_win.cc", "memlog_sender_pipe_win.h", "memlog_stream.cc",
diff --git a/chrome/common/profiling/memlog_allocator_shim.cc b/chrome/common/profiling/memlog_allocator_shim.cc index 9ff84cf..346837f5 100644 --- a/chrome/common/profiling/memlog_allocator_shim.cc +++ b/chrome/common/profiling/memlog_allocator_shim.cc
@@ -5,10 +5,12 @@ #include "chrome/common/profiling/memlog_allocator_shim.h" #include "base/allocator/allocator_shim.h" +#include "base/allocator/features.h" #include "base/debug/debugging_flags.h" #include "base/debug/stack_trace.h" #include "base/synchronization/lock.h" #include "base/trace_event/heap_profiler_allocation_register.h" +#include "build/build_config.h" #include "chrome/common/profiling/memlog_stream.h" namespace profiling { @@ -71,6 +73,7 @@ g_send_buffers[bin_to_use].Send(data, size); } +#if BUILDFLAG(USE_ALLOCATOR_SHIM) void* HookAlloc(const AllocatorDispatch* self, size_t size, void* context) { const AllocatorDispatch* const next = self->next; void* ptr = next->alloc_function(next, size, context); @@ -167,6 +170,7 @@ &HookFreeDefiniteSize, // free_definite_size_function nullptr, // next }; +#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) } // namespace @@ -174,7 +178,7 @@ g_send_buffers = new SendBuffer[kNumSendBuffers]; g_sender_pipe = sender_pipe; -#ifdef NDEBUG +#if BUILDFLAG(USE_ALLOCATOR_SHIM) base::allocator::InsertAllocatorDispatch(&g_memlog_hooks); #endif }
diff --git a/chrome/common/profiling/memlog_sender_pipe.h b/chrome/common/profiling/memlog_sender_pipe.h index ba2653e..5123ff0 100644 --- a/chrome/common/profiling/memlog_sender_pipe.h +++ b/chrome/common/profiling/memlog_sender_pipe.h
@@ -9,6 +9,8 @@ #if defined(OS_WIN) #include "chrome/common/profiling/memlog_sender_pipe_win.h" +#else +#include "chrome/common/profiling/memlog_sender_pipe_posix.h" #endif #endif // CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_H_
diff --git a/chrome/common/profiling/memlog_sender_pipe_posix.cc b/chrome/common/profiling/memlog_sender_pipe_posix.cc new file mode 100644 index 0000000..23cd27761 --- /dev/null +++ b/chrome/common/profiling/memlog_sender_pipe_posix.cc
@@ -0,0 +1,31 @@ +// Copyright 2017 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/common/profiling/memlog_sender_pipe_posix.h" + +#include <unistd.h> + +#include "base/logging.h" +#include "base/posix/eintr_wrapper.h" +#include "chrome/common/profiling/memlog_stream.h" + +namespace profiling { + +MemlogSenderPipe::MemlogSenderPipe(const std::string& pipe_id) + : pipe_id_(pipe_id), fd_(-1) {} + +MemlogSenderPipe::~MemlogSenderPipe() { + if (fd_ != -1) + IGNORE_EINTR(::close(fd_)); +} + +bool MemlogSenderPipe::Connect() { + return false; +} + +bool MemlogSenderPipe::Send(const void* data, size_t sz) { + return false; +} + +} // namespace profiling
diff --git a/chrome/common/profiling/memlog_sender_pipe_posix.h b/chrome/common/profiling/memlog_sender_pipe_posix.h new file mode 100644 index 0000000..41aef2f --- /dev/null +++ b/chrome/common/profiling/memlog_sender_pipe_posix.h
@@ -0,0 +1,33 @@ +// Copyright 2017 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_COMMON_PROFILING_MEMLOG_SENDER_PIPE_POSIX_H_ +#define CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_POSIX_H_ + +#include <string> + +#include "base/macros.h" + +namespace profiling { + +class MemlogSenderPipe { + public: + explicit MemlogSenderPipe(const std::string& pipe_id); + ~MemlogSenderPipe(); + + bool Connect(); + + bool Send(const void* data, size_t sz); + + private: + std::string pipe_id_; + + int fd_; + + DISALLOW_COPY_AND_ASSIGN(MemlogSenderPipe); +}; + +} // namespace profiling + +#endif // CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_POSIX_H_
diff --git a/chrome/common/shell_handler_win.mojom b/chrome/common/shell_handler_win.mojom index 0739aad99..099e084 100644 --- a/chrome/common/shell_handler_win.mojom +++ b/chrome/common/shell_handler_win.mojom
@@ -2,9 +2,59 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Utility process interface exposed to the browser process on OS_WIN, for +// calling OS_WIN task pinning and file open/save dialog API. + module chrome.mojom; +import "mojo/common/file_path.mojom"; +import "mojo/common/string16.mojom"; + interface ShellHandler { // Returns the pinned state of the current executable. IsPinnedToTaskbar() => (bool succeeded, bool is_pinned_to_taskbar); + + // Calls OS_WIN ::GetOpenFileName() with parameters: + // |owner| HWND to use as the parent of the modal dialog. + // |flags| OFN_* flags to use with OPENFILENAME. + // |filters| constrains the user's file type selections. + // |initial_directory| initial directory to be displayed. + // |initial_filename| file name initially selected. + // + // Returns the list of selected |files| from |directory|. On cancelation + // or failure, |files| will be empty. + [Sync] + CallGetOpenFileName(uint32 owner, + uint32 flags, + FileExtensionFilters filters, + mojo.common.mojom.FilePath initial_directory, + mojo.common.mojom.FilePath initial_filename) => + (mojo.common.mojom.FilePath directory, + array<mojo.common.mojom.FilePath> files); + + // Calls OS_WIN ::GetSaveFileName() with parameters: + // |owner| HWND to use as the parent of the modal dialog. + // |flags| OFN_* flags to use with OPENFILENAME. + // |filters| constrains the user's file type selections. + // |one_based_filter_index| index of the selected filter in |filters|. + // |initial_directory| initial directory to be displayed. + // |suggested_filename| save file name to suggest. + // |default_extension| file extension to use if the user doesn't type one. + // + // Returns the save file |path| selected, and the |filter_index| of the + // filter selected, by the user. On cancelation or failure, |path| will + // be empty. + [Sync] + CallGetSaveFileName(uint32 owner, + uint32 flags, + FileExtensionFilters filters, + uint32 one_based_filter_index, + mojo.common.mojom.FilePath initial_directory, + mojo.common.mojom.FilePath suggested_filename, + mojo.common.mojom.String16 default_extension) => + (mojo.common.mojom.FilePath path, + uint32 filter_index); }; + +[Native] +struct FileExtensionFilters;
diff --git a/chrome/common/shell_handler_win.typemap b/chrome/common/shell_handler_win.typemap new file mode 100644 index 0000000..0a596ac --- /dev/null +++ b/chrome/common/shell_handler_win.typemap
@@ -0,0 +1,14 @@ +# Copyright 2017 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. + +mojom = "//chrome/common/shell_handler_win.mojom" + +public_headers = [ "//base/strings/string16.h" ] + +deps = [ + "//base", +] + +type_mappings = [ "chrome.mojom.FileExtensionFilters=" + + "std::vector<std::tuple<base::string16, base::string16>>" ]
diff --git a/chrome/profiling/BUILD.gn b/chrome/profiling/BUILD.gn index 1adceab..5cd6cc4 100644 --- a/chrome/profiling/BUILD.gn +++ b/chrome/profiling/BUILD.gn
@@ -17,7 +17,11 @@ "memlog_connection_manager.cc", "memlog_connection_manager.h", "memlog_receiver.h", + "memlog_receiver_pipe_posix.cc", + "memlog_receiver_pipe_posix.h", "memlog_receiver_pipe_server.h", + "memlog_receiver_pipe_server_posix.cc", + "memlog_receiver_pipe_server_posix.h", "memlog_receiver_pipe_server_win.cc", "memlog_receiver_pipe_server_win.h", "memlog_receiver_pipe_win.cc",
diff --git a/chrome/profiling/README.md b/chrome/profiling/README.md index 4501ecf3..39beecd 100644 --- a/chrome/profiling/README.md +++ b/chrome/profiling/README.md
@@ -9,3 +9,5 @@ is enabled by setting the GN flag `enable_oop_heap_profiling`. The in-process code that communicates with the profiling process is in `//chrome/common/profiling`. + +The browser must be started with `--memlog`.
diff --git a/chrome/profiling/allocation_tracker.cc b/chrome/profiling/allocation_tracker.cc index 89c3b4b0..69fab82d 100644 --- a/chrome/profiling/allocation_tracker.cc +++ b/chrome/profiling/allocation_tracker.cc
@@ -13,6 +13,10 @@ AllocationTracker::Alloc::Alloc(size_t sz, BacktraceStorage::Key key) : size(sz), backtrace_key(key) {} +AllocationTracker::Alloc::~Alloc() {} +AllocationTracker::Alloc::Alloc(const Alloc& other) + : size(other.size), backtrace_key(other.backtrace_key) {} + AllocationTracker::AllocationTracker(CompleteCallback complete_cb) : complete_callback_(std::move(complete_cb)), backtrace_storage_(ProfilingGlobals::Get()->GetBacktraceStorage()) {}
diff --git a/chrome/profiling/allocation_tracker.h b/chrome/profiling/allocation_tracker.h index 5aa8ea4..3ee5f64 100644 --- a/chrome/profiling/allocation_tracker.h +++ b/chrome/profiling/allocation_tracker.h
@@ -34,6 +34,8 @@ struct Alloc { Alloc(size_t sz, BacktraceStorage::Key key); + Alloc(const Alloc& other); + ~Alloc(); size_t size; BacktraceStorage::Key backtrace_key;
diff --git a/chrome/profiling/memlog_receiver_pipe_posix.cc b/chrome/profiling/memlog_receiver_pipe_posix.cc new file mode 100644 index 0000000..dbce9ca --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_posix.cc
@@ -0,0 +1,57 @@ +// Copyright 2017 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/profiling/memlog_receiver_pipe_posix.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/posix/eintr_wrapper.h" +#include "base/strings/utf_string_conversions.h" +#include "base/threading/thread.h" +#include "chrome/profiling/memlog_stream_receiver.h" + +namespace profiling { + +MemlogReceiverPipe::CompletionThunk::CompletionThunk(int fd, Callback cb) + : controller_(FROM_HERE), fd_(fd), callback_(cb) { + base::MessageLoopForIO::current()->WatchFileDescriptor( + fd_, true, base::MessageLoopForIO::WATCH_READ, &controller_, this); +} + +MemlogReceiverPipe::CompletionThunk::~CompletionThunk() { + if (fd_ != -1) + IGNORE_EINTR(::close(fd_)); +} + +void MemlogReceiverPipe::CompletionThunk::OnFileCanReadWithoutBlocking(int fd) { + callback_.Run(fd); +} + +void MemlogReceiverPipe::CompletionThunk::OnFileCanWriteWithoutBlocking( + int fd) { + NOTREACHED(); +} + +MemlogReceiverPipe::MemlogReceiverPipe(std::unique_ptr<CompletionThunk> thunk) { +} + +MemlogReceiverPipe::~MemlogReceiverPipe() {} + +void MemlogReceiverPipe::StartReadingOnIOThread() { + // TODO(ajwong): Implement with something useful. +} + +int MemlogReceiverPipe::GetRemoteProcessID() { + // TODO(ajwong): Implement with something useful. + return 0; +} + +void MemlogReceiverPipe::SetReceiver( + scoped_refptr<base::TaskRunner> task_runner, + scoped_refptr<MemlogStreamReceiver> receiver) { + receiver_task_runner_ = task_runner; + receiver_ = receiver; +} + +} // namespace profiling
diff --git a/chrome/profiling/memlog_receiver_pipe_posix.h b/chrome/profiling/memlog_receiver_pipe_posix.h new file mode 100644 index 0000000..a5abb43 --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_posix.h
@@ -0,0 +1,67 @@ +// Copyright 2017 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_PROFILING_MEMLOG_RECEIVER_PIPE_POSIX_H_ +#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_POSIX_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop.h" +#include "build/build_config.h" + +namespace base { +class TaskRunner; +} // namespace base + +namespace profiling { + +class MemlogStreamReceiver; + +class MemlogReceiverPipe + : public base::RefCountedThreadSafe<MemlogReceiverPipe> { + public: + class CompletionThunk : public base::MessageLoopForIO::Watcher { + public: + using Callback = base::RepeatingCallback<void(int)>; + + CompletionThunk(int fd, Callback cb); + ~CompletionThunk() override; + + void set_callback(Callback cb) { callback_ = cb; } + + void OnFileCanReadWithoutBlocking(int fd) override; + void OnFileCanWriteWithoutBlocking(int fd) override; + + private: + base::MessageLoopForIO::FileDescriptorWatcher controller_; + + int fd_; + Callback callback_; + }; + + explicit MemlogReceiverPipe(std::unique_ptr<CompletionThunk> thunk); + + void StartReadingOnIOThread(); + + int GetRemoteProcessID(); + void SetReceiver(scoped_refptr<base::TaskRunner> task_runner, + scoped_refptr<MemlogStreamReceiver> receiver); + + private: + friend class base::RefCountedThreadSafe<MemlogReceiverPipe>; + ~MemlogReceiverPipe(); + + std::unique_ptr<CompletionThunk> thunk_; + + scoped_refptr<base::TaskRunner> receiver_task_runner_; + scoped_refptr<MemlogStreamReceiver> receiver_; + + DISALLOW_COPY_AND_ASSIGN(MemlogReceiverPipe); +}; + +} // namespace profiling + +#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_POSIX_H_
diff --git a/chrome/profiling/memlog_receiver_pipe_server.h b/chrome/profiling/memlog_receiver_pipe_server.h index 5ef925ac3..8650479 100644 --- a/chrome/profiling/memlog_receiver_pipe_server.h +++ b/chrome/profiling/memlog_receiver_pipe_server.h
@@ -9,6 +9,8 @@ #if defined(OS_WIN) #include "memlog_receiver_pipe_server_win.h" +#else +#include "memlog_receiver_pipe_server_posix.h" #endif #endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_H_
diff --git a/chrome/profiling/memlog_receiver_pipe_server_posix.cc b/chrome/profiling/memlog_receiver_pipe_server_posix.cc new file mode 100644 index 0000000..86540d1 --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_server_posix.cc
@@ -0,0 +1,27 @@ +// Copyright 2017 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/profiling/memlog_receiver_pipe_server_posix.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/common/profiling/memlog_stream.h" + +namespace profiling { + +MemlogReceiverPipeServer::MemlogReceiverPipeServer( + base::TaskRunner* io_runner, + const std::string& pipe_id, + NewConnectionCallback on_new_conn) + : io_runner_(io_runner), + pipe_id_(pipe_id), + on_new_connection_(on_new_conn) {} + +MemlogReceiverPipeServer::~MemlogReceiverPipeServer() {} + +void MemlogReceiverPipeServer::Start() {} + +} // namespace profiling
diff --git a/chrome/profiling/memlog_receiver_pipe_server_posix.h b/chrome/profiling/memlog_receiver_pipe_server_posix.h new file mode 100644 index 0000000..8cc511a --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_server_posix.h
@@ -0,0 +1,58 @@ +// Copyright 2017 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_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_POSIX_H_ +#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_POSIX_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_pump_libevent.h" +#include "chrome/profiling/memlog_receiver_pipe_posix.h" + +namespace base { +class TaskRunner; +} // namespace base + +namespace profiling { + +class MemlogReceiverPipe; + +// This class listens for new pipe connections and creates new +// MemlogReceiverPipe objects for each one. +class MemlogReceiverPipeServer + : public base::RefCountedThreadSafe<MemlogReceiverPipeServer> { + public: + using NewConnectionCallback = + base::RepeatingCallback<void(scoped_refptr<MemlogReceiverPipe>)>; + + // |io_runner| is the task runner for the I/O thread. When a new connection is + // established, the |on_new_conn| callback is called with the pipe. + MemlogReceiverPipeServer(base::TaskRunner* io_runner, + const std::string& pipe_id, + NewConnectionCallback on_new_conn); + + void set_on_new_connection(NewConnectionCallback on_new_connection) { + on_new_connection_ = on_new_connection; + } + + // Starts the server which opens the pipe and begins accepting connections. + void Start(); + + private: + friend class base::RefCountedThreadSafe<MemlogReceiverPipeServer>; + ~MemlogReceiverPipeServer(); + + scoped_refptr<base::TaskRunner> io_runner_; + std::string pipe_id_; + NewConnectionCallback on_new_connection_; + + DISALLOW_COPY_AND_ASSIGN(MemlogReceiverPipeServer); +}; + +} // namespace profiling + +#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_POSIX_H_
diff --git a/chrome/profiling/memlog_receiver_pipe_server_win.h b/chrome/profiling/memlog_receiver_pipe_server_win.h index c6ace10..8f12a7f 100644 --- a/chrome/profiling/memlog_receiver_pipe_server_win.h +++ b/chrome/profiling/memlog_receiver_pipe_server_win.h
@@ -60,6 +60,8 @@ // Current connection we're waiting on creation for. std::unique_ptr<MemlogReceiverPipe::CompletionThunk> current_; + + DISALLOW_COPY_AND_ASSIGN(MemlogReceiverPipeServer); }; } // namespace profiling
diff --git a/chrome/profiling/memlog_stream_parser.cc b/chrome/profiling/memlog_stream_parser.cc index b67d0d7..3fbc60f 100644 --- a/chrome/profiling/memlog_stream_parser.cc +++ b/chrome/profiling/memlog_stream_parser.cc
@@ -24,6 +24,8 @@ MemlogStreamParser::Block::Block(std::unique_ptr<char[]> d, size_t s) : data(std::move(d)), size(s) {} +MemlogStreamParser::Block::~Block() {} + MemlogStreamParser::MemlogStreamParser(MemlogReceiver* receiver) : receiver_(receiver) {}
diff --git a/chrome/profiling/memlog_stream_parser.h b/chrome/profiling/memlog_stream_parser.h index e2d0e48a..1418d0b 100644 --- a/chrome/profiling/memlog_stream_parser.h +++ b/chrome/profiling/memlog_stream_parser.h
@@ -18,7 +18,6 @@ public: // Receiver must outlive this class. explicit MemlogStreamParser(MemlogReceiver* receiver); - ~MemlogStreamParser() override; // StreamReceiver implementation. void OnStreamData(std::unique_ptr<char[]> data, size_t sz) override; @@ -27,6 +26,7 @@ private: struct Block { Block(std::unique_ptr<char[]> d, size_t s); + ~Block(); std::unique_ptr<char[]> data; size_t size; @@ -38,6 +38,8 @@ READ_NO_DATA // Not enough data, try again when we get more }; + ~MemlogStreamParser() override; + // Returns true if the given number of bytes are available now. bool AreBytesAvailable(size_t count) const;
diff --git a/chrome/profiling/memlog_stream_receiver.h b/chrome/profiling/memlog_stream_receiver.h index ea8a6d6..bd21d11a 100644 --- a/chrome/profiling/memlog_stream_receiver.h +++ b/chrome/profiling/memlog_stream_receiver.h
@@ -17,7 +17,6 @@ : public base::RefCountedThreadSafe<MemlogStreamReceiver> { public: MemlogStreamReceiver() {} - virtual ~MemlogStreamReceiver() {} // Returns true on success, false on unrecoverable error (in which case no // more blocks will be sent). May take a ref to the block, so the caller @@ -25,6 +24,10 @@ virtual void OnStreamData(std::unique_ptr<char[]> data, size_t sz) = 0; virtual void OnStreamComplete() = 0; + + protected: + friend class base::RefCountedThreadSafe<MemlogStreamReceiver>; + ~MemlogStreamReceiver() override {} }; } // namespace profiling
diff --git a/chrome/profiling/profiling_browsertest.cc b/chrome/profiling/profiling_browsertest.cc new file mode 100644 index 0000000..0f1f968 --- /dev/null +++ b/chrome/profiling/profiling_browsertest.cc
@@ -0,0 +1,38 @@ +// Copyright 2017 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/command_line.h" +#include "base/process/launch.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" + +namespace profiling { + +#if !defined(OS_MACOSX) +class ProfilingBrowserTest : public InProcessBrowserTest { + protected: + void RelaunchWithMemlog() { + // TODO(ajwong): Remove this once Brett lands is process model change so the + // browser process actually launches the profiling process. Until then, it's + // okay to have this skip on Mac (which has a different launch setup such + // that this sort of relaunch doesn't work). See GetCommandLineForRelaunch() + // function for details. + // TODO(awong): Can we do this with just SetUpCommandLine() and no Relaunch? + base::CommandLine new_command_line(GetCommandLineForRelaunch()); + new_command_line.AppendSwitch(switches::kMemlog); + + ui_test_utils::BrowserAddedObserver observer; + base::LaunchProcess(new_command_line, base::LaunchOptionsForTest()); + + observer.WaitForSingleNewBrowser(); + } +}; + +IN_PROC_BROWSER_TEST_F(ProfilingBrowserTest, InterceptsNew) { + RelaunchWithMemlog(); +} +#endif + +} // namespace profiling
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9294036..0db81e04b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1568,6 +1568,7 @@ "../common/mac/mock_launchd.cc", "../common/mac/mock_launchd.h", "../common/time_format_browsertest.cc", + "../profiling/profiling_browsertest.cc", "../renderer/autofill/autofill_renderer_browsertest.cc", "../renderer/autofill/fake_content_password_manager_driver.cc", "../renderer/autofill/fake_content_password_manager_driver.h", @@ -1733,6 +1734,9 @@ if (!enable_one_click_signin) { sources -= [ "../browser/ui/sync/one_click_signin_links_delegate_impl_browsertest.cc" ] } + if (!enable_oop_heap_profiling) { + sources -= [ "../profiling/profiling_browsertest.cc" ] + } if (enable_nacl) { sources += [ "../browser/chrome_service_worker_browsertest.cc",
diff --git a/chrome/test/data/webui/settings/device_page_tests.js b/chrome/test/data/webui/settings/device_page_tests.js index 1fdbe06..c818b96 100644 --- a/chrome/test/data/webui/settings/device_page_tests.js +++ b/chrome/test/data/webui/settings/device_page_tests.js
@@ -682,7 +682,7 @@ var powerSourceWrapper; var powerSourceSelect; var idleSelect; - var lidClosedSelect; + var lidClosedToggle; suiteSetup(function() { // Always show power settings. @@ -705,7 +705,7 @@ .updatePowerStatusCalled_); idleSelect = assert(powerPage.$$('#idleSelect')); - lidClosedSelect = assert(powerPage.$$('#lidClosedSelect')); + lidClosedToggle = assert(powerPage.$$('#lidClosedToggle')); assertEquals( 1, @@ -802,17 +802,31 @@ }); test('set lid behavior', function() { - selectValue(lidClosedSelect, settings.LidClosedBehavior.DO_NOTHING); + var sendLid = function(lidBehavior) { + sendPowerManagementSettings( + settings.IdleBehavior.DISPLAY_OFF, + false /* idleControlled */, lidBehavior, + false /* lidClosedControlled */, true /* hasLid */); + }; + + sendLid(settings.LidClosedBehavior.SUSPEND); + assertTrue(lidClosedToggle.checked); + + MockInteractions.tap(lidClosedToggle.$$('#control')); expectEquals( settings.LidClosedBehavior.DO_NOTHING, settings.DevicePageBrowserProxyImpl.getInstance() .lidClosedBehavior_); + sendLid(settings.LidClosedBehavior.DO_NOTHING); + expectFalse(lidClosedToggle.checked); - selectValue(lidClosedSelect, settings.LidClosedBehavior.SUSPEND); + MockInteractions.tap(lidClosedToggle.$$('#control')); expectEquals( settings.LidClosedBehavior.SUSPEND, settings.DevicePageBrowserProxyImpl.getInstance() .lidClosedBehavior_); + sendLid(settings.LidClosedBehavior.SUSPEND); + expectTrue(lidClosedToggle.checked); }); test('display idle and lid behavior', function() { @@ -827,11 +841,10 @@ settings.IdleBehavior.DISPLAY_ON.toString(), idleSelect.value); expectFalse(idleSelect.disabled); expectEquals(null, powerPage.$$('#idleControlledIndicator')); - expectEquals( - settings.LidClosedBehavior.DO_NOTHING.toString(), - lidClosedSelect.value); - expectFalse(lidClosedSelect.disabled); - expectEquals(null, powerPage.$$('#lidClosedControlledIndicator')); + expectEquals(loadTimeData.getString('powerLidSleepLabel'), + lidClosedToggle.label); + expectFalse(lidClosedToggle.checked); + expectFalse(lidClosedToggle.isPrefEnforced()); }).then(function() { sendPowerManagementSettings( settings.IdleBehavior.DISPLAY_OFF, @@ -843,21 +856,20 @@ idleSelect.value); expectFalse(idleSelect.disabled); expectEquals(null, powerPage.$$('#idleControlledIndicator')); - expectEquals( - settings.LidClosedBehavior.SUSPEND.toString(), - lidClosedSelect.value); - expectFalse(lidClosedSelect.disabled); - expectEquals(null, powerPage.$$('#lidClosedControlledIndicator')); + expectEquals(loadTimeData.getString('powerLidSleepLabel'), + lidClosedToggle.label); + expectTrue(lidClosedToggle.checked); + expectFalse(lidClosedToggle.isPrefEnforced()); }); }); test('display controlled idle and lid behavior', function() { - // When settings are controlled, the selects should be disabled and + // When settings are controlled, the controls should be disabled and // the indicators should be shown. return new Promise(function(resolve) { sendPowerManagementSettings( settings.IdleBehavior.OTHER, true /* idleControlled */, - settings.LidClosedBehavior.SUSPEND, + settings.LidClosedBehavior.SHUT_DOWN, true /* lidClosedControlled */, true /* hasLid */); powerPage.async(resolve); }).then(function() { @@ -865,12 +877,27 @@ settings.IdleBehavior.OTHER.toString(), idleSelect.value); expectTrue(idleSelect.disabled); expectNotEquals(null, powerPage.$$('#idleControlledIndicator')); + expectEquals(loadTimeData.getString('powerLidShutDownLabel'), + lidClosedToggle.label); + expectTrue(lidClosedToggle.checked); + expectTrue(lidClosedToggle.isPrefEnforced()); + }).then(function() { + sendPowerManagementSettings( + settings.IdleBehavior.DISPLAY_OFF, + true /* idleControlled */, + settings.LidClosedBehavior.STOP_SESSION, + true /* lidClosedControlled */, true /* hasLid */); + return new Promise(function(resolve) { powerPage.async(resolve); }); + }).then(function() { expectEquals( - settings.LidClosedBehavior.SUSPEND.toString(), - lidClosedSelect.value); - expectTrue(lidClosedSelect.disabled); - expectNotEquals( - null, powerPage.$$('#lidClosedControlledIndicator')); + settings.IdleBehavior.DISPLAY_OFF.toString(), + idleSelect.value); + expectTrue(idleSelect.disabled); + expectNotEquals(null, powerPage.$$('#idleControlledIndicator')); + expectEquals(loadTimeData.getString('powerLidSignOutLabel'), + lidClosedToggle.label); + expectTrue(lidClosedToggle.checked); + expectTrue(lidClosedToggle.isPrefEnforced()); }); });
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py index 803bb6f..1be7da6 100644 --- a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py +++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
@@ -31,11 +31,11 @@ """Cast page to open a cast-enabled page and open media router dialog.""" def __init__(self, page_set, url='file://basic_test.html', - shared_page_state_class=shared_page_state.SharedPageState): + shared_page_state_class=shared_page_state.SharedPageState, + name='basic_test.html'): super(CastDialogPage, self).__init__( url=url, page_set=page_set, - shared_page_state_class=shared_page_state_class, - name='basic_test.html') + shared_page_state_class=shared_page_state_class, name=name) def RunPageInteractions(self, action_runner): # Wait for 5s after Chrome is opened in order to get consistent results.
diff --git a/chrome/typemaps.gni b/chrome/typemaps.gni index b26165c..539ad98 100644 --- a/chrome/typemaps.gni +++ b/chrome/typemaps.gni
@@ -3,6 +3,7 @@ # found in the LICENSE file. typemaps = [ - "//chrome/common/safe_archive_analyzer.typemap", "//chrome/common/instant.typemap", + "//chrome/common/safe_archive_analyzer.typemap", + "//chrome/common/shell_handler_win.typemap", ]
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index ad67a975..3c64214 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -16,8 +16,6 @@ "cloud_print/bitmap_image.h", "cloud_print/pwg_encoder.cc", "cloud_print/pwg_encoder.h", - "ipc_shell_handler_win.cc", - "ipc_shell_handler_win.h", "printing_handler.cc", "printing_handler.h", "shell_handler_impl_win.cc",
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 4f308fc7..50f5ee4 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -43,7 +43,6 @@ #endif #if defined(OS_WIN) -#include "chrome/utility/ipc_shell_handler_win.h" #include "chrome/utility/shell_handler_impl_win.h" #endif @@ -241,10 +240,6 @@ (BUILDFLAG(ENABLE_BASIC_PRINTING) && defined(OS_WIN)) handlers_.push_back(base::MakeUnique<printing::PrintingHandler>()); #endif - -#if defined(OS_WIN) - handlers_.push_back(base::MakeUnique<IPCShellHandler>()); -#endif } ChromeContentUtilityClient::~ChromeContentUtilityClient() = default;
diff --git a/chrome/utility/ipc_shell_handler_win.cc b/chrome/utility/ipc_shell_handler_win.cc deleted file mode 100644 index cfdb765b..0000000 --- a/chrome/utility/ipc_shell_handler_win.cc +++ /dev/null
@@ -1,79 +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 "chrome/utility/ipc_shell_handler_win.h" - -#include <commdlg.h> - -#include <memory> - -#include "base/files/file_path.h" -#include "chrome/common/chrome_utility_messages.h" -#include "content/public/utility/utility_thread.h" -#include "ui/base/win/open_file_name_win.h" - -IPCShellHandler::IPCShellHandler() {} -IPCShellHandler::~IPCShellHandler() {} - -bool IPCShellHandler::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(IPCShellHandler, message) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetOpenFileName, OnGetOpenFileName) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetSaveFileName, OnGetSaveFileName) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void IPCShellHandler::OnGetOpenFileName(HWND owner, - DWORD flags, - const GetOpenFileNameFilter& filter, - const base::FilePath& initial_directory, - const base::FilePath& filename) { - ui::win::OpenFileName open_file_name(owner, flags); - open_file_name.SetInitialSelection(initial_directory, filename); - open_file_name.SetFilters(filter); - - base::FilePath directory; - std::vector<base::FilePath> filenames; - - if (::GetOpenFileName(open_file_name.GetOPENFILENAME())) - open_file_name.GetResult(&directory, &filenames); - - if (filenames.size()) { - content::UtilityThread::Get()->Send( - new ChromeUtilityHostMsg_GetOpenFileName_Result(directory, filenames)); - } else { - content::UtilityThread::Get()->Send( - new ChromeUtilityHostMsg_GetOpenFileName_Failed()); - } -} - -void IPCShellHandler::OnGetSaveFileName( - const ChromeUtilityMsg_GetSaveFileName_Params& params) { - ui::win::OpenFileName open_file_name(params.owner, params.flags); - open_file_name.SetInitialSelection(params.initial_directory, - params.suggested_filename); - open_file_name.SetFilters(params.filters); - open_file_name.GetOPENFILENAME()->nFilterIndex = - params.one_based_filter_index; - open_file_name.GetOPENFILENAME()->lpstrDefExt = - params.default_extension.c_str(); - - if (::GetSaveFileName(open_file_name.GetOPENFILENAME())) { - content::UtilityThread::Get()->Send( - new ChromeUtilityHostMsg_GetSaveFileName_Result( - base::FilePath(open_file_name.GetOPENFILENAME()->lpstrFile), - open_file_name.GetOPENFILENAME()->nFilterIndex)); - return; - } - - // Zero means the dialog was closed, otherwise we had an error. - DWORD error_code = ::CommDlgExtendedError(); - if (error_code != 0) - NOTREACHED() << "GetSaveFileName failed with code: " << error_code; - - content::UtilityThread::Get()->Send( - new ChromeUtilityHostMsg_GetSaveFileName_Failed()); -}
diff --git a/chrome/utility/ipc_shell_handler_win.h b/chrome/utility/ipc_shell_handler_win.h deleted file mode 100644 index 5c71df7..0000000 --- a/chrome/utility/ipc_shell_handler_win.h +++ /dev/null
@@ -1,53 +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 CHROME_UTILITY_IPC_SHELL_HANDLER_WIN_H_ -#define CHROME_UTILITY_IPC_SHELL_HANDLER_WIN_H_ - -#include <Windows.h> - -#include <tuple> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "chrome/utility/utility_message_handler.h" - -namespace base { -class FilePath; -} // namespace base - -using GetOpenFileNameFilter = - std::vector<std::tuple<base::string16, base::string16>>; - -struct ChromeUtilityMsg_GetSaveFileName_Params; - -// Handles requests to execute shell operations. Used to protect the browser -// process from instability due to 3rd-party shell extensions. Must be invoked -// in a non-sandboxed utility process. -// Note: This class is deprecated in favor of the Mojo version. -// See chrome/common/shell_handler_win.mojom and -// chrome/utility/shell_handler_impl_win.h -class IPCShellHandler : public UtilityMessageHandler { - public: - IPCShellHandler(); - ~IPCShellHandler() override; - - // IPC::Listener implementation - bool OnMessageReceived(const IPC::Message& message) override; - - private: - void OnGetOpenFileName(HWND owner, - DWORD flags, - const GetOpenFileNameFilter& filter, - const base::FilePath& initial_directory, - const base::FilePath& filename); - - void OnGetSaveFileName(const ChromeUtilityMsg_GetSaveFileName_Params& params); - - DISALLOW_COPY_AND_ASSIGN(IPCShellHandler); -}; - -#endif // CHROME_UTILITY_IPC_SHELL_HANDLER_WIN_H_
diff --git a/chrome/utility/shell_handler_impl_win.cc b/chrome/utility/shell_handler_impl_win.cc index 33119500..e4879a36 100644 --- a/chrome/utility/shell_handler_impl_win.cc +++ b/chrome/utility/shell_handler_impl_win.cc
@@ -12,14 +12,17 @@ #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/scoped_native_library.h" +#include "base/strings/string16.h" #include "base/win/scoped_bstr.h" #include "base/win/scoped_com_initializer.h" #include "base/win/scoped_comptr.h" #include "base/win/scoped_variant.h" #include "base/win/shortcut.h" +#include "base/win/win_util.h" #include "chrome/installer/util/install_util.h" #include "content/public/utility/utility_thread.h" #include "mojo/public/cpp/bindings/strong_binding.h" +#include "ui/base/win/open_file_name_win.h" namespace { @@ -230,3 +233,58 @@ bool is_pinned_to_taskbar = helper.GetResult(); callback.Run(!helper.error_occured(), is_pinned_to_taskbar); } + +void ShellHandlerImpl::CallGetOpenFileName( + uint32_t owner, + uint32_t flags, + const std::vector<std::tuple<base::string16, base::string16>>& filters, + const base::FilePath& initial_directory, + const base::FilePath& initial_filename, + const CallGetOpenFileNameCallback& callback) { + ui::win::OpenFileName open_file_name( + reinterpret_cast<HWND>(base::win::Uint32ToHandle(owner)), flags); + + open_file_name.SetInitialSelection(initial_directory, initial_filename); + open_file_name.SetFilters(filters); + + base::FilePath directory; + std::vector<base::FilePath> files; + if (::GetOpenFileName(open_file_name.GetOPENFILENAME())) + open_file_name.GetResult(&directory, &files); + + if (!files.empty()) { + callback.Run(directory, files); + } else { + callback.Run(base::FilePath(), std::vector<base::FilePath>()); + } +} + +void ShellHandlerImpl::CallGetSaveFileName( + uint32_t owner, + uint32_t flags, + const std::vector<std::tuple<base::string16, base::string16>>& filters, + uint32_t one_based_filter_index, + const base::FilePath& initial_directory, + const base::FilePath& suggested_filename, + const base::string16& default_extension, + const CallGetSaveFileNameCallback& callback) { + ui::win::OpenFileName open_file_name( + reinterpret_cast<HWND>(base::win::Uint32ToHandle(owner)), flags); + + open_file_name.SetInitialSelection(initial_directory, suggested_filename); + open_file_name.SetFilters(filters); + open_file_name.GetOPENFILENAME()->nFilterIndex = one_based_filter_index; + open_file_name.GetOPENFILENAME()->lpstrDefExt = default_extension.c_str(); + + if (::GetSaveFileName(open_file_name.GetOPENFILENAME())) { + callback.Run(base::FilePath(open_file_name.GetOPENFILENAME()->lpstrFile), + open_file_name.GetOPENFILENAME()->nFilterIndex); + return; + } + + // Error code 0 means the dialog was closed, otherwise there was an error. + if (DWORD error_code = ::CommDlgExtendedError()) + NOTREACHED() << "::GetSaveFileName() failed: error code " << error_code; + + callback.Run(base::FilePath(), 0); +}
diff --git a/chrome/utility/shell_handler_impl_win.h b/chrome/utility/shell_handler_impl_win.h index 1badd896..788152b 100644 --- a/chrome/utility/shell_handler_impl_win.h +++ b/chrome/utility/shell_handler_impl_win.h
@@ -7,9 +7,11 @@ #include "base/macros.h" #include "chrome/common/shell_handler_win.mojom.h" -#include "services/service_manager/public/cpp/bind_source_info.h" -// Implements the ShellHandler mojo interface. +namespace service_manager { +struct BindSourceInfo; +} + class ShellHandlerImpl : public chrome::mojom::ShellHandler { public: ShellHandlerImpl(); @@ -22,6 +24,24 @@ // chrome::mojom::ShellHandler: void IsPinnedToTaskbar(const IsPinnedToTaskbarCallback& callback) override; + void CallGetOpenFileName( + uint32_t owner, + uint32_t flags, + const std::vector<std::tuple<base::string16, base::string16>>& filters, + const base::FilePath& initial_directory, + const base::FilePath& initial_filename, + const CallGetOpenFileNameCallback& callback) override; + + void CallGetSaveFileName( + uint32_t owner, + uint32_t flags, + const std::vector<std::tuple<base::string16, base::string16>>& filters, + uint32_t one_based_filter_index, + const base::FilePath& initial_directory, + const base::FilePath& suggested_filename, + const base::string16& default_extension, + const CallGetSaveFileNameCallback& callback) override; + DISALLOW_COPY_AND_ASSIGN(ShellHandlerImpl); };
diff --git a/chromeos/cryptohome/cryptohome_parameters.h b/chromeos/cryptohome/cryptohome_parameters.h index bf3d290..8525f7f 100644 --- a/chromeos/cryptohome/cryptohome_parameters.h +++ b/chromeos/cryptohome/cryptohome_parameters.h
@@ -174,6 +174,9 @@ // If |true|, mounts the existing ecryptfs vault to a temporary location while // setting up a new dircrypto directory. bool to_migrate_from_ecryptfs = false; + + // If |true|, the home dir will be mounted as public mount. + bool public_mount = false; }; // This function returns true if cryptohome of |account_id| is migrated to
diff --git a/chromeos/cryptohome/homedir_methods.cc b/chromeos/cryptohome/homedir_methods.cc index e4ba8755..9671ae1 100644 --- a/chromeos/cryptohome/homedir_methods.cc +++ b/chromeos/cryptohome/homedir_methods.cc
@@ -225,6 +225,9 @@ if (request.to_migrate_from_ecryptfs) request_proto.set_to_migrate_from_ecryptfs(true); + if (request.public_mount) + request_proto.set_public_mount(true); + DBusThreadManager::Get()->GetCryptohomeClient()->MountEx( id, auth_proto, request_proto, base::Bind(&HomedirMethodsImpl::OnMountExCallback,
diff --git a/chromeos/dbus/fake_session_manager_client.cc b/chromeos/dbus/fake_session_manager_client.cc index 232d77a..763d491 100644 --- a/chromeos/dbus/fake_session_manager_client.cc +++ b/chromeos/dbus/fake_session_manager_client.cc
@@ -84,6 +84,8 @@ } void FakeSessionManagerClient::EmitLoginPromptVisible() { + for (auto& observer : observers_) + observer.EmitLoginPromptVisibleCalled(); } void FakeSessionManagerClient::RestartJob(
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc index f43aafc..e766360 100644 --- a/chromeos/login/auth/cryptohome_authenticator.cc +++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -40,6 +40,9 @@ // The label used for the key derived from the user's GAIA credentials. const char kCryptohomeGAIAKeyLabel[] = "gaia"; +// The label used for the key generated by Cryptohome for public mount. +const char kCryptohomePublicMountKeyLabel[] = "publicmount"; + // The name under which the type of key generated from the user's GAIA // credentials is stored. const char kKeyProviderDataTypeName[] = "type"; @@ -132,8 +135,14 @@ bool success, cryptohome::MountError return_code, const std::string& mount_hash) { - chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("CryptohomeMount-End", - false); + const bool public_mount = attempt->user_context.GetUserType() == + user_manager::USER_TYPE_KIOSK_APP || + attempt->user_context.GetUserType() == + user_manager::USER_TYPE_ARC_KIOSK_APP; + + chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker( + public_mount ? "CryptohomeMountPublic-End" : "CryptohomeMount-End", + false); attempt->RecordCryptohomeStatus(success, return_code); if (success) attempt->RecordUsernameHash(mount_hash); @@ -403,17 +412,25 @@ base::Bind(&TriggerResolveHash, attempt, resolver)); } -// Calls cryptohome's MountPublic method +// Calls cryptohome's MountEx method with the public_mount option. void MountPublic(const base::WeakPtr<AuthAttemptState>& attempt, scoped_refptr<CryptohomeAuthenticator> resolver, - int flags) { - cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountPublic( - cryptohome::Identification(attempt->user_context.GetAccountId()), flags, - base::Bind(&TriggerResolveWithLoginTimeMarker, - "CryptohomeMountPublic-End", attempt, resolver)); - cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername( + bool force_dircrypto_if_available) { + cryptohome::MountParameters mount(false /* ephemeral */); + mount.force_dircrypto_if_available = force_dircrypto_if_available; + mount.public_mount = true; + // Set the request to create a new homedir when missing. + mount.create_keys.push_back(cryptohome::KeyDefinition( + std::string(), kCryptohomePublicMountKeyLabel, cryptohome::PRIV_DEFAULT)); + + // For public mounts, authorization secret is filled by cryptohomed, hence it + // is left empty. Authentication's key label is also set to an empty string, + // which is a wildcard allowing any key to match to allow cryptohomes created + // in a legacy way. (See comments in DoMount.) + cryptohome::HomedirMethods::GetInstance()->MountEx( cryptohome::Identification(attempt->user_context.GetAccountId()), - base::Bind(&TriggerResolveHash, attempt, resolver)); + cryptohome::Authorization(cryptohome::KeyDefinition()), mount, + base::Bind(&OnMount, attempt, resolver)); } // Calls cryptohome's key migration method. @@ -612,7 +629,7 @@ if (!use_guest_mount) { MountPublic(current_state_->AsWeakPtr(), scoped_refptr<CryptohomeAuthenticator>(this), - cryptohome::CREATE_IF_MISSING); + false); // force_dircrypto_if_available } else { ephemeral_mount_attempted_ = true; MountGuestAndGetHash(current_state_->AsWeakPtr(), @@ -633,7 +650,7 @@ remove_user_data_on_failure_ = true; MountPublic(current_state_->AsWeakPtr(), scoped_refptr<CryptohomeAuthenticator>(this), - cryptohome::CREATE_IF_MISSING); + true); // force_dircrypto_if_available } void CryptohomeAuthenticator::OnAuthSuccess() {
diff --git a/components/BUILD.gn b/components/BUILD.gn index 98b413b..73dbdd4 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -225,6 +225,7 @@ "//components/subresource_filter/content/common:unit_tests", "//components/subresource_filter/content/renderer:unit_tests", "//components/tracing:unit_tests", + "//components/translate/content/renderer:unit_tests", "//components/visitedlink/test:unit_tests", "//components/viz/host:unit_tests", "//components/viz/service:unit_tests",
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index d228c05..d80c79b 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -233,6 +233,7 @@ "//base", "//base/test:test_support", "//chromeos", + "//chromeos:test_support_without_gmock", "//components/signin/core/account_id", "//components/user_manager", "//components/user_manager:test_support",
diff --git a/components/arc/arc_session.cc b/components/arc/arc_session.cc index f589ed3..69e0423 100644 --- a/components/arc/arc_session.cc +++ b/components/arc/arc_session.cc
@@ -17,6 +17,7 @@ #include "base/location.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" #include "base/posix/eintr_wrapper.h" #include "base/sys_info.h" #include "base/task_runner_util.h" @@ -125,9 +126,26 @@ // ConnectMojo() -> OnMojoConnected() -> // RUNNING // - // At any state, Stop() can be called. It does not immediately stop the - // instance, but will eventually stop it. - // The actual stop will be notified via ArcSession::Observer::OnStopped(). + // Also, StartForLoginScreen() may start ARC instance with + // |login_screen_instance_requested_| set to |true|. In that case, the state + // changes like the following: + // + // NOT_STARTED + // StartForLoginScreen() -> + // CREATING_SOCKET + // CreateSocket() -> OnSocketCreated() -> + // STARTING_INSTANCE + // -> OnInstanceStarted() -> + // RUNNING_FOR_LOGIN_SCREEN + // + // Start() can also be used at any of these 3 state (from CREATING_SOCKET to + // RUNNING_FOR_LOGIN_SCREEN) to turn the instance for login screen into a + // fully functional one. + // + // Regardless of whether the instance is for login screen or not, at any + // state, Stop() can be called. It may not immediately stop the instance, + // but will eventually stop it. The actual stop will be notified via + // ArcSession::Observer::OnSessionStopped(). // // When Stop() is called, it makes various behavior based on the current // phase. @@ -153,6 +171,7 @@ // whose read side is also polled. Then, in its callback, similar to // STARTING_INSTANCE, a request to stop the ARC instance is sent to // SessionManager, and ArcInstanceStopped handles remaining procedure. + // RUNNING_FOR_LOGIN_SCREEN: // RUNNING: // There is no more callback which runs on normal flow, so Stop() requests // to stop the ARC instance via SessionManager. @@ -161,19 +180,6 @@ // is an event ArcInstanceStopped() sent from SessionManager, when ARC // instace unexpectedly terminates. ArcInstanceStopped() turns the state into // STOPPED immediately. - // This happens only when STARTING_INSTANCE, CONNECTING_MOJO or RUNNING - // state. - // - // STARTING_INSTANCE: - // In OnInstanceStarted(), |state_| is checked at the beginning. If it is - // STOPPED, then ArcInstanceStopped() is called. Do nothing in that case. - // CONNECTING_MOJO: - // Similar to Stop() case above, ArcInstanceStopped() also notifies to - // BlockingPool thread to cancel it to unblock the thread. In - // OnMojoConnected(), similar to OnInstanceStarted(), check if |state_| is - // STOPPED, then do nothing. - // RUNNING: - // It is not necessary to do anything special here. // // In NOT_STARTED or STOPPED state, the instance can be safely destructed. // Specifically, in STOPPED state, there may be inflight operations or @@ -189,9 +195,13 @@ // An UNIX socket is being created. CREATING_SOCKET, - // The request to start the instance has been sent. + // The request to start or resume the instance has been sent. STARTING_INSTANCE, + // The instance is set up, but only a handful of processes NOT including + // arcbridgeservice (i.e. mojo endpoint) are running. + RUNNING_FOR_LOGIN_SCREEN, + // The instance has started. Waiting for it to connect to the IPC bridge. CONNECTING_MOJO, @@ -207,6 +217,8 @@ ~ArcSessionImpl() override; // ArcSession overrides: + void StartForLoginScreen() override; + bool IsForLoginScreen() override; void Start() override; void Stop() override; void OnShutdown() override; @@ -215,10 +227,12 @@ // Creates the UNIX socket on a worker pool and then processes its file // descriptor. static mojo::edk::ScopedPlatformHandle CreateSocket(); - void OnSocketCreated(mojo::edk::ScopedPlatformHandle fd); + void OnSocketCreated(bool instance_is_for_login_screen, + mojo::edk::ScopedPlatformHandle fd); // DBus callback for StartArcInstance(). - void OnInstanceStarted(mojo::edk::ScopedPlatformHandle socket_fd, + void OnInstanceStarted(bool instance_is_for_login_screen, + mojo::edk::ScopedPlatformHandle socket_fd, StartArcInstanceResult result, const std::string& container_instance_id); @@ -236,9 +250,15 @@ void ArcInstanceStopped(bool clean, const std::string& container_instance_id) override; - // Completes the termination procedure. + // Completes the termination procedure. Note that calling this may end up with + // deleting |this| because the function calls observers' OnSessionStopped(). void OnStopped(ArcStopReason reason); + // Sends a StartArcInstance D-Bus request to session_manager. + static void SendStartArcInstanceDBusMessage( + bool instance_is_for_login_screen, + const chromeos::SessionManagerClient::StartArcInstanceCallback& cb); + // Checks whether a function runs on the thread where the instance is // created. THREAD_CHECKER(thread_checker_); @@ -255,6 +275,14 @@ // When Stop() is called, this flag is set. bool stop_requested_ = false; + // When StartForLoginScreen() is called, this flag is set. After + // that, when Start() is called to resume the boot, the flag is unset. + bool login_screen_instance_requested_ = false; + + // The handle StartForLoginScreen() has created. The variable has a + // valid handle only when |state_| is RUNNING_FOR_LOGIN_SCREEN. + mojo::edk::ScopedPlatformHandle socket_fd_; + // Container instance id passed from session_manager. // Should be available only after OnInstanceStarted(). std::string container_instance_id_; @@ -296,15 +324,42 @@ void ArcSessionImpl::Start() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK_EQ(state_, State::NOT_STARTED); - VLOG(2) << "Starting ARC session."; - VLOG(2) << "Creating socket..."; + // Start() can be called either for starting ARC from scratch or for + // resuming an existing one. Start() must be able to start a fully + // functional instance from all of |state_| up to and including + // RUNNING_FOR_LOGIN_SCREEN. + DCHECK_GE(State::RUNNING_FOR_LOGIN_SCREEN, state_); - state_ = State::CREATING_SOCKET; - base::PostTaskAndReplyWithResult( - blocking_task_runner_.get(), FROM_HERE, - base::Bind(&ArcSessionImpl::CreateSocket), - base::Bind(&ArcSessionImpl::OnSocketCreated, weak_factory_.GetWeakPtr())); + // Flip the flag now so that callback functions like OnSocketCreated() + // can do the right thing. + login_screen_instance_requested_ = false; + + if (state_ == State::NOT_STARTED) { + // An instance for login screen does not exist. Start a new one from + // scratch. + VLOG(2) << "Starting ARC session"; + VLOG(2) << "Creating socket..."; + state_ = State::CREATING_SOCKET; + base::PostTaskAndReplyWithResult( + blocking_task_runner_.get(), FROM_HERE, + base::Bind(&ArcSessionImpl::CreateSocket), + base::Bind(&ArcSessionImpl::OnSocketCreated, weak_factory_.GetWeakPtr(), + false /* not for login screen */)); + } else if (state_ == State::CREATING_SOCKET) { + VLOG(2) << "Requested to start ARC instance with an existing socket"; + // OnSocketCreated() will start a fully featured instance. + } else if (state_ == State::STARTING_INSTANCE) { + VLOG(2) << "Requested to resume an existing ARC instance"; + // OnInstanceStarted() will start a fully featured instance. + } else if (state_ == State::RUNNING_FOR_LOGIN_SCREEN) { + VLOG(2) << "Resuming an existing ARC instance"; + state_ = State::STARTING_INSTANCE; + SendStartArcInstanceDBusMessage( + false /* not for login screen */, + base::Bind(&ArcSessionImpl::OnInstanceStarted, + weak_factory_.GetWeakPtr(), false /* the same */, + base::Passed(&socket_fd_))); + } } // static @@ -346,6 +401,7 @@ } void ArcSessionImpl::OnSocketCreated( + bool instance_is_for_login_screen, mojo::edk::ScopedPlatformHandle socket_fd) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_EQ(state_, State::CREATING_SOCKET); @@ -362,8 +418,29 @@ return; } - VLOG(2) << "Socket is created. Starting ARC instance..."; + VLOG(2) << "Socket is created. Starting ARC instance" + << (instance_is_for_login_screen ? " for login screen" : ""); state_ = State::STARTING_INSTANCE; + SendStartArcInstanceDBusMessage( + instance_is_for_login_screen, + base::Bind(&ArcSessionImpl::OnInstanceStarted, weak_factory_.GetWeakPtr(), + instance_is_for_login_screen, base::Passed(&socket_fd))); +} + +// static +void ArcSessionImpl::SendStartArcInstanceDBusMessage( + bool instance_is_for_login_screen, + const chromeos::SessionManagerClient::StartArcInstanceCallback& cb) { + chromeos::SessionManagerClient* session_manager_client = + chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); + if (instance_is_for_login_screen) { + session_manager_client->StartArcInstance( + chromeos::SessionManagerClient::ArcStartupMode::LOGIN_SCREEN, + // All variables below except |cb| will be ignored. + cryptohome::Identification(), false, false, cb); + return; + } + user_manager::UserManager* user_manager = user_manager::UserManager::Get(); DCHECK(user_manager->GetPrimaryUser()); const cryptohome::Identification cryptohome_id( @@ -377,22 +454,29 @@ const bool scan_vendor_priv_app = chromeos::switches::IsVoiceInteractionEnabled(); - chromeos::SessionManagerClient* session_manager_client = - chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); session_manager_client->StartArcInstance( chromeos::SessionManagerClient::ArcStartupMode::FULL, cryptohome_id, - skip_boot_completed_broadcast, scan_vendor_priv_app, - base::Bind(&ArcSessionImpl::OnInstanceStarted, weak_factory_.GetWeakPtr(), - base::Passed(&socket_fd))); + skip_boot_completed_broadcast, scan_vendor_priv_app, cb); } void ArcSessionImpl::OnInstanceStarted( + bool instance_is_for_login_screen, mojo::edk::ScopedPlatformHandle socket_fd, StartArcInstanceResult result, const std::string& container_instance_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_EQ(state_, State::STARTING_INSTANCE); - container_instance_id_ = container_instance_id; + + bool resumed = false; + if (!container_instance_id_.empty()) { + // |container_instance_id_| has already been initialized when the instance + // for login screen was started. + DCHECK(container_instance_id.empty()); + DCHECK(!instance_is_for_login_screen); + resumed = true; + } else { + container_instance_id_ = container_instance_id; + } if (stop_requested_) { if (result == StartArcInstanceResult::SUCCESS) { @@ -412,7 +496,26 @@ return; } - VLOG(2) << "ARC instance is successfully started. Connecting Mojo..."; + if (instance_is_for_login_screen) { + VLOG(2) << "ARC instance for login screen is successfully started."; + if (login_screen_instance_requested_) { + state_ = State::RUNNING_FOR_LOGIN_SCREEN; + socket_fd_ = std::move(socket_fd); + } else { + // Start() has been called. + VLOG(2) << "Resuming an existing ARC instance"; + state_ = State::STARTING_INSTANCE; + SendStartArcInstanceDBusMessage( + false /* not for login screen */, + base::Bind(&ArcSessionImpl::OnInstanceStarted, + weak_factory_.GetWeakPtr(), false /* the same */, + base::Passed(&socket_fd_))); + } + return; + } + + VLOG(2) << "ARC instance is successfully " + << (resumed ? "resumed" : "started") << ". Connecting Mojo..."; state_ = State::CONNECTING_MOJO; // Prepare a pipe so that AcceptInstanceConnection can be interrupted on @@ -539,6 +642,11 @@ // clean it up. return; + case State::RUNNING_FOR_LOGIN_SCREEN: + // An ARC instance for login screen is running. Request to stop it. + StopArcInstance(); + return; + case State::CONNECTING_MOJO: // Mojo connection is being waited on a BlockingPool thread. // Request to cancel it. Following stopping procedure will run @@ -560,10 +668,13 @@ void ArcSessionImpl::StopArcInstance() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(state_ == State::STARTING_INSTANCE || + state_ == State::RUNNING_FOR_LOGIN_SCREEN || state_ == State::CONNECTING_MOJO || state_ == State::RUNNING); - // Notification will arrive through ArcInstanceStopped(). - VLOG(2) << "Requesting to stop ARC instance"; + VLOG(2) << "Requesting session_manager to stop ARC instance"; + + // When the instance is not for login screen, change the |state_| in + // ArcInstanceStopped(). chromeos::SessionManagerClient* session_manager_client = chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); session_manager_client->StopArcInstance( @@ -578,6 +689,8 @@ << (clean ? "cleanly" : "uncleanly"); if (container_instance_id != container_instance_id_) { + // This path is taken e.g. when an instance for login screen is Stop()ped + // by ArcSessionRunner. VLOG(1) << "Container instance id mismatch. Do nothing." << container_instance_id << " vs " << container_instance_id_; return; @@ -607,6 +720,24 @@ OnStopped(reason); } +void ArcSessionImpl::StartForLoginScreen() { + DCHECK_EQ(State::NOT_STARTED, state_); + + VLOG(2) << "Starting ARC session for login screen"; + VLOG(2) << "Creating socket..."; + login_screen_instance_requested_ = true; + state_ = State::CREATING_SOCKET; + base::PostTaskAndReplyWithResult( + blocking_task_runner_.get(), FROM_HERE, + base::Bind(&ArcSessionImpl::CreateSocket), + base::Bind(&ArcSessionImpl::OnSocketCreated, weak_factory_.GetWeakPtr(), + true /* for login screen */)); +} + +bool ArcSessionImpl::IsForLoginScreen() { + return login_screen_instance_requested_; +} + void ArcSessionImpl::OnStopped(ArcStopReason reason) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // OnStopped() should be called once per instance. @@ -634,10 +765,12 @@ // Note that this may fail if ARC container is not actually running, but // ignore an error as described below. if (state_ == State::STARTING_INSTANCE || - state_ == State::CONNECTING_MOJO || state_ == State::RUNNING) + state_ == State::RUNNING_FOR_LOGIN_SCREEN || + state_ == State::CONNECTING_MOJO || state_ == State::RUNNING) { StopArcInstance(); + } - // Directly set to the STOPPED stateby OnStopped(). Note that calling + // Directly set to the STOPPED state by OnStopped(). Note that calling // StopArcInstance() may not work well. At least, because the UI thread is // already stopped here, ArcInstanceStopped() callback cannot be invoked. OnStopped(ArcStopReason::SHUTDOWN);
diff --git a/components/arc/arc_session.h b/components/arc/arc_session.h index 4f9f387..7ae7a19 100644 --- a/components/arc/arc_session.h +++ b/components/arc/arc_session.h
@@ -8,10 +8,7 @@ #include <memory> #include "base/macros.h" -#include "base/memory/ref_counted.h" #include "base/observer_list.h" -#include "base/sequenced_task_runner.h" -#include "base/single_thread_task_runner.h" #include "base/task_runner.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_stop_reason.h" @@ -21,8 +18,8 @@ // Starts the ARC instance and bootstraps the bridge connection. // Clients should implement the Delegate to be notified upon communications // being available. -// The instance can be safely removed 1) before Start() is called, or 2) after -// OnStopped() is called. +// The instance can be safely removed 1) before Start*() is called, or 2) after +// OnSessionStopped() is called. // The number of instances must be at most one. Otherwise, ARC instances will // conflict. class ArcSession { @@ -47,17 +44,29 @@ const scoped_refptr<base::TaskRunner>& blocking_task_runner); virtual ~ArcSession(); + // Starts an instance for login screen. The instance is not a fully functional + // one, and Observer::OnSessionReady() will *never* be called. + virtual void StartForLoginScreen() = 0; + + // Returns true if StartForLoginScreen() has been called but Start() hasn't. + virtual bool IsForLoginScreen() = 0; + // Starts and bootstraps a connection with the instance. The Observer's - // OnReady() will be called if the bootstrapping is successful, or - // OnStopped() if it is not. Start() should not be called twice or more. + // OnSessionReady() will be called if the bootstrapping is successful, or + // OnSessionStopped() if it is not. Start() should not be called twice or + // more. When StartForLoginScreen() has already been called, Start() turns + // the mini instance to a fully functional one. virtual void Start() = 0; - // Requests to stop the currently-running instance. - // The completion is notified via OnStopped() of the Delegate. + // Requests to stop the currently-running instance whether or not it is for + // login screen. + // The completion is notified via OnSessionStopped() of the Observer. virtual void Stop() = 0; // Called when Chrome is in shutdown state. This is called when the message - // loop is already stopped, and the instance will soon be deleted. + // loop is already stopped, and the instance will soon be deleted. Caller + // may expect that OnSessionStopped() is synchronously called back except + // when it has already been called before. virtual void OnShutdown() = 0; void AddObserver(Observer* observer);
diff --git a/components/arc/arc_session_runner.cc b/components/arc/arc_session_runner.cc index 4c3e8d9..d16f5efc 100644 --- a/components/arc/arc_session_runner.cc +++ b/components/arc/arc_session_runner.cc
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/task_runner.h" +#include "chromeos/dbus/dbus_thread_manager.h" namespace arc { @@ -15,17 +16,34 @@ constexpr base::TimeDelta kDefaultRestartDelay = base::TimeDelta::FromSeconds(5); +chromeos::SessionManagerClient* GetSessionManagerClient() { + // If the DBusThreadManager or the SessionManagerClient aren't available, + // there isn't much we can do. This should only happen when running tests. + if (!chromeos::DBusThreadManager::IsInitialized() || + !chromeos::DBusThreadManager::Get() || + !chromeos::DBusThreadManager::Get()->GetSessionManagerClient()) + return nullptr; + return chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); +} + } // namespace ArcSessionRunner::ArcSessionRunner(const ArcSessionFactory& factory) : restart_delay_(kDefaultRestartDelay), factory_(factory), - weak_ptr_factory_(this) {} + weak_ptr_factory_(this) { + chromeos::SessionManagerClient* client = GetSessionManagerClient(); + if (client) + client->AddObserver(this); +} ArcSessionRunner::~ArcSessionRunner() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (arc_session_) arc_session_->RemoveObserver(this); + chromeos::SessionManagerClient* client = GetSessionManagerClient(); + if (client) + client->RemoveObserver(this); } void ArcSessionRunner::AddObserver(Observer* observer) { @@ -52,30 +70,33 @@ // previous RequestStop() call). DCHECK(!restart_timer_.IsRunning()); - if (arc_session_) { + if (arc_session_ && state_ >= State::STARTING) { // In this case, RequestStop() was called, and before |arc_session_| had // finished stopping, RequestStart() was called. Do nothing in that case, // since when |arc_session_| does actually stop, OnSessionStopped() will // be called, where it should automatically restart. DCHECK_EQ(state_, State::STOPPING); } else { - DCHECK_EQ(state_, State::STOPPED); + DCHECK_LE(state_, State::STARTING_FOR_LOGIN_SCREEN); StartArcSession(); } } -void ArcSessionRunner::RequestStop() { +void ArcSessionRunner::RequestStop(bool always_stop_session) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Consecutive RequestStop() call. Do nothing. - if (!run_requested_) - return; + if (!run_requested_) { + // Call Stop() to stop an instance for login screen (if any.) If this is + // just a consecutive RequestStop() call, Stop() does nothing. + if (!always_stop_session || !arc_session_) + return; + } VLOG(1) << "Session ended"; run_requested_ = false; if (arc_session_) { - // The |state_| could be either STARTING, RUNNING or STOPPING. + // The |state_| could be either STARTING*, RUNNING or STOPPING. DCHECK_NE(state_, State::STOPPED); if (state_ == State::STOPPING) { @@ -124,20 +145,22 @@ void ArcSessionRunner::SetRestartDelayForTesting( const base::TimeDelta& restart_delay) { DCHECK_EQ(state_, State::STOPPED); - DCHECK(!arc_session_); DCHECK(!restart_timer_.IsRunning()); restart_delay_ = restart_delay; } void ArcSessionRunner::StartArcSession() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK_EQ(state_, State::STOPPED); - DCHECK(!arc_session_); DCHECK(!restart_timer_.IsRunning()); VLOG(1) << "Starting ARC instance"; - arc_session_ = factory_.Run(); - arc_session_->AddObserver(this); + if (!arc_session_) { + DCHECK_EQ(state_, State::STOPPED); + arc_session_ = factory_.Run(); + arc_session_->AddObserver(this); + } else { + DCHECK_EQ(state_, State::STARTING_FOR_LOGIN_SCREEN); + } state_ = State::STARTING; arc_session_->Start(); } @@ -159,6 +182,11 @@ DCHECK(!restart_timer_.IsRunning()); VLOG(0) << "ARC stopped: " << stop_reason; + + // The observers should be agnostic to the existence of the limited-purpose + // instance. + const bool notify_observers = !arc_session_->IsForLoginScreen(); + arc_session_->RemoveObserver(this); arc_session_.reset(); @@ -188,8 +216,23 @@ } state_ = State::STOPPED; - for (auto& observer : observer_list_) - observer.OnSessionStopped(stop_reason, restarting); + if (notify_observers) { + for (auto& observer : observer_list_) + observer.OnSessionStopped(stop_reason, restarting); + } +} + +void ArcSessionRunner::EmitLoginPromptVisibleCalled() { + DCHECK(!arc_session_); + // Since 'login-prompt-visible' Upstart signal starts all Upstart jobs the + // container may depend on such as cras, EmitLoginPromptVisibleCalled() is the + // safe place to start the container for login screen. + // TODO(yusukes): Once Chrome OS side is ready, uncomment the following: + + // arc_session_ = factory_.Run(); + // arc_session_->AddObserver(this); + // state_ = State::STARTING_FOR_LOGIN_SCREEN; + // arc_session_->StartForLoginScreen(); } } // namespace arc
diff --git a/components/arc/arc_session_runner.h b/components/arc/arc_session_runner.h index f5898b9..13bf3ea 100644 --- a/components/arc/arc_session_runner.h +++ b/components/arc/arc_session_runner.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "chromeos/dbus/session_manager_client.h" #include "components/arc/arc_session.h" #include "components/arc/arc_stop_reason.h" @@ -18,7 +19,8 @@ // Accept requests to start/stop ARC instance. Also supports automatic // restarting on unexpected ARC instance crash. -class ArcSessionRunner : public ArcSession::Observer { +class ArcSessionRunner : public ArcSession::Observer, + public chromeos::SessionManagerClient::Observer { public: // Observer to notify events across multiple ARC session runs. class Observer { @@ -50,7 +52,8 @@ void RequestStart(); // Stops the ARC service. - void RequestStop(); + // TODO(yusukes): Remove the parameter. + void RequestStop(bool always_stop_session); // OnShutdown() should be called when the browser is shutting down. This can // only be called on the thread that this class was created on. We assume that @@ -94,6 +97,10 @@ // ARC instance is not currently running. STOPPED, + // Request to start ARC instance for login screen is received. Starting an + // ARC instance. + STARTING_FOR_LOGIN_SCREEN, + // Request to start ARC instance is received. Starting an ARC instance. STARTING, @@ -112,6 +119,9 @@ void OnSessionReady() override; void OnSessionStopped(ArcStopReason reason) override; + // chromeos::SessionManagerClient::Observer: + void EmitLoginPromptVisibleCalled() override; + THREAD_CHECKER(thread_checker_); // Observers for the ARC instance state change events.
diff --git a/components/arc/arc_session_runner_unittest.cc b/components/arc/arc_session_runner_unittest.cc index c407a09..144d0b0b 100644 --- a/components/arc/arc_session_runner_unittest.cc +++ b/components/arc/arc_session_runner_unittest.cc
@@ -14,6 +14,7 @@ #include "base/single_thread_task_runner.h" #include "base/test/scoped_task_environment.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_session_manager_client.h" #include "components/arc/arc_session_runner.h" #include "components/arc/test/fake_arc_session.h" #include "mojo/public/cpp/system/message_pipe.h" @@ -40,10 +41,13 @@ base::test::ScopedTaskEnvironment::MainThreadType::UI) {} void SetUp() override { + chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( + base::MakeUnique<chromeos::FakeSessionManagerClient>()); chromeos::DBusThreadManager::Initialize(); stop_reason_ = ArcStopReason::SHUTDOWN; restarting_ = false; + stopped_called_ = false; // We inject FakeArcSession here so we do not need task_runner. arc_session_runner_ = @@ -65,8 +69,17 @@ arc_session_runner_->GetArcSessionForTesting()); } - ArcStopReason stop_reason() { return stop_reason_; } - bool restarting() { return restarting_; } + ArcStopReason stop_reason() { + EXPECT_TRUE(stopped_called()); + return stop_reason_; + } + + bool restarting() { + EXPECT_TRUE(stopped_called()); + return restarting_; + } + + bool stopped_called() { return stopped_called_; } void ResetArcSessionFactory( const ArcSessionRunner::ArcSessionFactory& factory) { @@ -95,10 +108,12 @@ // ArcSessionRunner::OnSessionStopped(). stop_reason_ = stop_reason; restarting_ = restarting; + stopped_called_ = true; } ArcStopReason stop_reason_; bool restarting_; + bool stopped_called_; std::unique_ptr<ArcSessionRunner> arc_session_runner_; base::test::ScopedTaskEnvironment scoped_task_environment_; @@ -138,7 +153,7 @@ arc_session_runner()->RequestStart(); EXPECT_TRUE(arc_session_runner()->IsRunning()); - arc_session_runner()->RequestStop(); + arc_session_runner()->RequestStop(false); EXPECT_TRUE(arc_session_runner()->IsStopped()); EXPECT_TRUE(observer.stopped_called()); } @@ -154,7 +169,7 @@ EXPECT_FALSE(arc_session_runner()->IsStopped()); EXPECT_FALSE(arc_session_runner()->IsRunning()); - arc_session_runner()->RequestStop(); + arc_session_runner()->RequestStop(false); EXPECT_TRUE(arc_session_runner()->IsStopped()); } @@ -171,6 +186,47 @@ EXPECT_TRUE(arc_session_runner()->IsStopped()); } +// Does the same with the mini instance for login screen. +// TODO(yusukes): Enable the test once EmitLoginPromptVisibleCalled() is fully +// enabled. +TEST_F(ArcSessionRunnerTest, DISABLED_BootFailureForLoginScreen) { + ResetArcSessionFactory( + base::Bind(&ArcSessionRunnerTest::CreateBootFailureArcSession, + ArcStopReason::CRASH)); + EXPECT_TRUE(arc_session_runner()->IsStopped()); + + chromeos::DBusThreadManager::Get() + ->GetSessionManagerClient() + ->EmitLoginPromptVisible(); + // If starting the mini instance fails, arc_session_runner()'s state goes back + // to STOPPED, but its observers won't be notified. + EXPECT_TRUE(arc_session_runner()->IsStopped()); + EXPECT_FALSE(stopped_called()); + + // Also make sure that RequestStart() works just fine after the boot + // failure. + ResetArcSessionFactory(base::Bind(FakeArcSession::Create)); + arc_session_runner()->RequestStart(); + EXPECT_TRUE(arc_session_runner()->IsRunning()); +} + +// Tests that RequestStart() works even after EmitLoginPromptVisibleCalled() +// is called. +// TODO(yusukes): Enable the test once EmitLoginPromptVisibleCalled() is fully +// enabled. +TEST_F(ArcSessionRunnerTest, DISABLED_StartWithLoginScreenInstance) { + EXPECT_TRUE(arc_session_runner()->IsStopped()); + + chromeos::DBusThreadManager::Get() + ->GetSessionManagerClient() + ->EmitLoginPromptVisible(); + EXPECT_FALSE(arc_session_runner()->IsStopped()); + EXPECT_FALSE(arc_session_runner()->IsRunning()); + + arc_session_runner()->RequestStart(); + EXPECT_TRUE(arc_session_runner()->IsRunning()); +} + // If the instance is stopped, it should be re-started. TEST_F(ArcSessionRunnerTest, Restart) { arc_session_runner()->SetRestartDelayForTesting(base::TimeDelta()); @@ -186,7 +242,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(arc_session_runner()->IsRunning()); - arc_session_runner()->RequestStop(); + arc_session_runner()->RequestStop(false); EXPECT_TRUE(arc_session_runner()->IsStopped()); } @@ -217,7 +273,7 @@ EXPECT_TRUE(arc_session_runner()->IsRunning()); // Graceful stop. - arc_session_runner()->RequestStop(); + arc_session_runner()->RequestStop(false); EXPECT_EQ(ArcStopReason::SHUTDOWN, stop_reason()); EXPECT_FALSE(restarting()); EXPECT_TRUE(arc_session_runner()->IsStopped());
diff --git a/components/arc/test/fake_arc_session.cc b/components/arc/test/fake_arc_session.cc index 93a99967..6b3b5c1 100644 --- a/components/arc/test/fake_arc_session.cc +++ b/components/arc/test/fake_arc_session.cc
@@ -15,7 +15,20 @@ FakeArcSession::~FakeArcSession() = default; +void FakeArcSession::StartForLoginScreen() { + is_for_login_screen_ = true; + if (boot_failure_emulation_enabled_) { + for (auto& observer : observer_list_) + observer.OnSessionStopped(boot_failure_reason_); + } +} + +bool FakeArcSession::IsForLoginScreen() { + return is_for_login_screen_; +} + void FakeArcSession::Start() { + is_for_login_screen_ = false; if (boot_failure_emulation_enabled_) { for (auto& observer : observer_list_) observer.OnSessionStopped(boot_failure_reason_);
diff --git a/components/arc/test/fake_arc_session.h b/components/arc/test/fake_arc_session.h index 132c86a..9e272d2 100644 --- a/components/arc/test/fake_arc_session.h +++ b/components/arc/test/fake_arc_session.h
@@ -20,6 +20,8 @@ ~FakeArcSession() override; // ArcSession overrides: + void StartForLoginScreen() override; + bool IsForLoginScreen() override; void Start() override; void Stop() override; void OnShutdown() override; @@ -29,11 +31,12 @@ // The following control Start() behavior for testing various situations. - // Enables/disables boot failure emulation, in which OnStopped(reason) will - // be called when Start() is called. + // Enables/disables boot failure emulation, in which OnSessionStopped(reason) + // will be called when Start() or StartForLoginScreen() is called. void EnableBootFailureEmulation(ArcStopReason reason); - // Emulate Start() is suspended at some phase, before OnReady() is invoked. + // Emulate Start() is suspended at some phase, before OnSessionReady() is + // invoked. void SuspendBoot(); // Returns FakeArcSession instance. This can be used for a factory @@ -45,6 +48,7 @@ ArcStopReason boot_failure_reason_; bool boot_suspended_ = false; + bool is_for_login_screen_ = false; DISALLOW_COPY_AND_ASSIGN(FakeArcSession); };
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index df5890d..cba036d 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -2621,23 +2621,27 @@ } bool AutofillTable::MigrateToVersion73AddMaskedCardBankName() { - sql::Transaction transaction(db_); - if (!transaction.Begin()) - return false; - // Add the new bank_name column to the masked_credit_cards table. - if (!db_->DoesColumnExist("masked_credit_cards", "bank_name") && - !db_->Execute("ALTER TABLE masked_credit_cards ADD COLUMN " - "bank_name VARCHAR")) { - return false; - } - - return transaction.Commit(); + return db_->DoesColumnExist("masked_credit_cards", "bank_name") || + db_->Execute( + "ALTER TABLE masked_credit_cards ADD COLUMN bank_name VARCHAR"); } bool AutofillTable::MigrateToVersion74AddServerCardTypeColumn() { - return db_->Execute( - "ALTER TABLE masked_credit_cards ADD COLUMN type INTEGER DEFAULT 0"); + // Version 73 was actually used by two different schemas; an attempt to add + // the "type" column (as in this version 74) was landed and reverted, and then + // the "bank_name" column was added (and stuck). Some clients may have been + // upgraded to one and some the other. Figure out which is the case. + const bool added_type_column_in_v73 = + db_->DoesColumnExist("masked_credit_cards", "type"); + + // If we previously added the "type" column, then it's already present with + // the correct semantics, but we now need to run the "bank_name" migration. + // Otherwise, we need to add "type" now. + return added_type_column_in_v73 ? MigrateToVersion73AddMaskedCardBankName() + : db_->Execute( + "ALTER TABLE masked_credit_cards ADD " + "COLUMN type INTEGER DEFAULT 0"); } } // namespace autofill
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc index 5ae9136..5ca4fee 100644 --- a/components/exo/wayland/clients/client_base.cc +++ b/components/exo/wayland/clients/client_base.cc
@@ -16,6 +16,7 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/message_loop/message_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -260,7 +261,7 @@ LOG(ERROR) << "Can't create gbm device"; return false; } - + ui_loop_.reset(new base::MessageLoopForUI); ui::OzonePlatform::InitParams params; params.single_process = true; ui::OzonePlatform::InitializeForGPU(params);
diff --git a/components/exo/wayland/clients/client_base.h b/components/exo/wayland/clients/client_base.h index be00a8c..2fef99a 100644 --- a/components/exo/wayland/clients/client_base.h +++ b/components/exo/wayland/clients/client_base.h
@@ -19,6 +19,7 @@ namespace base { class CommandLine; +class MessageLoopForUI; } namespace exo { @@ -92,6 +93,7 @@ std::unique_ptr<wl_shell_surface> shell_surface_; Globals globals_; #if defined(OZONE_PLATFORM_GBM) + std::unique_ptr<base::MessageLoopForUI> ui_loop_; base::ScopedFD drm_fd_; std::unique_ptr<gbm_device> device_; #endif
diff --git a/components/history/core/browser/expire_history_backend_unittest.cc b/components/history/core/browser/expire_history_backend_unittest.cc index 11cd46f..0a554fa8 100644 --- a/components/history/core/browser/expire_history_backend_unittest.cc +++ b/components/history/core/browser/expire_history_backend_unittest.cc
@@ -16,11 +16,11 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/scoped_observer.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "components/history/core/browser/history_backend_client.h" #include "components/history/core/browser/history_backend_notifier.h" #include "components/history/core/browser/history_constants.h" @@ -55,7 +55,9 @@ public: ExpireHistoryTest() : backend_client_(history_client_.CreateBackendClient()), - expirer_(this, backend_client_.get(), message_loop_.task_runner()), + expirer_(this, + backend_client_.get(), + scoped_task_environment_.GetMainThreadTaskRunner()), now_(base::Time::Now()) {} protected: @@ -96,11 +98,11 @@ // This must be destroyed last. base::ScopedTempDir tmp_dir_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + HistoryClientFakeBookmarks history_client_; std::unique_ptr<HistoryBackendClient> backend_client_; - base::MessageLoopForUI message_loop_; - ExpireHistoryBackend expirer_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; @@ -139,8 +141,7 @@ PrepopulatedPageList(), base::Bind(MockCanAddURLToHistory)); WaitTopSitesLoadedObserver wait_top_sites_observer(top_sites_); - top_sites_->Init(path().Append(kTopSitesFilename), - message_loop_.task_runner()); + top_sites_->Init(path().Append(kTopSitesFilename)); wait_top_sites_observer.Run(); }
diff --git a/components/history/core/browser/top_sites_backend.cc b/components/history/core/browser/top_sites_backend.cc index 7124e82..7b0437e 100644 --- a/components/history/core/browser/top_sites_backend.cc +++ b/components/history/core/browser/top_sites_backend.cc
@@ -14,6 +14,8 @@ #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/task/cancelable_task_tracker.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "components/history/core/browser/top_sites_database.h" @@ -21,9 +23,10 @@ namespace history { -TopSitesBackend::TopSitesBackend( - const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner) - : db_(new TopSitesDatabase()), db_task_runner_(db_task_runner) { +TopSitesBackend::TopSitesBackend() + : db_(new TopSitesDatabase()), + db_task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::TaskPriority::USER_VISIBLE, base::MayBlock()})) { DCHECK(db_task_runner_); } @@ -83,7 +86,7 @@ } void TopSitesBackend::InitDBOnDBThread(const base::FilePath& path) { - DCHECK(db_task_runner_->BelongsToCurrentThread()); + DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); if (!db_->Init(path)) { LOG(ERROR) << "Failed to initialize database."; db_.reset(); @@ -91,13 +94,13 @@ } void TopSitesBackend::ShutdownDBOnDBThread() { - DCHECK(db_task_runner_->BelongsToCurrentThread()); + DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); db_.reset(); } void TopSitesBackend::GetMostVisitedThumbnailsOnDBThread( scoped_refptr<MostVisitedThumbnails> thumbnails) { - DCHECK(db_task_runner_->BelongsToCurrentThread()); + DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); if (db_) { db_->GetPageThumbnails(&(thumbnails->most_visited), @@ -139,7 +142,7 @@ } void TopSitesBackend::ResetDatabaseOnDBThread(const base::FilePath& file_path) { - DCHECK(db_task_runner_->BelongsToCurrentThread()); + DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); db_.reset(NULL); sql::Connection::Delete(db_path_); db_.reset(new TopSitesDatabase());
diff --git a/components/history/core/browser/top_sites_backend.h b/components/history/core/browser/top_sites_backend.h index 807f337..620a76ac 100644 --- a/components/history/core/browser/top_sites_backend.h +++ b/components/history/core/browser/top_sites_backend.h
@@ -16,7 +16,7 @@ namespace base { class CancelableTaskTracker; class FilePath; -class SingleThreadTaskRunner; +class SequencedTaskRunner; } namespace history { @@ -42,8 +42,7 @@ typedef base::Callback<void(const scoped_refptr<MostVisitedThumbnails>&)> GetMostVisitedThumbnailsCallback; - explicit TopSitesBackend( - const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner); + TopSitesBackend(); void Init(const base::FilePath& path); @@ -103,7 +102,7 @@ base::FilePath db_path_; std::unique_ptr<TopSitesDatabase> db_; - scoped_refptr<base::SingleThreadTaskRunner> db_task_runner_; + scoped_refptr<base::SequencedTaskRunner> db_task_runner_; DISALLOW_COPY_AND_ASSIGN(TopSitesBackend); };
diff --git a/components/history/core/browser/top_sites_impl.cc b/components/history/core/browser/top_sites_impl.cc index f983265..aa758327 100644 --- a/components/history/core/browser/top_sites_impl.cc +++ b/components/history/core/browser/top_sites_impl.cc
@@ -120,12 +120,10 @@ DCHECK(!can_add_url_to_history_.is_null()); } -void TopSitesImpl::Init( - const base::FilePath& db_name, - const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner) { +void TopSitesImpl::Init(const base::FilePath& db_name) { // Create the backend here, rather than in the constructor, so that // unit tests that do not need the backend can run without a problem. - backend_ = new TopSitesBackend(db_task_runner); + backend_ = new TopSitesBackend(); backend_->Init(db_name); backend_->GetMostVisitedThumbnails( base::Bind(&TopSitesImpl::OnGotMostVisitedThumbnails,
diff --git a/components/history/core/browser/top_sites_impl.h b/components/history/core/browser/top_sites_impl.h index 98bc72f..e8d1023 100644 --- a/components/history/core/browser/top_sites_impl.h +++ b/components/history/core/browser/top_sites_impl.h
@@ -39,7 +39,6 @@ class FilePath; class RefCountedBytes; class RefCountedMemory; -class SingleThreadTaskRunner; } namespace history { @@ -64,8 +63,7 @@ const CanAddURLToHistoryFn& can_add_url_to_history); // Initializes TopSitesImpl. - void Init(const base::FilePath& db_name, - const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner); + void Init(const base::FilePath& db_name); // TopSites implementation. bool SetPageThumbnail(const GURL& url,
diff --git a/components/history/core/browser/top_sites_impl_unittest.cc b/components/history/core/browser/top_sites_impl_unittest.cc index 25c83ff..00d1e107 100644 --- a/components/history/core/browser/top_sites_impl_unittest.cc +++ b/components/history/core/browser/top_sites_impl_unittest.cc
@@ -11,10 +11,10 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/task/cancelable_task_tracker.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "components/history/core/browser/history_client.h" #include "components/history/core/browser/history_constants.h" @@ -72,13 +72,14 @@ bool wait, bool include_forced_urls) { int start_number_of_callbacks = number_of_callbacks_; + base::RunLoop run_loop; top_sites->GetMostVisitedURLs( base::Bind(&TopSitesQuerier::OnTopSitesAvailable, - weak_ptr_factory_.GetWeakPtr()), + weak_ptr_factory_.GetWeakPtr(), &run_loop), include_forced_urls); if (wait && start_number_of_callbacks == number_of_callbacks_) { waiting_ = true; - base::RunLoop().Run(); + run_loop.Run(); } } @@ -91,11 +92,12 @@ private: // Callback for TopSitesImpl::GetMostVisitedURLs. - void OnTopSitesAvailable(const history::MostVisitedURLList& data) { + void OnTopSitesAvailable(base::RunLoop* run_loop, + const history::MostVisitedURLList& data) { urls_ = data; number_of_callbacks_++; if (waiting_) { - base::MessageLoop::current()->QuitWhenIdle(); + run_loop->QuitWhenIdle(); waiting_ = false; } } @@ -166,15 +168,6 @@ BlockUntilHistoryProcessesPendingRequests(history_service()); } - // Waits for top sites to finish processing a task. This is useful if you need - // to wait until top sites finishes processing a task. - void WaitForTopSites() { - top_sites()->backend_->DoEmptyRequest( - base::Bind(&TopSitesImplTest::QuitCallback, base::Unretained(this)), - &top_sites_tracker_); - base::RunLoop().Run(); - } - TopSitesImpl* top_sites() { return top_sites_impl_.get(); } HistoryService* history_service() { return history_service_.get(); } @@ -196,10 +189,6 @@ } } - // Quit the current message loop when invoked. Useful when running a nested - // message loop. - void QuitCallback() { base::MessageLoop::current()->QuitWhenIdle(); } - // Adds a page to history. void AddPageToHistory(const GURL& url) { RedirectList redirects; @@ -299,8 +288,7 @@ top_sites_impl_ = new TopSitesImpl( pref_service_.get(), history_service_.get(), prepopulated_pages, base::Bind(MockCanAddURLToHistory)); - top_sites_impl_->Init(scoped_temp_dir_.GetPath().Append(kTopSitesFilename), - message_loop_.task_runner()); + top_sites_impl_->Init(scoped_temp_dir_.GetPath().Append(kTopSitesFilename)); } void DestroyTopSites() { @@ -308,8 +296,7 @@ top_sites_impl_->ShutdownOnUIThread(); top_sites_impl_ = nullptr; - if (base::MessageLoop::current()) - base::RunLoop().RunUntilIdle(); + scoped_task_environment_.RunUntilIdle(); } } @@ -320,8 +307,9 @@ } private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + base::ScopedTempDir scoped_temp_dir_; - base::MessageLoopForUI message_loop_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; std::unique_ptr<HistoryService> history_service_;
diff --git a/components/offline_pages/core/prefetch/BUILD.gn b/components/offline_pages/core/prefetch/BUILD.gn index e9c5d80..4604e9c4 100644 --- a/components/offline_pages/core/prefetch/BUILD.gn +++ b/components/offline_pages/core/prefetch/BUILD.gn
@@ -23,6 +23,8 @@ "prefetch_dispatcher.h", "prefetch_dispatcher_impl.cc", "prefetch_dispatcher_impl.h", + "prefetch_downloader.cc", + "prefetch_downloader.h", "prefetch_gcm_app_handler.cc", "prefetch_gcm_app_handler.h", "prefetch_gcm_handler.h", @@ -35,6 +37,8 @@ "prefetch_proto_utils.h", "prefetch_request_fetcher.cc", "prefetch_request_fetcher.h", + "prefetch_server_urls.cc", + "prefetch_server_urls.h", "prefetch_service.h", "prefetch_service_impl.cc", "prefetch_service_impl.h", @@ -50,6 +54,7 @@ deps = [ "//base", + "//components/download/public", "//components/gcm_driver", "//components/gcm_driver/common", "//components/keyed_service/core", @@ -109,6 +114,7 @@ "get_operation_request_unittest.cc", "get_operation_task_unittest.cc", "prefetch_dispatcher_impl_unittest.cc", + "prefetch_downloader_unittest.cc", "prefetch_gcm_app_handler_unittest.cc", "prefetch_item_unittest.cc", "prefetch_network_request_factory_impl_unittest.cc", @@ -120,6 +126,7 @@ deps = [ ":prefetch", ":test_support", + "//components/download/public", "//components/gcm_driver/instance_id", "//components/offline_pages/core", "//components/offline_pages/core:switches",
diff --git a/components/offline_pages/core/prefetch/DEPS b/components/offline_pages/core/prefetch/DEPS index 4a85e6c..5214a88 100644 --- a/components/offline_pages/core/prefetch/DEPS +++ b/components/offline_pages/core/prefetch/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/download/public", "+google_apis", "+components/gcm_driver", "+components/ntp_snippets",
diff --git a/components/offline_pages/core/prefetch/generate_page_bundle_request.cc b/components/offline_pages/core/prefetch/generate_page_bundle_request.cc index 94f9155..3cb6b2b6 100644 --- a/components/offline_pages/core/prefetch/generate_page_bundle_request.cc +++ b/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
@@ -9,16 +9,13 @@ #include "base/logging.h" #include "components/offline_pages/core/prefetch/prefetch_proto_utils.h" #include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h" +#include "components/offline_pages/core/prefetch/prefetch_server_urls.h" #include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h" #include "net/url_request/url_request_context_getter.h" #include "url/gurl.h" namespace offline_pages { -namespace { -const char kGeneratePageBundleRequestURLPath[] = "v1:GeneratePageBundle"; -} // namespace - GeneratePageBundleRequest::GeneratePageBundleRequest( const std::string& user_agent, const std::string& gcm_registration_id, @@ -44,7 +41,7 @@ request.SerializeToString(&upload_data); fetcher_ = PrefetchRequestFetcher::CreateForPost( - kGeneratePageBundleRequestURLPath, upload_data, channel, + GeneratePageBundleRequestURL(channel), upload_data, request_context_getter, base::Bind(&GeneratePageBundleRequest::OnCompleted, // Fetcher is owned by this instance.
diff --git a/components/offline_pages/core/prefetch/get_operation_request.cc b/components/offline_pages/core/prefetch/get_operation_request.cc index 77d2cd2..a8541ce8 100644 --- a/components/offline_pages/core/prefetch/get_operation_request.cc +++ b/components/offline_pages/core/prefetch/get_operation_request.cc
@@ -9,25 +9,20 @@ #include "base/logging.h" #include "components/offline_pages/core/prefetch/prefetch_proto_utils.h" #include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h" +#include "components/offline_pages/core/prefetch/prefetch_server_urls.h" #include "net/url_request/url_request_context_getter.h" #include "url/gurl.h" namespace offline_pages { -namespace { -const char kGetOperationURLPath[] = "v1/"; -} // namespace - GetOperationRequest::GetOperationRequest( const std::string& name, version_info::Channel channel, net::URLRequestContextGetter* request_context_getter, const PrefetchRequestFinishedCallback& callback) : callback_(callback) { - std::string path(kGetOperationURLPath); - path += name; fetcher_ = PrefetchRequestFetcher::CreateForGet( - path, channel, request_context_getter, + GetOperationRequestURL(name, channel), request_context_getter, base::Bind(&GetOperationRequest::OnCompleted, // Fetcher is owned by this instance. base::Unretained(this)));
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader.cc b/components/offline_pages/core/prefetch/prefetch_downloader.cc new file mode 100644 index 0000000..8f03b67 --- /dev/null +++ b/components/offline_pages/core/prefetch/prefetch_downloader.cc
@@ -0,0 +1,113 @@ +// Copyright 2017 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 "components/offline_pages/core/prefetch/prefetch_downloader.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "components/download/public/download_service.h" +#include "components/offline_pages/core/prefetch/prefetch_server_urls.h" +#include "url/gurl.h" + +namespace offline_pages { + +PrefetchDownloader::PrefetchDownloader( + download::DownloadService* download_service, + version_info::Channel channel) + : download_service_(download_service), + channel_(channel), + weak_ptr_factory_(this) { + DCHECK(download_service); + service_started_ = download_service->GetStatus() == + download::DownloadService::ServiceStatus::READY; +} + +PrefetchDownloader::PrefetchDownloader(version_info::Channel channel) + : channel_(channel), weak_ptr_factory_(this) {} + +PrefetchDownloader::~PrefetchDownloader() = default; + +void PrefetchDownloader::SetCompletedCallback( + const PrefetchDownloadCompletedCallback& callback) { + callback_ = callback; +} + +void PrefetchDownloader::StartDownload(const std::string& download_id, + const std::string& download_location) { + if (!service_started_) { + pending_downloads_.push_back( + std::make_pair(download_id, download_location)); + return; + } + + // TODO(jianli): Specify scheduling parameters, i.e. battery, network and etc. + // http://crbug.com/736156 + download::DownloadParams params; + params.client = download::DownloadClient::OFFLINE_PAGE_PREFETCH; + // TODO(jianli): Remove the uppercase after the download service fixes + // this issue. + params.guid = base::ToUpperASCII(download_id); + params.callback = base::Bind(&PrefetchDownloader::OnStartDownload, + weak_ptr_factory_.GetWeakPtr()); + params.request_params.url = PrefetchDownloadURL(download_location, channel_); + download_service_->StartDownload(params); +} + +void PrefetchDownloader::CancelDownload(const std::string& download_id) { + if (service_started_) { + download_service_->CancelDownload(download_id); + return; + } + for (auto iter = pending_downloads_.begin(); iter != pending_downloads_.end(); + ++iter) { + if (iter->first == download_id) { + pending_downloads_.erase(iter); + return; + } + } + pending_cancellations_.push_back(download_id); +} + +void PrefetchDownloader::OnDownloadServiceReady() { + DCHECK_EQ(download::DownloadService::ServiceStatus::READY, + download_service_->GetStatus()); + service_started_ = true; + + for (const auto& entry : pending_downloads_) + StartDownload(entry.first, entry.second); + pending_downloads_.clear(); + + for (const auto& entry : pending_cancellations_) + download_service_->CancelDownload(entry); + pending_cancellations_.clear(); +} + +void PrefetchDownloader::OnDownloadServiceShutdown() { + service_started_ = false; +} + +void PrefetchDownloader::OnDownloadSucceeded(const std::string& download_id, + const base::FilePath& file_path, + uint64_t file_size) { + if (callback_) + callback_.Run(PrefetchDownloadResult(download_id, file_path, file_size)); +} + +void PrefetchDownloader::OnDownloadFailed(const std::string& download_id) { + if (callback_) { + PrefetchDownloadResult result; + result.download_id = download_id; + callback_.Run(result); + } +} + +void PrefetchDownloader::OnStartDownload( + const std::string& download_id, + download::DownloadParams::StartResult result) { + if (result != download::DownloadParams::StartResult::ACCEPTED) + OnDownloadFailed(download_id); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader.h b/components/offline_pages/core/prefetch/prefetch_downloader.h new file mode 100644 index 0000000..4dd0f24 --- /dev/null +++ b/components/offline_pages/core/prefetch/prefetch_downloader.h
@@ -0,0 +1,96 @@ +// Copyright 2017 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 COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DOWNLOADER_H_ +#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DOWNLOADER_H_ + +#include <string> +#include <utility> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/download/public/download_params.h" +#include "components/offline_pages/core/prefetch/prefetch_types.h" +#include "components/version_info/channel.h" + +namespace download { +class DownloadService; +} // namespace download + +namespace offline_pages { + +class PrefetchServiceTestTaco; + +// Asynchronously downloads the archive. +class PrefetchDownloader { + public: + PrefetchDownloader(download::DownloadService* download_service, + version_info::Channel channel); + ~PrefetchDownloader(); + + void SetCompletedCallback(const PrefetchDownloadCompletedCallback& callback); + + // Starts to download an archive from |download_location|. + void StartDownload(const std::string& download_id, + const std::string& download_location); + + // Cancels a previous scheduled download. + void CancelDownload(const std::string& download_id); + + // Responding to download client event. + + // Called when the download service is initialized and can accept the + // downloads. + void OnDownloadServiceReady(); + + // Called when the download service is tearing down. + void OnDownloadServiceShutdown(); + + // Called when a download is completed successfully. Note that the download + // can be scheduled in preious sessions. + void OnDownloadSucceeded(const std::string& download_id, + const base::FilePath& file_path, + uint64_t file_size); + + // Called when a download fails. + void OnDownloadFailed(const std::string& download_id); + + private: + friend class PrefetchServiceTestTaco; + + // For test only. + explicit PrefetchDownloader(version_info::Channel channel); + + // Callback for StartDownload. + void OnStartDownload(const std::string& download_id, + download::DownloadParams::StartResult result); + + // Unowned. It is valid until |this| instance is disposed. + download::DownloadService* download_service_; + + version_info::Channel channel_; + PrefetchDownloadCompletedCallback callback_; + + // Flag to indicate if the download service is ready to take downloads. + bool service_started_ = false; + + // TODO(jianli): Investigate making PrefetchService waits for DownloadService + // ready in order to avoid queueing. + // List of downloads pending to start after the download service starts. Each + // item is a pair of download id and download location. + std::vector<std::pair<std::string, std::string>> pending_downloads_; + // List of ids of downloads waiting to be cancelled after the download service + // starts. + std::vector<std::string> pending_cancellations_; + + base::WeakPtrFactory<PrefetchDownloader> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PrefetchDownloader); +}; + +} // namespace offline_pages + +#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DOWNLOADER_H_
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader_unittest.cc b/components/offline_pages/core/prefetch/prefetch_downloader_unittest.cc new file mode 100644 index 0000000..9823617 --- /dev/null +++ b/components/offline_pages/core/prefetch/prefetch_downloader_unittest.cc
@@ -0,0 +1,285 @@ +// Copyright 2017 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 "components/offline_pages/core/prefetch/prefetch_downloader.h" + +#include <list> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/download/public/download_service.h" +#include "components/download/public/service_config.h" +#include "components/offline_pages/core/prefetch/prefetch_service.h" +#include "components/offline_pages/core/prefetch/prefetch_service_test_taco.h" +#include "net/base/url_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +const version_info::Channel kTestChannel = version_info::Channel::UNKNOWN; +const char kDownloadId[] = "1234"; +const char kDownloadId2[] = "ABCD"; +const char kFailedDownloadId[] = "FFFFFF"; +const char kDownloadLocation[] = "page/1"; +const char kDownloadLocation2[] = "page/zz"; +const char kServerPathForDownload[] = "/v1/media/page/1"; +const uint64_t kTestFileSize = 12345678u; +} // namespace + +namespace download { +class TestServiceConfig : public ServiceConfig { + public: + TestServiceConfig() = default; + ~TestServiceConfig() override = default; + + uint32_t GetMaxScheduledDownloadsPerClient() const override { return 0; } + const base::TimeDelta& GetFileKeepAliveTime() const override { + return time_delta_; + } + + private: + base::TimeDelta time_delta_; +}; + +class TestDownloadService : public DownloadService { + public: + TestDownloadService() = default; + ~TestDownloadService() override = default; + + // DownloadService implementation. + const ServiceConfig& GetConfig() override { return service_config_; } + void OnStartScheduledTask(DownloadTaskType task_type, + const TaskFinishedCallback& callback) override {} + bool OnStopScheduledTask(DownloadTaskType task_type) override { return true; } + ServiceStatus GetStatus() override { + return ready_ ? DownloadService::ServiceStatus::READY + : DownloadService::ServiceStatus::STARTING_UP; + } + + void StartDownload(const DownloadParams& download_params) override { + if (!ready_) { + OnDownloadFailed(download_params.guid); + return; + } + downloads_.push_back(download_params); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&TestDownloadService::ProcessDownload, + base::Unretained(this))); + } + + void PauseDownload(const std::string& guid) override {} + void ResumeDownload(const std::string& guid) override {} + + void CancelDownload(const std::string& guid) override { + for (auto iter = downloads_.begin(); iter != downloads_.end(); ++iter) { + if (iter->guid == guid) { + downloads_.erase(iter); + return; + } + } + } + + void ChangeDownloadCriteria(const std::string& guid, + const SchedulingParams& params) override {} + + DownloadParams GetDownload(const std::string& guid) const { + for (auto iter = downloads_.begin(); iter != downloads_.end(); ++iter) { + if (iter->guid == guid) + return *iter; + } + return DownloadParams(); + } + + void set_ready(bool ready) { ready_ = ready; } + void set_prefetch_downloader( + offline_pages::PrefetchDownloader* prefetch_downloader) { + prefetch_downloader_ = prefetch_downloader; + } + + private: + void ProcessDownload() { + if (!ready_ || downloads_.empty()) + return; + DownloadParams params = downloads_.front(); + downloads_.pop_front(); + if (params.guid == kFailedDownloadId) + OnDownloadFailed(params.guid); + else + OnDownloadSucceeded(params.guid, base::FilePath(), kTestFileSize); + } + + void OnDownloadSucceeded(const std::string& guid, + const base::FilePath& file_path, + uint64_t file_size) { + if (prefetch_downloader_) + prefetch_downloader_->OnDownloadSucceeded(guid, file_path, file_size); + } + + void OnDownloadFailed(const std::string& guid) { + if (prefetch_downloader_) + prefetch_downloader_->OnDownloadFailed(guid); + } + + bool ready_ = false; + offline_pages::PrefetchDownloader* prefetch_downloader_ = nullptr; + TestServiceConfig service_config_; + std::list<DownloadParams> downloads_; + + DISALLOW_COPY_AND_ASSIGN(TestDownloadService); +}; +} // namespace download + +namespace offline_pages { + +class PrefetchDownloaderTest : public testing::Test { + public: + PrefetchDownloaderTest() + : task_runner_(new base::TestSimpleTaskRunner), + task_runner_handle_(task_runner_) {} + + void SetUp() override { + auto downloader = + base::MakeUnique<PrefetchDownloader>(&download_service_, kTestChannel); + download_service_.set_prefetch_downloader(downloader.get()); + prefetch_service_taco_.SetPrefetchDownloader(std::move(downloader)); + + prefetch_service_taco_.CreatePrefetchService(); + GetPrefetchDownloader()->SetCompletedCallback(base::Bind( + &PrefetchDownloaderTest::OnDownloadCompleted, base::Unretained(this))); + } + + void SetDownloadServiceReady(bool ready) { + download_service_.set_ready(ready); + if (ready) + GetPrefetchDownloader()->OnDownloadServiceReady(); + else + GetPrefetchDownloader()->OnDownloadServiceShutdown(); + } + + void StartDownload(const std::string& download_id, + const std::string& download_location) { + GetPrefetchDownloader()->StartDownload(download_id, download_location); + } + + void CancelDownload(const std::string& download_id) { + GetPrefetchDownloader()->CancelDownload(download_id); + } + + download::DownloadParams GetDownload(const std::string& guid) const { + return download_service_.GetDownload(guid); + } + + void PumpLoop() { task_runner_->RunUntilIdle(); } + + const std::vector<PrefetchDownloadResult>& completed_downloads() const { + return completed_downloads_; + } + + private: + void OnDownloadCompleted(const PrefetchDownloadResult& result) { + completed_downloads_.push_back(result); + } + + PrefetchDownloader* GetPrefetchDownloader() const { + return prefetch_service_taco_.prefetch_service()->GetPrefetchDownloader(); + } + + scoped_refptr<base::TestSimpleTaskRunner> task_runner_; + base::ThreadTaskRunnerHandle task_runner_handle_; + download::TestDownloadService download_service_; + PrefetchServiceTestTaco prefetch_service_taco_; + std::vector<PrefetchDownloadResult> completed_downloads_; +}; + +TEST_F(PrefetchDownloaderTest, DownloadParams) { + SetDownloadServiceReady(true); + StartDownload(kDownloadId, kDownloadLocation); + download::DownloadParams params = GetDownload(kDownloadId); + EXPECT_EQ(kDownloadId, params.guid); + EXPECT_EQ(download::DownloadClient::OFFLINE_PAGE_PREFETCH, params.client); + GURL download_url = params.request_params.url; + EXPECT_TRUE(download_url.SchemeIs(url::kHttpsScheme)); + EXPECT_EQ(kServerPathForDownload, download_url.path()); + std::string key_value; + EXPECT_TRUE(net::GetValueForKeyInQuery(download_url, "key", &key_value)); + EXPECT_FALSE(key_value.empty()); + std::string alt_value; + EXPECT_TRUE(net::GetValueForKeyInQuery(download_url, "alt", &alt_value)); + EXPECT_EQ("media", alt_value); +} + +TEST_F(PrefetchDownloaderTest, StartDownloadBeforeServiceReady) { + SetDownloadServiceReady(false); + StartDownload(kDownloadId, kDownloadLocation); + StartDownload(kDownloadId2, kDownloadLocation2); + PumpLoop(); + ASSERT_EQ(0u, completed_downloads().size()); + SetDownloadServiceReady(true); + PumpLoop(); + ASSERT_EQ(2u, completed_downloads().size()); + EXPECT_EQ(kDownloadId, completed_downloads()[0].download_id); + EXPECT_TRUE(completed_downloads()[0].success); + EXPECT_EQ(kDownloadId2, completed_downloads()[1].download_id); + EXPECT_TRUE(completed_downloads()[1].success); +} + +TEST_F(PrefetchDownloaderTest, StartDownloadAfterServiceReady) { + SetDownloadServiceReady(true); + StartDownload(kDownloadId, kDownloadLocation); + StartDownload(kDownloadId2, kDownloadLocation2); + PumpLoop(); + ASSERT_EQ(2u, completed_downloads().size()); + EXPECT_EQ(kDownloadId, completed_downloads()[0].download_id); + EXPECT_TRUE(completed_downloads()[0].success); + EXPECT_EQ(kDownloadId2, completed_downloads()[1].download_id); + EXPECT_TRUE(completed_downloads()[1].success); +} + +TEST_F(PrefetchDownloaderTest, DownloadFailed) { + SetDownloadServiceReady(true); + StartDownload(kFailedDownloadId, kDownloadLocation); + PumpLoop(); + ASSERT_EQ(1u, completed_downloads().size()); + EXPECT_EQ(kFailedDownloadId, completed_downloads()[0].download_id); + EXPECT_FALSE(completed_downloads()[0].success); +} + +TEST_F(PrefetchDownloaderTest, CancelPendingDownloadBeforeServiceReady) { + SetDownloadServiceReady(false); + StartDownload(kDownloadId, kDownloadLocation); + StartDownload(kDownloadId2, kDownloadLocation2); + PumpLoop(); + ASSERT_EQ(0u, completed_downloads().size()); + CancelDownload(kDownloadId); + SetDownloadServiceReady(true); + PumpLoop(); + ASSERT_EQ(1u, completed_downloads().size()); + EXPECT_EQ(kDownloadId2, completed_downloads()[0].download_id); + EXPECT_TRUE(completed_downloads()[0].success); +} + +TEST_F(PrefetchDownloaderTest, CancelStartedDownloadBeforeServiceReady) { + SetDownloadServiceReady(true); + StartDownload(kDownloadId, kDownloadLocation); + SetDownloadServiceReady(false); + CancelDownload(kDownloadId); + SetDownloadServiceReady(true); + PumpLoop(); + ASSERT_EQ(0u, completed_downloads().size()); +} + +TEST_F(PrefetchDownloaderTest, CancelDownloadAfterServiceReady) { + SetDownloadServiceReady(true); + StartDownload(kDownloadId, kDownloadLocation); + StartDownload(kDownloadId2, kDownloadLocation2); + CancelDownload(kDownloadId); + PumpLoop(); + ASSERT_EQ(1u, completed_downloads().size()); + EXPECT_EQ(kDownloadId2, completed_downloads()[0].download_id); + EXPECT_TRUE(completed_downloads()[0].success); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc b/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc index cda960a3..d533ab1 100644 --- a/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc +++ b/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "components/offline_pages/core/prefetch/prefetch_server_urls.h" #include "google_apis/google_api_keys.h" #include "net/base/load_flags.h" #include "net/base/url_util.h" @@ -21,57 +22,34 @@ namespace { -const char kPrefetchServer[] = "https://offlinepages-pa.googleapis.com/"; -const char kPrefetchStagingServer[] = - "https://staging-offlinepages-pa.sandbox.googleapis.com/"; - -// Used in all offline prefetch request URLs to specify API Key. -const char kApiKeyName[] = "key"; - // Content type needed in order to communicate with the server in binary // proto format. const char kRequestContentType[] = "application/x-protobuf"; -GURL CompleteURL(const std::string& url_path, version_info::Channel channel) { - bool is_stable_channel = channel == version_info::Channel::STABLE; - GURL server_url(is_stable_channel ? kPrefetchServer : kPrefetchStagingServer); - - GURL::Replacements replacements; - replacements.SetPathStr(url_path); - GURL url = server_url.ReplaceComponents(replacements); - - std::string api_key = is_stable_channel ? google_apis::GetAPIKey() - : google_apis::GetNonStableAPIKey(); - return net::AppendQueryParameter(url, kApiKeyName, api_key); -} - } // namespace // static std::unique_ptr<PrefetchRequestFetcher> PrefetchRequestFetcher::CreateForGet( - const std::string& url_path, - version_info::Channel channel, + const GURL& url, net::URLRequestContextGetter* request_context_getter, const FinishedCallback& callback) { return base::WrapUnique(new PrefetchRequestFetcher( - url_path, std::string(), channel, request_context_getter, callback)); + url, std::string(), request_context_getter, callback)); } // static std::unique_ptr<PrefetchRequestFetcher> PrefetchRequestFetcher::CreateForPost( - const std::string& url_path, + const GURL& url, const std::string& message, - version_info::Channel channel, net::URLRequestContextGetter* request_context_getter, const FinishedCallback& callback) { return base::WrapUnique(new PrefetchRequestFetcher( - url_path, message, channel, request_context_getter, callback)); + url, message, request_context_getter, callback)); } PrefetchRequestFetcher::PrefetchRequestFetcher( - const std::string& url_path, + const GURL& url, const std::string& message, - version_info::Channel channel, net::URLRequestContextGetter* request_context_getter, const FinishedCallback& callback) : request_context_getter_(request_context_getter), callback_(callback) { @@ -97,8 +75,7 @@ "Not implemented, considered not useful." })"); url_fetcher_ = net::URLFetcher::Create( - CompleteURL(url_path, channel), - message.empty() ? net::URLFetcher::GET : net::URLFetcher::POST, this, + url, message.empty() ? net::URLFetcher::GET : net::URLFetcher::POST, this, traffic_annotation); url_fetcher_->SetRequestContext(request_context_getter_.get()); url_fetcher_->SetAutomaticallyRetryOn5xx(false);
diff --git a/components/offline_pages/core/prefetch/prefetch_request_fetcher.h b/components/offline_pages/core/prefetch/prefetch_request_fetcher.h index ea3d7c1..4ac8640 100644 --- a/components/offline_pages/core/prefetch/prefetch_request_fetcher.h +++ b/components/offline_pages/core/prefetch/prefetch_request_fetcher.h
@@ -9,8 +9,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "components/offline_pages/core/prefetch/prefetch_types.h" -#include "components/version_info/channel.h" #include "net/url_request/url_fetcher_delegate.h" +#include "url/gurl.h" namespace net { class URLRequestContextGetter; @@ -26,16 +26,14 @@ // Creates a fetcher that will sends a GET request to the server. static std::unique_ptr<PrefetchRequestFetcher> CreateForGet( - const std::string& url_path, - version_info::Channel channel, + const GURL& url, net::URLRequestContextGetter* request_context_getter, const FinishedCallback& callback); // Creates a fetcher that will sends a POST request to the server. static std::unique_ptr<PrefetchRequestFetcher> CreateForPost( - const std::string& url_path, + const GURL& url, const std::string& message, - version_info::Channel channel, net::URLRequestContextGetter* request_context_getter, const FinishedCallback& callback); @@ -47,9 +45,8 @@ private: // If |message| is empty, the GET request is sent. Otherwise, the POST request // is sent with |message| as post data. - PrefetchRequestFetcher(const std::string& url_path, + PrefetchRequestFetcher(const GURL& url, const std::string& message, - version_info::Channel channel, net::URLRequestContextGetter* request_context_getter, const FinishedCallback& callback);
diff --git a/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc b/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc index 8464c3c..39b5d218 100644 --- a/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc +++ b/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc
@@ -20,8 +20,7 @@ namespace offline_pages { namespace { -const version_info::Channel kTestChannel = version_info::Channel::UNKNOWN; -const char kTestURLPath[] = "/test"; +const GURL kTestURL("http://exmaple.org"); const char kTestMessage[] = "Testing"; } // namespace @@ -73,9 +72,8 @@ std::string* data_received) { base::MockCallback<PrefetchRequestFetcher::FinishedCallback> callback; std::unique_ptr<PrefetchRequestFetcher> fetcher = - PrefetchRequestFetcher::CreateForPost(kTestURLPath, kTestMessage, - kTestChannel, request_context(), - callback.Get()); + PrefetchRequestFetcher::CreateForPost(kTestURL, kTestMessage, + request_context(), callback.Get()); PrefetchRequestStatus status; std::string data;
diff --git a/components/offline_pages/core/prefetch/prefetch_server_urls.cc b/components/offline_pages/core/prefetch/prefetch_server_urls.cc new file mode 100644 index 0000000..84135e6ba --- /dev/null +++ b/components/offline_pages/core/prefetch/prefetch_server_urls.cc
@@ -0,0 +1,71 @@ +// Copyright 2017 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 "components/offline_pages/core/prefetch/prefetch_server_urls.h" + +#include "google_apis/google_api_keys.h" +#include "net/base/url_util.h" + +namespace offline_pages { + +namespace { + +const char kPrefetchServer[] = "https://offlinepages-pa.googleapis.com/"; +const char kPrefetchStagingServer[] = + "https://staging-offlinepages-pa.sandbox.googleapis.com/"; + +const char kGeneratePageBundleRequestURLPath[] = "v1:GeneratePageBundle"; +const char kGetOperationLeadingURLPath[] = "v1/"; +const char kDownloadLeadingURLPath[] = "v1/media/"; + +// Used in all offline prefetch request URLs to specify API Key. +const char kApiKeyName[] = "key"; +// Needed to download as a file. +const char kAltKeyName[] = "alt"; +const char kAltKeyValueForDownload[] = "media"; + +GURL GetServerURLForPath(const std::string& url_path, + version_info::Channel channel) { + bool is_stable_channel = channel == version_info::Channel::STABLE; + GURL server_url(is_stable_channel ? kPrefetchServer : kPrefetchStagingServer); + + GURL::Replacements replacements; + replacements.SetPathStr(url_path); + return server_url.ReplaceComponents(replacements); +} + +GURL AppendApiKeyToURL(const GURL& url, version_info::Channel channel) { + bool is_stable_channel = channel == version_info::Channel::STABLE; + std::string api_key = is_stable_channel ? google_apis::GetAPIKey() + : google_apis::GetNonStableAPIKey(); + return net::AppendQueryParameter(url, kApiKeyName, api_key); +} + +} // namespace + +GURL GeneratePageBundleRequestURL(version_info::Channel channel) { + GURL server_url = + GetServerURLForPath(kGeneratePageBundleRequestURLPath, channel); + return AppendApiKeyToURL(server_url, channel); +} + +GURL GetOperationRequestURL(const std::string& name, + version_info::Channel channel) { + std::string url_path = kGetOperationLeadingURLPath + name; + GURL server_url = GetServerURLForPath(url_path, channel); + return AppendApiKeyToURL(server_url, channel); +} + +GURL PrefetchDownloadURL(const std::string& download_location, + version_info::Channel channel) { + std::string url_path = kDownloadLeadingURLPath + download_location; + GURL server_url = GetServerURLForPath(url_path, channel); + + server_url = net::AppendQueryParameter(server_url, kAltKeyName, + kAltKeyValueForDownload); + + return AppendApiKeyToURL(server_url, channel); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_server_urls.h b/components/offline_pages/core/prefetch/prefetch_server_urls.h new file mode 100644 index 0000000..626b4684 --- /dev/null +++ b/components/offline_pages/core/prefetch/prefetch_server_urls.h
@@ -0,0 +1,27 @@ +// Copyright 2017 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 COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVER_URLS_H_ +#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVER_URLS_H_ + +#include <string> +#include "components/version_info/channel.h" +#include "url/gurl.h" + +namespace offline_pages { + +// Returns the URL to send a request to generate page bundle. +GURL GeneratePageBundleRequestURL(version_info::Channel channel); + +// Returns the URL to send a request to get operation info. +GURL GetOperationRequestURL(const std::string& name, + version_info::Channel channel); + +// Returns the URL to download an archive. +GURL PrefetchDownloadURL(const std::string& download_location, + version_info::Channel channel); + +} // namespace offline_pages + +#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVER_URLS_H_
diff --git a/components/offline_pages/core/prefetch/prefetch_service.h b/components/offline_pages/core/prefetch/prefetch_service.h index a168a1d..10e7105 100644 --- a/components/offline_pages/core/prefetch/prefetch_service.h +++ b/components/offline_pages/core/prefetch/prefetch_service.h
@@ -11,6 +11,7 @@ class OfflineEventLogger; class OfflineMetricsCollector; class PrefetchDispatcher; +class PrefetchDownloader; class PrefetchGCMHandler; class PrefetchNetworkRequestFactory; class SuggestedArticlesObserver; @@ -31,6 +32,7 @@ virtual PrefetchDispatcher* GetPrefetchDispatcher() = 0; virtual PrefetchGCMHandler* GetPrefetchGCMHandler() = 0; virtual PrefetchNetworkRequestFactory* GetPrefetchNetworkRequestFactory() = 0; + virtual PrefetchDownloader* GetPrefetchDownloader() = 0; // May be |nullptr| in tests. The PrefetchService does not depend on the // SuggestedArticlesObserver, it merely owns it for lifetime purposes.
diff --git a/components/offline_pages/core/prefetch/prefetch_service_impl.cc b/components/offline_pages/core/prefetch/prefetch_service_impl.cc index 2c07a03..478d4109 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_impl.cc +++ b/components/offline_pages/core/prefetch/prefetch_service_impl.cc
@@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "components/offline_pages/core/prefetch/offline_metrics_collector.h" #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h" +#include "components/offline_pages/core/prefetch/prefetch_downloader.h" #include "components/offline_pages/core/prefetch/prefetch_gcm_handler.h" #include "components/offline_pages/core/prefetch/prefetch_network_request_factory.h" #include "components/offline_pages/core/prefetch/suggested_articles_observer.h" @@ -21,15 +22,19 @@ std::unique_ptr<PrefetchDispatcher> dispatcher, std::unique_ptr<PrefetchGCMHandler> gcm_handler, std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory, - std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer) + std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer, + std::unique_ptr<PrefetchDownloader> prefetch_downloader) : offline_metrics_collector_(std::move(offline_metrics_collector)), prefetch_dispatcher_(std::move(dispatcher)), prefetch_gcm_handler_(std::move(gcm_handler)), network_request_factory_(std::move(network_request_factory)), - suggested_articles_observer_(std::move(suggested_articles_observer)) { + suggested_articles_observer_(std::move(suggested_articles_observer)), + prefetch_downloader_(std::move(prefetch_downloader)) { prefetch_dispatcher_->SetService(this); prefetch_gcm_handler_->SetService(this); suggested_articles_observer_->SetPrefetchService(this); + prefetch_downloader_->SetCompletedCallback(base::Bind( + &PrefetchServiceImpl::OnDownloadCompleted, base::Unretained(this))); } PrefetchServiceImpl::~PrefetchServiceImpl() = default; @@ -59,8 +64,23 @@ return &logger_; } +PrefetchDownloader* PrefetchServiceImpl::GetPrefetchDownloader() { + return prefetch_downloader_.get(); +} + void PrefetchServiceImpl::Shutdown() { suggested_articles_observer_.reset(); + prefetch_downloader_.reset(); +} + +void PrefetchServiceImpl::OnDownloadCompleted( + const PrefetchDownloadResult& result) { + logger_.RecordActivity("Download " + result.download_id + + (result.success ? " succeeded" : " failed")); + if (result.success) { + logger_.RecordActivity("Downloaded as " + result.file_path.MaybeAsASCII() + + " with size " + std::to_string(result.file_size)); + } } } // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_service_impl.h b/components/offline_pages/core/prefetch/prefetch_service_impl.h index ed1b629..98e5d61 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_impl.h +++ b/components/offline_pages/core/prefetch/prefetch_service_impl.h
@@ -10,10 +10,12 @@ #include "base/macros.h" #include "components/offline_pages/core/offline_event_logger.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" +#include "components/offline_pages/core/prefetch/prefetch_types.h" namespace offline_pages { class OfflineMetricsCollector; class PrefetchDispatcher; +class PrefetchDownloader; class PrefetchGCMHandler; class PrefetchNetworkRequestFactory; class SuggestedArticlesObserver; @@ -25,7 +27,8 @@ std::unique_ptr<PrefetchDispatcher> dispatcher, std::unique_ptr<PrefetchGCMHandler> gcm_handler, std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory, - std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer); + std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer, + std::unique_ptr<PrefetchDownloader> prefetch_downloader); ~PrefetchServiceImpl() override; // PrefetchService implementation: @@ -35,11 +38,15 @@ PrefetchNetworkRequestFactory* GetPrefetchNetworkRequestFactory() override; SuggestedArticlesObserver* GetSuggestedArticlesObserver() override; OfflineEventLogger* GetLogger() override; + PrefetchDownloader* GetPrefetchDownloader() override; // KeyedService implementation: void Shutdown() override; private: + // Called when a download completes. + void OnDownloadCompleted(const PrefetchDownloadResult& result); + OfflineEventLogger logger_; std::unique_ptr<OfflineMetricsCollector> offline_metrics_collector_; @@ -47,6 +54,7 @@ std::unique_ptr<PrefetchGCMHandler> prefetch_gcm_handler_; std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory_; std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer_; + std::unique_ptr<PrefetchDownloader> prefetch_downloader_; DISALLOW_COPY_AND_ASSIGN(PrefetchServiceImpl); };
diff --git a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc index f16cd86..d18c8b9 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc +++ b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
@@ -10,6 +10,7 @@ #include "base/test/test_simple_task_runner.h" #include "components/offline_pages/core/prefetch/offline_metrics_collector.h" #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h" +#include "components/offline_pages/core/prefetch/prefetch_downloader.h" #include "components/offline_pages/core/prefetch/prefetch_gcm_handler.h" #include "components/offline_pages/core/prefetch/prefetch_service_impl.h" #include "components/offline_pages/core/prefetch/suggested_articles_observer.h" @@ -20,6 +21,10 @@ namespace offline_pages { +namespace { +const version_info::Channel kTestChannel = version_info::Channel::UNKNOWN; +} // namespace + PrefetchServiceTestTaco::PrefetchServiceTestTaco() { metrics_collector_ = base::MakeUnique<TestOfflineMetricsCollector>(); dispatcher_ = base::MakeUnique<TestPrefetchDispatcher>(); @@ -28,6 +33,7 @@ base::MakeUnique<TestPrefetchNetworkRequestFactory>(); suggested_articles_observer_ = base::MakeUnique<SuggestedArticlesObserver>(); + prefetch_downloader_ = base::WrapUnique(new PrefetchDownloader(kTestChannel)); // This sets up the testing articles as an empty vector, we can ignore the // result here. This allows us to not create a ContentSuggestionsService. suggested_articles_observer_->GetTestingArticles(); @@ -65,13 +71,20 @@ suggested_articles_observer_ = std::move(suggested_articles_observer); } +void PrefetchServiceTestTaco::SetPrefetchDownloader( + std::unique_ptr<PrefetchDownloader> prefetch_downloader) { + CHECK(!prefetch_service_); + prefetch_downloader_ = std::move(prefetch_downloader); +} + void PrefetchServiceTestTaco::CreatePrefetchService() { CHECK(metrics_collector_ && dispatcher_ && gcm_handler_ && - suggested_articles_observer_ && network_request_factory_); + suggested_articles_observer_ && network_request_factory_ && + prefetch_downloader_); prefetch_service_ = base::MakeUnique<PrefetchServiceImpl>( std::move(metrics_collector_), std::move(dispatcher_), std::move(gcm_handler_), std::move(network_request_factory_), - std::move(suggested_articles_observer_)); + std::move(suggested_articles_observer_), std::move(prefetch_downloader_)); } std::unique_ptr<PrefetchService>
diff --git a/components/offline_pages/core/prefetch/prefetch_service_test_taco.h b/components/offline_pages/core/prefetch/prefetch_service_test_taco.h index 4b7668e3..aa56544 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_test_taco.h +++ b/components/offline_pages/core/prefetch/prefetch_service_test_taco.h
@@ -14,6 +14,7 @@ namespace offline_pages { class OfflineMetricsCollector; class PrefetchDispatcher; +class PrefetchDownloader; class PrefetchGCMHandler; class PrefetchService; class PrefetchNetworkRequestFactory; @@ -46,6 +47,8 @@ // by default, so no ContentSuggestionsService is required.. void SetSuggestedArticlesObserver( std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer); + void SetPrefetchDownloader( + std::unique_ptr<PrefetchDownloader> prefetch_downloader); // Creates and caches an instance of PrefetchService, using default or // overridden test dependencies. @@ -53,7 +56,7 @@ // Once CreatePrefetchService() is called, this accessor method starts // returning the PrefetchService. - PrefetchService* prefetch_service() { + PrefetchService* prefetch_service() const { CHECK(prefetch_service_); return prefetch_service_.get(); } @@ -68,6 +71,7 @@ std::unique_ptr<PrefetchGCMHandler> gcm_handler_; std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory_; std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer_; + std::unique_ptr<PrefetchDownloader> prefetch_downloader_; std::unique_ptr<PrefetchService> prefetch_service_; };
diff --git a/components/offline_pages/core/prefetch/prefetch_types.cc b/components/offline_pages/core/prefetch/prefetch_types.cc index 8f06ddd..7f68f57 100644 --- a/components/offline_pages/core/prefetch/prefetch_types.cc +++ b/components/offline_pages/core/prefetch/prefetch_types.cc
@@ -6,8 +6,21 @@ namespace offline_pages { -RenderPageInfo::RenderPageInfo() {} +RenderPageInfo::RenderPageInfo() = default; RenderPageInfo::RenderPageInfo(const RenderPageInfo& other) = default; +PrefetchDownloadResult::PrefetchDownloadResult() = default; + +PrefetchDownloadResult::PrefetchDownloadResult(const std::string& download_id, + const base::FilePath& file_path, + uint64_t file_size) + : download_id(download_id), + success(true), + file_path(file_path), + file_size(file_size) {} + +PrefetchDownloadResult::PrefetchDownloadResult( + const PrefetchDownloadResult& other) = default; + } // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_types.h b/components/offline_pages/core/prefetch/prefetch_types.h index 20d9abea..1fdb49a 100644 --- a/components/offline_pages/core/prefetch/prefetch_types.h +++ b/components/offline_pages/core/prefetch/prefetch_types.h
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/files/file_path.h" #include "base/time/time.h" #include "components/offline_pages/core/client_id.h" #include "url/gurl.h" @@ -123,6 +124,24 @@ GURL url; }; +// Result of a completed download. +struct PrefetchDownloadResult { + PrefetchDownloadResult(); + PrefetchDownloadResult(const std::string& download_id, + const base::FilePath& file_path, + uint64_t file_size); + PrefetchDownloadResult(const PrefetchDownloadResult& other); + + std::string download_id; + bool success = false; + base::FilePath file_path; + uint64_t file_size = 0u; +}; + +// Callback invoked upon completion of a download. +using PrefetchDownloadCompletedCallback = + base::Callback<void(const PrefetchDownloadResult& result)>; + } // namespace offline_pages #endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_TYPES_H_
diff --git a/components/security_interstitials/core/browser/resources/list_of_interstitials.html b/components/security_interstitials/core/browser/resources/list_of_interstitials.html index a759c82..9f53597 100644 --- a/components/security_interstitials/core/browser/resources/list_of_interstitials.html +++ b/components/security_interstitials/core/browser/resources/list_of_interstitials.html
@@ -40,6 +40,9 @@ <li> <a href="clock?clock_manipulation=-2">Clock is behind</a> </li> + <li> + <a href="ssl?type=hpkp_failure">Pinned certificate error</a> + </li> </ul> <h3>SafeBrowsing</h3> <h4>Loud</h4>
diff --git a/components/test/data/web_database/version_73_with_type_column.sql b/components/test/data/web_database/version_73_with_type_column.sql new file mode 100644 index 0000000..5da24ee --- /dev/null +++ b/components/test/data/web_database/version_73_with_type_column.sql
@@ -0,0 +1,25 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); +INSERT INTO "meta" VALUES('mmap_status','-1'); +INSERT INTO "meta" VALUES('version','73'); +INSERT INTO "meta" VALUES('last_compatible_version','72'); +CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); +CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR,search_terms_replacement_key VARCHAR,image_url VARCHAR,search_url_post_params VARCHAR,suggest_url_post_params VARCHAR,instant_url_post_params VARCHAR,image_url_post_params VARCHAR,new_tab_url VARCHAR, last_visited INTEGER DEFAULT 0); +CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, date_created INTEGER DEFAULT 0, date_last_used INTEGER DEFAULT 0, count INTEGER DEFAULT 1, PRIMARY KEY (name, value)); +CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0, origin VARCHAR DEFAULT '', use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, billing_address_id VARCHAR); +CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, street_address VARCHAR, dependent_locality VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, sorting_code VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0, origin VARCHAR DEFAULT '', language_code VARCHAR, use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0); +CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, full_name VARCHAR); +CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); +CREATE TABLE autofill_profile_phones ( guid VARCHAR, number VARCHAR); +CREATE TABLE autofill_profiles_trash ( guid VARCHAR); +CREATE TABLE masked_credit_cards (id VARCHAR,status VARCHAR,name_on_card VARCHAR,network VARCHAR,last_four VARCHAR,exp_month INTEGER DEFAULT 0,exp_year INTEGER DEFAULT 0, type INTEGER DEFAULT 0); +CREATE TABLE unmasked_credit_cards (id VARCHAR,card_number_encrypted VARCHAR, use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, unmask_date INTEGER NOT NULL DEFAULT 0); +CREATE TABLE server_card_metadata (id VARCHAR NOT NULL,use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, billing_address_id VARCHAR); +CREATE TABLE server_addresses (id VARCHAR,company_name VARCHAR,street_address VARCHAR,address_1 VARCHAR,address_2 VARCHAR,address_3 VARCHAR,address_4 VARCHAR,postal_code VARCHAR,sorting_code VARCHAR,country_code VARCHAR,language_code VARCHAR, recipient_name VARCHAR, phone_number VARCHAR); +CREATE TABLE server_address_metadata (id VARCHAR NOT NULL,use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, has_converted BOOL NOT NULL DEFAULT FALSE); +CREATE TABLE autofill_sync_metadata (storage_key VARCHAR PRIMARY KEY NOT NULL,value BLOB); +CREATE TABLE autofill_model_type_state (id INTEGER PRIMARY KEY, value BLOB); +CREATE INDEX autofill_name ON autofill (name); +CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); +COMMIT;
diff --git a/components/translate/content/renderer/BUILD.gn b/components/translate/content/renderer/BUILD.gn index 17ab7fa..773039fa0 100644 --- a/components/translate/content/renderer/BUILD.gn +++ b/components/translate/content/renderer/BUILD.gn
@@ -24,3 +24,15 @@ "//v8", ] } + +source_set("unit_tests") { + testonly = true + sources = [ + "translate_helper_unittest.cc", + ] + deps = [ + ":renderer", + "//base", + "//testing/gtest", + ] +}
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc index f1b8ce4..14251b6b 100644 --- a/components/translate/content/renderer/translate_helper.cc +++ b/components/translate/content/renderer/translate_helper.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" +#include "base/json/string_escape.h" #include "base/location.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -167,12 +168,8 @@ } bool TranslateHelper::StartTranslation() { - std::string script = "cr.googleTranslate.translate('" + - source_lang_ + - "','" + - target_lang_ + - "')"; - return ExecuteScriptAndGetBoolResult(script, false); + return ExecuteScriptAndGetBoolResult( + BuildTranslationScript(source_lang_, target_lang_), false); } std::string TranslateHelper::GetOriginalPageLanguage() { @@ -430,4 +427,13 @@ delete this; } +/* static */ +std::string TranslateHelper::BuildTranslationScript( + const std::string& source_lang, + const std::string& target_lang) { + return "cr.googleTranslate.translate(" + + base::GetQuotedJSONString(source_lang) + "," + + base::GetQuotedJSONString(target_lang) + ")"; +} + } // namespace translate
diff --git a/components/translate/content/renderer/translate_helper.h b/components/translate/content/renderer/translate_helper.h index 622e718..58f2c88 100644 --- a/components/translate/content/renderer/translate_helper.h +++ b/components/translate/content/renderer/translate_helper.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" @@ -99,9 +100,16 @@ virtual double ExecuteScriptAndGetDoubleResult(const std::string& script); private: + FRIEND_TEST_ALL_PREFIXES(TranslateHelperTest, TestBuildTranslationScript); + // Converts language code to the one used in server supporting list. static void ConvertLanguageCodeSynonym(std::string* code); + // Builds the translation JS used to translate from source_lang to + // target_lang. + static std::string BuildTranslationScript(const std::string& source_lang, + const std::string& target_lang); + const mojom::ContentTranslateDriverPtr& GetTranslateDriver(); // Cleanups all states and pending callbacks associated with the current
diff --git a/components/translate/content/renderer/translate_helper_unittest.cc b/components/translate/content/renderer/translate_helper_unittest.cc new file mode 100644 index 0000000..f62df230 --- /dev/null +++ b/components/translate/content/renderer/translate_helper_unittest.cc
@@ -0,0 +1,29 @@ +// Copyright 2017 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 "components/translate/content/renderer/translate_helper.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace translate { + +class TranslateHelperTest : public testing::Test {}; + +TEST_F(TranslateHelperTest, TestBuildTranslationScript) { + // Test expected cases. + EXPECT_EQ(TranslateHelper::BuildTranslationScript("en", "es"), + "cr.googleTranslate.translate(\"en\",\"es\")"); + EXPECT_EQ(TranslateHelper::BuildTranslationScript("en-US", "zh-TW"), + "cr.googleTranslate.translate(\"en-US\",\"zh-TW\")"); + + // Test that quote gets quoted. + EXPECT_EQ(TranslateHelper::BuildTranslationScript("en\"", "es"), + "cr.googleTranslate.translate(\"en\\\"\",\"es\")"); + + // Test that < gets quoted. + EXPECT_EQ(TranslateHelper::BuildTranslationScript("en<", "es"), + "cr.googleTranslate.translate(\"en\\u003C\",\"es\")"); +} + +} // namespace translate
diff --git a/components/translate/core/browser/translate_browser_metrics.h b/components/translate/core/browser/translate_browser_metrics.h index c83c6bb9..e15759a 100644 --- a/components/translate/core/browser/translate_browser_metrics.h +++ b/components/translate/core/browser/translate_browser_metrics.h
@@ -42,6 +42,8 @@ INITIATION_STATUS_DISABLED_BY_KEY, INITIATION_STATUS_LANGUAGE_IN_ULP, INITIATION_STATUS_ABORTED_BY_RANKER, + INITIATION_STATUS_ABORTED_BY_TOO_OFTEN_DENIED, + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE, // Insert new items here. INITIATION_STATUS_MAX, };
diff --git a/components/translate/core/browser/translate_browser_metrics_unittest.cc b/components/translate/core/browser/translate_browser_metrics_unittest.cc index 283dfd5..b5bfc35 100644 --- a/components/translate/core/browser/translate_browser_metrics_unittest.cc +++ b/components/translate/core/browser/translate_browser_metrics_unittest.cc
@@ -29,17 +29,22 @@ base_samples_ = histogram->SnapshotSamples(); } - void CheckInitiationStatus(int expected_disabled_by_prefs, - int expected_disabled_by_config, - int expected_disabled_by_build, - int expected_language_is_not_supported, - int expected_mime_type_is_not_supported, - int expected_url_is_not_supported, - int expected_similar_languages, - int expected_accept_languages, - int expected_auto_by_config, - int expected_auto_by_link, - int expected_show_infobar) { + void CheckInitiationStatus( + int expected_disabled_by_prefs, + int expected_disabled_by_config, + int expected_disabled_by_build, + int expected_language_is_not_supported, + int expected_mime_type_is_not_supported, + int expected_url_is_not_supported, + int expected_similar_languages, + int expected_accept_languages, + int expected_auto_by_config, + int expected_auto_by_link, + int expected_show_infobar, + int expected_language_in_ulp, + int expected_aborted_by_ranker, + int expected_aborted_by_too_often_denied, + int expected_aborted_by_matches_previous_language) { Snapshot(); EXPECT_EQ(expected_disabled_by_prefs, @@ -80,6 +85,20 @@ EXPECT_EQ(expected_show_infobar, GetCountWithoutSnapshot(translate::TranslateBrowserMetrics:: INITIATION_STATUS_SHOW_INFOBAR)); + EXPECT_EQ(expected_language_in_ulp, + GetCountWithoutSnapshot(translate::TranslateBrowserMetrics:: + INITIATION_STATUS_LANGUAGE_IN_ULP)); + EXPECT_EQ(expected_aborted_by_ranker, + GetCountWithoutSnapshot(translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_RANKER)); + EXPECT_EQ(expected_aborted_by_too_often_denied, + GetCountWithoutSnapshot( + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_TOO_OFTEN_DENIED)); + EXPECT_EQ(expected_aborted_by_matches_previous_language, + GetCountWithoutSnapshot( + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE)); } HistogramBase::Count GetTotalCount() { @@ -127,43 +146,57 @@ MetricsRecorder recorder(translate::TranslateBrowserMetrics::GetMetricsName( translate::TranslateBrowserMetrics::UMA_INITIATION_STATUS)); - recorder.CheckInitiationStatus(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS); - recorder.CheckInitiationStatus(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG); - recorder.CheckInitiationStatus(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_KEY); - recorder.CheckInitiationStatus(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics:: INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED); - recorder.CheckInitiationStatus(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics:: INITIATION_STATUS_MIME_TYPE_IS_NOT_SUPPORTED); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics:: INITIATION_STATUS_URL_IS_NOT_SUPPORTED); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_ACCEPT_LANGUAGES); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0); translate::TranslateBrowserMetrics::ReportInitiationStatus( translate::TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); - recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0); + translate::TranslateBrowserMetrics::ReportInitiationStatus( + translate::TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IN_ULP); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0); + translate::TranslateBrowserMetrics::ReportInitiationStatus( + translate::TranslateBrowserMetrics::INITIATION_STATUS_ABORTED_BY_RANKER); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0); + translate::TranslateBrowserMetrics::ReportInitiationStatus( + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_TOO_OFTEN_DENIED); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0); + translate::TranslateBrowserMetrics::ReportInitiationStatus( + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE); + recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); } TEST(TranslateBrowserMetricsTest, ReportLanguageDetectionError) {
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index 06812c57..538b3215 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -595,6 +595,9 @@ !language_state_.HasLanguageChanged() && !ShouldOverrideDecision( metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE)) { + TranslateBrowserMetrics::ReportInitiationStatus( + TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE); return true; } @@ -605,6 +608,8 @@ source_language) && !ShouldOverrideDecision( metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_AUTO_BLACKLIST)) { + TranslateBrowserMetrics::ReportInitiationStatus( + TranslateBrowserMetrics::INITIATION_STATUS_ABORTED_BY_TOO_OFTEN_DENIED); return true; }
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc index 5e6537f1..83970f1f 100644 --- a/components/translate/core/browser/translate_manager_unittest.cc +++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -39,6 +39,7 @@ namespace { const char kTrialName[] = "MyTrial"; +const char kInitiationStatusName[] = "Translate.InitiationStatus.v2"; // Overrides NetworkChangeNotifier, simulating connection type changes // for tests. @@ -299,7 +300,6 @@ // The test measures that the "Translate was disabled" exit can only be // reached after the early-out tests including IsOffline() passed. - const char kMetricName[] = "Translate.InitiationStatus.v2"; base::HistogramTester histogram_tester; prefs_.SetBoolean(prefs::kEnableTranslate, false); @@ -310,13 +310,13 @@ // key test. network_notifier_.SimulateOffline(); translate_manager_->InitiateTranslation("de"); - histogram_tester.ExpectTotalCount(kMetricName, 0); + histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); // In the online case, InitiateTranslation will proceed past early out tests. network_notifier_.SimulateOnline(); translate_manager_->InitiateTranslation("de"); histogram_tester.ExpectUniqueSample( - kMetricName, + kInitiationStatusName, translate::TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS, 1); } @@ -505,8 +505,10 @@ TEST_F(TranslateManagerTest, ShouldSuppressBubbleUI_Default) { PrepareTranslateManager(); SetHasLanguageChanged(true); + base::HistogramTester histogram_tester; EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(false, "en")); EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(true, "en")); + histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); } TEST_F(TranslateManagerTest, ShouldSuppressBubbleUI_HasLanguageChangedFalse) { @@ -517,20 +519,33 @@ ShouldOverrideDecision( metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE, _, _)) .WillOnce(Return(false)); + base::HistogramTester histogram_tester; EXPECT_TRUE(translate_manager_->ShouldSuppressBubbleUI(false, "en")); + histogram_tester.ExpectUniqueSample( + kInitiationStatusName, + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE, + 1); EXPECT_CALL(mock_translate_ranker_, ShouldOverrideDecision(_, _, _)) .WillOnce(Return(false)); EXPECT_TRUE(translate_manager_->ShouldSuppressBubbleUI(true, "en")); + histogram_tester.ExpectUniqueSample( + kInitiationStatusName, + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_MATCHES_PREVIOUS_LANGUAGE, + 2); } TEST_F(TranslateManagerTest, ShouldSuppressBubbleUI_NewUI) { PrepareTranslateManager(); base::test::ScopedFeatureList scoped_feature_list; + base::HistogramTester histogram_tester; scoped_feature_list.InitAndEnableFeature(translate::kTranslateUI2016Q2); SetHasLanguageChanged(false); EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(false, "en")); + histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); } TEST_F(TranslateManagerTest, ShouldSuppressBubbleUI_IsTooOftenDenied) { @@ -543,13 +558,20 @@ metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_AUTO_BLACKLIST, _, _)) .WillOnce(Return(false)); + base::HistogramTester histogram_tester; EXPECT_TRUE(translate_manager_->ShouldSuppressBubbleUI(false, "en")); EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(false, "de")); EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(true, "en")); + histogram_tester.ExpectUniqueSample( + kInitiationStatusName, + translate::TranslateBrowserMetrics:: + INITIATION_STATUS_ABORTED_BY_TOO_OFTEN_DENIED, + 1); } TEST_F(TranslateManagerTest, ShouldSuppressBubbleUI_Override) { PrepareTranslateManager(); + base::HistogramTester histogram_tester; EXPECT_CALL( mock_translate_ranker_, ShouldOverrideDecision( @@ -564,6 +586,7 @@ SetHasLanguageChanged(false); SetLanguageTooOftenDenied("en"); EXPECT_FALSE(translate_manager_->ShouldSuppressBubbleUI(false, "en")); + histogram_tester.ExpectTotalCount(kInitiationStatusName, 0); } } // namespace testing
diff --git a/components/webdata/common/BUILD.gn b/components/webdata/common/BUILD.gn index 7a11220..921d444 100644 --- a/components/webdata/common/BUILD.gn +++ b/components/webdata/common/BUILD.gn
@@ -60,6 +60,7 @@ "//components/test/data/web_database/version_71.sql", "//components/test/data/web_database/version_72.sql", "//components/test/data/web_database/version_73.sql", + "//components/test/data/web_database/version_73_with_type_column.sql", ] outputs = [ "{{bundle_resources_dir}}/" +
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc index 8c6a30f5..a119b444 100644 --- a/components/webdata/common/web_database_migration_unittest.cc +++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -1359,3 +1359,52 @@ EXPECT_EQ(CreditCard::CARD_TYPE_UNKNOWN, cards.ColumnInt(2)); } } + +// Tests that version 73 with "type" column instead of "bank_name" column can be +// migrated to version 74 with both of these columns. This is necessary to +// verify that the version 73 collision resolves itself. +TEST_F(WebDatabaseMigrationTest, MigrateVersion73WithTypeColumnToCurrent) { + ASSERT_NO_FATAL_FAILURE( + LoadDatabase(FILE_PATH_LITERAL("version_73_with_type_column.sql"))); + + // Verify pre-conditions. + { + sql::Connection connection; + ASSERT_TRUE(connection.Open(GetDatabasePath())); + ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); + + sql::MetaTable meta_table; + ASSERT_TRUE(meta_table.Init(&connection, 73, 73)); + + EXPECT_FALSE( + connection.DoesColumnExist("masked_credit_cards", "bank_name")); + EXPECT_TRUE(connection.DoesColumnExist("masked_credit_cards", "type")); + + EXPECT_TRUE(connection.Execute( + "INSERT INTO masked_credit_cards (type) VALUES (2)")); + } + + DoMigration(); + + // Verify post-conditions. + { + sql::Connection connection; + ASSERT_TRUE(connection.Open(GetDatabasePath())); + ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); + + // Check version. + EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); + + // The bank_name column should exist. + EXPECT_TRUE(connection.DoesColumnExist("masked_credit_cards", "bank_name")); + + // The type column should exist. + EXPECT_TRUE(connection.DoesColumnExist("masked_credit_cards", "type")); + + // Make sure that the existing value of the type column is preserved. + sql::Statement s_masked_cards( + connection.GetUniqueStatement("SELECT type FROM masked_credit_cards")); + ASSERT_TRUE(s_masked_cards.Step()); + EXPECT_EQ(2, s_masked_cards.ColumnInt(0)); + } +}
diff --git a/content/app/strings/content_strings.grd b/content/app/strings/content_strings.grd index 8b521fc..bed0ca1 100644 --- a/content/app/strings/content_strings.grd +++ b/content/app/strings/content_strings.grd
@@ -171,24 +171,12 @@ <message name="IDS_DOWNLOAD_BUTTON_LABEL" desc="Clickable button label to download media file."> Save </message> - <message name="IDS_SEARCHABLE_INDEX_INTRO" desc="Text that appears at the start of nearly-obsolete webpages in the form of a 'searchable index'."> - This is a searchable index. Enter search keywords: ''' - </message> <message name="IDS_FORM_CALENDAR_CLEAR" desc="Label for a button which clears a date input field."> Clear </message> <message name="IDS_FORM_CALENDAR_TODAY" desc="Label for a button which sets today to a date input field."> Today </message> - <message name="IDS_FORM_DATE_FORMAT_DAY_IN_MONTH" desc="Short word to indicate which is the day-in-month part in a date format. e.g. 'Day' in 'Month/Day/Year'"> - Day - </message> - <message name="IDS_FORM_DATE_FORMAT_MONTH" desc="Short word to indicate which is the month part in a date format. e.g. 'Month' in 'Month/Day/Year'"> - Month - </message> - <message name="IDS_FORM_DATE_FORMAT_YEAR" desc="Short word to indicate which is the year part in a date format. e.g. 'Year' in 'Month/Day/Year'"> - Year - </message> <message name="IDS_FORM_SUBMIT_LABEL" desc="Default label for Submit buttons in forms on webpages."> Submit </message> @@ -219,9 +207,6 @@ <message name="IDS_FORM_OTHER_MONTH_LABEL" desc="Label for button that opens a full month picker so the user can choose dates other than the ones in the list." meaning="for month label"> Other... </message> - <message name="IDS_FORM_OTHER_TIME_LABEL" desc="Label for button that opens a full time picker so the user can choose dates other than the ones in the list." meaning="for time label"> - Other... - </message> <message name="IDS_FORM_OTHER_WEEK_LABEL" desc="Label for button that opens a full week picker so the user can choose dates other than the ones in the list." meaning="for week label"> Other... </message> @@ -247,16 +232,6 @@ Week </message> - <message name="IDS_RECENT_SEARCHES_NONE" desc="Label for only item in menu that appears when clicking on the search field image, when no searches have been performed"> - No recent searches - </message> - <message name="IDS_RECENT_SEARCHES" desc="label for first item in the menu that appears when clicking on the search field image, used as embedded menu title"> - Recent Searches - </message> - <message name="IDS_RECENT_SEARCHES_CLEAR" desc="menu item in Recent Searches menu that empties menu's contents"> - Clear Recent Searches - </message> - <message name="IDS_AX_CALENDAR_SHOW_MONTH_SELECTOR" desc="Accessible description of a button to show month selection panel in a calendar picker."> Show month selection panel </message> @@ -320,15 +295,9 @@ <message name="IDS_AX_ROLE_HEADING" desc="Accessibility role description for headings"> heading </message> - <message name="IDS_AX_ROLE_IMAGE_MAP" desc="Accessibility role description for image map"> - image map - </message> <message name="IDS_AX_ROLE_LINK" desc="Accessibility role description for link"> link </message> - <message name="IDS_AX_ROLE_LIST_MARKER" desc="Accessibility role description for list marker"> - list marker - </message> <message name="IDS_AX_ROLE_MAIN_CONTENT" desc="Accessibility role description for main content of the document."> main </message> @@ -558,14 +527,6 @@ pause </message> - <message name="IDS_AX_MEDIA_SLIDER" desc="Accessibility role description for timeline slider"> - movie time - </message> - - <message name="IDS_AX_MEDIA_SLIDER_THUMB" desc="Accessibility role description for timeline thumb"> - movie timeline thumb - </message> - <message name="IDS_AX_MEDIA_CURRENT_TIME_DISPLAY" desc="Accessibility role description for elapsed time display"> elapsed time </message> @@ -574,10 +535,6 @@ remaining time </message> - <message name="IDS_AX_MEDIA_STATUS_DISPLAY" desc="Accessibility role description for movie status"> - status - </message> - <message name="IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON" desc="Accessibility role description for enter fullscreen button"> enter full screen </message> @@ -642,10 +599,6 @@ movie time scrubber </message> - <message name="IDS_AX_MEDIA_SLIDER_THUMB_HELP" desc="Accessibility help description for timeline thumb"> - movie time scrubber thumb - </message> - <message name="IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP" desc="Accessibility help description for elapsed time display"> current time in seconds </message> @@ -654,10 +607,6 @@ number of seconds of movie remaining </message> - <message name="IDS_AX_MEDIA_STATUS_DISPLAY_HELP" desc="Accessibility help description for movie status"> - current movie status - </message> - <message name="IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP" desc="Accessibility help description for enter fullscreen button"> play movie in full screen mode </message>
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 36cd4f8..06f8106 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -743,13 +743,14 @@ BrowserAccessibility* BrowserAccessibility::GetTable() const { BrowserAccessibility* table = const_cast<BrowserAccessibility*>(this); - while (table && !table->IsTableLikeRole()) + while (table && !ui::IsTableLikeRole(table->GetRole())) table = table->PlatformGetParent(); return table; } BrowserAccessibility* BrowserAccessibility::GetTableCell(int index) const { - if (!IsTableLikeRole() && !IsCellOrTableHeaderRole()) + if (!ui::IsTableLikeRole(GetRole()) && + !ui::IsCellOrTableHeaderRole(GetRole())) return nullptr; BrowserAccessibility* table = GetTable(); @@ -764,7 +765,8 @@ BrowserAccessibility* BrowserAccessibility::GetTableCell(int row, int column) const { - if (!IsTableLikeRole() && !IsCellOrTableHeaderRole()) + if (!ui::IsTableLikeRole(GetRole()) && + !ui::IsCellOrTableHeaderRole(GetRole())) return nullptr; if (row < 0 || row >= GetTableRowCount() || column < 0 || column >= GetTableColumnCount()) { @@ -788,7 +790,7 @@ } int BrowserAccessibility::GetTableCellIndex() const { - if (!IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(GetRole())) return -1; BrowserAccessibility* table = GetTable(); @@ -818,7 +820,7 @@ } int BrowserAccessibility::GetTableColumnSpan() const { - if (!IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(GetRole())) return 0; int column_span; @@ -840,7 +842,7 @@ } int BrowserAccessibility::GetTableRowSpan() const { - if (!IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(GetRole())) return 0; int row_span; @@ -861,18 +863,6 @@ return GetData().HasAction(action_enum); } -bool BrowserAccessibility::IsCellOrTableHeaderRole() const { - return (GetRole() == ui::AX_ROLE_CELL || - GetRole() == ui::AX_ROLE_COLUMN_HEADER || - GetRole() == ui::AX_ROLE_ROW_HEADER); -} - -bool BrowserAccessibility::IsTableLikeRole() const { - return (GetRole() == ui::AX_ROLE_TABLE || - GetRole() == ui::AX_ROLE_GRID || - GetRole() == ui::AX_ROLE_TREE_GRID); -} - bool BrowserAccessibility::HasCaret() const { if (IsSimpleTextControl() && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) {
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 74b5d89..b7a098d 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -344,12 +344,6 @@ bool HasState(ui::AXState state_enum) const; bool HasAction(ui::AXAction action_enum) const; - // Returns true if this node is a cell or a table header. - bool IsCellOrTableHeaderRole() const; - - // Returns true if this node is a table, a grid or a treegrid. - bool IsTableLikeRole() const; - // Returns true if the caret is active on this object. bool HasCaret() const;
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index 52b84c6..4e9d9362 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -14,6 +14,7 @@ #include "content/common/accessibility_messages.h" #include "content/public/common/content_client.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/platform/ax_android_constants.h" #include "ui/accessibility/platform/ax_snapshot_node_android_platform.h" @@ -168,8 +169,9 @@ return HasState(ui::AX_STATE_COLLAPSED); } +// TODO(dougt) Move to ax_role_properties? bool BrowserAccessibilityAndroid::IsCollection() const { - return (IsTableLikeRole() || GetRole() == ui::AX_ROLE_LIST || + return (ui::IsTableLikeRole(GetRole()) || GetRole() == ui::AX_ROLE_LIST || GetRole() == ui::AX_ROLE_LIST_BOX || GetRole() == ui::AX_ROLE_DESCRIPTION_LIST || GetRole() == ui::AX_ROLE_TREE); @@ -1145,7 +1147,7 @@ } int BrowserAccessibilityAndroid::RowCount() const { - if (IsTableLikeRole()) { + if (ui::IsTableLikeRole(GetRole())) { return CountChildrenWithRole(ui::AX_ROLE_ROW); } @@ -1160,7 +1162,7 @@ } int BrowserAccessibilityAndroid::ColumnCount() const { - if (IsTableLikeRole()) { + if (ui::IsTableLikeRole(GetRole())) { return CountChildrenWithRole(ui::AX_ROLE_COLUMN); } return 0;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 2698d30..c75b854 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -27,6 +27,8 @@ #include "content/public/common/content_client.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/accessibility/ax_range.h" +#include "ui/accessibility/ax_role_properties.h" + #import "ui/accessibility/platform/ax_platform_node_mac.h" using AXPlatformPositionInstance = @@ -657,7 +659,7 @@ } - (NSNumber*)ariaColumnCount { - if (!browserAccessibility_->IsTableLikeRole()) + if (!ui::IsTableLikeRole(browserAccessibility_->GetRole())) return nil; int count = -1; if (!browserAccessibility_->GetIntAttribute(ui::AX_ATTR_ARIA_COLUMN_COUNT, @@ -668,7 +670,7 @@ } - (NSNumber*)ariaColumnIndex { - if (!browserAccessibility_->IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole())) return nil; int index = -1; if (!browserAccessibility_->GetIntAttribute( @@ -700,7 +702,7 @@ } - (NSNumber*)ariaRowCount { - if (!browserAccessibility_->IsTableLikeRole()) + if (!ui::IsTableLikeRole(browserAccessibility_->GetRole())) return nil; int count = -1; if (!browserAccessibility_->GetIntAttribute(ui::AX_ATTR_ARIA_ROW_COUNT, @@ -711,7 +713,7 @@ } - (NSNumber*)ariaRowIndex { - if (!browserAccessibility_->IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole())) return nil; int index = -1; if (!browserAccessibility_->GetIntAttribute(ui::AX_ATTR_ARIA_CELL_ROW_INDEX, @@ -781,7 +783,7 @@ - (NSArray*)columnHeaders { if (![self instanceActive]) return nil; - if (!browserAccessibility_->IsTableLikeRole()) { + if (!ui::IsTableLikeRole(browserAccessibility_->GetRole())) { return nil; } @@ -801,7 +803,7 @@ - (NSValue*)columnIndexRange { if (![self instanceActive]) return nil; - if (!browserAccessibility_->IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole())) return nil; int column = -1; @@ -1009,7 +1011,7 @@ if (![self instanceActive]) return nil; int headerElementId = -1; - if (browserAccessibility_->IsTableLikeRole()) { + if (ui::IsTableLikeRole(browserAccessibility_->GetRole())) { browserAccessibility_->GetIntAttribute( ui::AX_ATTR_TABLE_HEADER_ID, &headerElementId); } else if ([self internalRole] == ui::AX_ROLE_COLUMN) { @@ -1507,7 +1509,7 @@ - (NSArray*)rowHeaders { if (![self instanceActive]) return nil; - if (!browserAccessibility_->IsTableLikeRole()) { + if (!ui::IsTableLikeRole(browserAccessibility_->GetRole())) { return nil; } @@ -1527,7 +1529,7 @@ - (NSValue*)rowIndexRange { if (![self instanceActive]) return nil; - if (!browserAccessibility_->IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole())) return nil; int row = -1; @@ -2112,7 +2114,7 @@ j < child->PlatformChildCount(); ++j) { BrowserAccessibility* cell = child->PlatformGetChild(j); - if (!cell->IsCellOrTableHeaderRole()) + if (!ui::IsCellOrTableHeaderRole(cell->GetRole())) continue; int colIndex; if (!cell->GetIntAttribute(
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index 19473d8..809a6ce4 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -27,6 +27,7 @@ #include "content/common/accessibility_mode.h" #include "content/public/common/content_client.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/ax_text_utils.h" #include "ui/base/win/accessibility_ids_win.h" #include "ui/base/win/accessibility_misc_utils.h" @@ -3413,7 +3414,7 @@ return E_NOINTERFACE; } } else if (iid == IID_IAccessibleTableCell) { - if (!accessibility->owner()->IsCellOrTableHeaderRole()) { + if (!ui::IsCellOrTableHeaderRole(accessibility->owner()->GetRole())) { *object = NULL; return E_NOINTERFACE; } @@ -3628,9 +3629,9 @@ } // Expose table cell index. - if (owner()->IsCellOrTableHeaderRole()) { + if (ui::IsCellOrTableHeaderRole(owner()->GetRole())) { BrowserAccessibility* table = owner()->PlatformGetParent(); - while (table && !table->IsTableLikeRole()) + while (table && !ui::IsTableLikeRole(table->GetRole())) table = table->PlatformGetParent(); if (table) { const std::vector<int32_t>& unique_cell_ids = @@ -3645,13 +3646,13 @@ } // Expose aria-colcount and aria-rowcount in a table, grid or treegrid. - if (owner()->IsTableLikeRole()) { + if (ui::IsTableLikeRole(owner()->GetRole())) { IntAttributeToIA2(ui::AX_ATTR_ARIA_COLUMN_COUNT, "colcount"); IntAttributeToIA2(ui::AX_ATTR_ARIA_ROW_COUNT, "rowcount"); } // Expose aria-colindex and aria-rowindex in a cell or row. - if (owner()->IsCellOrTableHeaderRole() || + if (ui::IsCellOrTableHeaderRole(owner()->GetRole()) || owner()->GetRole() == ui::AX_ROLE_ROW) { if (owner()->GetRole() != ui::AX_ROLE_ROW) IntAttributeToIA2(ui::AX_ATTR_ARIA_CELL_COLUMN_INDEX, "colindex"); @@ -4845,7 +4846,7 @@ } void BrowserAccessibilityComWin::UpdateRequiredAttributes() { - if (owner()->IsCellOrTableHeaderRole()) { + if (ui::IsCellOrTableHeaderRole(owner()->GetRole())) { // Expose colspan attribute. base::string16 colspan; if (owner()->GetHtmlAttribute("aria-colspan", &colspan)) {
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index c71ffbe..a625b52 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -5,11 +5,11 @@ #include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" #import "base/mac/mac_util.h" #import "base/mac/scoped_nsobject.h" #import "base/mac/sdk_forward_declarations.h" -#include "base/location.h" -#include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -17,6 +17,7 @@ #import "content/browser/accessibility/browser_accessibility_mac.h" #include "content/common/accessibility_messages.h" #include "content/public/browser/browser_thread.h" +#include "ui/accessibility/ax_role_properties.h" namespace { @@ -210,7 +211,7 @@ mac_notification = NSAccessibilityInvalidStatusChangedNotification; break; case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED: - if (node->IsTableLikeRole()) { + if (ui::IsTableLikeRole(node->GetRole())) { mac_notification = NSAccessibilitySelectedRowsChangedNotification; } else { mac_notification = NSAccessibilitySelectedChildrenChangedNotification; @@ -431,36 +432,6 @@ } } -bool IsContainerWithSelectableChildrenRole(ui::AXRole role) { - switch (role) { - case ui::AX_ROLE_COMBO_BOX: - case ui::AX_ROLE_GRID: - case ui::AX_ROLE_LIST_BOX: - case ui::AX_ROLE_MENU: - case ui::AX_ROLE_MENU_BAR: - case ui::AX_ROLE_RADIO_GROUP: - case ui::AX_ROLE_TAB_LIST: - case ui::AX_ROLE_TOOLBAR: - case ui::AX_ROLE_TREE: - case ui::AX_ROLE_TREE_GRID: - return true; - default: - return false; - } -} - -bool IsRowContainer(ui::AXRole role) { - switch (role) { - case ui::AX_ROLE_TREE: - case ui::AX_ROLE_TREE_GRID: - case ui::AX_ROLE_GRID: - case ui::AX_ROLE_TABLE: - return true; - default: - return false; - } -} - void BrowserAccessibilityManagerMac::OnStateChanged(ui::AXTree* tree, ui::AXNode* node, ui::AXState state, @@ -474,7 +445,7 @@ else tree_events_[node->id()].insert(ui::AX_EVENT_ROW_COLLAPSED); ui::AXNode* container = node; - while (container && !IsRowContainer(container->data().role)) + while (container && !ui::IsRowContainer(container->data().role)) container = container->parent(); if (container) tree_events_[container->id()].insert(ui::AX_EVENT_ROW_COUNT_CHANGED); @@ -485,7 +456,7 @@ if (state == ui::AX_STATE_SELECTED) { ui::AXNode* container = node; while (container && - !IsContainerWithSelectableChildrenRole(container->data().role)) + !ui::IsContainerWithSelectableChildrenRole(container->data().role)) container = container->parent(); if (container) tree_events_[container->id()].insert( @@ -577,6 +548,9 @@ tree_events_[live_root->id()].insert(ui::AX_EVENT_LIVE_REGION_CHANGED); } } + + if (root_changed && tree->data().loaded) + tree_events_[tree->root()->id()].insert(ui::AX_EVENT_LOAD_COMPLETE); } NSDictionary* BrowserAccessibilityManagerMac::
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index dc0c5e9..b9d545a2 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -346,8 +346,8 @@ } IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest, - AccessibilityEventsRemoveSubtree) { - RunEventTest(FILE_PATH_LITERAL("remove-subtree.html")); + AccessibilityEventsTableColumnHidden) { + RunEventTest(FILE_PATH_LITERAL("table-column-hidden.html")); } IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index df73588..af077e5f 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -838,6 +838,11 @@ RunAriaTest(FILE_PATH_LITERAL("input-text-aria-placeholder.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, + AccessibilityTableColumnHidden) { + RunAriaTest(FILE_PATH_LITERAL("table-column-hidden.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityArticle) { RunHtmlTest(FILE_PATH_LITERAL("article.html")); }
diff --git a/content/browser/accessibility/one_shot_accessibility_tree_search.cc b/content/browser/accessibility/one_shot_accessibility_tree_search.cc index 7cfbd16..45f1512 100644 --- a/content/browser/accessibility/one_shot_accessibility_tree_search.cc +++ b/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -12,6 +12,7 @@ #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "ui/accessibility/ax_enums.h" +#include "ui/accessibility/ax_role_properties.h" namespace content { @@ -409,7 +410,7 @@ bool AccessibilityTablePredicate( BrowserAccessibility* start, BrowserAccessibility* node) { - return node->IsTableLikeRole(); + return ui::IsTableLikeRole(node->GetRole()); } bool AccessibilityTextfieldPredicate(
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 94bade54..809d3e5 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -18,6 +18,7 @@ #include "base/process/process_handle.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" #include "content/browser/child_process_launcher.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/service_manager/common_browser_interfaces.h" @@ -70,7 +71,9 @@ base::LazyInstance<std::unique_ptr<service_manager::Connector>>::Leaky g_io_thread_connector = LAZY_INSTANCE_INITIALIZER; -void DestroyConnectorOnIOThread() { g_io_thread_connector.Get().reset(); } +void DestroyConnectorOnIOThread() { + g_io_thread_connector.Get().reset(); +} void StartServiceInUtilityProcess( const std::string& service_name, @@ -199,9 +202,11 @@ } void ShutDown() { - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask( - FROM_HERE, - base::Bind(&InProcessServiceManagerContext::ShutDownOnIOThread, this)); + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO) + ->PostTask( + FROM_HERE, + base::Bind(&InProcessServiceManagerContext::ShutDownOnIOThread, + this)); } private: @@ -296,8 +301,11 @@ std::move(root_browser_service), mojo::MakeRequest(&pid_receiver)); pid_receiver->SetPID(base::GetCurrentProcId()); - ServiceInfo device_info; + scoped_refptr<base::SequencedTaskRunner> background_task_runner = + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND}); + #if defined(OS_ANDROID) JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaGlobalRef<jobject> java_nfc_delegate; @@ -307,15 +315,13 @@ // See the comments on wake_lock_context_host.h and ContentNfcDelegate.java // respectively for comments on those parameters. device_info.factory = - base::Bind(&device::CreateDeviceService, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE), + base::Bind(&device::CreateDeviceService, background_task_runner, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), base::Bind(&WakeLockContextHost::GetNativeViewForContext), std::move(java_nfc_delegate)); #else device_info.factory = - base::Bind(&device::CreateDeviceService, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE), + base::Bind(&device::CreateDeviceService, background_task_runner, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); #endif device_info.task_runner = base::ThreadTaskRunnerHandle::Get(); @@ -343,9 +349,8 @@ g_io_thread_connector.Get() = browser_connection->GetConnector()->Clone(); ContentBrowserClient::OutOfProcessServiceMap sandboxed_services; - GetContentClient() - ->browser() - ->RegisterOutOfProcessServices(&sandboxed_services); + GetContentClient()->browser()->RegisterOutOfProcessServices( + &sandboxed_services); sandboxed_services.insert( std::make_pair(data_decoder::mojom::kServiceName, base::ASCIIToUTF16("Data Decoder Service"))); @@ -356,9 +361,8 @@ } ContentBrowserClient::OutOfProcessServiceMap unsandboxed_services; - GetContentClient() - ->browser() - ->RegisterUnsandboxedOutOfProcessServices(&unsandboxed_services); + GetContentClient()->browser()->RegisterUnsandboxedOutOfProcessServices( + &unsandboxed_services); bool network_service_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index 71bf19c..305d39bb 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -88,16 +88,8 @@ return IDS_AX_CALENDAR_WEEK_DESCRIPTION; case WebLocalizedString::kAXDayOfMonthFieldText: return IDS_AX_DAY_OF_MONTH_FIELD_TEXT; - case WebLocalizedString::kAXHeadingText: - return IDS_AX_ROLE_HEADING; case WebLocalizedString::kAXHourFieldText: return IDS_AX_HOUR_FIELD_TEXT; - case WebLocalizedString::kAXImageMapText: - return IDS_AX_ROLE_IMAGE_MAP; - case WebLocalizedString::kAXLinkText: - return IDS_AX_ROLE_LINK; - case WebLocalizedString::kAXListMarkerText: - return IDS_AX_ROLE_LIST_MARKER; case WebLocalizedString::kAXMediaDefault: return IDS_AX_MEDIA_DEFAULT; case WebLocalizedString::kAXMediaAudioElement: @@ -112,16 +104,10 @@ return IDS_AX_MEDIA_PLAY_BUTTON; case WebLocalizedString::kAXMediaPauseButton: return IDS_AX_MEDIA_PAUSE_BUTTON; - case WebLocalizedString::kAXMediaSlider: - return IDS_AX_MEDIA_SLIDER; - case WebLocalizedString::kAXMediaSliderThumb: - return IDS_AX_MEDIA_SLIDER_THUMB; case WebLocalizedString::kAXMediaCurrentTimeDisplay: return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY; case WebLocalizedString::kAXMediaTimeRemainingDisplay: return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY; - case WebLocalizedString::kAXMediaStatusDisplay: - return IDS_AX_MEDIA_STATUS_DISPLAY; case WebLocalizedString::kAXMediaEnterFullscreenButton: return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON; case WebLocalizedString::kAXMediaExitFullscreenButton: @@ -154,14 +140,10 @@ return IDS_AX_MEDIA_AUDIO_SLIDER_HELP; case WebLocalizedString::kAXMediaVideoSliderHelp: return IDS_AX_MEDIA_VIDEO_SLIDER_HELP; - case WebLocalizedString::kAXMediaSliderThumbHelp: - return IDS_AX_MEDIA_SLIDER_THUMB_HELP; case WebLocalizedString::kAXMediaCurrentTimeDisplayHelp: return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP; case WebLocalizedString::kAXMediaTimeRemainingDisplayHelp: return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY_HELP; - case WebLocalizedString::kAXMediaStatusDisplayHelp: - return IDS_AX_MEDIA_STATUS_DISPLAY_HELP; case WebLocalizedString::kAXMediaEnterFullscreenButtonHelp: return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP; case WebLocalizedString::kAXMediaExitFullscreenButtonHelp: @@ -184,8 +166,6 @@ return IDS_AX_MONTH_FIELD_TEXT; case WebLocalizedString::kAXSecondFieldText: return IDS_AX_SECOND_FIELD_TEXT; - case WebLocalizedString::kAXWebAreaText: - return IDS_AX_ROLE_WEB_AREA; case WebLocalizedString::kAXWeekOfYearFieldText: return IDS_AX_WEEK_OF_YEAR_FIELD_TEXT; case WebLocalizedString::kAXYearFieldText: @@ -194,12 +174,6 @@ return IDS_FORM_CALENDAR_CLEAR; case WebLocalizedString::kCalendarToday: return IDS_FORM_CALENDAR_TODAY; - case WebLocalizedString::kDateFormatDayInMonthLabel: - return IDS_FORM_DATE_FORMAT_DAY_IN_MONTH; - case WebLocalizedString::kDateFormatMonthLabel: - return IDS_FORM_DATE_FORMAT_MONTH; - case WebLocalizedString::kDateFormatYearLabel: - return IDS_FORM_DATE_FORMAT_YEAR; case WebLocalizedString::kDetailsLabel: return IDS_DETAILS_WITHOUT_SUMMARY_LABEL; case WebLocalizedString::kDownloadButtonLabel: @@ -226,8 +200,6 @@ return IDS_FORM_OTHER_DATE_LABEL; case WebLocalizedString::kOtherMonthLabel: return IDS_FORM_OTHER_MONTH_LABEL; - case WebLocalizedString::kOtherTimeLabel: - return IDS_FORM_OTHER_TIME_LABEL; case WebLocalizedString::kOtherWeekLabel: return IDS_FORM_OTHER_WEEK_LABEL; case WebLocalizedString::kOverflowMenuCaptions: @@ -258,14 +230,6 @@ return IDS_FORM_PLACEHOLDER_FOR_YEAR_FIELD; case WebLocalizedString::kResetButtonDefaultLabel: return IDS_FORM_RESET_LABEL; - case WebLocalizedString::kSearchableIndexIntroduction: - return IDS_SEARCHABLE_INDEX_INTRO; - case WebLocalizedString::kSearchMenuClearRecentSearchesText: - return IDS_RECENT_SEARCHES_CLEAR; - case WebLocalizedString::kSearchMenuNoRecentSearchesText: - return IDS_RECENT_SEARCHES_NONE; - case WebLocalizedString::kSearchMenuRecentSearchesText: - return IDS_RECENT_SEARCHES; case WebLocalizedString::kSelectMenuListText: return IDS_FORM_SELECT_MENU_LIST_TEXT; case WebLocalizedString::kSubmitButtonDefaultLabel:
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index c5613269..bd7a586 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -70,6 +70,11 @@ WebRuntimeFeatures::EnableWebBluetooth(true); #endif +// Web Share is shipped on Android, experimental otherwise. +#if defined(OS_ANDROID) + WebRuntimeFeatures::EnableWebShare(true); +#endif + #if defined(OS_CHROMEOS) WebRuntimeFeatures::EnableForceTallerSelectPopup(true); #endif
diff --git a/content/network/network_context.cc b/content/network/network_context.cc index ea81b5c..5862ea6 100644 --- a/content/network/network_context.cc +++ b/content/network/network_context.cc
@@ -9,7 +9,6 @@ #include "base/strings/string_number_conversions.h" #include "components/network_session_configurator/common/network_switches.h" #include "content/network/cache_url_loader.h" -#include "content/network/network_service.h" #include "content/network/network_service_url_loader_factory_impl.h" #include "content/network/url_loader_impl.h" #include "content/public/common/content_client.h" @@ -87,17 +86,11 @@ } // namespace -NetworkContext::NetworkContext(NetworkService* network_service, - mojom::NetworkContextRequest request, +NetworkContext::NetworkContext(mojom::NetworkContextRequest request, mojom::NetworkContextParamsPtr params) - : network_service_(network_service), - url_request_context_(MakeURLRequestContext()), + : url_request_context_(MakeURLRequestContext()), params_(std::move(params)), - binding_(this, std::move(request)) { - network_service_->RegisterNetworkContext(this); - binding_.set_connection_error_handler( - base::Bind(&NetworkContext::OnConnectionError, base::Unretained(this))); -} + binding_(this, std::move(request)) {} NetworkContext::~NetworkContext() { // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the @@ -106,10 +99,6 @@ // so have to be careful. while (!url_loaders_.empty()) (*url_loaders_.begin())->Cleanup(); - - // May be nullptr in tests. - if (network_service_) - network_service_->DeregisterNetworkContext(this); } std::unique_ptr<NetworkContext> NetworkContext::CreateForTesting() { @@ -139,22 +128,8 @@ StartCacheURLLoader(url, url_request_context_.get(), std::move(client)); } -void NetworkContext::Cleanup() { - // The NetworkService is going away, so have to destroy the - // net::URLRequestContext held by this NetworkContext. - delete this; -} - NetworkContext::NetworkContext() - : network_service_(nullptr), - url_request_context_(MakeURLRequestContext()), + : url_request_context_(MakeURLRequestContext()), binding_(this) {} -void NetworkContext::OnConnectionError() { - // Don't delete |this| in response to connection errors when it was created by - // CreateForTesting. - if (network_service_) - delete this; -} - } // namespace content
diff --git a/content/network/network_context.h b/content/network/network_context.h index b6b5332f..a4dd42c 100644 --- a/content/network/network_context.h +++ b/content/network/network_context.h
@@ -22,13 +22,11 @@ } namespace content { -class NetworkService; class URLLoaderImpl; class NetworkContext : public mojom::NetworkContext { public: - NetworkContext(NetworkService* network_service, - mojom::NetworkContextRequest request, + NetworkContext(mojom::NetworkContextRequest request, mojom::NetworkContextParamsPtr params); ~NetworkContext() override; @@ -49,18 +47,9 @@ void HandleViewCacheRequest(const GURL& url, mojom::URLLoaderClientPtr client) override; - // Called when the associated NetworkService is going away. Guaranteed to - // destroy NetworkContext's URLRequestContext. - void Cleanup(); - private: NetworkContext(); - // On connection errors the NetworkContext destroys itself. - void OnConnectionError(); - - NetworkService* const network_service_; - std::unique_ptr<net::URLRequestContext> url_request_context_; // Put it below |url_request_context_| so that it outlives all the
diff --git a/content/network/network_service.cc b/content/network/network_service.cc index a133884..28d947b 100644 --- a/content/network/network_service.cc +++ b/content/network/network_service.cc
@@ -55,44 +55,11 @@ NetworkService::NetworkService( std::unique_ptr<service_manager::BinderRegistry> registry) : net_log_(new MojoNetLog), registry_(std::move(registry)), binding_(this) { - // |registry_| may be nullptr in tests. - if (registry_) { - registry_->AddInterface<mojom::NetworkService>( - base::Bind(&NetworkService::Create, base::Unretained(this))); - } + registry_->AddInterface<mojom::NetworkService>( + base::Bind(&NetworkService::Create, base::Unretained(this))); } -NetworkService::~NetworkService() { - // Call each Network and ask it to release its net::URLRequestContext, as they - // may have references to shared objects owned by the NetworkService. The - // NetworkContexts deregister themselves in Cleanup(), so have to be careful. - while (!network_contexts_.empty()) - (*network_contexts_.begin())->Cleanup(); -} - -std::unique_ptr<NetworkService> NetworkService::CreateForTesting() { - return base::WrapUnique(new NetworkService()); -} - -void NetworkService::RegisterNetworkContext(NetworkContext* network_context) { - DCHECK_EQ(0u, network_contexts_.count(network_context)); - network_contexts_.insert(network_context); -} - -void NetworkService::DeregisterNetworkContext(NetworkContext* network_context) { - DCHECK_EQ(1u, network_contexts_.count(network_context)); - network_contexts_.erase(network_context); -} - -void NetworkService::CreateNetworkContext( - mojom::NetworkContextRequest request, - mojom::NetworkContextParamsPtr params) { - // The NetworkContext will destroy itself on connection error, or when the - // service is destroyed. - new NetworkContext(this, std::move(request), std::move(params)); -} - -NetworkService::NetworkService() : NetworkService(nullptr) {} +NetworkService::~NetworkService() = default; void NetworkService::OnBindInterface( const service_manager::BindSourceInfo& source_info, @@ -108,4 +75,12 @@ binding_.Bind(std::move(request)); } +void NetworkService::CreateNetworkContext( + mojom::NetworkContextRequest request, + mojom::NetworkContextParamsPtr params) { + mojo::MakeStrongBinding( + base::MakeUnique<NetworkContext>(std::move(request), std::move(params)), + std::move(request)); +} + } // namespace content
diff --git a/content/network/network_service.h b/content/network/network_service.h index c945b9ad..e139546d 100644 --- a/content/network/network_service.h +++ b/content/network/network_service.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/macros.h" -#include "content/common/content_export.h" #include "content/common/network_service.mojom.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -16,8 +15,6 @@ namespace content { -class NetworkContext; - class NetworkService : public service_manager::Service, public mojom::NetworkService { public: @@ -25,23 +22,9 @@ std::unique_ptr<service_manager::BinderRegistry> registry); ~NetworkService() override; - CONTENT_EXPORT static std::unique_ptr<NetworkService> CreateForTesting(); - - // These are called by NetworkContexts as they are being created and - // destroyed. - void RegisterNetworkContext(NetworkContext* network_context); - void DeregisterNetworkContext(NetworkContext* network_context); - - // mojom::NetworkService implementation: - void CreateNetworkContext(mojom::NetworkContextRequest request, - mojom::NetworkContextParamsPtr params) override; - private: class MojoNetLog; - // Used for tests. - NetworkService(); - // service_manager::Service implementation. void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, @@ -50,18 +33,16 @@ void Create(const service_manager::BindSourceInfo& source_info, mojom::NetworkServiceRequest request); + // mojom::NetworkService implementation: + void CreateNetworkContext(mojom::NetworkContextRequest request, + mojom::NetworkContextParamsPtr params) override; + std::unique_ptr<MojoNetLog> net_log_; std::unique_ptr<service_manager::BinderRegistry> registry_; mojo::Binding<mojom::NetworkService> binding_; - // NetworkContexts register themselves with the NetworkService so that they - // can be cleaned up when the NetworkService goes away. This is needed as - // NetworkContexts share global state with the NetworkService, so must be - // destroyed first. - std::set<NetworkContext*> network_contexts_; - DISALLOW_COPY_AND_ASSIGN(NetworkService); };
diff --git a/content/network/network_service_unittest.cc b/content/network/network_service_unittest.cc deleted file mode 100644 index 4897e12..0000000 --- a/content/network/network_service_unittest.cc +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2017 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 <memory> - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "content/common/network_service.mojom.h" -#include "content/network/network_context.h" -#include "content/network/network_service.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -namespace { - -class NetworkServiceTest : public testing::Test { - public: - NetworkServiceTest() : service_(NetworkService::CreateForTesting()) {} - ~NetworkServiceTest() override {} - - NetworkService* service() const { return service_.get(); } - - void DestroyService() { service_.reset(); } - - private: - base::MessageLoopForIO message_loop_; - std::unique_ptr<NetworkService> service_; -}; - -// Test shutdown in the case a NetworkContext is destroyed before the -// NetworkService. -TEST_F(NetworkServiceTest, CreateAndDestroyContext) { - mojom::NetworkContextPtr network_context; - mojom::NetworkContextParamsPtr context_params = - mojom::NetworkContextParams::New(); - - service()->CreateNetworkContext(mojo::MakeRequest(&network_context), - std::move(context_params)); - network_context.reset(); - // Make sure the NetworkContext is destroyed. - base::RunLoop().RunUntilIdle(); -} - -// Test shutdown in the case there is still a live NetworkContext when the -// NetworkService is destroyed. The service should destroy the NetworkContext -// itself. -TEST_F(NetworkServiceTest, DestroyingServiceDestroysContext) { - mojom::NetworkContextPtr network_context; - mojom::NetworkContextParamsPtr context_params = - mojom::NetworkContextParams::New(); - - service()->CreateNetworkContext(mojo::MakeRequest(&network_context), - std::move(context_params)); - base::RunLoop run_loop; - network_context.set_connection_error_handler(run_loop.QuitClosure()); - DestroyService(); - - // Destroying the service should destroy the context, causing a connection - // error. - run_loop.Run(); -} - -} // namespace - -} // namespace content
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 071ae907..dd60b833 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -469,6 +469,7 @@ "junit/src/org/chromium/content/browser/ChildConnectionAllocatorTest.java", "junit/src/org/chromium/content/browser/MenuDescriptorTest.java", "junit/src/org/chromium/content/browser/SpareChildConnectionTest.java", + "junit/src/org/chromium/content/browser/TestChildProcessConnection.java", "junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java", "junit/src/org/chromium/content/browser/input/RangeTest.java", "junit/src/org/chromium/content/browser/input/TextInputStateTest.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java index b0767b8..ce2e033 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java
@@ -57,23 +57,6 @@ // Delay between the call to freeConnection and the connection actually beeing freed. private static final long FREE_CONNECTION_DELAY_MILLIS = 1; - // Factory used by the SpareConnection to create the actual ChildProcessConnection. - private static final SpareChildConnection.ConnectionFactory SANDBOXED_CONNECTION_FACTORY = - new SpareChildConnection.ConnectionFactory() { - @Override - public ChildProcessConnection allocateBoundConnection(Context context, - ChildProcessCreationParams creationParams, - ChildProcessConnection.ServiceCallback serviceCallback) { - boolean bindToCallerCheck = - creationParams == null ? false : creationParams.getBindToCallerCheck(); - ChildConnectionAllocator allocator = - getConnectionAllocator(context, creationParams, true /* sandboxed */); - Bundle serviceBundle = - ChildProcessLauncherHelper.createServiceBundle(bindToCallerCheck); - return allocator.allocate(context, serviceBundle, serviceCallback); - } - }; - // A warmed-up connection to a sandboxed service. private static SpareChildConnection sSpareSandboxedConnection; @@ -189,9 +172,16 @@ if (sSpareSandboxedConnection != null && !sSpareSandboxedConnection.isEmpty()) { return; } + + ChildProcessCreationParams creationParams = ChildProcessCreationParams.getDefault(); + boolean bindToCallerCheck = + creationParams == null ? false : creationParams.getBindToCallerCheck(); + Bundle serviceBundle = + ChildProcessLauncherHelper.createServiceBundle(bindToCallerCheck); + ChildConnectionAllocator allocator = + getConnectionAllocator(context, creationParams, true /* sandboxed */); sSpareSandboxedConnection = - new SpareChildConnection(context, SANDBOXED_CONNECTION_FACTORY, - ChildProcessCreationParams.getDefault(), true /* sandboxed */); + new SpareChildConnection(context, allocator, serviceBundle); } }); } @@ -417,7 +407,7 @@ // Try to use the spare connection if there's one. if (sSpareSandboxedConnection != null) { mConnection = sSpareSandboxedConnection.getConnection( - mCreationParams, mSandboxed, serviceCallback); + mConnectionAllocator, serviceCallback); if (mConnection != null) { Log.d(TAG, "Using warmed-up connection for service %s.", mConnection.getServiceName());
diff --git a/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java b/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java index 8372db4..79e20c3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java +++ b/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java
@@ -5,11 +5,11 @@ package org.chromium.content.browser; import android.content.Context; +import android.os.Bundle; import android.support.annotation.NonNull; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; -import org.chromium.base.process_launcher.ChildProcessCreationParams; /** * This class is used to create a single spare ChildProcessConnection (usually early on during @@ -18,19 +18,8 @@ public class SpareChildConnection { private static final String TAG = "SpareChildConn"; - // Factory interface used to create the actual connection. - interface ConnectionFactory { - ChildProcessConnection allocateBoundConnection(Context context, - ChildProcessCreationParams creationParams, - ChildProcessConnection.ServiceCallback serviceCallback); - } - - // The parameters passed to the Connectionfactory when creating the connection. - // Also used to identify the connection when the connection is retrieved. - private final ChildProcessCreationParams mCreationParams; - - // Whether the connection is sandboxed. - private final boolean mSandoxed; + // The allocator used to create the connection. + private final ChildConnectionAllocator mConnectionAllocator; // The actual spare connection. private ChildProcessConnection mConnection; @@ -43,12 +32,11 @@ private ChildProcessConnection.ServiceCallback mConnectionServiceCallback; /** Creates and binds a ChildProcessConnection using the specified parameters. */ - public SpareChildConnection(Context context, ConnectionFactory connectionFactory, - ChildProcessCreationParams creationParams, boolean sandboxed) { + public SpareChildConnection( + Context context, ChildConnectionAllocator connectionAllocator, Bundle serviceBundle) { assert LauncherThread.runningOnLauncherThread(); - mCreationParams = creationParams; - mSandoxed = sandboxed; + mConnectionAllocator = connectionAllocator; ChildProcessConnection.ServiceCallback serviceCallback = new ChildProcessConnection.ServiceCallback() { @@ -86,19 +74,17 @@ } }; - mConnection = connectionFactory.allocateBoundConnection( - context, mCreationParams, serviceCallback); + mConnection = mConnectionAllocator.allocate(context, serviceBundle, serviceCallback); } /** - * @return a connection that has been bound or is being bound matching the given paramters, null - * otherwise. + * @return a connection that has been bound or is being bound if one was created with the same + * allocator as the one provided, null otherwise. */ - public ChildProcessConnection getConnection(ChildProcessCreationParams creationParams, - boolean sandboxed, + public ChildProcessConnection getConnection(ChildConnectionAllocator allocator, @NonNull final ChildProcessConnection.ServiceCallback serviceCallback) { assert LauncherThread.runningOnLauncherThread(); - if (mConnection == null || creationParams != mCreationParams || sandboxed != mSandoxed + if (mConnection == null || allocator != mConnectionAllocator || mConnectionServiceCallback != null) { return null; }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java index ab28c54..3a36065f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
@@ -461,31 +461,31 @@ @Test @MediumTest @Feature({"ProcessManagement"}) + @ChildProcessAllocatorSettings(sandboxedServiceCount = 4) public void testCustomCreationParamDoesNotReuseWarmupConnection() { // Since warmUp only uses default params. final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); ChildProcessCreationParams defaultCreationParams = getDefaultChildProcessCreationParams(context.getPackageName()); - ChildProcessCreationParams otherCreationParams = - getDefaultChildProcessCreationParams(context.getPackageName()); ChildProcessCreationParams.registerDefault(defaultCreationParams); + ChildProcessCreationParams otherCreationParams = getDefaultChildProcessCreationParams( + InstrumentationRegistry.getInstrumentation().getContext().getPackageName()); warmUpOnUiThreadBlocking(context); Assert.assertEquals(1, getConnectedSandboxedServicesCount()); - // First create a connnection with different creation params then the default. It should not - // use the warm-up connection which uses the default creation params (check uses object - // identity, having the params match exactly is fine). + // First create a connnection with different creation params than the default, it should not + // use the warmup connection (note that it won't bind since we are using the wrong package, + // but we need to use a different package to differentiate them, and we can only have 1 + // valid package per app). startSandboxedChildProcessWithCreationParams( - otherCreationParams, BLOCK_UNTIL_SETUP, true /* doSetupConnection */); - Assert.assertEquals(2, getConnectedSandboxedServicesCount()); + otherCreationParams, DONT_BLOCK, false /* doSetupConnection */); Assert.assertNotNull(getWarmUpConnection()); // Then start a process with the default creation params, the warmup-connection should be // used. startSandboxedChildProcessWithCreationParams( defaultCreationParams, BLOCK_UNTIL_SETUP, true /* doSetupConnection */); - Assert.assertEquals(2, getConnectedSandboxedServicesCount()); Assert.assertNull(getWarmUpConnection()); }
diff --git a/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java b/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java index 84ca0c3..2711464 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java
@@ -37,77 +37,18 @@ @RunWith(LocalRobolectricTestRunner.class) @Config(manifest = Config.NONE) public class BindingManagerImplTest { - private static class MockChildServiceConnection - implements ChildProcessConnection.ChildServiceConnection { - private boolean mBound; - - @Override - public boolean bind() { - mBound = true; - return true; - } - - @Override - public void unbind() { - mBound = false; - } - - @Override - public boolean isBound() { - return mBound; - } - } - - private static class TestChildProcessConnection extends ChildProcessConnection { - private final int mPid; - private boolean mConnected; - - /** - * Creates a mock binding corresponding to real ManagedChildProcessConnection after the - * connection is established: with initial binding bound and no strong binding. - */ - private TestChildProcessConnection(int pid) { - super(null /* context */, new ComponentName("org.chromium.test", "TestService"), - false /* isExternalService */, null /* childProcessCommonParameters */, - new ChildProcessCreationParams("org.chromium.test", - false /* isExternalService */, 0 /* libraryProcessType */, - false /* bindToCallerCheck */)); - mPid = pid; - } - - @Override - public int getPid() { - return mPid; - } - - @Override - protected ChildServiceConnection createServiceConnection(int bindFlags) { - return new MockChildServiceConnection(); - } - - // We don't have a real service so we have to mock the connection status. - @Override - public void start(boolean useStrongBinding, ServiceCallback serviceCallback) { - super.start(useStrongBinding, serviceCallback); - mConnected = true; - } - - @Override - public void stop() { - super.stop(); - mConnected = false; - } - - @Override - public boolean isConnected() { - return mConnected; - } - } // Creates a mocked ChildProcessConnection that is optionally added to a BindingManager. private static ChildProcessConnection createTestChildProcessConnection( int pid, BindingManager manager) { - ChildProcessConnection connection = new TestChildProcessConnection(pid); + String packageName = "org.chromium.test"; + ChildProcessCreationParams creationParams = + new ChildProcessCreationParams(packageName, false /* isExternalService */, + 0 /* libraryProcessType */, false /* bindToCallerCheck */); + TestChildProcessConnection connection = new TestChildProcessConnection( + new ComponentName(packageName, "TestService"), false /* bindAsExternalService */, + null /* serviceBundle */, creationParams); + connection.setPid(pid); connection.start(false /* useStrongBinding */, null /* serviceCallback */); if (manager != null) { manager.addNewConnection(pid, connection);
diff --git a/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java b/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java index 7d92b395..1779db5 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java
@@ -4,12 +4,13 @@ package org.chromium.content.browser; +import android.content.ComponentName; import android.content.Context; +import android.os.Bundle; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -33,33 +34,44 @@ @Mock private ChildProcessConnection.ServiceCallback mServiceCallback; - static class TestConnectionFactory implements SpareChildConnection.ConnectionFactory { - private ChildProcessConnection mConnection; - private ChildProcessConnection.ServiceCallback mServiceCallback; + // A connection allocator not used to create connections. + private final ChildConnectionAllocator mWrongConnectionAllocator = + ChildConnectionAllocator.createForTest(null /* creationParams */, "org.chromium.test", + "TestServiceName", 3 /* serviceCount */, false /* bindAsExternalService */, + false /* useStrongBinding */); + + // The allocator used to allocate the actual connection. + private ChildConnectionAllocator mConnectionAllocator; + + private static class TestConnectionFactory + implements ChildConnectionAllocator.ConnectionFactory { + private TestChildProcessConnection mConnection; @Override - public ChildProcessConnection allocateBoundConnection(Context context, - ChildProcessCreationParams creationParams, - ChildProcessConnection.ServiceCallback serviceCallback) { - mConnection = mock(ChildProcessConnection.class); - mServiceCallback = serviceCallback; + public ChildProcessConnection createConnection(Context context, ComponentName serviceName, + boolean bindAsExternalService, Bundle serviceBundle, + ChildProcessCreationParams creationParams) { + // We expect to create only one connection in these tests. + assert mConnection == null; + mConnection = new TestChildProcessConnection( + serviceName, bindAsExternalService, serviceBundle, creationParams); return mConnection; } public void simulateConnectionBindingSuccessfully() { - mServiceCallback.onChildStarted(); + mConnection.getServiceCallback().onChildStarted(); } public void simulateConnectionFailingToBind() { - mServiceCallback.onChildStartFailed(); + mConnection.getServiceCallback().onChildStartFailed(); } public void simulateConnectionDied() { - mServiceCallback.onChildProcessDied(mConnection); + mConnection.getServiceCallback().onChildProcessDied(mConnection); } - } + }; - private final TestConnectionFactory mTestConnectionfactory = new TestConnectionFactory(); + private final TestConnectionFactory mTestConnectionFactory = new TestConnectionFactory(); // For some reason creating ChildProcessCreationParams from a static context makes the launcher // unhappy. (some Dalvik native library is not found when initializing a SparseArray) @@ -77,8 +89,13 @@ // asserts are not triggered. LauncherThread.setCurrentThreadAsLauncherThread(); + mConnectionAllocator = ChildConnectionAllocator.createForTest(mCreationParams, + mCreationParams.getPackageNameForSandboxedService(), "TestServiceName", + 5 /* serviceCount */, false /* bindAsExternalService */, + false /* useStrongBinding */); + mConnectionAllocator.setConnectionFactoryForTesting(mTestConnectionFactory); mSpareConnection = new SpareChildConnection( - null /* context */, mTestConnectionfactory, mCreationParams, true /* sandboxed */); + null /* context */, mConnectionAllocator, null /* serviceBundle */); } @After @@ -90,33 +107,28 @@ @Test @Feature({"ProcessManagement"}) public void testCreateAndGet() { - // Tests retrieving the connection with the wrong parameters. - ChildProcessConnection connection = mSpareConnection.getConnection( - null /* creationParams */, true /* sandboxed */, mServiceCallback); - assertNull(connection); - connection = mSpareConnection.getConnection( - mCreationParams, false /* sandboxed */, mServiceCallback); + // Tests retrieving the connection with the wrong allocator. + ChildProcessConnection connection = + mSpareConnection.getConnection(mWrongConnectionAllocator, mServiceCallback); assertNull(connection); // And with the right one. - connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + connection = mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNotNull(connection); // The connection has been used, subsequent calls should return null. - connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + connection = mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNull(connection); } @Test @Feature({"ProcessManagement"}) public void testCallbackNotCalledWhenNoConnection() { - mTestConnectionfactory.simulateConnectionBindingSuccessfully(); + mTestConnectionFactory.simulateConnectionBindingSuccessfully(); // Retrieve the wrong connection, no callback should be fired. - ChildProcessConnection connection = mSpareConnection.getConnection( - null /* creationParams */, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mWrongConnectionAllocator, mServiceCallback); assertNull(connection); ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); verify(mServiceCallback, times(0)).onChildStarted(); @@ -127,11 +139,11 @@ @Test @Feature({"ProcessManagement"}) public void testCallbackCalledConnectionReady() { - mTestConnectionfactory.simulateConnectionBindingSuccessfully(); + mTestConnectionFactory.simulateConnectionBindingSuccessfully(); // Now retrieve the connection, the callback should be invoked. - ChildProcessConnection connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNotNull(connection); ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); verify(mServiceCallback, times(1)).onChildStarted(); @@ -142,8 +154,8 @@ @Feature({"ProcessManagement"}) public void testCallbackCalledConnectionNotReady() { // Retrieve the connection before it's bound. - ChildProcessConnection connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNotNull(connection); ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); // No callbacks are called. @@ -151,7 +163,7 @@ verify(mServiceCallback, times(0)).onChildStartFailed(); // Simulate the connection getting bound, it should trigger the callback. - mTestConnectionfactory.simulateConnectionBindingSuccessfully(); + mTestConnectionFactory.simulateConnectionBindingSuccessfully(); verify(mServiceCallback, times(1)).onChildStarted(); verify(mServiceCallback, times(0)).onChildStartFailed(); } @@ -159,11 +171,11 @@ @Test @Feature({"ProcessManagement"}) public void testUnretrievedConnectionFailsToBind() { - mTestConnectionfactory.simulateConnectionFailingToBind(); + mTestConnectionFactory.simulateConnectionFailingToBind(); // We should not have a spare connection. - ChildProcessConnection connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNull(connection); } @@ -171,11 +183,11 @@ @Feature({"ProcessManagement"}) public void testRetrievedConnectionFailsToBind() { // Retrieve the spare connection before it's bound. - ChildProcessConnection connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNotNull(connection); - mTestConnectionfactory.simulateConnectionFailingToBind(); + mTestConnectionFactory.simulateConnectionFailingToBind(); // We should get a failure callback. verify(mServiceCallback, times(0)).onChildStarted(); @@ -186,11 +198,11 @@ @Feature({"ProcessManagement"}) public void testRetrievedConnectionStops() { // Retrieve the spare connection before it's bound. - ChildProcessConnection connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNotNull(connection); - mTestConnectionfactory.simulateConnectionDied(); + mTestConnectionFactory.simulateConnectionDied(); // We should get a failure callback. verify(mServiceCallback, times(0)).onChildStarted(); @@ -202,11 +214,11 @@ @Feature({"ProcessManagement"}) public void testConnectionFreeing() { // Simulate the connection dying. - mTestConnectionfactory.simulateConnectionDied(); + mTestConnectionFactory.simulateConnectionDied(); // Connection should be gone. - ChildProcessConnection connection = mSpareConnection.getConnection( - mCreationParams, true /* sandboxed */, mServiceCallback); + ChildProcessConnection connection = + mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback); assertNull(connection); } }
diff --git a/content/public/android/junit/src/org/chromium/content/browser/TestChildProcessConnection.java b/content/public/android/junit/src/org/chromium/content/browser/TestChildProcessConnection.java new file mode 100644 index 0000000..94f8dd8 --- /dev/null +++ b/content/public/android/junit/src/org/chromium/content/browser/TestChildProcessConnection.java
@@ -0,0 +1,85 @@ +// Copyright 2017 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.content.browser; + +import android.content.ComponentName; +import android.os.Bundle; + +import org.chromium.base.process_launcher.ChildProcessCreationParams; + +/** An implementation of ChildProcessConnection that does not connect to a real service. */ +class TestChildProcessConnection extends ChildProcessConnection { + private static class MockChildServiceConnection + implements ChildProcessConnection.ChildServiceConnection { + private boolean mBound; + + @Override + public boolean bind() { + mBound = true; + return true; + } + + @Override + public void unbind() { + mBound = false; + } + + @Override + public boolean isBound() { + return mBound; + } + } + + private int mPid; + private boolean mConnected; + private ServiceCallback mServiceCallback; + + /** + * Creates a mock binding corresponding to real ManagedChildProcessConnection after the + * connection is established: with initial binding bound and no strong binding. + */ + TestChildProcessConnection(ComponentName serviceName, boolean bindAsExternalService, + Bundle serviceBundle, ChildProcessCreationParams creationParams) { + super(null /* context */, serviceName, bindAsExternalService, serviceBundle, + creationParams); + } + + public void setPid(int pid) { + mPid = pid; + } + + @Override + public int getPid() { + return mPid; + } + + @Override + protected ChildServiceConnection createServiceConnection(int bindFlags) { + return new MockChildServiceConnection(); + } + + // We don't have a real service so we have to mock the connection status. + @Override + public void start(boolean useStrongBinding, ServiceCallback serviceCallback) { + super.start(useStrongBinding, serviceCallback); + mConnected = true; + mServiceCallback = serviceCallback; + } + + @Override + public void stop() { + super.stop(); + mConnected = false; + } + + @Override + public boolean isConnected() { + return mConnected; + } + + public ServiceCallback getServiceCallback() { + return mServiceCallback; + } +}
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 7c8f196..059bd19 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -261,6 +261,17 @@ serializer_.DeleteClientSubtree(obj); #endif + // If some cell IDs have been added or removed, we need to update the whole + // table. + if (obj.Role() == blink::kWebAXRoleRow && + event == ui::AX_EVENT_CHILDREN_CHANGED) { + WebAXObject table_like_object = obj.ParentObject(); + if (!table_like_object.IsDetached()) { + serializer_.DeleteClientSubtree(table_like_object); + HandleAXEvent(table_like_object, ui::AX_EVENT_CHILDREN_CHANGED); + } + } + // Add the accessibility object to our cache and ensure it's valid. AccessibilityHostMsg_EventParams acc_event; acc_event.id = obj.AxID();
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 5b61ab4..03ed2f2 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -526,19 +526,6 @@ return handled; } -bool BlinkTestController::OnMessageReceived( - const IPC::Message& message, - RenderFrameHost* render_frame_host) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BlinkTestController, message, - render_frame_host) - IPC_MESSAGE_HANDLER(ShellViewHostMsg_LayoutDumpResponse, - OnLayoutDumpResponse) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - void BlinkTestController::PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -791,7 +778,9 @@ continue; ++number_of_messages; - GetLayoutTestControlPtr(rfh)->LayoutDumpRequest(); + GetLayoutTestControlPtr(rfh)->DumpFrameLayout( + base::Bind(&BlinkTestController::OnDumpFrameLayoutResponse, + base::Unretained(this), rfh->GetFrameTreeNodeId())); } pending_layout_dumps_ = number_of_messages; @@ -817,11 +806,11 @@ } } -void BlinkTestController::OnLayoutDumpResponse(RenderFrameHost* sender, - const std::string& dump) { +void BlinkTestController::OnDumpFrameLayoutResponse(int frame_tree_node_id, + const std::string& dump) { // Store the result. auto pair = frame_to_layout_dump_map_.insert( - std::make_pair(sender->GetFrameTreeNodeId(), dump)); + std::make_pair(frame_tree_node_id, dump)); bool insertion_took_place = pair.second; DCHECK(insertion_took_place);
diff --git a/content/shell/browser/layout_test/blink_test_controller.h b/content/shell/browser/layout_test/blink_test_controller.h index e854c88..5bdc5900 100644 --- a/content/shell/browser/layout_test/blink_test_controller.h +++ b/content/shell/browser/layout_test/blink_test_controller.h
@@ -159,8 +159,6 @@ // WebContentsObserver implementation. bool OnMessageReceived(const IPC::Message& message) override; - bool OnMessageReceived(const IPC::Message& message, - RenderFrameHost* render_frame_host) override; void PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) override; void RenderFrameCreated(RenderFrameHost* render_frame_host) override; @@ -204,7 +202,8 @@ void OnImageDump(const std::string& actual_pixel_hash, const SkBitmap& image); void OnTextDump(const std::string& dump); void OnInitiateLayoutDump(); - void OnLayoutDumpResponse(RenderFrameHost* sender, const std::string& dump); + void OnDumpFrameLayoutResponse(int frame_tree_node_id, + const std::string& dump); void OnPrintMessageToStderr(const std::string& message); void OnPrintMessage(const std::string& message); void OnOverridePreferences(const WebPreferences& prefs); @@ -283,7 +282,7 @@ // Map from frame_tree_node_id into frame-specific dumps. std::map<int, std::string> frame_to_layout_dump_map_; - // Number of ShellViewHostMsg_LayoutDumpResponse messages we are waiting for. + // Number of LayoutTestControl.DumpFrameLayout responses we are waiting for. int pending_layout_dumps_; // Renderer processes are observed to detect crashes.
diff --git a/content/shell/common/layout_test.mojom b/content/shell/common/layout_test.mojom index dd61553..19146dd 100644 --- a/content/shell/common/layout_test.mojom +++ b/content/shell/common/layout_test.mojom
@@ -35,9 +35,8 @@ }; interface LayoutTestControl { - // Asks a frame to dump its contents into a string and send them back over - // IPC. - LayoutDumpRequest(); + // Dumps the frame's contents into a string. + DumpFrameLayout() => (string frame_layout_dump); // Replicates test config (for an already started test) to a new renderer // that hosts parts of the main test window.
diff --git a/content/shell/common/shell_content_client.cc b/content/shell/common/shell_content_client.cc index 7e06a28..3cc7fd0 100644 --- a/content/shell/common/shell_content_client.cc +++ b/content/shell/common/shell_content_client.cc
@@ -43,8 +43,6 @@ return base::ASCIIToUTF16("<<OtherDateLabel>>"); case IDS_FORM_OTHER_MONTH_LABEL: return base::ASCIIToUTF16("<<OtherMonthLabel>>"); - case IDS_FORM_OTHER_TIME_LABEL: - return base::ASCIIToUTF16("<<OtherTimeLabel>>"); case IDS_FORM_OTHER_WEEK_LABEL: return base::ASCIIToUTF16("<<OtherWeekLabel>>"); case IDS_FORM_CALENDAR_CLEAR:
diff --git a/content/shell/common/shell_messages.h b/content/shell/common/shell_messages.h index 275c96f..db671cd 100644 --- a/content/shell/common/shell_messages.h +++ b/content/shell/common/shell_messages.h
@@ -51,14 +51,11 @@ std::string /* dump */) // Asks the browser process to perform a layout dump spanning all the -// (potentially cross-process) frames. This triggers multiple -// ShellViewMsg_LayoutDumpRequest / ShellViewHostMsg_LayoutDumpResponse messages -// and ends with sending of ShellViewMsg_LayoutDumpCompleted. +// (potentially cross-process) frames. This goes through multiple +// LayoutTestControl.DumpFrameLayout calls and ends with sending of +// ShellViewMsg_LayoutDumpCompleted. IPC_MESSAGE_ROUTED0(ShellViewHostMsg_InitiateLayoutDump) -// Sends a layout dump of a frame (response to ShellViewMsg_LayoutDumpRequest). -IPC_MESSAGE_ROUTED1(ShellViewHostMsg_LayoutDumpResponse, std::string /* dump */) - // Send an image dump of the WebContents to the render host. IPC_MESSAGE_ROUTED2(ShellViewHostMsg_ImageDump, std::string /* actual pixel hash */,
diff --git a/content/shell/renderer/layout_test/layout_test_render_frame_observer.cc b/content/shell/renderer/layout_test/layout_test_render_frame_observer.cc index e10cca7d..b4193023 100644 --- a/content/shell/renderer/layout_test/layout_test_render_frame_observer.cc +++ b/content/shell/renderer/layout_test/layout_test_render_frame_observer.cc
@@ -8,12 +8,10 @@ #include "content/public/common/associated_interface_registry.h" #include "content/public/renderer/render_frame.h" -#include "content/shell/common/shell_messages.h" #include "content/shell/renderer/layout_test/blink_test_runner.h" #include "content/shell/renderer/layout_test/layout_test_render_thread_observer.h" #include "content/shell/test_runner/web_test_interfaces.h" #include "content/shell/test_runner/web_test_runner.h" -#include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" namespace content { @@ -44,13 +42,14 @@ delete this; } -void LayoutTestRenderFrameObserver::LayoutDumpRequest() { +void LayoutTestRenderFrameObserver::DumpFrameLayout( + DumpFrameLayoutCallback callback) { std::string dump = LayoutTestRenderThreadObserver::GetInstance() ->test_interfaces() ->TestRunner() ->DumpLayout(render_frame()->GetWebFrame()); - Send(new ShellViewHostMsg_LayoutDumpResponse(routing_id(), dump)); + std::move(callback).Run(dump); } void LayoutTestRenderFrameObserver::ReplicateTestConfiguration(
diff --git a/content/shell/renderer/layout_test/layout_test_render_frame_observer.h b/content/shell/renderer/layout_test/layout_test_render_frame_observer.h index bd620c08..cc86135e 100644 --- a/content/shell/renderer/layout_test/layout_test_render_frame_observer.h +++ b/content/shell/renderer/layout_test/layout_test_render_frame_observer.h
@@ -22,7 +22,7 @@ // RenderFrameObserver implementation. void OnDestruct() override; - void LayoutDumpRequest() override; + void DumpFrameLayout(DumpFrameLayoutCallback callback) override; void SetTestConfiguration(mojom::ShellTestConfigurationPtr config) override; void ReplicateTestConfiguration( mojom::ShellTestConfigurationPtr config) override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 6963f2b..fe4acf6 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1420,7 +1420,6 @@ "../common/service_worker/service_worker_utils_unittest.cc", "../common/throttling_url_loader_unittest.cc", "../common/webplugininfo_unittest.cc", - "../network/network_service_unittest.cc", "../network/url_loader_unittest.cc", "../public/test/referrer_unittest.cc", "../public/test/test_browser_thread_bundle_unittest.cc",
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt new file mode 100644 index 0000000..d9de919 --- /dev/null +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt
@@ -0,0 +1,39 @@ +rootWebArea +++grid ariaColumnCount=4 tableRowCount=3 tableColumnCount=3 cellIds=columnHeader,columnHeader,columnHeader,cell,cell,cell,cell,cell,cell +++++row +++++++columnHeader name='Month' ariaCellColumnIndex=1 ariaCellRowIndex=1 +++++++++staticText name='Month' +++++++++++inlineTextBox name='Month' +++++++columnHeader name='Day' ariaCellColumnIndex=2 ariaCellRowIndex=1 +++++++++staticText name='Day' +++++++++++inlineTextBox name='Day' +++++++columnHeader name='Weather' ariaCellColumnIndex=4 ariaCellRowIndex=1 +++++++++staticText name='Weather' +++++++++++inlineTextBox name='Weather' +++++row +++++++cell selectable name='January' ariaCellColumnIndex=1 ariaCellRowIndex=2 +++++++++staticText name='January' +++++++++++inlineTextBox name='January' +++++++cell selectable name='01' ariaCellColumnIndex=2 ariaCellRowIndex=2 +++++++++staticText name='01' +++++++++++inlineTextBox name='01' +++++++cell selectable name='Sunny' ariaCellColumnIndex=4 ariaCellRowIndex=2 +++++++++staticText name='Sunny' +++++++++++inlineTextBox name='Sunny' +++++row +++++++cell selectable name='January' ariaCellColumnIndex=1 ariaCellRowIndex=2 +++++++++staticText name='January' +++++++++++inlineTextBox name='January' +++++++cell selectable name='02' ariaCellColumnIndex=2 ariaCellRowIndex=2 +++++++++staticText name='02' +++++++++++inlineTextBox name='02' +++++++cell selectable name='Rainy' ariaCellColumnIndex=4 ariaCellRowIndex=2 +++++++++staticText name='Rainy' +++++++++++inlineTextBox name='Rainy' +++++column +++++column +++++column +++++tableHeaderContainer +++paragraph +++++staticText name='done' +++++++inlineTextBox name='done'
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt new file mode 100644 index 0000000..073f663 --- /dev/null +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt
@@ -0,0 +1,29 @@ +AXWebArea +++AXGrid AXARIAColumnCount='4' +++++AXRow +++++++AXCell AXTitle='Month' AXARIAColumnIndex='1' AXARIARowIndex='1' +++++++++AXStaticText AXValue='Month' +++++++AXCell AXTitle='Day' AXARIAColumnIndex='2' AXARIARowIndex='1' +++++++++AXStaticText AXValue='Day' +++++++AXCell AXTitle='Weather' AXARIAColumnIndex='4' AXARIARowIndex='1' +++++++++AXStaticText AXValue='Weather' +++++AXRow +++++++AXCell AXTitle='January' AXARIAColumnIndex='1' AXARIARowIndex='2' +++++++++AXStaticText AXValue='January' +++++++AXCell AXTitle='01' AXARIAColumnIndex='2' AXARIARowIndex='2' +++++++++AXStaticText AXValue='01' +++++++AXCell AXTitle='Sunny' AXARIAColumnIndex='4' AXARIARowIndex='2' +++++++++AXStaticText AXValue='Sunny' +++++AXRow +++++++AXCell AXTitle='January' AXARIAColumnIndex='1' AXARIARowIndex='2' +++++++++AXStaticText AXValue='January' +++++++AXCell AXTitle='02' AXARIAColumnIndex='2' AXARIARowIndex='2' +++++++++AXStaticText AXValue='02' +++++++AXCell AXTitle='Rainy' AXARIAColumnIndex='4' AXARIARowIndex='2' +++++++++AXStaticText AXValue='Rainy' +++++AXColumn +++++AXColumn +++++AXColumn +++++AXGroup +++AXGroup +++++AXStaticText AXValue='done'
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt new file mode 100644 index 0000000..6a5ec4bc --- /dev/null +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt
@@ -0,0 +1,29 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++ROLE_SYSTEM_TABLE colcount:4 +++++ROLE_SYSTEM_ROW +++++++ROLE_SYSTEM_COLUMNHEADER name='Month' colindex:1 rowindex:1 +++++++++ROLE_SYSTEM_STATICTEXT name='Month' +++++++ROLE_SYSTEM_COLUMNHEADER name='Day' colindex:2 rowindex:1 +++++++++ROLE_SYSTEM_STATICTEXT name='Day' +++++++ROLE_SYSTEM_COLUMNHEADER name='Weather' colindex:4 rowindex:1 +++++++++ROLE_SYSTEM_STATICTEXT name='Weather' +++++ROLE_SYSTEM_ROW +++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:1 rowindex:2 +++++++++ROLE_SYSTEM_STATICTEXT name='January' +++++++ROLE_SYSTEM_CELL name='01' FOCUSABLE colindex:2 rowindex:2 +++++++++ROLE_SYSTEM_STATICTEXT name='01' +++++++ROLE_SYSTEM_CELL name='Sunny' FOCUSABLE colindex:4 rowindex:2 +++++++++ROLE_SYSTEM_STATICTEXT name='Sunny' +++++ROLE_SYSTEM_ROW +++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:1 rowindex:2 +++++++++ROLE_SYSTEM_STATICTEXT name='January' +++++++ROLE_SYSTEM_CELL name='02' FOCUSABLE colindex:2 rowindex:2 +++++++++ROLE_SYSTEM_STATICTEXT name='02' +++++++ROLE_SYSTEM_CELL name='Rainy' FOCUSABLE colindex:4 rowindex:2 +++++++++ROLE_SYSTEM_STATICTEXT name='Rainy' +++++ROLE_SYSTEM_COLUMN +++++ROLE_SYSTEM_COLUMN +++++ROLE_SYSTEM_COLUMN +++++IA2_ROLE_SECTION +++IA2_ROLE_PARAGRAPH +++++ROLE_SYSTEM_STATICTEXT name='done'
diff --git a/content/test/data/accessibility/aria/table-column-hidden.html b/content/test/data/accessibility/aria/table-column-hidden.html new file mode 100644 index 0000000..85802a1 --- /dev/null +++ b/content/test/data/accessibility/aria/table-column-hidden.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<!-- +@WAIT-FOR:done +@WIN-ALLOW:colcount* +@WIN-ALLOW:colindex* +@WIN-ALLOW:rowcount* +@WIN-ALLOW:rowindex* +@MAC-ALLOW:AXARIAColumn* +@MAC-ALLOW:AXARIARow* +@BLINK-ALLOW:cellIds* +@BLINK-ALLOW:*ColumnCount* +@BLINK-ALLOW:ariaCellColumnIndex* +@BLINK-ALLOW:*RowCount* +@BLINK-ALLOW:ariaCellRowIndex* +--> +<table role="grid" aria-rowcount="3" aria-colcount="4"> + <tbody><tr> + <th aria-rowindex="1" aria-colindex="1">Month</th> + <th aria-rowindex="1" aria-colindex="2">Day</th> + <th aria-rowindex="1" aria-colindex="3">Year</th> + <th aria-rowindex="1" aria-colindex="4">Weather</th> + </tr> + <tr> + <td role="gridcell" tabindex="0" aria-rowindex="2" aria-colindex="1">January</td> + <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="2">01</td> + <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="3">2017</td> + <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="4">Sunny</td> + </tr> + <tr> + <td role="gridcell" tabindex="0" aria-rowindex="2" aria-colindex="1">January</td> + <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="2">02</td> + <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="3">2017</td> + <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="4">Rainy</td> + </tr> + </tbody> +</table> +<p></p> + +<script> + // Hide the year column. + let cells = document.querySelectorAll('[aria-colindex="3"]'); + for (let cell of cells) { + cell.style.display = 'none'; + } + document.querySelector('p').textContent = 'done'; +</script>
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index 636209c1..a06bce8 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -259,12 +259,6 @@ self.Flaky('conformance/canvas/canvas-test.html', ['win7', 'nvidia', 'd3d9'], bug=690248) - # Win / AMD flakiness seen on new tryservers. - # It's unfortunate that this suppression needs to be so broad, but - # basically any test that uses readPixels is potentially flaky, and - # it's infeasible to suppress individual failures one by one. - self.Flaky('conformance/*', ['win', ('amd', 0x6779)], bug=491419) - # Win AMD failures # This test is probably flaky on all AMD, but only visible on the # new AMD (the whole test suite is flaky on the old config). @@ -314,12 +308,6 @@ # Win / OpenGL / AMD failures self.Skip('conformance/attribs/gl-bindAttribLocation-aliasing.html', ['win', 'amd', 'opengl'], bug=649824) - self.Flaky('conformance/attribs/gl-bindAttribLocation-matrix.html', - ['win', ('amd', 0x6779), 'opengl'], bug=649824) - self.Flaky('conformance/attribs/gl-bindAttribLocation-repeated.html', - ['win', ('amd', 0x6779), 'opengl'], bug=649824) - self.Fail('conformance/extensions/webgl-draw-buffers.html', - ['win', ('amd', 0x6779), 'opengl', 'no_passthrough'], bug=649824) self.Skip('conformance/glsl/misc/shader-struct-scope.html', ['win', 'amd', 'opengl'], bug=1007) # angle bug ID self.Skip('conformance/glsl/misc/shaders-with-invariance.html', @@ -446,30 +434,8 @@ # AMD Radeon 6450 and/or R7 240 self.Fail('conformance/extensions/angle-instanced-arrays.html', ['linux', 'amd', 'no_angle'], bug=479260) - self.Flaky('conformance/extensions/ext-texture-filter-anisotropic.html', - ['linux', ('amd', 0x6779)], bug=436212) - self.Flaky('conformance/glsl/misc/shader-struct-scope.html', - ['linux', ('amd', 0x6779), 'no_passthrough'], bug=436212) - self.Flaky('conformance/glsl/misc/struct-nesting-of-variable-names.html', - ['linux', ('amd', 0x6779), 'no_passthrough'], bug=436212) - self.Flaky('conformance/rendering/point-size.html', - ['linux', ('amd', 0x6779)], bug=436212) - self.Flaky('conformance/textures/misc/texture-sub-image-cube-maps.html', - ['linux', ('amd', 0x6779)], bug=436212) - self.Flaky('conformance/more/functions/uniformf.html', - ['linux', ('amd', 0x6779)], bug=436212) self.Fail('conformance/glsl/misc/shaders-with-invariance.html', ['linux', 'amd', 'no_passthrough'], bug=479952) - self.Flaky('conformance/textures/misc/texture-mips.html', - ['linux', ('amd', 0x6779), 'no_passthrough'], bug=479981) - self.Flaky('conformance/textures/misc/texture-size-cube-maps.html', - ['linux', ('amd', 0x6779)], bug=479983) - self.Flaky('conformance/uniforms/uniform-default-values.html', - ['linux', ('amd', 0x6779)], bug=482013) - self.Flaky('conformance/glsl/samplers/glsl-function-texture2dlod.html', - ['linux', ('amd', 0x6779)], bug=436212) - self.Flaky('conformance/glsl/samplers/glsl-function-texture2dprojlod.html', - ['linux', ('amd', 0x6779)], bug=436212) # Intel # See https://bugs.freedesktop.org/show_bug.cgi?id=94477 self.Skip('conformance/glsl/bugs/temp-expressions-should-not-crash.html',
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc index 7150daf1..c8e4a28 100644 --- a/content/test/test_blink_web_unit_test_support.cc +++ b/content/test/test_blink_web_unit_test_support.cc
@@ -214,8 +214,6 @@ return WebString::FromASCII("<<OtherDateLabel>>"); case blink::WebLocalizedString::kOtherMonthLabel: return WebString::FromASCII("<<OtherMonthLabel>>"); - case blink::WebLocalizedString::kOtherTimeLabel: - return WebString::FromASCII("<<OtherTimeLabel>>"); case blink::WebLocalizedString::kOtherWeekLabel: return WebString::FromASCII("<<OtherWeekLabel>>"); case blink::WebLocalizedString::kCalendarClear:
diff --git a/device/generic_sensor/platform_sensor_provider_base.h b/device/generic_sensor/platform_sensor_provider_base.h index c38443b..eb5d86c0 100644 --- a/device/generic_sensor/platform_sensor_provider_base.h +++ b/device/generic_sensor/platform_sensor_provider_base.h
@@ -38,7 +38,7 @@ // Implementations might want to override this in order to be able // to read from sensor files. For example, linux does so. virtual void SetFileTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {} + scoped_refptr<base::SequencedTaskRunner> file_task_runner) {} protected: PlatformSensorProviderBase();
diff --git a/device/generic_sensor/platform_sensor_provider_linux.cc b/device/generic_sensor/platform_sensor_provider_linux.cc index 4db2a4c..4e296e18 100644 --- a/device/generic_sensor/platform_sensor_provider_linux.cc +++ b/device/generic_sensor/platform_sensor_provider_linux.cc
@@ -78,7 +78,7 @@ } void PlatformSensorProviderLinux::SetFileTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { + scoped_refptr<base::SequencedTaskRunner> file_task_runner) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!file_task_runner_) file_task_runner_ = file_task_runner; @@ -109,7 +109,7 @@ void PlatformSensorProviderLinux::StopPollingThread() { DCHECK(file_task_runner_); - DCHECK(file_task_runner_->BelongsToCurrentThread()); + DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); if (polling_thread_ && polling_thread_->IsRunning()) polling_thread_->Stop(); } @@ -147,7 +147,7 @@ } void PlatformSensorProviderLinux::SetFileTaskRunnerForTesting( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + scoped_refptr<base::SequencedTaskRunner> task_runner) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); file_task_runner_ = std::move(task_runner); }
diff --git a/device/generic_sensor/platform_sensor_provider_linux.h b/device/generic_sensor/platform_sensor_provider_linux.h index 5bde10f..e7e0a08f 100644 --- a/device/generic_sensor/platform_sensor_provider_linux.h +++ b/device/generic_sensor/platform_sensor_provider_linux.h
@@ -15,7 +15,7 @@ template <typename T> struct DefaultSingletonTraits; class Thread; -} +} // namespace base namespace device { @@ -33,7 +33,7 @@ // Sets task runner for tests. void SetFileTaskRunnerForTesting( - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + scoped_refptr<base::SequencedTaskRunner> task_runner); protected: ~PlatformSensorProviderLinux() override; @@ -45,7 +45,7 @@ void AllSensorsRemoved() override; void SetFileTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) override; + scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; private: friend struct base::DefaultSingletonTraits<PlatformSensorProviderLinux>; @@ -112,7 +112,7 @@ // Browser's file thread task runner passed from renderer. Used by this // provider to stop a polling thread and passed to a manager that // runs a linux device monitor service on this task runner. - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; DISALLOW_COPY_AND_ASSIGN(PlatformSensorProviderLinux); };
diff --git a/device/generic_sensor/sensor_provider_impl.cc b/device/generic_sensor/sensor_provider_impl.cc index 3e78e3a1..501c67a 100644 --- a/device/generic_sensor/sensor_provider_impl.cc +++ b/device/generic_sensor/sensor_provider_impl.cc
@@ -34,7 +34,7 @@ // static void SensorProviderImpl::Create( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> file_task_runner, mojom::SensorProviderRequest request) { PlatformSensorProvider* provider = PlatformSensorProvider::GetInstance(); if (provider) {
diff --git a/device/generic_sensor/sensor_provider_impl.h b/device/generic_sensor/sensor_provider_impl.h index 2dd3728b..380fa7bc 100644 --- a/device/generic_sensor/sensor_provider_impl.h +++ b/device/generic_sensor/sensor_provider_impl.h
@@ -6,7 +6,7 @@ #define DEVICE_GENERIC_SENSOR_SENSOR_PROVIDER_IMPL_H_ #include "base/macros.h" -#include "base/single_thread_task_runner.h" +#include "base/sequenced_task_runner.h" #include "device/generic_sensor/generic_sensor_export.h" #include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" @@ -21,9 +21,8 @@ class DEVICE_GENERIC_SENSOR_EXPORT SensorProviderImpl final : public mojom::SensorProvider { public: - static void Create( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, - mojom::SensorProviderRequest request); + static void Create(scoped_refptr<base::SequencedTaskRunner> file_task_runner, + mojom::SensorProviderRequest request); ~SensorProviderImpl() override;
diff --git a/device/power_save_blocker/power_save_blocker.h b/device/power_save_blocker/power_save_blocker.h index 621eaef..a9544b8 100644 --- a/device/power_save_blocker/power_save_blocker.h +++ b/device/power_save_blocker/power_save_blocker.h
@@ -58,7 +58,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner); + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); virtual ~PowerSaveBlocker(); #if defined(OS_ANDROID)
diff --git a/device/power_save_blocker/power_save_blocker_android.cc b/device/power_save_blocker/power_save_blocker_android.cc index 3aa5346..5227065 100644 --- a/device/power_save_blocker/power_save_blocker_android.cc +++ b/device/power_save_blocker/power_save_blocker_android.cc
@@ -71,7 +71,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : ui_task_runner_(ui_task_runner), blocking_task_runner_(blocking_task_runner) { // Don't support kPowerSaveBlockPreventAppSuspension
diff --git a/device/power_save_blocker/power_save_blocker_chromeos.cc b/device/power_save_blocker/power_save_blocker_chromeos.cc index f3390147..0dd1bee 100644 --- a/device/power_save_blocker/power_save_blocker_chromeos.cc +++ b/device/power_save_blocker/power_save_blocker_chromeos.cc
@@ -97,7 +97,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : delegate_(new Delegate(type, reason, description, ui_task_runner)), ui_task_runner_(ui_task_runner), blocking_task_runner_(blocking_task_runner) {
diff --git a/device/power_save_blocker/power_save_blocker_mac.cc b/device/power_save_blocker/power_save_blocker_mac.cc index 4ce6c18..97f6734d 100644 --- a/device/power_save_blocker/power_save_blocker_mac.cc +++ b/device/power_save_blocker/power_save_blocker_mac.cc
@@ -84,8 +84,8 @@ base::SysUTF8ToCFStringRef(description_)); IOReturn result = IOPMAssertionCreateWithName(level, kIOPMAssertionLevelOn, cf_description, &assertion_); - LOG_IF(ERROR, result != kIOReturnSuccess) << "IOPMAssertionCreate: " - << result; + LOG_IF(ERROR, result != kIOReturnSuccess) + << "IOPMAssertionCreate: " << result; } } @@ -95,8 +95,8 @@ if (assertion_ != kIOPMNullAssertionID) { IOReturn result = IOPMAssertionRelease(assertion_); - LOG_IF(ERROR, result != kIOReturnSuccess) << "IOPMAssertionRelease: " - << result; + LOG_IF(ERROR, result != kIOReturnSuccess) + << "IOPMAssertionRelease: " << result; } } @@ -105,7 +105,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : delegate_(new Delegate(type, description)), ui_task_runner_(ui_task_runner), blocking_task_runner_(blocking_task_runner) {
diff --git a/device/power_save_blocker/power_save_blocker_ozone.cc b/device/power_save_blocker/power_save_blocker_ozone.cc index 981794eb..21f0f25 100644 --- a/device/power_save_blocker/power_save_blocker_ozone.cc +++ b/device/power_save_blocker/power_save_blocker_ozone.cc
@@ -30,7 +30,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : delegate_(new Delegate()), ui_task_runner_(ui_task_runner), blocking_task_runner_(blocking_task_runner) {}
diff --git a/device/power_save_blocker/power_save_blocker_win.cc b/device/power_save_blocker/power_save_blocker_win.cc index 83830a7..ee7b92a 100644 --- a/device/power_save_blocker/power_save_blocker_win.cc +++ b/device/power_save_blocker/power_save_blocker_win.cc
@@ -113,7 +113,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : delegate_(new Delegate(type, description, ui_task_runner)), ui_task_runner_(ui_task_runner), blocking_task_runner_(blocking_task_runner) {
diff --git a/device/power_save_blocker/power_save_blocker_x11.cc b/device/power_save_blocker/power_save_blocker_x11.cc index 56e6584b..e2a66147 100644 --- a/device/power_save_blocker/power_save_blocker_x11.cc +++ b/device/power_save_blocker/power_save_blocker_x11.cc
@@ -81,7 +81,7 @@ const std::string& description, bool freedesktop_only, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner); + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); // Post a task to initialize the delegate on the UI thread, which will itself // then post a task to apply the power save block on the FILE thread. @@ -164,7 +164,7 @@ uint32_t inhibit_cookie_; scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner_; + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; DISALLOW_COPY_AND_ASSIGN(Delegate); }; @@ -174,7 +174,7 @@ const std::string& description, bool freedesktop_only, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : type_(type), description_(description), freedesktop_only_(freedesktop_only), @@ -486,7 +486,7 @@ Reason reason, const std::string& description, scoped_refptr<base::SequencedTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : delegate_(new Delegate(type, description, false /* freedesktop_only */,
diff --git a/device/wake_lock/wake_lock.cc b/device/wake_lock/wake_lock.cc index 2bef9ed..d767587 100644 --- a/device/wake_lock/wake_lock.cc +++ b/device/wake_lock/wake_lock.cc
@@ -51,7 +51,7 @@ const std::string& description, int context_id, WakeLockContextCallback native_view_getter, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) + scoped_refptr<base::SequencedTaskRunner> file_task_runner) : num_lock_requests_(0), type_(type), reason_(reason),
diff --git a/device/wake_lock/wake_lock.h b/device/wake_lock/wake_lock.h index 4686570..5dfee6b 100644 --- a/device/wake_lock/wake_lock.h +++ b/device/wake_lock/wake_lock.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" +#include "base/sequenced_task_runner.h" #include "device/power_save_blocker/power_save_blocker.h" #include "device/wake_lock/public/interfaces/wake_lock.mojom.h" #include "device/wake_lock/public/interfaces/wake_lock_context.mojom.h" @@ -27,7 +27,7 @@ const std::string& description, int context_id, WakeLockContextCallback native_view_getter, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); + scoped_refptr<base::SequencedTaskRunner> file_task_runner); ~WakeLock() override; // WakeLockSevice implementation. @@ -59,7 +59,7 @@ #endif scoped_refptr<base::SequencedTaskRunner> main_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; // The actual power save blocker for screen. std::unique_ptr<PowerSaveBlocker> wake_lock_;
diff --git a/device/wake_lock/wake_lock_context.cc b/device/wake_lock/wake_lock_context.cc index dd11d52..ef7131b 100644 --- a/device/wake_lock/wake_lock_context.cc +++ b/device/wake_lock/wake_lock_context.cc
@@ -14,7 +14,7 @@ WakeLockContext::WakeLockContext( int context_id, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> file_task_runner, const WakeLockContextCallback& native_view_getter) : file_task_runner_(std::move(file_task_runner)), context_id_(context_id),
diff --git a/device/wake_lock/wake_lock_context.h b/device/wake_lock/wake_lock_context.h index 2e02be8..a897b4d 100644 --- a/device/wake_lock/wake_lock_context.h +++ b/device/wake_lock/wake_lock_context.h
@@ -10,7 +10,7 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" +#include "base/sequenced_task_runner.h" #include "device/wake_lock/public/interfaces/wake_lock_context.mojom.h" #include "ui/gfx/native_widget_types.h" @@ -25,7 +25,7 @@ class WakeLockContext : public mojom::WakeLockContext { public: WakeLockContext(int context_id, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> file_task_runner, const WakeLockContextCallback& native_view_getter); ~WakeLockContext() override; @@ -38,7 +38,7 @@ static const int WakeLockInvalidContextId; private: - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; int context_id_; WakeLockContextCallback native_view_getter_;
diff --git a/device/wake_lock/wake_lock_for_testing.cc b/device/wake_lock/wake_lock_for_testing.cc index 776bd56..bc4bfac 100644 --- a/device/wake_lock/wake_lock_for_testing.cc +++ b/device/wake_lock/wake_lock_for_testing.cc
@@ -15,7 +15,7 @@ const std::string& description, int context_id, WakeLockContextCallback native_view_getter, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) + scoped_refptr<base::SequencedTaskRunner> file_task_runner) : WakeLock(std::move(request), type, reason,
diff --git a/device/wake_lock/wake_lock_for_testing.h b/device/wake_lock/wake_lock_for_testing.h index 3de901ca..8ab62ff5 100644 --- a/device/wake_lock/wake_lock_for_testing.h +++ b/device/wake_lock/wake_lock_for_testing.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" +#include "base/sequenced_task_runner.h" #include "device/wake_lock/public/interfaces/wake_lock.mojom.h" #include "device/wake_lock/public/interfaces/wake_lock_context.mojom.h" #include "device/wake_lock/wake_lock.h" @@ -20,14 +20,13 @@ class WakeLockForTesting : public WakeLock { public: - WakeLockForTesting( - mojom::WakeLockRequest request, - mojom::WakeLockType type, - mojom::WakeLockReason reason, - const std::string& description, - int context_id, - WakeLockContextCallback native_view_getter, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); + WakeLockForTesting(mojom::WakeLockRequest request, + mojom::WakeLockType type, + mojom::WakeLockReason reason, + const std::string& description, + int context_id, + WakeLockContextCallback native_view_getter, + scoped_refptr<base::SequencedTaskRunner> file_task_runner); ~WakeLockForTesting() override; void HasWakeLockForTests(HasWakeLockForTestsCallback callback) override;
diff --git a/device/wake_lock/wake_lock_provider.cc b/device/wake_lock/wake_lock_provider.cc index 26e4aa1..c1062e19 100644 --- a/device/wake_lock/wake_lock_provider.cc +++ b/device/wake_lock/wake_lock_provider.cc
@@ -17,7 +17,7 @@ // static void WakeLockProvider::Create( mojom::WakeLockProviderRequest request, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> file_task_runner, const WakeLockContextCallback& native_view_getter) { mojo::MakeStrongBinding(base::MakeUnique<WakeLockProvider>( std::move(file_task_runner), native_view_getter), @@ -25,7 +25,7 @@ } WakeLockProvider::WakeLockProvider( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> file_task_runner, const WakeLockContextCallback& native_view_getter) : file_task_runner_(std::move(file_task_runner)), native_view_getter_(native_view_getter) {}
diff --git a/device/wake_lock/wake_lock_provider.h b/device/wake_lock/wake_lock_provider.h index 297c0ee..72b4442f1 100644 --- a/device/wake_lock/wake_lock_provider.h +++ b/device/wake_lock/wake_lock_provider.h
@@ -6,7 +6,6 @@ #define DEVICE_WAKE_LOCK_WAKE_LOCK_PROVIDER_H_ #include "base/sequenced_task_runner.h" -#include "base/single_thread_task_runner.h" #include "device/wake_lock/public/interfaces/wake_lock_context.mojom.h" #include "device/wake_lock/public/interfaces/wake_lock_provider.mojom.h" #include "device/wake_lock/wake_lock_context.h" @@ -18,14 +17,13 @@ // Serves requests for WakeLockContext connections. class WakeLockProvider : public mojom::WakeLockProvider { public: - WakeLockProvider(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + WakeLockProvider(scoped_refptr<base::SequencedTaskRunner> file_task_runner, const WakeLockContextCallback& native_view_getter); ~WakeLockProvider() override; - static void Create( - mojom::WakeLockProviderRequest request, - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, - const WakeLockContextCallback& native_view_getter); + static void Create(mojom::WakeLockProviderRequest request, + scoped_refptr<base::SequencedTaskRunner> file_task_runner, + const WakeLockContextCallback& native_view_getter); // mojom::WakeLockProvider: void GetWakeLockContextForID( @@ -40,7 +38,7 @@ static bool is_in_unittest_; private: - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; WakeLockContextCallback native_view_getter_; DISALLOW_COPY_AND_ASSIGN(WakeLockProvider);
diff --git a/extensions/browser/api/api_resource_manager.h b/extensions/browser/api/api_resource_manager.h index 8626e21..d8ca7c33 100644 --- a/extensions/browser/api/api_resource_manager.h +++ b/extensions/browser/api/api_resource_manager.h
@@ -36,7 +36,7 @@ class TCPServerSocketEventDispatcher; class TCPSocketEventDispatcher; class UDPSocketEventDispatcher; -} +} // namespace api template <typename T> struct NamedThreadTraits { @@ -126,12 +126,12 @@ } // BrowserContextKeyedAPI implementation. - static BrowserContextKeyedAPIFactory<ApiResourceManager<T> >* - GetFactoryInstance(); + static BrowserContextKeyedAPIFactory<ApiResourceManager<T>>* + GetFactoryInstance(); // Convenience method to get the ApiResourceManager for a profile. static ApiResourceManager<T>* Get(content::BrowserContext* context) { - return BrowserContextKeyedAPIFactory<ApiResourceManager<T> >::Get(context); + return BrowserContextKeyedAPIFactory<ApiResourceManager<T>>::Get(context); } // BrowserContextKeyedAPI implementation. @@ -171,7 +171,7 @@ friend class api::TCPServerSocketEventDispatcher; friend class api::TCPSocketEventDispatcher; friend class api::UDPSocketEventDispatcher; - friend class BrowserContextKeyedAPIFactory<ApiResourceManager<T> >; + friend class BrowserContextKeyedAPIFactory<ApiResourceManager<T>>; static const bool kServiceHasOwnInstanceInIncognito = true; static const bool kServiceIsNULLWhileTesting = true; @@ -182,7 +182,7 @@ public: typedef std::map<int, std::unique_ptr<T>> ApiResourceMap; // Lookup map from extension id's to allocated resource id's. - typedef std::map<std::string, base::hash_set<int> > ExtensionToResourceMap; + typedef std::map<std::string, base::hash_set<int>> ExtensionToResourceMap; ApiResourceData() : next_id_(1) { sequence_checker_.DetachFromSequence(); } @@ -197,8 +197,9 @@ ExtensionToResourceMap::iterator it = extension_resource_map_.find(extension_id); if (it == extension_resource_map_.end()) { - it = extension_resource_map_.insert( - std::make_pair(extension_id, base::hash_set<int>())).first; + it = extension_resource_map_ + .insert(std::make_pair(extension_id, base::hash_set<int>())) + .first; } it->second.insert(id); return id; @@ -243,24 +244,22 @@ } void InitiateExtensionUnloadedCleanup(const std::string& extension_id) { - ThreadingTraits::GetSequencedTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension, - this, - extension_id)); + ThreadingTraits::GetSequencedTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension, + this, extension_id)); } void InitiateExtensionSuspendedCleanup(const std::string& extension_id) { - ThreadingTraits::GetSequencedTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension, - this, - extension_id)); + ThreadingTraits::GetSequencedTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension, + this, extension_id)); } void InititateCleanup() { - ThreadingTraits::GetSequencedTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ApiResourceData::Cleanup, this)); + ThreadingTraits::GetSequencedTaskRunner()->PostTask( + FROM_HERE, base::Bind(&ApiResourceData::Cleanup, this)); } private: @@ -378,65 +377,6 @@ } }; -// With WorkerPoolThreadTraits, ApiResourceManager can be used to manage the -// lifetime of a set of resources that live on sequenced task runner threads -// which ApiFunctions use. Examples of such resources are temporary file -// resources produced by certain API calls. -// -// Instead of kThreadId. classes used for tracking such resources should define -// kSequenceToken and kShutdownBehavior to identify sequence task runner for -// ApiResourceManager to work on and how pending tasks should behave on -// shutdown. -// The user must also define a static const char* service_name() that returns -// the name of the service, and in order for ApiWorkerPoolResourceManager to use -// service_name() friend this class. -// -// In the cc file the user must define a GetFactoryInstance() and manage their -// own instances (typically using LazyInstance or Singleton). -// -// E.g.: -// -// class PoolResource { -// public: -// static const char kSequenceToken[] = "temp_files"; -// static const base::SequencedWorkerPool::WorkerShutdown kShutdownBehavior = -// base::SequencedWorkerPool::BLOCK_SHUTDOWN; -// private: -// friend class ApiResourceManager<WorkerPoolResource, -// WorkerPoolThreadTraits>; -// static const char* service_name() { -// return "TempFilesResourceManager"; -// } -// }; -// -// In the cc file: -// -// static base::LazyInstance<BrowserContextKeyedAPIFactory< -// ApiResourceManager<Resource, WorkerPoolThreadTraits> > > -// g_factory = LAZY_INSTANCE_INITIALIZER; -// -// -// template <> -// BrowserContextKeyedAPIFactory<ApiResourceManager<WorkerPoolResource> >* -// ApiResourceManager<WorkerPoolPoolResource, -// WorkerPoolThreadTraits>::GetFactoryInstance() { -// return g_factory.Pointer(); -// } -template <typename T> -struct WorkerPoolThreadTraits { - static bool IsMessageLoopValid() { - return content::BrowserThread::GetBlockingPool() != NULL; - } - - static scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() { - return content::BrowserThread::GetBlockingPool() - ->GetSequencedTaskRunnerWithShutdownBehavior( - content::BrowserThread::GetBlockingPool()->GetNamedSequenceToken( - T::kSequenceToken), - T::kShutdownBehavior); - } -}; - } // namespace extensions #endif // EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_
diff --git a/extensions/browser/api/async_api_function.cc b/extensions/browser/api/async_api_function.cc index a4e40f6f..b17063f 100644 --- a/extensions/browser/api/async_api_function.cc +++ b/extensions/browser/api/async_api_function.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/async_api_function.h" #include "base/bind.h" +#include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" using content::BrowserThread; @@ -12,7 +13,9 @@ namespace extensions { // AsyncApiFunction -AsyncApiFunction::AsyncApiFunction() : work_thread_id_(BrowserThread::IO) {} +AsyncApiFunction::AsyncApiFunction() + : work_task_runner_( + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) {} AsyncApiFunction::~AsyncApiFunction() {} @@ -22,15 +25,15 @@ if (!PrePrepare() || !Prepare()) { return false; } - bool rv = BrowserThread::PostTask( - work_thread_id_, - FROM_HERE, - base::Bind(&AsyncApiFunction::WorkOnWorkThread, this)); + bool rv = work_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&AsyncApiFunction::WorkOnWorkThread, this)); DCHECK(rv); return true; } -bool AsyncApiFunction::PrePrepare() { return true; } +bool AsyncApiFunction::PrePrepare() { + return true; +} void AsyncApiFunction::Work() {} @@ -42,8 +45,7 @@ void AsyncApiFunction::AsyncWorkCompleted() { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { bool rv = BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, + BrowserThread::UI, FROM_HERE, base::Bind(&AsyncApiFunction::RespondOnUIThread, this)); DCHECK(rv); } else { @@ -52,11 +54,7 @@ } void AsyncApiFunction::WorkOnWorkThread() { - DCHECK_CURRENTLY_ON(work_thread_id_); - DLOG_IF(ERROR, (work_thread_id_ == BrowserThread::UI)) - << "You have specified that AsyncApiFunction::Work() should happen on " - "the UI thread. This nullifies the point of this class. Either " - "specify a different thread or derive from a different class."; + DCHECK(work_task_runner_->RunsTasksInCurrentSequence()); AsyncWorkStart(); }
diff --git a/extensions/browser/api/async_api_function.h b/extensions/browser/api/async_api_function.h index e260806..ab47953 100644 --- a/extensions/browser/api/async_api_function.h +++ b/extensions/browser/api/async_api_function.h
@@ -5,7 +5,8 @@ #ifndef EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_ #define EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_ -#include "content/public/browser/browser_thread.h" +#include "base/memory/ref_counted.h" +#include "base/sequenced_task_runner.h" #include "extensions/browser/extension_function.h" namespace extensions { @@ -25,11 +26,11 @@ // thread. virtual bool Prepare() = 0; - // Do actual work. Guaranteed to happen on the thread specified in - // work_thread_id_. + // Do actual work. Guaranteed to happen on the task runner specified in + // |work_task_runner_| if non-null; or on the IO thread otherwise. virtual void Work(); - // Start the asynchronous work. Guraranteed to happen on requested thread. + // Start the asynchronous work. Guraranteed to happen on work thread. virtual void AsyncWorkStart(); // Notify AsyncIOApiFunction that the work is completed @@ -42,9 +43,12 @@ bool RunAsync() override; protected: - content::BrowserThread::ID work_thread_id() const { return work_thread_id_; } - void set_work_thread_id(content::BrowserThread::ID work_thread_id) { - work_thread_id_ = work_thread_id; + scoped_refptr<base::SequencedTaskRunner> work_task_runner() const { + return work_task_runner_; + } + void set_work_task_runner( + scoped_refptr<base::SequencedTaskRunner> work_task_runner) { + work_task_runner_ = work_task_runner; } private: @@ -52,8 +56,8 @@ void RespondOnUIThread(); // If you don't want your Work() method to happen on the IO thread, then set - // this to the thread that you do want, preferably in Prepare(). - content::BrowserThread::ID work_thread_id_; + // this to the SequenceTaskRunner you do want to use, preferably in Prepare(). + scoped_refptr<base::SequencedTaskRunner> work_task_runner_; }; } // namespace extensions
diff --git a/extensions/browser/api/document_scan/document_scan_api.cc b/extensions/browser/api/document_scan/document_scan_api.cc index 317199f..54e9b95f 100644 --- a/extensions/browser/api/document_scan/document_scan_api.cc +++ b/extensions/browser/api/document_scan/document_scan_api.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/document_scan/document_scan_api.h" #include "base/stl_util.h" +#include "base/task_scheduler/post_task.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" @@ -23,14 +24,13 @@ namespace api { DocumentScanScanFunction::DocumentScanScanFunction() - : document_scan_interface_(DocumentScanInterface::CreateInstance()) { -} + : document_scan_interface_(DocumentScanInterface::CreateInstance()) {} -DocumentScanScanFunction::~DocumentScanScanFunction() { -} +DocumentScanScanFunction::~DocumentScanScanFunction() {} bool DocumentScanScanFunction::Prepare() { - set_work_thread_id(BrowserThread::FILE); + set_work_task_runner(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); params_ = document_scan::Scan::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); return true;
diff --git a/extensions/browser/api/serial/serial_api.cc b/extensions/browser/api/serial/serial_api.cc index d7326aa..734b6b3 100644 --- a/extensions/browser/api/serial/serial_api.cc +++ b/extensions/browser/api/serial/serial_api.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <vector> +#include "base/task_scheduler/post_task.h" #include "base/values.h" #include "build/build_config.h" #include "content/public/browser/browser_thread.h" @@ -50,11 +51,9 @@ } // namespace -SerialAsyncApiFunction::SerialAsyncApiFunction() : manager_(NULL) { -} +SerialAsyncApiFunction::SerialAsyncApiFunction() : manager_(NULL) {} -SerialAsyncApiFunction::~SerialAsyncApiFunction() { -} +SerialAsyncApiFunction::~SerialAsyncApiFunction() {} bool SerialAsyncApiFunction::PrePrepare() { manager_ = ApiResourceManager<SerialConnection>::Get(browser_context()); @@ -75,16 +74,16 @@ manager_->Remove(extension_->id(), api_resource_id); } -SerialGetDevicesFunction::SerialGetDevicesFunction() { -} +SerialGetDevicesFunction::SerialGetDevicesFunction() {} bool SerialGetDevicesFunction::Prepare() { - set_work_thread_id(BrowserThread::FILE); + set_work_task_runner(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); return true; } void SerialGetDevicesFunction::Work() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + DCHECK(work_task_runner()->RunsTasksInCurrentSequence()); std::unique_ptr<device::SerialDeviceEnumerator> enumerator = device::SerialDeviceEnumerator::Create(); @@ -93,11 +92,9 @@ mojo::ConvertTo<std::vector<serial::DeviceInfo>>(devices)); } -SerialConnectFunction::SerialConnectFunction() { -} +SerialConnectFunction::SerialConnectFunction() {} -SerialConnectFunction::~SerialConnectFunction() { -} +SerialConnectFunction::~SerialConnectFunction() {} bool SerialConnectFunction::Prepare() { params_ = serial::Connect::Params::Create(*args_); @@ -144,8 +141,7 @@ } BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, + BrowserThread::IO, FROM_HERE, base::Bind(&SerialConnectFunction::FinishConnect, this)); } @@ -174,11 +170,9 @@ return new SerialConnection(port, extension_id); } -SerialUpdateFunction::SerialUpdateFunction() { -} +SerialUpdateFunction::SerialUpdateFunction() {} -SerialUpdateFunction::~SerialUpdateFunction() { -} +SerialUpdateFunction::~SerialUpdateFunction() {} bool SerialUpdateFunction::Prepare() { params_ = serial::Update::Params::Create(*args_); @@ -197,11 +191,9 @@ results_ = serial::Update::Results::Create(success); } -SerialDisconnectFunction::SerialDisconnectFunction() { -} +SerialDisconnectFunction::SerialDisconnectFunction() {} -SerialDisconnectFunction::~SerialDisconnectFunction() { -} +SerialDisconnectFunction::~SerialDisconnectFunction() {} bool SerialDisconnectFunction::Prepare() { params_ = serial::Disconnect::Params::Create(*args_); @@ -220,11 +212,9 @@ results_ = serial::Disconnect::Results::Create(true); } -SerialSendFunction::SerialSendFunction() { -} +SerialSendFunction::SerialSendFunction() {} -SerialSendFunction::~SerialSendFunction() { -} +SerialSendFunction::~SerialSendFunction() {} bool SerialSendFunction::Prepare() { params_ = serial::Send::Params::Create(*args_); @@ -257,11 +247,9 @@ AsyncWorkCompleted(); } -SerialFlushFunction::SerialFlushFunction() { -} +SerialFlushFunction::SerialFlushFunction() {} -SerialFlushFunction::~SerialFlushFunction() { -} +SerialFlushFunction::~SerialFlushFunction() {} bool SerialFlushFunction::Prepare() { params_ = serial::Flush::Params::Create(*args_); @@ -280,11 +268,9 @@ results_ = serial::Flush::Results::Create(success); } -SerialSetPausedFunction::SerialSetPausedFunction() { -} +SerialSetPausedFunction::SerialSetPausedFunction() {} -SerialSetPausedFunction::~SerialSetPausedFunction() { -} +SerialSetPausedFunction::~SerialSetPausedFunction() {} bool SerialSetPausedFunction::Prepare() { params_ = serial::SetPaused::Params::Create(*args_); @@ -313,11 +299,9 @@ results_ = serial::SetPaused::Results::Create(); } -SerialGetInfoFunction::SerialGetInfoFunction() { -} +SerialGetInfoFunction::SerialGetInfoFunction() {} -SerialGetInfoFunction::~SerialGetInfoFunction() { -} +SerialGetInfoFunction::~SerialGetInfoFunction() {} bool SerialGetInfoFunction::Prepare() { params_ = serial::GetInfo::Params::Create(*args_); @@ -339,11 +323,9 @@ results_ = serial::GetInfo::Results::Create(info); } -SerialGetConnectionsFunction::SerialGetConnectionsFunction() { -} +SerialGetConnectionsFunction::SerialGetConnectionsFunction() {} -SerialGetConnectionsFunction::~SerialGetConnectionsFunction() { -} +SerialGetConnectionsFunction::~SerialGetConnectionsFunction() {} bool SerialGetConnectionsFunction::Prepare() { return true; @@ -355,8 +337,7 @@ manager_->GetResourceIds(extension_->id()); if (connection_ids) { for (base::hash_set<int>::const_iterator it = connection_ids->begin(); - it != connection_ids->end(); - ++it) { + it != connection_ids->end(); ++it) { int connection_id = *it; SerialConnection* connection = GetSerialConnection(connection_id); if (connection) { @@ -370,11 +351,9 @@ results_ = serial::GetConnections::Results::Create(infos); } -SerialGetControlSignalsFunction::SerialGetControlSignalsFunction() { -} +SerialGetControlSignalsFunction::SerialGetControlSignalsFunction() {} -SerialGetControlSignalsFunction::~SerialGetControlSignalsFunction() { -} +SerialGetControlSignalsFunction::~SerialGetControlSignalsFunction() {} bool SerialGetControlSignalsFunction::Prepare() { params_ = serial::GetControlSignals::Params::Create(*args_); @@ -399,11 +378,9 @@ results_ = serial::GetControlSignals::Results::Create(signals); } -SerialSetControlSignalsFunction::SerialSetControlSignalsFunction() { -} +SerialSetControlSignalsFunction::SerialSetControlSignalsFunction() {} -SerialSetControlSignalsFunction::~SerialSetControlSignalsFunction() { -} +SerialSetControlSignalsFunction::~SerialSetControlSignalsFunction() {} bool SerialSetControlSignalsFunction::Prepare() { params_ = serial::SetControlSignals::Params::Create(*args_); @@ -423,11 +400,9 @@ results_ = serial::SetControlSignals::Results::Create(success); } -SerialSetBreakFunction::SerialSetBreakFunction() { -} +SerialSetBreakFunction::SerialSetBreakFunction() {} -SerialSetBreakFunction::~SerialSetBreakFunction() { -} +SerialSetBreakFunction::~SerialSetBreakFunction() {} bool SerialSetBreakFunction::Prepare() { params_ = serial::SetBreak::Params::Create(*args_); @@ -446,11 +421,9 @@ results_ = serial::SetBreak::Results::Create(success); } -SerialClearBreakFunction::SerialClearBreakFunction() { -} +SerialClearBreakFunction::SerialClearBreakFunction() {} -SerialClearBreakFunction::~SerialClearBreakFunction() { -} +SerialClearBreakFunction::~SerialClearBreakFunction() {} bool SerialClearBreakFunction::Prepare() { params_ = serial::ClearBreak::Params::Create(*args_);
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc index 73930c1e..100d76d 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc
@@ -36,13 +36,9 @@ }; TEST_F(SocketsTcpUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketsTcpCreateFunction* function = new SocketsTcpCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc b/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc index 4d3cf42..2b651825 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc
@@ -35,13 +35,9 @@ }; TEST_F(SocketsUdpUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketsUdpCreateFunction* function = new SocketsUdpCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/extensions/browser/content_hash_fetcher_unittest.cc b/extensions/browser/content_hash_fetcher_unittest.cc index 46be54e5..01d6bdc 100644 --- a/extensions/browser/content_hash_fetcher_unittest.cc +++ b/extensions/browser/content_hash_fetcher_unittest.cc
@@ -14,6 +14,7 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/sequenced_worker_pool.h" #include "base/version.h" #include "content/public/browser/browser_thread.h" @@ -172,7 +173,8 @@ url.scheme(), url.host(), content::BrowserThread::GetTaskRunnerForThread( content::BrowserThread::IO), - content::BrowserThread::GetBlockingPool()); + base::CreateTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); interceptor_->SetResponse(url, response_path); }
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index 8f30ca6..706fa86e 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -999,7 +999,7 @@ // static bool DirectCompositionSurfaceWin::IsHDRSupported() { - bool hdr_monitor_found = true; + bool hdr_monitor_found = false; #if defined(ENABLE_HDR_DETECTION) base::win::ScopedComPtr<ID3D11Device> d3d11_device = gl::QueryD3D11DeviceObjectFromANGLE(); @@ -1031,14 +1031,11 @@ if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) { hdr_monitor_found = true; - return true; } } UMA_HISTOGRAM_BOOLEAN("GPU.Output.HDR", hdr_monitor_found); - return hdr_monitor_found; -#else - return false; #endif + return hdr_monitor_found; } bool DirectCompositionSurfaceWin::InitializeNativeWindow() {
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index dc80bda..21ae063 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc
@@ -1182,14 +1182,14 @@ void GpuChannel::AddFilter(IPC::MessageFilter* filter) { io_task_runner_->PostTask( - FROM_HERE, - base::Bind(&GpuChannelMessageFilter::AddChannelFilter, filter_, filter)); + FROM_HERE, base::Bind(&GpuChannelMessageFilter::AddChannelFilter, filter_, + base::RetainedRef(filter))); } void GpuChannel::RemoveFilter(IPC::MessageFilter* filter) { io_task_runner_->PostTask( FROM_HERE, base::Bind(&GpuChannelMessageFilter::RemoveChannelFilter, - filter_, filter)); + filter_, base::RetainedRef(filter))); } uint64_t GpuChannel::GetMemoryUsage() {
diff --git a/ios/chrome/app/resources/XCTRunnerAddition+Info.plist b/ios/chrome/app/resources/XCTRunnerAddition+Info.plist new file mode 100644 index 0000000..a0ba439 --- /dev/null +++ b/ios/chrome/app/resources/XCTRunnerAddition+Info.plist
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleIdentifier</key> + <string>com.apple.test.${PRODUCT_NAME}-Runner</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> +</dict> +</plist>
diff --git a/ios/chrome/browser/history/top_sites_factory.cc b/ios/chrome/browser/history/top_sites_factory.cc index d2a80b7..e19ea43 100644 --- a/ios/chrome/browser/history/top_sites_factory.cc +++ b/ios/chrome/browser/history/top_sites_factory.cc
@@ -50,8 +50,7 @@ browser_state, ServiceAccessType::EXPLICIT_ACCESS), history::PrepopulatedPageList(), base::Bind(CanAddURLToHistory))); top_sites->Init( - browser_state->GetStatePath().Append(history::kTopSitesFilename), - web::WebThread::GetTaskRunnerForThread(web::WebThread::DB)); + browser_state->GetStatePath().Append(history::kTopSitesFilename)); return top_sites; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h index 82d6ab7..c290a783 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h
@@ -47,12 +47,6 @@ // The delegate needs to be set before calling this method. - (void)setAppearanceForTab:(Tab*)tab cellSize:(CGSize)cellSize; -// PLACEHOLDER: Sets the cell's appearance using information in |title| and -// |favicon|. -- (void)setAppearanceForTabTitle:(NSString*)title - favicon:(UIImage*)favicon - cellSize:(CGSize)cellSize; - // Sets the cell's appearance depending on |type|. - (void)setSessionType:(TabSwitcherSessionType)type;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm index 396b374..b9ebf28 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm
@@ -102,16 +102,22 @@ @end +@interface TabSwitcherLocalSessionCell () +@property(nonatomic, strong) UILabel* titleLabel; +@property(nonatomic, strong) UIImageView* favicon; +@property(nonatomic, strong) TabSwitcherButton* snapshotButton; +@end + @implementation TabSwitcherLocalSessionCell { UIView* _topBar; - UILabel* _titleLabel; - UIImageView* _favicon; UIButton* _closeButton; UIImageView* _shadow; UIImageView* _snapshot; - TabSwitcherButton* _snapshotButton; PendingSnapshotRequest _currentPendingSnapshotRequest; } +@synthesize titleLabel = _titleLabel; +@synthesize favicon = _favicon; +@synthesize snapshotButton = _snapshotButton; - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -245,22 +251,6 @@ }]; } -- (void)setAppearanceForTabTitle:(NSString*)title - favicon:(UIImage*)favicon - cellSize:(CGSize)cellSize { - [_titleLabel setText:title]; - [_snapshotButton setAccessibilityIdentifier: - [NSString stringWithFormat:@"%@_button", title]]; - [self contentView].accessibilityLabel = title; - if (favicon) { - [_favicon setImage:favicon]; - } else { - [_favicon setImage:NativeImage(IDR_IOS_OMNIBOX_HTTP)]; - } - - // PLACEHOLDER: Set snapshot here. -} - - (void)setSessionType:(TabSwitcherSessionType)type { UIColor* topBarBackgroundColor; UIColor* closeButtonTintColor;
diff --git a/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn b/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn index 2301668..66b56153 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn
@@ -28,6 +28,8 @@ ] deps = [ "//base", + "//ios/chrome/app/theme:theme_grit", + "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/tab_switcher", "//ios/clean/chrome/browser/ui/commands", ]
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.h b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.h index ca0ec15..ed919d5 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.h +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.h
@@ -9,12 +9,14 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h" +@class TabCollectionItem; + // Cell represents a tab for use in the tab collection. It has a title, favicon, // screenshot image, and close button. Cell selection is represented by a border // highlight in the tintColor. // PLACEHOLDER: Create custom implemementation rather than subclassing. @interface TabCollectionTabCell : TabSwitcherLocalSessionCell - +@property(nonatomic, strong) TabCollectionItem* item; @end #endif // IOS_CLEAN_CHROME_BROWSER_UI_TAB_COLLECTION_TAB_COLLECTION_TAB_CELL_H_
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.mm b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.mm index ff06540a..f9c7914 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.mm +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.mm
@@ -4,6 +4,11 @@ #import "ios/clean/chrome/browser/ui/tab_collection/tab_collection_tab_cell.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_switcher_button.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" +#include "ios/chrome/grit/ios_theme_resources.h" +#import "ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @@ -14,7 +19,17 @@ const CGFloat kSelectedBorderWidth = 4.0f; } +@interface TabCollectionTabCell () +@property(nonatomic, strong) UILabel* titleLabel; +@property(nonatomic, strong) UIImageView* favicon; +@property(nonatomic, strong) TabSwitcherButton* snapshotButton; +@end + @implementation TabCollectionTabCell +@synthesize item = _item; +@dynamic titleLabel; +@dynamic favicon; +@dynamic snapshotButton; - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { @@ -23,6 +38,20 @@ return self; } +#pragma mark - Properties + +- (void)setItem:(TabCollectionItem*)item { + DCHECK(item); + _item = item; + self.titleLabel.text = item.title; + self.snapshotButton.accessibilityIdentifier = + [NSString stringWithFormat:@"%@_button", item.title]; + self.contentView.accessibilityLabel = item.title; + self.favicon.image = NativeImage(IDR_IOS_OMNIBOX_HTTP); +} + +#pragma mark - Private + - (void)setupSelectedBackgroundView { self.selectedBackgroundView = [[UIView alloc] init]; self.selectedBackgroundView.backgroundColor = [UIColor blackColor];
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_view_controller.mm b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_view_controller.mm index 4fa101e..dba8b4c 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_view_controller.mm +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_view_controller.mm
@@ -118,9 +118,7 @@ [cell setSessionType:TabSwitcherSessionType::REGULAR_SESSION]; DCHECK_LE(indexPath.item, INT_MAX); int index = static_cast<int>(indexPath.item); - [cell setAppearanceForTabTitle:self.items[index].title - favicon:nil - cellSize:CGSizeZero]; + cell.item = self.items[index]; return cell; } @@ -194,9 +192,7 @@ TabCollectionTabCell* cell = base::mac::ObjCCastStrict<TabCollectionTabCell>( [self.tabs cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]); - [cell setAppearanceForTabTitle:self.items[index].title - favicon:nil - cellSize:CGSizeZero]; + cell.item = self.items[index]; } - (void)populateItems:(NSArray<TabCollectionItem*>*)items
diff --git a/ios/web/webui/web_ui_ios_data_source_impl.mm b/ios/web/webui/web_ui_ios_data_source_impl.mm index 189722f..80da6f8 100644 --- a/ios/web/webui/web_ui_ios_data_source_impl.mm +++ b/ios/web/webui/web_ui_ios_data_source_impl.mm
@@ -66,7 +66,7 @@ source_name_(source_name), default_resource_(-1), deny_xframe_options_(true), - load_time_data_defaults_added_(true), + load_time_data_defaults_added_(false), replace_existing_source_(true) {} WebUIIOSDataSourceImpl::~WebUIIOSDataSourceImpl() {} @@ -142,10 +142,10 @@ } void WebUIIOSDataSourceImpl::EnsureLoadTimeDataDefaultsAdded() { - if (!load_time_data_defaults_added_) + if (load_time_data_defaults_added_) return; - load_time_data_defaults_added_ = false; + load_time_data_defaults_added_ = true; base::DictionaryValue defaults; webui::SetLoadTimeDataDefaults(web::GetWebClient()->GetApplicationLocale(), &defaults);
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index cbd429c..2986a27c 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -350,7 +350,8 @@ bool WebMediaPlayerImpl::SupportsOverlayFullscreenVideo() { #if defined(OS_ANDROID) - return !using_media_player_renderer_; + return !using_media_player_renderer_ && + overlay_mode_ == OverlayMode::kUseContentVideoView; #else return false; #endif
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 2c234226e..1e5b1d0 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -182,6 +182,9 @@ sources += [ "android/device_info.cc", "android/device_info.h", + "android/promotion_hint_aggregator.h", + "android/promotion_hint_aggregator_impl.cc", + "android/promotion_hint_aggregator_impl.h", "android_video_decode_accelerator.cc", "android_video_decode_accelerator.h", "android_video_surface_chooser.h", @@ -464,6 +467,7 @@ "android/fake_codec_allocator.h", "android/mock_device_info.cc", "android/mock_device_info.h", + "android/promotion_hint_aggregator_impl_unittest.cc", "android_video_decode_accelerator_unittest.cc", "android_video_surface_chooser_impl_unittest.cc", "avda_codec_allocator_unittest.cc",
diff --git a/media/gpu/android/promotion_hint_aggregator.h b/media/gpu/android/promotion_hint_aggregator.h new file mode 100644 index 0000000..44e5561 --- /dev/null +++ b/media/gpu/android/promotion_hint_aggregator.h
@@ -0,0 +1,41 @@ +// Copyright 2017 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_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_H_ +#define MEDIA_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_H_ + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "media/gpu/media_gpu_export.h" + +namespace media { + +// Receive lots of promotion hints, and aggregate them into a single signal. A +// promotion hint is feedback from the compositor about whether a quad could be +// promoted to an overlay, or whether the compositor would refuse to do so. +// For example, the compositor won't promote a quad that's rotated, since an +// overlay can't do that. +class MEDIA_GPU_EXPORT PromotionHintAggregator { + public: + struct Hint { + int x = 0; + int y = 0; + bool is_promotable = false; + }; + + using NotifyPromotionHintCB = base::Callback<void(const Hint& hint)>; + + virtual ~PromotionHintAggregator() = default; + + // Notify us that an image has / would be drawn with the given hint. + virtual void NotifyPromotionHint(const Hint& hint) = 0; + + // Returns true if and only if it's probably okay to promote the video. + virtual bool IsSafeToPromote() = 0; +}; + +} // namespace media + +#endif // MEDIA_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_H_
diff --git a/media/gpu/android/promotion_hint_aggregator_impl.cc b/media/gpu/android/promotion_hint_aggregator_impl.cc new file mode 100644 index 0000000..ec5ab788 --- /dev/null +++ b/media/gpu/android/promotion_hint_aggregator_impl.cc
@@ -0,0 +1,73 @@ +// Copyright 2017 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/gpu/android/promotion_hint_aggregator_impl.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/time/default_tick_clock.h" + +namespace media { + +// Minimum amount of time between promotable frames before we start over. The +// idea is to prevent promoting on paused / background rendering. Note that +// this time is only enforced when transitioning from unpromotable to promotable +// frames. We don't unpromote later because of this. +constexpr base::TimeDelta MaximumInterFrameTime = + base::TimeDelta::FromMilliseconds(100); + +// Minimum number of consecutive promotable frames before we actually start +// promoting frames. +constexpr int MinimumPromotableFrames = 10; + +// Minimum time since the last unpromotable frame that we require before we will +// promote new ones. +constexpr base::TimeDelta MinimumUnpromotableFrameTime = + base::TimeDelta::FromMilliseconds(2000); + +PromotionHintAggregatorImpl::PromotionHintAggregatorImpl( + base::TickClock* tick_clock) + : weak_ptr_factory_(this) { + if (!tick_clock) { + clock_we_own_ = base::MakeUnique<base::DefaultTickClock>(); + tick_clock = clock_we_own_.get(); + } + + tick_clock_ = tick_clock; +} + +PromotionHintAggregatorImpl::~PromotionHintAggregatorImpl() {} + +void PromotionHintAggregatorImpl::NotifyPromotionHint(const Hint& hint) { + base::TimeTicks now = tick_clock_->NowTicks(); + + if (!hint.is_promotable) { + most_recent_unpromotable_ = now; + consecutive_promotable_frames_ = 0; + } else if (!IsSafeToPromote() && + now - most_recent_update_ > MaximumInterFrameTime) { + // Promotable, but we aren't getting frames fast enough to count. We + // don't want to transition to promotable unless frames are actually + // playing. We check IsSafeToPromote() so that we don't transition back + // to unpromotable just because it's paused; that would cause the frame + // to become unrenderable. We just want to delay the transition into + // promotable until it works. + consecutive_promotable_frames_ = 1; + } else { + // Promotable frame, and we're getting frames fast enough. + consecutive_promotable_frames_++; + } + + most_recent_update_ = now; +} + +bool PromotionHintAggregatorImpl::IsSafeToPromote() { + base::TimeTicks now = tick_clock_->NowTicks(); + base::TimeDelta since_last_unpromotable = now - most_recent_unpromotable_; + + return consecutive_promotable_frames_ >= MinimumPromotableFrames && + since_last_unpromotable >= MinimumUnpromotableFrameTime; +} + +} // namespace media
diff --git a/media/gpu/android/promotion_hint_aggregator_impl.h b/media/gpu/android/promotion_hint_aggregator_impl.h new file mode 100644 index 0000000..94ba04f --- /dev/null +++ b/media/gpu/android/promotion_hint_aggregator_impl.h
@@ -0,0 +1,54 @@ +// Copyright 2017 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_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_IMPL_H_ +#define MEDIA_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_IMPL_H_ + +#include <memory> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/time/tick_clock.h" +#include "media/gpu/android/promotion_hint_aggregator.h" +#include "media/gpu/media_gpu_export.h" + +namespace media { + +// Receive lots of promotion hints, and aggregate them into a single signal. +class MEDIA_GPU_EXPORT PromotionHintAggregatorImpl + : public PromotionHintAggregator { + public: + // |tick_clock| may be null, in which case we will use wall clock. If it is + // not null, then it must outlive |this|. It is provided for tests. + PromotionHintAggregatorImpl(base::TickClock* tick_clock = nullptr); + ~PromotionHintAggregatorImpl() override; + + void NotifyPromotionHint(const Hint& hint) override; + bool IsSafeToPromote() override; + + private: + // Clock, which we might not own, that we'll use. + base::TickClock* tick_clock_; + + // Will be non-null if we allocate our own clock. Use |tick_clock| instead. + std::unique_ptr<base::TickClock> clock_we_own_; + + // When did we receive the most recent "not promotable" frame? + base::TimeTicks most_recent_unpromotable_; + + // When did we last receive an update? + base::TimeTicks most_recent_update_; + + // Number of frames which were promotable in a row. + int consecutive_promotable_frames_ = 0; + + base::WeakPtrFactory<PromotionHintAggregatorImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PromotionHintAggregatorImpl); +}; + +} // namespace media + +#endif // MEDIA_GPU_ANDROID_PROMOTION_HINT_AGGREGATOR_IMPL_H_
diff --git a/media/gpu/android/promotion_hint_aggregator_impl_unittest.cc b/media/gpu/android/promotion_hint_aggregator_impl_unittest.cc new file mode 100644 index 0000000..c8a16aeb --- /dev/null +++ b/media/gpu/android/promotion_hint_aggregator_impl_unittest.cc
@@ -0,0 +1,98 @@ +// Copyright 2017 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/gpu/android/promotion_hint_aggregator_impl.h" + +#include <stdint.h> + +#include <memory> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/test/simple_test_tick_clock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::TimeDelta; + +namespace { +// Default elapsed time between frames. +constexpr TimeDelta FrameTime = TimeDelta::FromMilliseconds(10); +} // namespace + +namespace media { + +// Unit tests for PromotionHintAggregatorImplTest +class PromotionHintAggregatorImplTest : public testing::Test { + public: + ~PromotionHintAggregatorImplTest() override {} + + void SetUp() override { + // Advance the clock so that time 0 isn't recent. + tick_clock_.Advance(TimeDelta::FromSeconds(10000)); + impl_ = base::MakeUnique<PromotionHintAggregatorImpl>(&tick_clock_); + } + + void TearDown() override {} + + // Sends a new frame that's |is_promotable| or not, with |elapsed| since the + // previous frame. Returns whether the video is promotable. + bool SendFrame(bool is_promotable, TimeDelta elapsed = FrameTime) { + tick_clock_.Advance(elapsed); + PromotionHintAggregator::Hint hint; + hint.is_promotable = is_promotable; + impl_->NotifyPromotionHint(hint); + return impl_->IsSafeToPromote(); + } + + base::SimpleTestTickClock tick_clock_; + + std::unique_ptr<PromotionHintAggregatorImpl> impl_; +}; + +TEST_F(PromotionHintAggregatorImplTest, InitiallyNotPromotable) { + // A new aggregator shouldn't promote. + ASSERT_FALSE(impl_->IsSafeToPromote()); +} + +TEST_F(PromotionHintAggregatorImplTest, SomePromotableFramesArePromotable) { + // We should have to send 10 frames before promoting. + for (int i = 0; i < 9; i++) + ASSERT_FALSE(SendFrame(true)); + ASSERT_TRUE(SendFrame(true)); + + // Waiting a while should't cause un-promotion. + ASSERT_TRUE(SendFrame(true, TimeDelta::FromMilliseconds(10000))); + ASSERT_TRUE(SendFrame(true, TimeDelta::FromMilliseconds(10000))); +} + +TEST_F(PromotionHintAggregatorImplTest, UnpromotableFramesDelayPromotion) { + // Start with an unpromotable frame. + ASSERT_FALSE(SendFrame(false)); + base::TimeTicks start = tick_clock_.NowTicks(); + + // Send more until the minimum time has elapsed. Note that this will also be + // at least enough promotable frames in a row. + while (tick_clock_.NowTicks() - start + FrameTime < TimeDelta::FromSeconds(2)) + ASSERT_FALSE(SendFrame(true)); + + // The next frame should do it. + ASSERT_TRUE(SendFrame(true)); +} + +TEST_F(PromotionHintAggregatorImplTest, PromotableFramesMustBeFastEnough) { + // Send some promotable frames, but not enough to promote. + for (int i = 0; i < 8; i++) + ASSERT_FALSE(SendFrame(true)); + + // Time passes. + tick_clock_.Advance(TimeDelta::FromMilliseconds(500)); + + // We should now start over. + for (int i = 0; i < 9; i++) + ASSERT_FALSE(SendFrame(true)); + ASSERT_TRUE(SendFrame(true)); +} + +} // namespace media
diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc index 2a56994..f22e5e7 100644 --- a/media/gpu/android_video_decode_accelerator.cc +++ b/media/gpu/android_video_decode_accelerator.cc
@@ -35,6 +35,7 @@ #include "media/base/timestamp_constants.h" #include "media/base/video_decoder_config.h" #include "media/gpu/android/device_info.h" +#include "media/gpu/android/promotion_hint_aggregator_impl.h" #include "media/gpu/android_video_surface_chooser_impl.h" #include "media/gpu/avda_picture_buffer_manager.h" #include "media/gpu/content_video_view_overlay.h" @@ -249,6 +250,8 @@ device_info_(device_info), force_defer_surface_creation_for_testing_(false), overlay_factory_cb_(overlay_factory_cb), + promotion_hint_aggregator_( + base::MakeUnique<PromotionHintAggregatorImpl>()), weak_this_factory_(this) {} AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { @@ -889,13 +892,23 @@ if (size_changed) picture_buffer.set_size(size_); - // TODO(liberato): request a hint for promotability. crbug.com/671365 . + // Only ask for promotion hints if we can actually switch surfaces. + const bool want_promotion_hint = device_info_->IsSetOutputSurfaceSupported(); const bool allow_overlay = picture_buffer_manager_.ArePicturesOverlayable(); UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay); + // We unconditionally mark the picture as overlayable, even if + // |!allow_overlay|, if we want to get hints. It's required, else we won't + // get hints. // TODO(hubbe): Insert the correct color space. http://crbug.com/647725 Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_), - gfx::ColorSpace(), allow_overlay); + gfx::ColorSpace(), + want_promotion_hint ? true : allow_overlay); picture.set_size_changed(size_changed); + if (want_promotion_hint) { + picture.set_wants_promotion_hint(true); + // This will prevent it from actually being promoted if it shouldn't be. + picture.set_surface_texture(!allow_overlay); + } // Notify picture ready before calling UseCodecBufferForPictureBuffer() since // that process may be slow and shouldn't delay delivery of the frame to the @@ -1539,6 +1552,23 @@ client_->NotifyError(error); } +PromotionHintAggregator::NotifyPromotionHintCB +AndroidVideoDecodeAccelerator::GetPromotionHintCB() { + return base::Bind(&AndroidVideoDecodeAccelerator::NotifyPromotionHint, + weak_this_factory_.GetWeakPtr()); +} + +void AndroidVideoDecodeAccelerator::NotifyPromotionHint( + const PromotionHintAggregator::Hint& hint) { + promotion_hint_aggregator_->NotifyPromotionHint(hint); + bool promotable = promotion_hint_aggregator_->IsSafeToPromote(); + if (promotable != chooser_state_.is_compositor_promotable) { + chooser_state_.is_compositor_promotable = promotable; + surface_chooser_->UpdateState(base::Optional<AndroidOverlayFactoryCB>(), + chooser_state_); + } +} + void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { bool should_be_running = true;
diff --git a/media/gpu/android_video_decode_accelerator.h b/media/gpu/android_video_decode_accelerator.h index 4f74687..f01ea5ab 100644 --- a/media/gpu/android_video_decode_accelerator.h +++ b/media/gpu/android_video_decode_accelerator.h
@@ -35,6 +35,7 @@ namespace media { class SharedMemoryRegion; +class PromotionHintAggregator; // A VideoDecodeAccelerator implementation for Android. This class decodes the // encoded input stream using Android's MediaCodec. It handles the work of @@ -80,6 +81,7 @@ // failure. If deferred init is pending, then we'll fail deferred init. // Otherwise, we'll signal errors normally. void NotifyError(Error error) override; + PromotionHintAggregator::NotifyPromotionHintCB GetPromotionHintCB() override; // AVDACodecAllocatorClient implementation: void OnCodecConfigured( @@ -254,6 +256,9 @@ // another codec. Normally, one doesn't. void ReleaseCodecAndBundle(); + // Send a |hint| to |promotion_hint_aggregator_|. + void NotifyPromotionHint(const PromotionHintAggregator::Hint& hint); + // Used to DCHECK that we are called on the correct thread. base::ThreadChecker thread_checker_; @@ -392,6 +397,8 @@ // Optional factory to produce mojo AndroidOverlay instances. AndroidOverlayMojoFactoryCB overlay_factory_cb_; + std::unique_ptr<PromotionHintAggregator> promotion_hint_aggregator_; + // WeakPtrFactory for posting tasks back to |this|. base::WeakPtrFactory<AndroidVideoDecodeAccelerator> weak_this_factory_;
diff --git a/media/gpu/android_video_surface_chooser.h b/media/gpu/android_video_surface_chooser.h index 34a40ae1..67051a3 100644 --- a/media/gpu/android_video_surface_chooser.h +++ b/media/gpu/android_video_surface_chooser.h
@@ -24,10 +24,11 @@ // Does playback require a secure surface? bool is_secure = false; - // TODO(liberato): add compositor feedback. - // Is the player's frame hidden / closed? bool is_frame_hidden = false; + + // Is the compositor willing to promote this? + bool is_compositor_promotable = false; }; // Notify the client that |overlay| is ready for use. The client may get
diff --git a/media/gpu/android_video_surface_chooser_impl.cc b/media/gpu/android_video_surface_chooser_impl.cc index 89df36d5..8266e208 100644 --- a/media/gpu/android_video_surface_chooser_impl.cc +++ b/media/gpu/android_video_surface_chooser_impl.cc
@@ -106,10 +106,14 @@ if (current_state_.is_fullscreen) new_overlay_state = kUsingOverlay; - // TODO(liberato): add other checks for things like "safe for overlay". + // If the compositor won't promote, then don't. + if (!current_state_.is_compositor_promotable) + new_overlay_state = kUsingSurfaceTexture; // If we need a secure surface, then we must choose an overlay. The only way - // we won't is if we don't have a factory. + // we won't is if we don't have a factory. If the compositor won't promote, + // we still use the overlay, since hopefully it's a temporary restriction. + // If we drop the overlay, then playback will fail. if (current_state_.is_secure) new_overlay_state = kUsingOverlay;
diff --git a/media/gpu/android_video_surface_chooser_impl_unittest.cc b/media/gpu/android_video_surface_chooser_impl_unittest.cc index 010057a..acf4bd4f 100644 --- a/media/gpu/android_video_surface_chooser_impl_unittest.cc +++ b/media/gpu/android_video_surface_chooser_impl_unittest.cc
@@ -56,16 +56,23 @@ enum class IsFullscreen { No, Yes }; enum class IsSecure { No, Yes }; enum class IsFrameHidden { No, Yes }; +enum class IsCCPromotable { No, Yes }; using TestParams = std::tuple<ShouldUseOverlay, AllowDynamic, IsFullscreen, IsSecure, - IsFrameHidden>; + IsFrameHidden, + IsCCPromotable>; // Useful macro for instantiating tests. #define Either(x) Values(x::No, x::Yes) +// Check if a parameter of type |type| is Yes. |n| is the location of the +// parameter of that type. +// c++14 can remove |n|, and std::get() by type. +#define IsYes(type, n) (::testing::get<n>(GetParam()) == type::Yes); + } // namespace namespace media { @@ -82,6 +89,9 @@ // Advance the clock just so we're not at 0. tick_clock_.Advance(base::TimeDelta::FromSeconds(10)); + // Don't prevent promotions because of the compositor. + chooser_state_.is_compositor_promotable = true; + // We create a destruction observer. By default, the overlay must not be // destroyed until the test completes. Of course, the test may ask the // observer to expect something else. @@ -288,17 +298,16 @@ } TEST_P(AndroidVideoSurfaceChooserImplTest, OverlayIsUsedOrNotBasedOnState) { -// Provide a factory, and verify that it is used when the state says that it -// should be. If the overlay is used, then we also verify that it does not -// switch to SurfaceTexture first, since pre-M requires it. + // Provide a factory, and verify that it is used when the state says that it + // should be. If the overlay is used, then we also verify that it does not + // switch to SurfaceTexture first, since pre-M requires it. -// c++14 can remove |n|, and std::get() by type. -#define IsTrue(x, n) (::testing::get<n>(GetParam()) == x::Yes); - const bool should_use_overlay = IsTrue(ShouldUseOverlay, 0); - allow_dynamic_ = IsTrue(AllowDynamic, 1); - chooser_state_.is_fullscreen = IsTrue(IsFullscreen, 2); - chooser_state_.is_secure = IsTrue(IsSecure, 3); - chooser_state_.is_frame_hidden = IsTrue(IsFrameHidden, 4); + const bool should_use_overlay = IsYes(ShouldUseOverlay, 0); + allow_dynamic_ = IsYes(AllowDynamic, 1); + chooser_state_.is_fullscreen = IsYes(IsFullscreen, 2); + chooser_state_.is_secure = IsYes(IsSecure, 3); + chooser_state_.is_frame_hidden = IsYes(IsFrameHidden, 4); + chooser_state_.is_compositor_promotable = IsYes(IsCCPromotable, 5); if (should_use_overlay) { EXPECT_CALL(client_, UseSurfaceTexture()).Times(0); @@ -323,27 +332,45 @@ Either(AllowDynamic), Values(IsFullscreen::No), Values(IsSecure::No), - Values(IsFrameHidden::No))); + Values(IsFrameHidden::No), + Either(IsCCPromotable))); INSTANTIATE_TEST_CASE_P(FullscreenUsesOverlay, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), Either(AllowDynamic), Values(IsFullscreen::Yes), Values(IsSecure::No), - Values(IsFrameHidden::No))); + Values(IsFrameHidden::No), + Values(IsCCPromotable::Yes))); INSTANTIATE_TEST_CASE_P(SecureUsesOverlay, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), Either(AllowDynamic), Either(IsFullscreen), Values(IsSecure::Yes), - Values(IsFrameHidden::No))); + Values(IsFrameHidden::No), + Values(IsCCPromotable::Yes))); + INSTANTIATE_TEST_CASE_P(HiddenFramesUseSurfaceTexture, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::No), Values(AllowDynamic::Yes), Either(IsFullscreen), Either(IsSecure), - Values(IsFrameHidden::Yes))); + Values(IsFrameHidden::Yes), + Either(IsCCPromotable))); +// For all dynamic cases, we shouldn't use an overlay if the compositor won't +// promote it. For L1, it will fail either way until the CC supports "must +// promote" overlays, so we ignore those cases. Non-dynamic is excluded, since +// we don't get (or use) compositor feedback before the first frame. At that +// point, we've already chosen the output surface and can't switch it. +INSTANTIATE_TEST_CASE_P(NotCCPromotableNotSecureUsesSurfaceTexture, + AndroidVideoSurfaceChooserImplTest, + Combine(Values(ShouldUseOverlay::No), + Values(AllowDynamic::Yes), + Either(IsFullscreen), + Values(IsSecure::No), + Values(IsFrameHidden::No), + Values(IsCCPromotable::No))); } // namespace media
diff --git a/media/gpu/avda_codec_image.cc b/media/gpu/avda_codec_image.cc index d8688d2..00db66b 100644 --- a/media/gpu/avda_codec_image.cc +++ b/media/gpu/avda_codec_image.cc
@@ -232,6 +232,17 @@ YInvertMatrix(matrix); } +void AVDACodecImage::NotifyPromotionHint(bool promotion_hint, + int display_x, + int display_y) { + // TODO(liberato): this should just be given to us. + PromotionHintAggregator::Hint hint; + hint.x = display_x; + hint.y = display_y; + hint.is_promotable = promotion_hint; + shared_state_->GetPromotionHintCB().Run(hint); +} + bool AVDACodecImage::IsCodecBufferOutstanding() const { static_assert(kUpdateOnly < 0 && kUpdateOnly > kRendered && kRendered > kInvalidCodecBufferIndex,
diff --git a/media/gpu/avda_codec_image.h b/media/gpu/avda_codec_image.h index 4b0bd9c..c8c8c26 100644 --- a/media/gpu/avda_codec_image.h +++ b/media/gpu/avda_codec_image.h
@@ -48,6 +48,9 @@ const std::string& dump_name) override; // gpu::gles2::GLStreamTextureMatrix implementation void GetTextureMatrix(float xform[16]) override; + void NotifyPromotionHint(bool promotion_hint, + int display_x, + int display_y) override; enum class UpdateMode { // Discards the codec buffer, no UpdateTexImage().
diff --git a/media/gpu/avda_picture_buffer_manager.cc b/media/gpu/avda_picture_buffer_manager.cc index 330e309..1442d3e 100644 --- a/media/gpu/avda_picture_buffer_manager.cc +++ b/media/gpu/avda_picture_buffer_manager.cc
@@ -66,6 +66,7 @@ // Only do this once the surface texture is filled in, since the constructor // assumes that it will be. shared_state_ = new AVDASharedState(surface_bundle); + shared_state_->SetPromotionHintCB(state_provider_->GetPromotionHintCB()); return true; }
diff --git a/media/gpu/avda_shared_state.cc b/media/gpu/avda_shared_state.cc index 3dd8cec..57330b1 100644 --- a/media/gpu/avda_shared_state.cc +++ b/media/gpu/avda_shared_state.cc
@@ -66,4 +66,14 @@ surface_bundle_ = nullptr; } +void AVDASharedState::SetPromotionHintCB( + PromotionHintAggregator::NotifyPromotionHintCB cb) { + promotion_hint_cb_ = cb; +} + +const PromotionHintAggregator::NotifyPromotionHintCB& +AVDASharedState::GetPromotionHintCB() { + return promotion_hint_cb_; +} + } // namespace media
diff --git a/media/gpu/avda_shared_state.h b/media/gpu/avda_shared_state.h index aa4bfd3..e41d40a4 100644 --- a/media/gpu/avda_shared_state.h +++ b/media/gpu/avda_shared_state.h
@@ -10,6 +10,7 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "media/base/android/android_overlay.h" #include "media/base/android/media_codec_bridge.h" +#include "media/gpu/android/promotion_hint_aggregator.h" #include "media/gpu/avda_shared_state.h" #include "media/gpu/avda_surface_bundle.h" #include "ui/gl/gl_bindings.h" @@ -86,6 +87,9 @@ void ClearOverlay(AndroidOverlay* overlay); + void SetPromotionHintCB(PromotionHintAggregator::NotifyPromotionHintCB cb); + const PromotionHintAggregator::NotifyPromotionHintCB& GetPromotionHintCB(); + protected: virtual ~AVDASharedState(); @@ -97,6 +101,8 @@ scoped_refptr<AVDASurfaceBundle> surface_bundle_; + PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb_; + base::WeakPtrFactory<AVDASharedState> weak_this_factory_; DISALLOW_COPY_AND_ASSIGN(AVDASharedState);
diff --git a/media/gpu/avda_state_provider.h b/media/gpu/avda_state_provider.h index 819992d..c1c0161 100644 --- a/media/gpu/avda_state_provider.h +++ b/media/gpu/avda_state_provider.h
@@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "base/threading/thread_checker.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "media/gpu/android/promotion_hint_aggregator.h" #include "media/video/video_decode_accelerator.h" namespace gpu { @@ -30,6 +31,10 @@ // error state. virtual void NotifyError(VideoDecodeAccelerator::Error error) = 0; + // Return a callback that may be used to signal promotion hint info. + virtual PromotionHintAggregator::NotifyPromotionHintCB + GetPromotionHintCB() = 0; + protected: ~AVDAStateProvider() = default; };
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h index d2f8ecfd72..044b9d0 100644 --- a/mojo/public/cpp/bindings/lib/array_serialization.h +++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -278,8 +278,7 @@ BelongsTo<typename MojomType::Element, MojomTypeCategory::ASSOCIATED_INTERFACE | MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST | - MojomTypeCategory::HANDLE | - MojomTypeCategory::INTERFACE | + MojomTypeCategory::HANDLE | MojomTypeCategory::INTERFACE | MojomTypeCategory::INTERFACE_REQUEST>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; @@ -289,14 +288,10 @@ static size_t GetSerializedSize(UserTypeIterator* input, SerializationContext* context) { size_t element_count = input->GetSize(); - if (BelongsTo<Element, - MojomTypeCategory::ASSOCIATED_INTERFACE | - MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST>::value) { - for (size_t i = 0; i < element_count; ++i) { - typename UserTypeIterator::GetNextResult next = input->GetNext(); - size_t size = PrepareToSerialize<Element>(next, context); - DCHECK_EQ(size, 0u); - } + for (size_t i = 0; i < element_count; ++i) { + typename UserTypeIterator::GetNextResult next = input->GetNext(); + size_t size = PrepareToSerialize<Element>(next, context); + DCHECK_EQ(size, 0u); } return sizeof(Data) + Align(element_count * sizeof(typename Data::Element)); } @@ -509,7 +504,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; ArrayIterator<Traits, MaybeConstUserType> iterator(input); return Impl::GetSerializedSize(&iterator, context); @@ -520,7 +517,7 @@ Data** output, const ContainerValidateParams* validate_params, SerializationContext* context) { - if (!CallIsNullIfExists<Traits>(input)) { + if (!context->IsNextFieldNull()) { MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( validate_params->expected_num_elements != 0 && Traits::GetSize(input) != validate_params->expected_num_elements,
diff --git a/mojo/public/cpp/bindings/lib/handle_interface_serialization.h b/mojo/public/cpp/bindings/lib/handle_interface_serialization.h index 1641d55..cfc2fd9f 100644 --- a/mojo/public/cpp/bindings/lib/handle_interface_serialization.h +++ b/mojo/public/cpp/bindings/lib/handle_interface_serialization.h
@@ -108,18 +108,18 @@ struct Serializer<InterfacePtrDataView<Base>, InterfacePtr<T>> { static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch."); - static size_t PrepareToSerialize(const InterfacePtr<T>& input, + static size_t PrepareToSerialize(InterfacePtr<T>& input, SerializationContext* context) { + InterfacePtrInfo<T> info = input.PassInterface(); + context->handles.AddInterfaceInfo(info.PassHandle(), info.version()); return 0; } - static void Serialize(InterfacePtr<T>& input, + static void Serialize(const InterfacePtr<T>& input, Interface_Data* output, SerializationContext* context) { - InterfacePtrInfo<T> info = input.PassInterface(); - output->handle = - context->handles.AddHandle(ScopedHandle::From(info.PassHandle())); - output->version = info.version(); + DCHECK(!input.is_bound()); + context->handles.ConsumeNextSerializedInterfaceInfo(output); } static bool Deserialize(Interface_Data* input, @@ -136,16 +136,17 @@ struct Serializer<InterfaceRequestDataView<Base>, InterfaceRequest<T>> { static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch."); - static size_t PrepareToSerialize(const InterfaceRequest<T>& input, + static size_t PrepareToSerialize(InterfaceRequest<T>& input, SerializationContext* context) { + context->handles.AddHandle(ScopedHandle::From(input.PassMessagePipe())); return 0; } - static void Serialize(InterfaceRequest<T>& input, + static void Serialize(const InterfaceRequest<T>& input, Handle_Data* output, SerializationContext* context) { - *output = - context->handles.AddHandle(ScopedHandle::From(input.PassMessagePipe())); + DCHECK(!input.is_pending()); + context->handles.ConsumeNextSerializedHandle(output); } static bool Deserialize(Handle_Data* input, @@ -159,15 +160,17 @@ template <typename T> struct Serializer<ScopedHandleBase<T>, ScopedHandleBase<T>> { - static size_t PrepareToSerialize(const ScopedHandleBase<T>& input, + static size_t PrepareToSerialize(ScopedHandleBase<T>& input, SerializationContext* context) { + context->handles.AddHandle(ScopedHandle::From(std::move(input))); return 0; } - static void Serialize(ScopedHandleBase<T>& input, + static void Serialize(const ScopedHandleBase<T>& input, Handle_Data* output, SerializationContext* context) { - *output = context->handles.AddHandle(ScopedHandle::From(std::move(input))); + DCHECK(!input.is_valid()); + context->handles.ConsumeNextSerializedHandle(output); } static bool Deserialize(Handle_Data* input,
diff --git a/mojo/public/cpp/bindings/lib/map_serialization.h b/mojo/public/cpp/bindings/lib/map_serialization.h index 718a763..08287608 100644 --- a/mojo/public/cpp/bindings/lib/map_serialization.h +++ b/mojo/public/cpp/bindings/lib/map_serialization.h
@@ -97,7 +97,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; size_t struct_overhead = sizeof(Data); @@ -118,7 +120,7 @@ SerializationContext* context) { DCHECK(validate_params->key_validate_params); DCHECK(validate_params->element_validate_params); - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { *output = nullptr; return; }
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc index c543994..6658e60 100644 --- a/mojo/public/cpp/bindings/lib/message.cc +++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -181,9 +181,10 @@ Message::Message(uint32_t name, uint32_t flags, size_t payload_size, - size_t payload_interface_id_count) { + size_t payload_interface_id_count, + std::vector<ScopedHandle>* handles) { CreateSerializedMessageObject(name, flags, payload_size, - payload_interface_id_count, nullptr, &handle_, + payload_interface_id_count, handles, &handle_, &payload_buffer_); data_ = payload_buffer_.data(); data_size_ = payload_buffer_.size(); @@ -274,45 +275,6 @@ return array_pointer ? array_pointer->storage() : nullptr; } -void Message::AttachHandles(std::vector<ScopedHandle>* handles) { - DCHECK(handles); - if (handles->empty()) - return; - - // Sanity-check the current serialized message state. We must have a valid - // message handle and it must have no serialized handles. - DCHECK(handle_.is_valid()); - DCHECK(payload_buffer_.is_valid()); - void* buffer; - uint32_t num_bytes; - uint32_t num_handles = 0; - MojoResult rv = MojoGetSerializedMessageContents( - handle_->value(), &buffer, &num_bytes, nullptr, &num_handles, - MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE); - DCHECK_EQ(MOJO_RESULT_OK, rv); - - MessageInfo new_info(data_size_, handles); - ScopedMessageHandle new_handle; - rv = mojo::CreateMessage(reinterpret_cast<uintptr_t>(&new_info), - &kMessageInfoThunks, &new_handle); - DCHECK_EQ(MOJO_RESULT_OK, rv); - DCHECK(new_handle.is_valid()); - - rv = MojoSerializeMessage(new_handle->value()); - DCHECK_EQ(MOJO_RESULT_OK, rv); - DCHECK(new_info.payload_buffer.is_valid()); - - // Copy the existing payload into the new message. - void* storage = new_info.payload_buffer.Allocate(payload_buffer_.cursor()); - memcpy(storage, data_, data_size_); - - handle_ = std::move(new_handle); - payload_buffer_ = std::move(new_info.payload_buffer); - data_ = payload_buffer_.data(); - data_size_ = payload_buffer_.size(); - transferable_ = true; -} - ScopedMessageHandle Message::TakeMojoMessage() { // If there are associated endpoints transferred, // SerializeAssociatedEndpointHandles() must be called before this method.
diff --git a/mojo/public/cpp/bindings/lib/serialization_context.cc b/mojo/public/cpp/bindings/lib/serialization_context.cc index 8e4d86b..5748d10 100644 --- a/mojo/public/cpp/bindings/lib/serialization_context.cc +++ b/mojo/public/cpp/bindings/lib/serialization_context.cc
@@ -17,7 +17,7 @@ SerializedHandleVector::~SerializedHandleVector() = default; -Handle_Data SerializedHandleVector::AddHandle(mojo::ScopedHandle handle) { +void SerializedHandleVector::AddHandle(mojo::ScopedHandle handle) { Handle_Data data; if (!handle.is_valid()) { data.value = kEncodedInvalidHandleValue; @@ -26,7 +26,29 @@ data.value = static_cast<uint32_t>(handles_.size()); handles_.emplace_back(std::move(handle)); } - return data; + serialized_handles_.emplace_back(data); +} + +void SerializedHandleVector::AddInterfaceInfo( + mojo::ScopedMessagePipeHandle handle, + uint32_t version) { + AddHandle(ScopedHandle::From(std::move(handle))); + serialized_interface_versions_.emplace_back(version); +} + +void SerializedHandleVector::ConsumeNextSerializedHandle( + Handle_Data* out_data) { + DCHECK_LT(next_serialized_handle_index_, serialized_handles_.size()); + *out_data = serialized_handles_[next_serialized_handle_index_++]; +} + +void SerializedHandleVector::ConsumeNextSerializedInterfaceInfo( + Interface_Data* out_data) { + ConsumeNextSerializedHandle(&out_data->handle); + DCHECK_LT(next_serialized_version_index_, + serialized_interface_versions_.size()); + out_data->version = + serialized_interface_versions_[next_serialized_version_index_++]; } mojo::ScopedHandle SerializedHandleVector::TakeHandle( @@ -50,7 +72,6 @@ void SerializationContext::AttachHandlesToMessage(Message* message) { associated_endpoint_handles.swap( *message->mutable_associated_endpoint_handles()); - message->AttachHandles(handles.mutable_handles()); } } // namespace internal
diff --git a/mojo/public/cpp/bindings/lib/serialization_context.h b/mojo/public/cpp/bindings/lib/serialization_context.h index 6a6e5142..bc355044 100644 --- a/mojo/public/cpp/bindings/lib/serialization_context.h +++ b/mojo/public/cpp/bindings/lib/serialization_context.h
@@ -11,6 +11,7 @@ #include <queue> #include <vector> +#include "base/containers/stack_container.h" #include "base/macros.h" #include "mojo/public/cpp/bindings/bindings_export.h" #include "mojo/public/cpp/bindings/lib/bindings_internal.h" @@ -31,9 +32,22 @@ size_t size() const { return handles_.size(); } std::vector<mojo::ScopedHandle>* mutable_handles() { return &handles_; } + std::vector<Handle_Data>* serialized_handles() { + return &serialized_handles_; + } - // Adds a handle to the handle list and returns its index for encoding. - Handle_Data AddHandle(mojo::ScopedHandle handle); + // Adds a handle to the handle and serialized handle data lists. + void AddHandle(mojo::ScopedHandle handle); + + // Adds an interface info to the handle and serialized handle+version data + // lists. + void AddInterfaceInfo(mojo::ScopedMessagePipeHandle handle, uint32_t version); + + // Consumes the next available serialized handle data. + void ConsumeNextSerializedHandle(Handle_Data* out_data); + + // Consumes the next available serialized handle and version data. + void ConsumeNextSerializedInterfaceInfo(Interface_Data* out_data); // Takes a handle from the list of serialized handle data. mojo::ScopedHandle TakeHandle(const Handle_Data& encoded_handle); @@ -52,6 +66,14 @@ // Handles are owned by this object. std::vector<mojo::ScopedHandle> handles_; + // Serialized handle and (optional) version data. This is accumulated during + // pre-serialization by AddHandle and AddInterfaceInfo calls, and later + // consumed during serialization by ConsumeNextSerializedHandle/InterfaceInfo. + size_t next_serialized_handle_index_ = 0; + std::vector<Handle_Data> serialized_handles_; + size_t next_serialized_version_index_ = 0; + std::vector<uint32_t> serialized_interface_versions_; + DISALLOW_COPY_AND_ASSIGN(SerializedHandleVector); }; @@ -61,13 +83,23 @@ ~SerializationContext(); - // Transfers ownership of any accumulated handles and associated endpoint - // handles into |*message|. + bool IsNextFieldNull() { + DCHECK_LT(null_state_index, null_states.container().size()); + return null_states.container()[null_state_index++]; + } + + // Transfers ownership of any accumulated associated endpoint handles into + // |*message|. void AttachHandlesToMessage(Message* message); // Opaque context pointers returned by StringTraits::SetUpContext(). std::unique_ptr<std::queue<void*>> custom_contexts; + // A container for tracking the null-ness of every nullable field as a + // message's arguments are walked during serialization. + base::StackVector<bool, 32> null_states; + size_t null_state_index = 0; + // Stashes handles encoded in a message by index. SerializedHandleVector handles;
diff --git a/mojo/public/cpp/bindings/lib/string_serialization.h b/mojo/public/cpp/bindings/lib/string_serialization.h index 6e0c758..68165dd 100644 --- a/mojo/public/cpp/bindings/lib/string_serialization.h +++ b/mojo/public/cpp/bindings/lib/string_serialization.h
@@ -24,7 +24,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; void* custom_context = CustomContextHelper<Traits>::SetUp(input, context); @@ -36,7 +38,7 @@ Buffer* buffer, String_Data** output, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { *output = nullptr; return; }
diff --git a/mojo/public/cpp/bindings/message.h b/mojo/public/cpp/bindings/message.h index 9fabda4..cfd4664 100644 --- a/mojo/public/cpp/bindings/message.h +++ b/mojo/public/cpp/bindings/message.h
@@ -45,13 +45,13 @@ // This message is fully functional and may be exchanged for a // ScopedMessageHandle for transit over a message pipe. See TakeMojoMessage(). // - // If |handles| are not known at Message construction time, they may be - // attached later by calling |AttachHandles()|. See the note on that method - // regarding performance considerations. + // If |handles| is non-null, any handles in |*handles| are attached to the + // newly constructed message. Message(uint32_t name, uint32_t flags, size_t payload_size, - size_t payload_interface_id_count); + size_t payload_interface_id_count, + std::vector<ScopedHandle>* handles = nullptr); // Constructs a new serialized Message object from an existing // ScopedMessageHandle; e.g., one read from a message pipe. @@ -148,11 +148,6 @@ return &associated_endpoint_handles_; } - // Attaches handles to this Message. Note that this requires the underlying - // message object to be reallocated and the payload to be copied into a new - // buffer. Takes ownership of the contents of |*handles|. - void AttachHandles(std::vector<ScopedHandle>* handles); - // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for // transmission. Note that this invalidates this Message object, taking // ownership of its internal storage and any attached handles.
diff --git a/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h index a0c7b4f..99e13a4 100644 --- a/mojo/public/cpp/bindings/sync_call_restrictions.h +++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
@@ -15,6 +15,8 @@ #define ENABLE_SYNC_CALL_RESTRICTIONS 0 #endif +class ChromeSelectFileDialogFactory; + namespace sync_preferences { class PrefServiceSyncable; } @@ -79,7 +81,8 @@ friend class prefs::PersistentPrefStoreClient; // Incognito pref service instances are created synchronously. friend class sync_preferences::PrefServiceSyncable; - + // For file open and save dialogs created synchronously. + friend class ::ChromeSelectFileDialogFactory; // END ALLOWED USAGE. // BEGIN USAGE THAT NEEDS TO BE FIXED.
diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc index 3f5b8f44..a163458d 100644 --- a/mojo/public/cpp/bindings/tests/connector_unittest.cc +++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -91,9 +91,7 @@ public: ConnectorTest() {} - void SetUp() override { - CreateMessagePipe(nullptr, &handle0_, &handle1_); - } + void SetUp() override { CreateMessagePipe(nullptr, &handle0_, &handle1_); } void TearDown() override {} @@ -101,9 +99,8 @@ const char* text, std::vector<ScopedHandle> handles = std::vector<ScopedHandle>()) { const size_t size = strlen(text) + 1; // Plus null terminator. - Message message(1, 0, size, 0); + Message message(1, 0, size, 0, &handles); memcpy(message.payload_buffer()->Allocate(size), text, size); - message.AttachHandles(&handles); return message; } @@ -418,16 +415,14 @@ Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, base::ThreadTaskRunnerHandle::Get()); bool error_handler_called0 = false; - connector0.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called0, - run_loop.QuitClosure())); + connector0.set_connection_error_handler(base::Bind( + &ForwardErrorHandler, &error_handler_called0, run_loop.QuitClosure())); Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, base::ThreadTaskRunnerHandle::Get()); bool error_handler_called1 = false; - connector1.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called1, - run_loop2.QuitClosure())); + connector1.set_connection_error_handler(base::Bind( + &ForwardErrorHandler, &error_handler_called1, run_loop2.QuitClosure())); const char kText[] = "hello world"; Message message = CreateMessage(kText); @@ -489,9 +484,8 @@ base::RunLoop run_loop; // Configure the accumulator such that it pauses after the first message is // received. - MessageAccumulator accumulator( - base::Bind(&PauseConnectorAndRunClosure, &connector1, - run_loop.QuitClosure())); + MessageAccumulator accumulator(base::Bind( + &PauseConnectorAndRunClosure, &connector1, run_loop.QuitClosure())); connector1.set_incoming_receiver(&accumulator); run_loop.Run();
diff --git a/mojo/public/cpp/bindings/tests/struct_unittest.cc b/mojo/public/cpp/bindings/tests/struct_unittest.cc index a687052..fa9b370 100644 --- a/mojo/public/cpp/bindings/tests/struct_unittest.cc +++ b/mojo/public/cpp/bindings/tests/struct_unittest.cc
@@ -124,15 +124,17 @@ TEST_F(StructTest, Serialization_Basic) { RectPtr rect(MakeRect()); - size_t size = mojo::internal::PrepareToSerialize<RectDataView>(rect, nullptr); + mojo::internal::SerializationContext context; + size_t size = + mojo::internal::PrepareToSerialize<RectDataView>(rect, &context); EXPECT_EQ(8U + 16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::Rect_Data* data; - mojo::internal::Serialize<RectDataView>(rect, &buf, &data, nullptr); + mojo::internal::Serialize<RectDataView>(rect, &buf, &data, &context); RectPtr rect2; - mojo::internal::Deserialize<RectDataView>(data, &rect2, nullptr); + mojo::internal::Deserialize<RectDataView>(data, &rect2, &context); CheckRect(*rect2); } @@ -155,16 +157,17 @@ TEST_F(StructTest, Serialization_StructPointers) { RectPairPtr pair(RectPair::New(MakeRect(), MakeRect())); + mojo::internal::SerializationContext context; size_t size = - mojo::internal::PrepareToSerialize<RectPairDataView>(pair, nullptr); + mojo::internal::PrepareToSerialize<RectPairDataView>(pair, &context); EXPECT_EQ(8U + 16U + 2 * (8U + 16U), size); mojo::internal::FixedBufferForTesting buf(size); internal::RectPair_Data* data; - mojo::internal::Serialize<RectPairDataView>(pair, &buf, &data, nullptr); + mojo::internal::Serialize<RectPairDataView>(pair, &buf, &data, &context); RectPairPtr pair2; - mojo::internal::Deserialize<RectPairDataView>(data, &pair2, nullptr); + mojo::internal::Deserialize<RectPairDataView>(data, &pair2, &context); CheckRect(*pair2->first); CheckRect(*pair2->second); @@ -179,8 +182,9 @@ NamedRegionPtr region( NamedRegion::New(std::string("region"), std::move(rects))); + mojo::internal::SerializationContext context; size_t size = - mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr); + mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, &context); EXPECT_EQ(8U + // header 8U + // name pointer 8U + // rects pointer @@ -194,10 +198,10 @@ mojo::internal::FixedBufferForTesting buf(size); internal::NamedRegion_Data* data; - mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr); + mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, &context); NamedRegionPtr region2; - mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, nullptr); + mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, &context); EXPECT_EQ("region", *region2->name); @@ -212,8 +216,9 @@ EXPECT_FALSE(region->name); EXPECT_FALSE(region->rects); + mojo::internal::SerializationContext context; size_t size = - mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr); + mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, &context); EXPECT_EQ(8U + // header 8U + // name pointer 8U, // rects pointer @@ -221,10 +226,10 @@ mojo::internal::FixedBufferForTesting buf(size); internal::NamedRegion_Data* data; - mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr); + mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, &context); NamedRegionPtr region2; - mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, nullptr); + mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, &context); EXPECT_FALSE(region2->name); EXPECT_FALSE(region2->rects); @@ -364,40 +369,42 @@ { // Serialization of a null native struct. NativeStructPtr native; + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); + native, &context); EXPECT_EQ(0u, size); mojo::internal::FixedBufferForTesting buf(size); Data* data = nullptr; mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); + &data, &context); EXPECT_EQ(nullptr, data); NativeStructPtr output_native; mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); + &context); EXPECT_TRUE(output_native.is_null()); } { // Serialization of a native struct with null data. NativeStructPtr native(NativeStruct::New()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); + native, &context); EXPECT_EQ(0u, size); mojo::internal::FixedBufferForTesting buf(size); Data* data = nullptr; mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); + &data, &context); EXPECT_EQ(nullptr, data); NativeStructPtr output_native; mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); + &context); EXPECT_TRUE(output_native.is_null()); } @@ -405,20 +412,21 @@ NativeStructPtr native(NativeStruct::New()); native->data = std::vector<uint8_t>{'X', 'Y'}; + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); + native, &context); EXPECT_EQ(16u, size); mojo::internal::FixedBufferForTesting buf(size); Data* data = nullptr; mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); + &data, &context); EXPECT_NE(nullptr, data); NativeStructPtr output_native; mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); + &context); ASSERT_TRUE(output_native); ASSERT_FALSE(output_native->data->empty()); EXPECT_EQ(2u, output_native->data->size());
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc index 159192f..92e25828 100644 --- a/mojo/public/cpp/bindings/tests/union_unittest.cc +++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -205,14 +205,15 @@ TEST(UnionTest, EnumSerialization) { PodUnionPtr pod1(PodUnion::NewFEnum(AnEnum::SECOND)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>( - pod1, false, nullptr); + pod1, false, &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; mojo::internal::Serialize<PodUnionDataView>(pod1, &buf, &data, false, - nullptr); + &context); PodUnionPtr pod2; mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, nullptr); @@ -226,13 +227,15 @@ PodUnionPtr pod(PodUnion::New()); pod->set_f_int8(10); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -245,18 +248,21 @@ TEST(UnionTest, SerializeNotNull) { PodUnionPtr pod(PodUnion::New()); pod->set_f_int8(0); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); EXPECT_FALSE(data->is_null()); } TEST(UnionTest, SerializeIsNullInlined) { PodUnionPtr pod; - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); @@ -266,7 +272,7 @@ data->tag = PodUnion::Tag::F_UINT16; data->data.f_f_int16 = 20; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, true, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, true, &context); EXPECT_TRUE(data->is_null()); PodUnionPtr pod2; @@ -276,12 +282,14 @@ TEST(UnionTest, SerializeIsNullNotInlined) { PodUnionPtr pod; - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); EXPECT_EQ(nullptr, data); } @@ -336,13 +344,15 @@ TEST(UnionTest, UnknownEnumValueValidation) { PodUnionPtr pod(PodUnion::NewFEnum(static_cast<AnEnum>(0xFFFF))); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -356,13 +366,15 @@ PodUnionPtr pod( PodUnion::NewFExtensibleEnum(static_cast<AnExtensibleEnum>(0xFFFF))); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -415,12 +427,13 @@ std::string hello("hello world"); ObjectUnionPtr pod1(ObjectUnion::NewFString(hello)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - pod1, false, nullptr); + pod1, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(pod1, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr pod2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &pod2, nullptr); @@ -500,16 +513,17 @@ array[1]->set_f_int16(12); EXPECT_EQ(2U, array.size()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>( - array, nullptr); + array, &context); EXPECT_EQ(40U, size); mojo::internal::FixedBufferForTesting buf(size); mojo::internal::Array_Data<internal::PodUnion_Data>* data; mojo::internal::ContainerValidateParams validate_params(0, false, nullptr); mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); + array, &buf, &data, &validate_params, &context); std::vector<PodUnionPtr> array2; mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2, @@ -528,16 +542,17 @@ array[0]->set_f_int8(10); EXPECT_EQ(2U, array.size()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>( - array, nullptr); + array, &context); EXPECT_EQ(40U, size); mojo::internal::FixedBufferForTesting buf(size); mojo::internal::Array_Data<internal::PodUnion_Data>* data; mojo::internal::ContainerValidateParams validate_params(0, true, nullptr); mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); + array, &buf, &data, &validate_params, &context); std::vector<PodUnionPtr> array2; mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2, @@ -558,9 +573,10 @@ array[1]->set_f_string("world"); EXPECT_EQ(2U, array.size()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<ObjectUnionDataView>>( - array, nullptr); + array, &context); EXPECT_EQ(72U, size); mojo::internal::FixedBufferForTesting buf(size); @@ -568,7 +584,7 @@ mojo::internal::Array_Data<internal::ObjectUnion_Data>* data; mojo::internal::ContainerValidateParams validate_params(0, false, nullptr); mojo::internal::Serialize<ArrayDataView<ObjectUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); + array, &buf, &data, &validate_params, &context); std::vector<char> new_buf; new_buf.resize(size); @@ -635,13 +651,14 @@ std::string hello("hello world"); obj_struct->obj_union->set_f_string(hello); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<SmallObjStructDataView>( - obj_struct, nullptr); + obj_struct, &context); mojo::internal::FixedBufferForTesting buf(size); internal::SmallObjStruct_Data* data = nullptr; mojo::internal::Serialize<SmallObjStructDataView>(obj_struct, &buf, &data, - nullptr); + &context); SmallObjStructPtr deserialized; mojo::internal::Deserialize<SmallObjStructDataView>(data, &deserialized, @@ -702,9 +719,10 @@ SmallStructNonNullableUnionPtr small_struct( SmallStructNonNullableUnion::New()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<SmallStructNonNullableUnionDataView>( - small_struct, nullptr); + small_struct, &context); mojo::internal::FixedBufferForTesting buf(size); internal::SmallStructNonNullableUnion_Data* data = @@ -829,14 +847,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_dummy(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr obj2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); @@ -850,13 +869,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_dummy(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -874,13 +894,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_dummy(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -896,13 +917,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_nullable(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -932,14 +954,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_array_int8(std::move(array)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr obj2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); @@ -956,12 +979,13 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_array_int8(std::move(array)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -1062,14 +1086,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_pod_union(std::move(pod)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr obj2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); @@ -1083,14 +1108,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_pod_union(std::move(pod)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -1108,13 +1134,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_pod_union(std::move(pod)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context(
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl index fcf1596..bbc1777 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -161,7 +161,8 @@ mojo::Message message( {{message_name}}, mojo::Message::kFlagIsSync | mojo::Message::kFlagExpectsResponse, - size, serialization_context.associated_endpoint_count); + size, serialization_context.associated_endpoint_count, + serialization_context.handles.mutable_handles()); {{build_message(params_struct, "param_%s", params_description, "&serialization_context", "&message")}} @@ -188,7 +189,8 @@ constexpr uint32_t kFlags = 0; {%- endif %} mojo::Message message({{message_name}}, kFlags, size, - serialization_context.associated_endpoint_count); + serialization_context.associated_endpoint_count, + serialization_context.handles.mutable_handles()); {{build_message(params_struct, "in_%s", params_description, "&serialization_context", "&message")}} @@ -270,7 +272,8 @@ uint32_t flags = (is_sync_ ? mojo::Message::kFlagIsSync : 0) | mojo::Message::kFlagIsResponse; mojo::Message message({{message_name}}, flags, size, - serialization_context.associated_endpoint_count); + serialization_context.associated_endpoint_count, + serialization_context.handles.mutable_handles()); {{build_message(response_params_struct, "in_%s", params_description, "&serialization_context", "&message")}} message.set_request_id(request_id_);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl index bb5fb9c..3e43c88a 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl
@@ -20,7 +20,8 @@ input_may_be_temp=False) -%} size_t size = sizeof({{struct|get_qualified_name_for_kind(internal=True)}}); {%- for pf in struct.packed.packed_fields_in_ordinal_order - if pf.field.kind|is_object_kind or pf.field.kind|is_associated_kind %} + if pf.field.kind|is_object_kind or + pf.field.kind|is_any_handle_or_interface_kind %} {%- set name = pf.field.name -%} {%- set kind = pf.field.kind -%} {%- set original_input_field = input_field_pattern|format(name) %} @@ -73,7 +74,14 @@ {%- set input_field = "in_%s"|format(name) if input_may_be_temp else original_input_field %} {%- if input_may_be_temp %} +{%- if kind|is_associated_kind or kind|is_object_kind %} decltype({{original_input_field}}) in_{{name}} = {{original_input_field}}; +{%- else %} + // Dummy input value. The serialized value is already stored in the + // SerializationContext. + typename std::remove_reference<decltype({{original_input_field}})>::type + in_{{name}}; +{%- endif %} {%- endif %} {%- endif %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl index 835178bed..02af440 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
@@ -11,7 +11,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; void* custom_context = CustomContextHelper<Traits>::SetUp(input, context); @@ -27,7 +29,7 @@ Buffer* buffer, {{data_type}}** output, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { *output = nullptr; return; }
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl index b589ae91..cc513c3 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
@@ -12,8 +12,9 @@ bool inlined, SerializationContext* context) { size_t size = inlined ? 0 : sizeof({{data_type}}); - - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return size; void* custom_context = CustomContextHelper<Traits>::SetUp(input, context); @@ -23,7 +24,8 @@ {%- for field in union.fields %} {%- set name = field.name %} case {{data_view}}::Tag::{{name|upper}}: { -{%- if field.kind|is_object_kind or field.kind|is_associated_kind %} +{%- if field.kind|is_object_kind or + field.kind|is_any_handle_or_interface_kind %} {%- set kind = field.kind %} {%- set serializer_type = kind|unmapped_type_for_serializer %} decltype(CallWithContext(Traits::{{name}}, input, custom_context)) @@ -49,7 +51,7 @@ {{data_type}}** output, bool inlined, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { if (inlined) (*output)->set_null(); else
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc index 962456c..30d6dbc8 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -287,7 +287,7 @@ void It2MeNativeMessagingHostTest::SetPolicies( const base::DictionaryValue& dict) { - DCHECK(test_message_loop_->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(test_message_loop_->task_runner()->RunsTasksInCurrentSequence()); // Copy |dict| into |policy_bundle|. policy::PolicyNamespace policy_namespace = policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()); @@ -494,7 +494,7 @@ } void It2MeNativeMessagingHostTest::StartHost() { - DCHECK(host_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(host_task_runner_->RunsTasksInCurrentSequence()); base::File input_read_file; base::File output_write_file; @@ -536,7 +536,7 @@ } void It2MeNativeMessagingHostTest::ExitTest() { - if (!test_message_loop_->task_runner()->RunsTasksOnCurrentThread()) { + if (!test_message_loop_->task_runner()->RunsTasksInCurrentSequence()) { test_message_loop_->task_runner()->PostTask( FROM_HERE, base::Bind(&It2MeNativeMessagingHostTest::ExitTest, @@ -547,7 +547,7 @@ } void It2MeNativeMessagingHostTest::ExitPolicyRunLoop() { - DCHECK(test_message_loop_->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(test_message_loop_->task_runner()->RunsTasksInCurrentSequence()); if (policy_run_loop_) { policy_run_loop_->Quit(); }
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc index 112a5db..26940eb 100644 --- a/remoting/host/native_messaging/native_messaging_reader.cc +++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -88,7 +88,7 @@ NativeMessagingReader::Core::~Core() {} void NativeMessagingReader::Core::ReadMessage() { - DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(read_task_runner_->RunsTasksInCurrentSequence()); // Keep reading messages until the stream is closed or an error occurs. while (true) { @@ -136,7 +136,7 @@ } void NativeMessagingReader::Core::NotifyEof() { - DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(read_task_runner_->RunsTasksInCurrentSequence()); caller_task_runner_->PostTask( FROM_HERE, base::Bind(&NativeMessagingReader::InvokeEofCallback, reader_));
diff --git a/remoting/host/security_key/security_key_message_reader.cc b/remoting/host/security_key/security_key_message_reader.cc index bb222110..c6ba1b1c6 100644 --- a/remoting/host/security_key/security_key_message_reader.cc +++ b/remoting/host/security_key/security_key_message_reader.cc
@@ -32,7 +32,7 @@ } SecurityKeyMessageReader::~SecurityKeyMessageReader() { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); // In order to ensure the reader thread is stopped cleanly, we close the // stream it is blocking on and then wait for the thread to exit. @@ -43,7 +43,7 @@ void SecurityKeyMessageReader::Start( SecurityKeyMessageCallback message_callback, base::Closure error_callback) { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); message_callback_ = message_callback; error_callback_ = error_callback; @@ -56,7 +56,7 @@ } void SecurityKeyMessageReader::ReadMessage() { - DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(read_task_runner_->RunsTasksInCurrentSequence()); while (true) { if (!read_stream_.IsValid()) { @@ -112,7 +112,7 @@ } void SecurityKeyMessageReader::NotifyError() { - DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(read_task_runner_->RunsTasksInCurrentSequence()); main_task_runner_->PostTask( FROM_HERE, base::Bind(&SecurityKeyMessageReader::InvokeErrorCallback, @@ -121,12 +121,12 @@ void SecurityKeyMessageReader::InvokeMessageCallback( std::unique_ptr<SecurityKeyMessage> message) { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); message_callback_.Run(std::move(message)); } void SecurityKeyMessageReader::InvokeErrorCallback() { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); error_callback_.Run(); }
diff --git a/remoting/host/security_key/security_key_message_reader_impl.cc b/remoting/host/security_key/security_key_message_reader_impl.cc index 14b8f03..ae3b07e8 100644 --- a/remoting/host/security_key/security_key_message_reader_impl.cc +++ b/remoting/host/security_key/security_key_message_reader_impl.cc
@@ -33,7 +33,7 @@ } SecurityKeyMessageReaderImpl::~SecurityKeyMessageReaderImpl() { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); // In order to ensure the reader thread is stopped cleanly, we want to stop // the thread before the task runners and weak pointers are invalidated. @@ -43,7 +43,7 @@ void SecurityKeyMessageReaderImpl::Start( const SecurityKeyMessageCallback& message_callback, const base::Closure& error_callback) { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); message_callback_ = message_callback; error_callback_ = error_callback; @@ -56,7 +56,7 @@ } void SecurityKeyMessageReaderImpl::ReadMessage() { - DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(read_task_runner_->RunsTasksInCurrentSequence()); while (true) { if (!read_stream_.IsValid()) { @@ -124,7 +124,7 @@ } void SecurityKeyMessageReaderImpl::NotifyError() { - DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(read_task_runner_->RunsTasksInCurrentSequence()); main_task_runner_->PostTask( FROM_HERE, base::Bind(&SecurityKeyMessageReaderImpl::InvokeErrorCallback, @@ -133,12 +133,12 @@ void SecurityKeyMessageReaderImpl::InvokeMessageCallback( std::unique_ptr<SecurityKeyMessage> message) { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); message_callback_.Run(std::move(message)); } void SecurityKeyMessageReaderImpl::InvokeErrorCallback() { - DCHECK(main_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); error_callback_.Run(); }
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc index c03f2a75..2f837578 100644 --- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc +++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -322,7 +322,7 @@ } void Me2MeNativeMessagingHostTest::StartHost() { - DCHECK(host_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(host_task_runner_->RunsTasksInCurrentSequence()); base::File input_read_file; base::File output_write_file; @@ -366,7 +366,7 @@ } void Me2MeNativeMessagingHostTest::StopHost() { - DCHECK(host_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(host_task_runner_->RunsTasksInCurrentSequence()); native_messaging_pipe_.reset(); @@ -378,7 +378,7 @@ } void Me2MeNativeMessagingHostTest::ExitTest() { - if (!test_message_loop_->task_runner()->RunsTasksOnCurrentThread()) { + if (!test_message_loop_->task_runner()->RunsTasksInCurrentSequence()) { test_message_loop_->task_runner()->PostTask( FROM_HERE, base::Bind(&Me2MeNativeMessagingHostTest::ExitTest,
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd index fbbc6e2a..e578cb0 100644 --- a/remoting/resources/remoting_strings.grd +++ b/remoting/resources/remoting_strings.grd
@@ -87,7 +87,7 @@ <output filename="remoting/webapp/_locales/da/messages.json" lang="da" type="chrome_messages_json"/> <output filename="remoting/webapp/_locales/de/messages.json" lang="de" type="chrome_messages_json"/> <output filename="remoting/webapp/_locales/fa/messages.json" lang="fa" type="chrome_messages_json"/> - <output filename="remoting/webapp/_locales/fake_bidi/messages.json" lang="fake_bidi" type="chrome_messages_json"/> + <output filename="remoting/webapp/_locales/fake_bidi/messages.json" lang="fake-bidi" type="chrome_messages_json"/> <output filename="remoting/webapp/_locales/el/messages.json" lang="el" type="chrome_messages_json"/> <output filename="remoting/webapp/_locales/en/messages.json" lang="en" type="chrome_messages_json"/> <if expr="chromeos or is_ios">
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index ca19aa5..271878b1 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -39,7 +39,7 @@ #if defined(OS_ANDROID) std::unique_ptr<service_manager::Service> CreateDeviceService( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, const WakeLockContextCallback& wake_lock_context_callback, const base::android::JavaRef<jobject>& java_nfc_delegate) { @@ -49,25 +49,25 @@ } return base::MakeUnique<DeviceService>( - std::move(file_task_runner), std::move(io_task_runner), + std::move(blocking_task_runner), std::move(io_task_runner), wake_lock_context_callback, java_nfc_delegate); } #else std::unique_ptr<service_manager::Service> CreateDeviceService( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) { - return base::MakeUnique<DeviceService>(std::move(file_task_runner), + return base::MakeUnique<DeviceService>(std::move(blocking_task_runner), std::move(io_task_runner)); } #endif #if defined(OS_ANDROID) DeviceService::DeviceService( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, const WakeLockContextCallback& wake_lock_context_callback, const base::android::JavaRef<jobject>& java_nfc_delegate) - : file_task_runner_(std::move(file_task_runner)), + : blocking_task_runner_(std::move(blocking_task_runner)), io_task_runner_(std::move(io_task_runner)), wake_lock_context_callback_(wake_lock_context_callback), java_interface_provider_initialized_(false) { @@ -75,9 +75,9 @@ } #else DeviceService::DeviceService( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) - : file_task_runner_(std::move(file_task_runner)), + : blocking_task_runner_(std::move(blocking_task_runner)), io_task_runner_(std::move(io_task_runner)) {} #endif @@ -245,7 +245,7 @@ if (io_task_runner_) { io_task_runner_->PostTask( FROM_HERE, base::Bind(&device::SensorProviderImpl::Create, - file_task_runner_, base::Passed(&request))); + blocking_task_runner_, base::Passed(&request))); } } @@ -253,14 +253,14 @@ const service_manager::BindSourceInfo& source_info, mojom::TimeZoneMonitorRequest request) { if (!time_zone_monitor_) - time_zone_monitor_ = TimeZoneMonitor::Create(file_task_runner_); + time_zone_monitor_ = TimeZoneMonitor::Create(blocking_task_runner_); time_zone_monitor_->Bind(std::move(request)); } void DeviceService::BindWakeLockProviderRequest( const service_manager::BindSourceInfo& source_info, mojom::WakeLockProviderRequest request) { - WakeLockProvider::Create(std::move(request), file_task_runner_, + WakeLockProvider::Create(std::move(request), blocking_task_runner_, wake_lock_context_callback_); }
diff --git a/services/device/device_service.h b/services/device/device_service.h index 69ddb654..35e8814 100644 --- a/services/device/device_service.h +++ b/services/device/device_service.h
@@ -6,6 +6,7 @@ #define SERVICES_DEVICE_DEVICE_SERVICE_H_ #include "base/memory/ref_counted.h" +#include "base/sequenced_task_runner.h" #include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" #include "device/screen_orientation/public/interfaces/screen_orientation.mojom.h" #include "device/sensors/public/interfaces/motion.mojom.h" @@ -41,25 +42,25 @@ // and NFCDelegate.java to understand the semantics and usage of these // parameters. std::unique_ptr<service_manager::Service> CreateDeviceService( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, const WakeLockContextCallback& wake_lock_context_callback, const base::android::JavaRef<jobject>& java_nfc_delegate); #else std::unique_ptr<service_manager::Service> CreateDeviceService( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); #endif class DeviceService : public service_manager::Service { public: #if defined(OS_ANDROID) - DeviceService(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + DeviceService(scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, const WakeLockContextCallback& wake_lock_context_callback, const base::android::JavaRef<jobject>& java_nfc_delegate); #else - DeviceService(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, + DeviceService(scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); #endif ~DeviceService() override; @@ -122,7 +123,7 @@ std::unique_ptr<PowerMonitorMessageBroadcaster> power_monitor_message_broadcaster_; std::unique_ptr<TimeZoneMonitor> time_zone_monitor_; - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; WakeLockContextCallback wake_lock_context_callback_;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index b8d5041..b8c9ede2 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1909,22 +1909,13 @@ "name": "SearchOrTypeUrl" }, { - "name": "SearchOrTypeWebsiteName" + "name": "SearchOrTypeWebAddress" }, { - "name": "SearchTheWeb" + "name": "TypeWhatYouAreLookingFor" }, { - "name": "EnterASearchOrWebsite" - }, - { - "name": "SearchNews" - }, - { - "name": "SearchRecipes" - }, - { - "name": "SearchWeather" + "name": "FindNewsRecipesWeather" }, { "name": "Blank" @@ -3345,6 +3336,24 @@ ] } ], + "VideoCaptureService": [ + { + "platforms": [ + "linux", + "mac", + "win", + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MojoVideoCapture" + ] + } + ] + } + ], "ViewsSimplifiedFullscreenUI": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations index ae1ecbd..5ce9785 100644 --- a/third_party/WebKit/LayoutTests/W3CImportExpectations +++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -174,7 +174,8 @@ external/wpt/css/css-speech-1 [ Skip ] external/wpt/css/css-syntax-3 [ Skip ] external/wpt/css/css-style-attr [ Skip ] -external/wpt/css/css-tables-3 [ Skip ] +## Owners: dgrogan@chromium.org,joysyu@google.com +# external/wpt/css/css-tables-3 [ Pass ] external/wpt/css/css-text-3/hanging-punctuation [ Skip ] ## Owners: kojii@chromium.org # external/wpt/css/css-text-3/i18n [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/listbox-no-force-layout.html b/third_party/WebKit/LayoutTests/fast/forms/select/listbox-no-force-layout.html new file mode 100644 index 0000000..1133966 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/select/listbox-no-force-layout.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<body> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> + +<select size="4" multiple> +<option>option 1</option> +<option>option 2</option> +<option>option 3</option> +<option>option 4</option> +<option id="o5">option 5</option> +</select> +<script> +var preCount; +var t = async_test('OPTION selection should not force layout.'); +requestAnimationFrame(t.step_func(() => { + assert_exists(window, 'internals'); + preCount = internals.forceLayoutCount; + // Make sure layout-dirty + document.body.append('text'); + document.querySelector('#o5').selected = true; + + requestAnimationFrame(t.step_func_done(() => { + assert_equals(internals.forceLayoutCount - preCount, 0); + })); +})); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/select-initial-position.html b/third_party/WebKit/LayoutTests/fast/forms/select/select-initial-position.html index 7e24851..966565a 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/select/select-initial-position.html +++ b/third_party/WebKit/LayoutTests/fast/forms/select/select-initial-position.html
@@ -143,6 +143,26 @@ sel.appendChild(opt); </script> -</body> +<p>Display 'none' to 'inline-block'</p> +<select style="display:none;" id="select-none" size="4"> +<option>option1</option> +<option>option2</option> +<option>option3</option> +<option>option4</option> +<option>option5</option> +<option>option6</option> +<option selected>This should be selected and visible.</option> +</select> +<script> +// Force layout with display:none. +document.body.offsetHeight; +if (window.testRunner) + testRunner.waitUntilDone(); +requestAnimationFrame(() => { + document.querySelector('#select-none').style.display = 'inline-block'; + testRunner.notifyDone(); +}); +</script> +</body> </html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input-expected.txt index 964fb32..aac4641 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input-expected.txt
@@ -948,7 +948,7 @@ "type": "relatedElement", "value": { "type": "computedString", - "value": "label-wrapping-text10 " + "value": "label-wrapping-text10" }, "nativeSource": "labelwrapped", "nativeSourceValue": { @@ -956,7 +956,7 @@ "relatedNodes": [ { "backendDOMNodeId": "<number>", - "text": "label-wrapping-text10 " + "text": "label-wrapping-text10" } ] } @@ -1037,7 +1037,7 @@ "type": "nodeList", "relatedNodes": [ { - "text": "label-wrapping-text10 ", + "text": "label-wrapping-text10", "nodeResult": "label" } ]
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input.js b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input.js index 2e46958..c6d5d94f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-nameSources-input.js
@@ -35,8 +35,7 @@ <label for='text9'>label-for-text9</label> <label>label-wrapping-text9<input data-dump id='text9' type='text' title='text9-title' aria-placeholder='text9-aria-placeholder' placeholder='text9-placeholder'></label> - <label>label-wrapping-text10<input data-dump id='text10' type='text' title='text10-title' aria-placeholder='text10-aria-placeholder' placeholder='text10-placeholder'> - </label> + <label>label-wrapping-text10<input data-dump id='text10' type='text' title='text10-title' aria-placeholder='text10-aria-placeholder' placeholder='text10-placeholder'></label> <input data-dump id='text11' type='text'> <label for='text11'>first-label-for-text11</label>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt index ff1d5575..3339db2 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt
@@ -60,7 +60,7 @@ [0] : { attributes : [ [0] : src - [1] : ../dom/resources/shadow-dom-iframe.html + [1] : ./shadow-dom-iframe.html ] backendNodeId : <backendNodeId> childNodeCount : 0
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.js b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.js index 6c807ff..f9d57a7 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.js
@@ -1,14 +1,5 @@ (async function(testRunner) { - var {page, session, dp} = await testRunner.startHTML(` - <div id='depth-1'> - <div id='depth-2'> - <div id='depth-3'> - <iframe src='../dom/resources/shadow-dom-iframe.html'></iframe> - </div> - </div> - <div id='targetDiv'></div> - </div> - `, ''); + var {page, session, dp} = await testRunner.startURL('./resources/dom-request-document-with-child-nodes.html', ''); var response = await dp.DOM.getDocument({depth: -1}); var iframeOwner = response.result.root.children[0].children[1].children[0].children[0].children[0].children[0]; if (iframeOwner.contentDocument.children) {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/resources/dom-request-document-with-child-nodes.html b/third_party/WebKit/LayoutTests/inspector-protocol/dom/resources/dom-request-document-with-child-nodes.html new file mode 100644 index 0000000..08ec4a0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/resources/dom-request-document-with-child-nodes.html
@@ -0,0 +1,8 @@ +<div id='depth-1'> + <div id='depth-2'> + <div id='depth-3'> + <iframe src='./shadow-dom-iframe.html'></iframe> + </div> + </div> + <div id='targetDiv'></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling.js b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling.js index dd9354ef..ce2e839 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-without-enabling.js
@@ -2,7 +2,9 @@ let {page, session, dp} = await testRunner.startBlank(`Tests that default execution context accessed without enabling Runtime domain gets properly cleaned up on reload.`); await session.evaluate('window.dummyObject = { a : 1 };'); var result = await dp.Runtime.evaluate({expression: 'window.dummyObject' }); - await dp.Page.reload(); + dp.Page.enable(); + dp.Page.reload(); + await dp.Page.onceLoadEventFired(); testRunner.logMessage(await dp.Runtime.getProperties({ objectId: result.result.result.objectId, ownProperties: true })); testRunner.completeTest(); })
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/stylesheet-tracking-restart.js b/third_party/WebKit/LayoutTests/inspector-protocol/stylesheet-tracking-restart.js index 5ca5a040..d2ed8c2 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/stylesheet-tracking-restart.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/stylesheet-tracking-restart.js
@@ -18,10 +18,11 @@ await runTest(session); testRunner.log('Closing inspector.'); testRunner.log('\nRemoving style sheet.\n'); - session.evaluate('setTimeout(() => { document.head.removeChild(styleElement1); document.body.offsetWidth; }, 0)'); + session.evaluate('Promise.resolve().then(() => { document.head.removeChild(styleElement1); document.body.offsetWidth; })'); await session.disconnect(); testRunner.log('Reopening inspector.'); session = await page.createSession(); + await session.evaluateAsync('new Promise(f => setTimeout(f, 0))'); testRunner.log('Running test'); testRunner.log('Opening front-end second time'); await runTest(session);
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.png index 1357295f..d7419ab 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.txt index 457600a..70291bd 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 93x19 - text run at (0,0) width 93: "initial selected:" - LayoutBR {BR} at (93,15) size 0x0 - LayoutText {#text} at (155,71) size 4x19 - text run at (155,71) width 4: " " - LayoutBR {BR} at (159,86) size 0x0 - LayoutText {#text} at (0,91) size 161x19 - text run at (0,91) width 161: "dynamic selected change:" - LayoutBR {BR} at (161,106) size 0x0 - LayoutText {#text} at (155,162) size 4x19 - text run at (155,162) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,182) size 211x19 - text run at (0,182) width 211: "dynamic insert of selected option:" - LayoutBR {BR} at (211,197) size 0x0 - LayoutText {#text} at (155,253) size 4x19 - text run at (155,253) width 4: " " - LayoutBR {BR} at (159,268) size 0x0 - LayoutText {#text} at (0,273) size 93x19 - text run at (0,273) width 93: "initial selected:" - LayoutBR {BR} at (93,288) size 0x0 - LayoutMenuList {SELECT} at (0,293) size 156x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutBlockFlow (anonymous) at (1,1) size 154x18 - LayoutText (anonymous) at (4,1) size 134x16 - text run at (4,1) width 134: "this should be selected" - LayoutText {#text} at (156,293) size 4x19 - text run at (156,293) width 4: " " - LayoutBR {BR} at (160,308) size 0x0 - LayoutText {#text} at (0,313) size 161x19 - text run at (0,313) width 161: "dynamic selected change:" - LayoutBR {BR} at (161,328) size 0x0 - LayoutMenuList {SELECT} at (0,333) size 156x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutBlockFlow (anonymous) at (1,1) size 154x18 - LayoutText (anonymous) at (4,1) size 134x16 - text run at (4,1) width 134: "this should be selected" - LayoutText {#text} at (156,333) size 4x19 - text run at (156,333) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,353) size 211x19 - text run at (0,353) width 211: "dynamic insert of selected option:" - LayoutBR {BR} at (211,368) size 0x0 - LayoutMenuList {SELECT} at (0,373) size 156x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutBlockFlow (anonymous) at (1,1) size 154x18 - LayoutText (anonymous) at (4,1) size 134x16 - text run at (4,1) width 134: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x393 + LayoutText {#text} at (0,0) size 93x19 + text run at (0,0) width 93: "initial selected:" + LayoutBR {BR} at (93,15) size 0x0 + LayoutText {#text} at (155,71) size 4x19 + text run at (155,71) width 4: " " + LayoutBR {BR} at (159,86) size 0x0 + LayoutText {#text} at (0,91) size 161x19 + text run at (0,91) width 161: "dynamic selected change:" + LayoutBR {BR} at (161,106) size 0x0 + LayoutText {#text} at (155,162) size 4x19 + text run at (155,162) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,182) size 211x19 + text run at (0,182) width 211: "dynamic insert of selected option:" + LayoutBR {BR} at (211,197) size 0x0 + LayoutText {#text} at (155,253) size 4x19 + text run at (155,253) width 4: " " + LayoutBR {BR} at (159,268) size 0x0 + LayoutText {#text} at (0,273) size 93x19 + text run at (0,273) width 93: "initial selected:" + LayoutBR {BR} at (93,288) size 0x0 + LayoutMenuList {SELECT} at (0,293) size 156x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] + LayoutBlockFlow (anonymous) at (1,1) size 154x18 + LayoutText (anonymous) at (4,1) size 134x16 + text run at (4,1) width 134: "this should be selected" + LayoutText {#text} at (156,293) size 4x19 + text run at (156,293) width 4: " " + LayoutBR {BR} at (160,308) size 0x0 + LayoutText {#text} at (0,313) size 161x19 + text run at (0,313) width 161: "dynamic selected change:" + LayoutBR {BR} at (161,328) size 0x0 + LayoutMenuList {SELECT} at (0,333) size 156x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] + LayoutBlockFlow (anonymous) at (1,1) size 154x18 + LayoutText (anonymous) at (4,1) size 134x16 + text run at (4,1) width 134: "this should be selected" + LayoutText {#text} at (156,333) size 4x19 + text run at (156,333) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,353) size 211x19 + text run at (0,353) width 211: "dynamic insert of selected option:" + LayoutBR {BR} at (211,368) size 0x0 + LayoutMenuList {SELECT} at (0,373) size 156x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] + LayoutBlockFlow (anonymous) at (1,1) size 154x18 + LayoutText (anonymous) at (4,1) size 134x16 + text run at (4,1) width 134: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,409) size 784x20 + LayoutText {#text} at (0,0) size 191x19 + text run at (0,0) width 191: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,445) size 784x70 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,28) size 155x70 clip at (9,29) size 138x68 scrollY 119.00 scrollHeight 238 LayoutListBox {SELECT} at (0,20) size 155x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] LayoutBlockFlow {OPTION} at (1,1) size 138x17 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,120) size 138x17 LayoutText {#text} at (2,0) size 18x16 text run at (2,0) width 18: "opt" +layer at (8,453) size 229x70 clip at (9,454) size 212x68 scrollY 51.00 scrollHeight 119 + LayoutListBox {SELECT} at (0,0) size 229x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] + LayoutBlockFlow {OPTION} at (1,1) size 212x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option1" + LayoutBlockFlow {OPTION} at (1,18) size 212x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option2" + LayoutBlockFlow {OPTION} at (1,35) size 212x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option3" + LayoutBlockFlow {OPTION} at (1,52) size 212x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option4" + LayoutBlockFlow {OPTION} at (1,69) size 212x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option5" + LayoutBlockFlow {OPTION} at (1,86) size 212x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option6" + LayoutBlockFlow {OPTION} at (1,103) size 212x17 [color=#FFFFFF] [bgcolor=#999999] + LayoutText {#text} at (2,0) size 208x16 + text run at (2,0) width 208: "This should be selected and visible."
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.png index a3d3813..a7c497d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.txt index 4b74084..73d65c36 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 98x18 - text run at (0,0) width 98: "initial selected:" - LayoutBR {BR} at (97,14) size 1x0 - LayoutText {#text} at (132,59) size 5x18 - text run at (132,59) width 5: " " - LayoutBR {BR} at (136,73) size 1x0 - LayoutText {#text} at (0,77) size 165x18 - text run at (0,77) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,91) size 1x0 - LayoutText {#text} at (132,136) size 5x18 - text run at (132,136) width 5: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,154) size 217x18 - text run at (0,154) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,168) size 1x0 - LayoutText {#text} at (132,213) size 5x18 - text run at (132,213) width 5: " " - LayoutBR {BR} at (136,227) size 1x0 - LayoutText {#text} at (0,231) size 98x18 - text run at (0,231) width 98: "initial selected:" - LayoutBR {BR} at (97,245) size 1x0 - LayoutMenuList {SELECT} at (0,250) size 147x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 147x18 - LayoutText (anonymous) at (8,2) size 116x13 - text run at (8,2) width 116: "this should be selected" - LayoutText {#text} at (147,249) size 4x18 - text run at (147,249) width 4: " " - LayoutBR {BR} at (151,263) size 0x0 - LayoutText {#text} at (0,268) size 165x18 - text run at (0,268) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,282) size 1x0 - LayoutMenuList {SELECT} at (0,287) size 147x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 147x18 - LayoutText (anonymous) at (8,2) size 116x13 - text run at (8,2) width 116: "this should be selected" - LayoutText {#text} at (147,286) size 4x18 - text run at (147,286) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,305) size 217x18 - text run at (0,305) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,319) size 1x0 - LayoutMenuList {SELECT} at (0,323) size 147x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 147x18 - LayoutText (anonymous) at (8,2) size 116x13 - text run at (8,2) width 116: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x341 + LayoutText {#text} at (0,0) size 98x18 + text run at (0,0) width 98: "initial selected:" + LayoutBR {BR} at (97,14) size 1x0 + LayoutText {#text} at (132,59) size 5x18 + text run at (132,59) width 5: " " + LayoutBR {BR} at (136,73) size 1x0 + LayoutText {#text} at (0,77) size 165x18 + text run at (0,77) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,91) size 1x0 + LayoutText {#text} at (132,136) size 5x18 + text run at (132,136) width 5: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,154) size 217x18 + text run at (0,154) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,168) size 1x0 + LayoutText {#text} at (132,213) size 5x18 + text run at (132,213) width 5: " " + LayoutBR {BR} at (136,227) size 1x0 + LayoutText {#text} at (0,231) size 98x18 + text run at (0,231) width 98: "initial selected:" + LayoutBR {BR} at (97,245) size 1x0 + LayoutMenuList {SELECT} at (0,250) size 147x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 147x18 + LayoutText (anonymous) at (8,2) size 116x13 + text run at (8,2) width 116: "this should be selected" + LayoutText {#text} at (147,249) size 4x18 + text run at (147,249) width 4: " " + LayoutBR {BR} at (151,263) size 0x0 + LayoutText {#text} at (0,268) size 165x18 + text run at (0,268) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,282) size 1x0 + LayoutMenuList {SELECT} at (0,287) size 147x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 147x18 + LayoutText (anonymous) at (8,2) size 116x13 + text run at (8,2) width 116: "this should be selected" + LayoutText {#text} at (147,286) size 4x18 + text run at (147,286) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,305) size 217x18 + text run at (0,305) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,319) size 1x0 + LayoutMenuList {SELECT} at (0,323) size 147x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 147x18 + LayoutText (anonymous) at (8,2) size 116x13 + text run at (8,2) width 116: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,357) size 784x18 + LayoutText {#text} at (0,0) size 195x18 + text run at (0,0) width 195: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,391) size 784x59 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,26) size 133x59 clip at (9,27) size 120x57 scrollY 99.00 scrollHeight 199 LayoutListBox {SELECT} at (0,18.25) size 132.55x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 119.55x14.19 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,100.31) size 119.55x14.19 LayoutText {#text} at (2,0) size 17x13 text run at (2,0) width 17: "opt" +layer at (8,399) size 195x59 clip at (9,400) size 182x57 scrollY 42.00 scrollHeight 100 + LayoutListBox {SELECT} at (0,0.25) size 194.88x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 181.88x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option1" + LayoutBlockFlow {OPTION} at (1,15.19) size 181.88x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option2" + LayoutBlockFlow {OPTION} at (1,29.38) size 181.88x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option3" + LayoutBlockFlow {OPTION} at (1,43.56) size 181.88x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option4" + LayoutBlockFlow {OPTION} at (1,57.75) size 181.88x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option5" + LayoutBlockFlow {OPTION} at (1,71.94) size 181.88x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option6" + LayoutBlockFlow {OPTION} at (1,86.13) size 181.88x14.19 [bgcolor=#D4D4D4] + LayoutText {#text} at (2,0) size 178x13 + text run at (2,0) width 178: "This should be selected and visible."
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.png index 0a800ca..35b041f6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.txt index 8909f11..569a8e6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 98x18 - text run at (0,0) width 98: "initial selected:" - LayoutBR {BR} at (97,14) size 1x0 - LayoutText {#text} at (137,59) size 5x18 - text run at (137,59) width 5: " " - LayoutBR {BR} at (141,73) size 1x0 - LayoutText {#text} at (0,77) size 165x18 - text run at (0,77) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,91) size 1x0 - LayoutText {#text} at (137,136) size 5x18 - text run at (137,136) width 5: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,154) size 217x18 - text run at (0,154) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,168) size 1x0 - LayoutText {#text} at (137,213) size 5x18 - text run at (137,213) width 5: " " - LayoutBR {BR} at (141,227) size 1x0 - LayoutText {#text} at (0,231) size 98x18 - text run at (0,231) width 98: "initial selected:" - LayoutBR {BR} at (97,245) size 1x0 - LayoutMenuList {SELECT} at (0,250) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (152,249) size 4x18 - text run at (152,249) width 4: " " - LayoutBR {BR} at (156,263) size 0x0 - LayoutText {#text} at (0,268) size 165x18 - text run at (0,268) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,282) size 1x0 - LayoutMenuList {SELECT} at (0,287) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (152,286) size 4x18 - text run at (152,286) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,305) size 217x18 - text run at (0,305) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,319) size 1x0 - LayoutMenuList {SELECT} at (0,323) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x341 + LayoutText {#text} at (0,0) size 98x18 + text run at (0,0) width 98: "initial selected:" + LayoutBR {BR} at (97,14) size 1x0 + LayoutText {#text} at (137,59) size 5x18 + text run at (137,59) width 5: " " + LayoutBR {BR} at (141,73) size 1x0 + LayoutText {#text} at (0,77) size 165x18 + text run at (0,77) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,91) size 1x0 + LayoutText {#text} at (137,136) size 5x18 + text run at (137,136) width 5: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,154) size 217x18 + text run at (0,154) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,168) size 1x0 + LayoutText {#text} at (137,213) size 5x18 + text run at (137,213) width 5: " " + LayoutBR {BR} at (141,227) size 1x0 + LayoutText {#text} at (0,231) size 98x18 + text run at (0,231) width 98: "initial selected:" + LayoutBR {BR} at (97,245) size 1x0 + LayoutMenuList {SELECT} at (0,250) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (152,249) size 4x18 + text run at (152,249) width 4: " " + LayoutBR {BR} at (156,263) size 0x0 + LayoutText {#text} at (0,268) size 165x18 + text run at (0,268) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,282) size 1x0 + LayoutMenuList {SELECT} at (0,287) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (152,286) size 4x18 + text run at (152,286) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,305) size 217x18 + text run at (0,305) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,319) size 1x0 + LayoutMenuList {SELECT} at (0,323) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,357) size 784x18 + LayoutText {#text} at (0,0) size 195x18 + text run at (0,0) width 195: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,391) size 784x59 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,26) size 137x59 clip at (9,27) size 124x57 scrollY 99.00 scrollHeight 199 LayoutListBox {SELECT} at (0,18.25) size 137.41x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 124.41x14.19 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,100.31) size 124.41x14.19 LayoutText {#text} at (2,0) size 18x13 text run at (2,0) width 18: "opt" +layer at (8,399) size 202x59 clip at (9,400) size 189x57 scrollY 42.00 scrollHeight 100 + LayoutListBox {SELECT} at (0,0.25) size 202.05x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 189.05x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option1" + LayoutBlockFlow {OPTION} at (1,15.19) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option2" + LayoutBlockFlow {OPTION} at (1,29.38) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option3" + LayoutBlockFlow {OPTION} at (1,43.56) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option4" + LayoutBlockFlow {OPTION} at (1,57.75) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option5" + LayoutBlockFlow {OPTION} at (1,71.94) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option6" + LayoutBlockFlow {OPTION} at (1,86.13) size 189.05x14.19 [bgcolor=#D4D4D4] + LayoutText {#text} at (2,0) size 186x13 + text run at (2,0) width 186: "This should be selected and visible."
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.png index d7ba591..1278f1c6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.txt index 2c82af23..8774e74 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 98x18 - text run at (0,0) width 98: "initial selected:" - LayoutBR {BR} at (97,14) size 1x0 - LayoutText {#text} at (140,59) size 5x18 - text run at (140,59) width 5: " " - LayoutBR {BR} at (144,73) size 1x0 - LayoutText {#text} at (0,77) size 165x18 - text run at (0,77) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,91) size 1x0 - LayoutText {#text} at (140,136) size 5x18 - text run at (140,136) width 5: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,154) size 217x18 - text run at (0,154) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,168) size 1x0 - LayoutText {#text} at (140,213) size 5x18 - text run at (140,213) width 5: " " - LayoutBR {BR} at (144,227) size 1x0 - LayoutText {#text} at (0,231) size 98x18 - text run at (0,231) width 98: "initial selected:" - LayoutBR {BR} at (97,245) size 1x0 - LayoutMenuList {SELECT} at (0,250) size 155x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 155x18 - LayoutText (anonymous) at (8,2) size 124x13 - text run at (8,2) width 124: "this should be selected" - LayoutText {#text} at (155,249) size 4x18 - text run at (155,249) width 4: " " - LayoutBR {BR} at (159,263) size 0x0 - LayoutText {#text} at (0,268) size 165x18 - text run at (0,268) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,282) size 1x0 - LayoutMenuList {SELECT} at (0,287) size 155x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 155x18 - LayoutText (anonymous) at (8,2) size 124x13 - text run at (8,2) width 124: "this should be selected" - LayoutText {#text} at (155,286) size 4x18 - text run at (155,286) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,305) size 217x18 - text run at (0,305) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,319) size 1x0 - LayoutMenuList {SELECT} at (0,323) size 155x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 155x18 - LayoutText (anonymous) at (8,2) size 124x13 - text run at (8,2) width 124: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x341 + LayoutText {#text} at (0,0) size 98x18 + text run at (0,0) width 98: "initial selected:" + LayoutBR {BR} at (97,14) size 1x0 + LayoutText {#text} at (140,59) size 5x18 + text run at (140,59) width 5: " " + LayoutBR {BR} at (144,73) size 1x0 + LayoutText {#text} at (0,77) size 165x18 + text run at (0,77) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,91) size 1x0 + LayoutText {#text} at (140,136) size 5x18 + text run at (140,136) width 5: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,154) size 217x18 + text run at (0,154) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,168) size 1x0 + LayoutText {#text} at (140,213) size 5x18 + text run at (140,213) width 5: " " + LayoutBR {BR} at (144,227) size 1x0 + LayoutText {#text} at (0,231) size 98x18 + text run at (0,231) width 98: "initial selected:" + LayoutBR {BR} at (97,245) size 1x0 + LayoutMenuList {SELECT} at (0,250) size 155x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 155x18 + LayoutText (anonymous) at (8,2) size 124x13 + text run at (8,2) width 124: "this should be selected" + LayoutText {#text} at (155,249) size 4x18 + text run at (155,249) width 4: " " + LayoutBR {BR} at (159,263) size 0x0 + LayoutText {#text} at (0,268) size 165x18 + text run at (0,268) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,282) size 1x0 + LayoutMenuList {SELECT} at (0,287) size 155x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 155x18 + LayoutText (anonymous) at (8,2) size 124x13 + text run at (8,2) width 124: "this should be selected" + LayoutText {#text} at (155,286) size 4x18 + text run at (155,286) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,305) size 217x18 + text run at (0,305) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,319) size 1x0 + LayoutMenuList {SELECT} at (0,323) size 155x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 155x18 + LayoutText (anonymous) at (8,2) size 124x13 + text run at (8,2) width 124: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,357) size 784x18 + LayoutText {#text} at (0,0) size 195x18 + text run at (0,0) width 195: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,391) size 784x59 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,26) size 140x59 clip at (9,27) size 127x57 scrollY 99.00 scrollHeight 199 LayoutListBox {SELECT} at (0,18.25) size 140.19x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 127.19x14.19 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,100.31) size 127.19x14.19 LayoutText {#text} at (2,0) size 18x13 text run at (2,0) width 18: "opt" +layer at (8,399) size 207x59 clip at (9,400) size 194x57 scrollY 42.00 scrollHeight 100 + LayoutListBox {SELECT} at (0,0.25) size 207.19x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 194.19x14.19 + LayoutText {#text} at (2,0) size 42x13 + text run at (2,0) width 42: "option1" + LayoutBlockFlow {OPTION} at (1,15.19) size 194.19x14.19 + LayoutText {#text} at (2,0) size 42x13 + text run at (2,0) width 42: "option2" + LayoutBlockFlow {OPTION} at (1,29.38) size 194.19x14.19 + LayoutText {#text} at (2,0) size 42x13 + text run at (2,0) width 42: "option3" + LayoutBlockFlow {OPTION} at (1,43.56) size 194.19x14.19 + LayoutText {#text} at (2,0) size 42x13 + text run at (2,0) width 42: "option4" + LayoutBlockFlow {OPTION} at (1,57.75) size 194.19x14.19 + LayoutText {#text} at (2,0) size 42x13 + text run at (2,0) width 42: "option5" + LayoutBlockFlow {OPTION} at (1,71.94) size 194.19x14.19 + LayoutText {#text} at (2,0) size 42x13 + text run at (2,0) width 42: "option6" + LayoutBlockFlow {OPTION} at (1,86.13) size 194.19x14.19 [bgcolor=#D4D4D4] + LayoutText {#text} at (2,0) size 191x13 + text run at (2,0) width 191: "This should be selected and visible."
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.png index 0a800ca..35b041f6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.txt index 8909f11..569a8e6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 98x18 - text run at (0,0) width 98: "initial selected:" - LayoutBR {BR} at (97,14) size 1x0 - LayoutText {#text} at (137,59) size 5x18 - text run at (137,59) width 5: " " - LayoutBR {BR} at (141,73) size 1x0 - LayoutText {#text} at (0,77) size 165x18 - text run at (0,77) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,91) size 1x0 - LayoutText {#text} at (137,136) size 5x18 - text run at (137,136) width 5: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,154) size 217x18 - text run at (0,154) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,168) size 1x0 - LayoutText {#text} at (137,213) size 5x18 - text run at (137,213) width 5: " " - LayoutBR {BR} at (141,227) size 1x0 - LayoutText {#text} at (0,231) size 98x18 - text run at (0,231) width 98: "initial selected:" - LayoutBR {BR} at (97,245) size 1x0 - LayoutMenuList {SELECT} at (0,250) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (152,249) size 4x18 - text run at (152,249) width 4: " " - LayoutBR {BR} at (156,263) size 0x0 - LayoutText {#text} at (0,268) size 165x18 - text run at (0,268) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,282) size 1x0 - LayoutMenuList {SELECT} at (0,287) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (152,286) size 4x18 - text run at (152,286) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,305) size 217x18 - text run at (0,305) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,319) size 1x0 - LayoutMenuList {SELECT} at (0,323) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x341 + LayoutText {#text} at (0,0) size 98x18 + text run at (0,0) width 98: "initial selected:" + LayoutBR {BR} at (97,14) size 1x0 + LayoutText {#text} at (137,59) size 5x18 + text run at (137,59) width 5: " " + LayoutBR {BR} at (141,73) size 1x0 + LayoutText {#text} at (0,77) size 165x18 + text run at (0,77) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,91) size 1x0 + LayoutText {#text} at (137,136) size 5x18 + text run at (137,136) width 5: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,154) size 217x18 + text run at (0,154) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,168) size 1x0 + LayoutText {#text} at (137,213) size 5x18 + text run at (137,213) width 5: " " + LayoutBR {BR} at (141,227) size 1x0 + LayoutText {#text} at (0,231) size 98x18 + text run at (0,231) width 98: "initial selected:" + LayoutBR {BR} at (97,245) size 1x0 + LayoutMenuList {SELECT} at (0,250) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (152,249) size 4x18 + text run at (152,249) width 4: " " + LayoutBR {BR} at (156,263) size 0x0 + LayoutText {#text} at (0,268) size 165x18 + text run at (0,268) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,282) size 1x0 + LayoutMenuList {SELECT} at (0,287) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (152,286) size 4x18 + text run at (152,286) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,305) size 217x18 + text run at (0,305) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,319) size 1x0 + LayoutMenuList {SELECT} at (0,323) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,357) size 784x18 + LayoutText {#text} at (0,0) size 195x18 + text run at (0,0) width 195: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,391) size 784x59 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,26) size 137x59 clip at (9,27) size 124x57 scrollY 99.00 scrollHeight 199 LayoutListBox {SELECT} at (0,18.25) size 137.41x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 124.41x14.19 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,100.31) size 124.41x14.19 LayoutText {#text} at (2,0) size 18x13 text run at (2,0) width 18: "opt" +layer at (8,399) size 202x59 clip at (9,400) size 189x57 scrollY 42.00 scrollHeight 100 + LayoutListBox {SELECT} at (0,0.25) size 202.05x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 189.05x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option1" + LayoutBlockFlow {OPTION} at (1,15.19) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option2" + LayoutBlockFlow {OPTION} at (1,29.38) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option3" + LayoutBlockFlow {OPTION} at (1,43.56) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option4" + LayoutBlockFlow {OPTION} at (1,57.75) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option5" + LayoutBlockFlow {OPTION} at (1,71.94) size 189.05x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option6" + LayoutBlockFlow {OPTION} at (1,86.13) size 189.05x14.19 [bgcolor=#D4D4D4] + LayoutText {#text} at (2,0) size 186x13 + text run at (2,0) width 186: "This should be selected and visible."
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.png index 3aec5c5..d712ea60 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.txt index 37e2e6c..834660a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 98x18 - text run at (0,0) width 98: "initial selected:" - LayoutBR {BR} at (97,14) size 1x0 - LayoutText {#text} at (137,59) size 5x18 - text run at (137,59) width 5: " " - LayoutBR {BR} at (141,73) size 1x0 - LayoutText {#text} at (0,77) size 165x18 - text run at (0,77) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,91) size 1x0 - LayoutText {#text} at (137,136) size 5x18 - text run at (137,136) width 5: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,154) size 217x18 - text run at (0,154) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,168) size 1x0 - LayoutText {#text} at (137,213) size 5x18 - text run at (137,213) width 5: " " - LayoutBR {BR} at (141,227) size 1x0 - LayoutText {#text} at (0,231) size 98x18 - text run at (0,231) width 98: "initial selected:" - LayoutBR {BR} at (97,245) size 1x0 - LayoutMenuList {SELECT} at (0,250) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (152,249) size 4x18 - text run at (152,249) width 4: " " - LayoutBR {BR} at (156,263) size 0x0 - LayoutText {#text} at (0,268) size 165x18 - text run at (0,268) width 165: "dynamic selected change:" - LayoutBR {BR} at (164,282) size 1x0 - LayoutMenuList {SELECT} at (0,287) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (152,286) size 4x18 - text run at (152,286) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,305) size 217x18 - text run at (0,305) width 217: "dynamic insert of selected option:" - LayoutBR {BR} at (216,319) size 1x0 - LayoutMenuList {SELECT} at (0,323) size 152x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 152x18 - LayoutText (anonymous) at (8,2) size 121x13 - text run at (8,2) width 121: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x341 + LayoutText {#text} at (0,0) size 98x18 + text run at (0,0) width 98: "initial selected:" + LayoutBR {BR} at (97,14) size 1x0 + LayoutText {#text} at (137,59) size 5x18 + text run at (137,59) width 5: " " + LayoutBR {BR} at (141,73) size 1x0 + LayoutText {#text} at (0,77) size 165x18 + text run at (0,77) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,91) size 1x0 + LayoutText {#text} at (137,136) size 5x18 + text run at (137,136) width 5: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,154) size 217x18 + text run at (0,154) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,168) size 1x0 + LayoutText {#text} at (137,213) size 5x18 + text run at (137,213) width 5: " " + LayoutBR {BR} at (141,227) size 1x0 + LayoutText {#text} at (0,231) size 98x18 + text run at (0,231) width 98: "initial selected:" + LayoutBR {BR} at (97,245) size 1x0 + LayoutMenuList {SELECT} at (0,250) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (152,249) size 4x18 + text run at (152,249) width 4: " " + LayoutBR {BR} at (156,263) size 0x0 + LayoutText {#text} at (0,268) size 165x18 + text run at (0,268) width 165: "dynamic selected change:" + LayoutBR {BR} at (164,282) size 1x0 + LayoutMenuList {SELECT} at (0,287) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (152,286) size 4x18 + text run at (152,286) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,305) size 217x18 + text run at (0,305) width 217: "dynamic insert of selected option:" + LayoutBR {BR} at (216,319) size 1x0 + LayoutMenuList {SELECT} at (0,323) size 152x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 152x18 + LayoutText (anonymous) at (8,2) size 121x13 + text run at (8,2) width 121: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,357) size 784x18 + LayoutText {#text} at (0,0) size 195x18 + text run at (0,0) width 195: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,391) size 784x59 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,26) size 137x59 clip at (9,27) size 124x57 scrollY 99.00 scrollHeight 199 LayoutListBox {SELECT} at (0,18.25) size 137.39x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 124.39x14.19 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,100.31) size 124.39x14.19 LayoutText {#text} at (2,0) size 18x13 text run at (2,0) width 18: "opt" +layer at (8,399) size 202x59 clip at (9,400) size 189x57 scrollY 42.00 scrollHeight 100 + LayoutListBox {SELECT} at (0,0.25) size 202.03x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 189.03x14.19 + LayoutText {#text} at (2,0) size 38x13 + text run at (2,0) width 38: "option1" + LayoutBlockFlow {OPTION} at (1,15.19) size 189.03x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option2" + LayoutBlockFlow {OPTION} at (1,29.38) size 189.03x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option3" + LayoutBlockFlow {OPTION} at (1,43.56) size 189.03x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option4" + LayoutBlockFlow {OPTION} at (1,57.75) size 189.03x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option5" + LayoutBlockFlow {OPTION} at (1,71.94) size 189.03x14.19 + LayoutText {#text} at (2,0) size 40x13 + text run at (2,0) width 40: "option6" + LayoutBlockFlow {OPTION} at (1,86.13) size 189.03x14.19 [bgcolor=#D4D4D4] + LayoutText {#text} at (2,0) size 186x13 + text run at (2,0) width 186: "This should be selected and visible."
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.png index c00e1ec8..d83413b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.txt index 15e784c..fec1120 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-initial-position-expected.txt
@@ -3,54 +3,61 @@ layer at (0,0) size 800x600 LayoutBlockFlow {HTML} at (0,0) size 800x600 LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 86x19 - text run at (0,0) width 86: "initial selected:" - LayoutBR {BR} at (86,15) size 0x0 - LayoutText {#text} at (155,71) size 4x19 - text run at (155,71) width 4: " " - LayoutBR {BR} at (159,86) size 0x0 - LayoutText {#text} at (0,91) size 152x19 - text run at (0,91) width 152: "dynamic selected change:" - LayoutBR {BR} at (152,106) size 0x0 - LayoutText {#text} at (155,162) size 4x19 - text run at (155,162) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,182) size 200x19 - text run at (0,182) width 200: "dynamic insert of selected option:" - LayoutBR {BR} at (200,197) size 0x0 - LayoutText {#text} at (155,253) size 4x19 - text run at (155,253) width 4: " " - LayoutBR {BR} at (159,268) size 0x0 - LayoutText {#text} at (0,273) size 86x19 - text run at (0,273) width 86: "initial selected:" - LayoutBR {BR} at (86,288) size 0x0 - LayoutMenuList {SELECT} at (0,293) size 156x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] - LayoutBlockFlow (anonymous) at (1,1) size 154x18 - LayoutText (anonymous) at (4,1) size 134x16 - text run at (4,1) width 134: "this should be selected" - LayoutText {#text} at (156,293) size 4x19 - text run at (156,293) width 4: " " - LayoutBR {BR} at (160,308) size 0x0 - LayoutText {#text} at (0,313) size 152x19 - text run at (0,313) width 152: "dynamic selected change:" - LayoutBR {BR} at (152,328) size 0x0 - LayoutMenuList {SELECT} at (0,333) size 156x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] - LayoutBlockFlow (anonymous) at (1,1) size 154x18 - LayoutText (anonymous) at (4,1) size 134x16 - text run at (4,1) width 134: "this should be selected" - LayoutText {#text} at (156,333) size 4x19 - text run at (156,333) width 4: " " - LayoutText {#text} at (0,0) size 0x0 - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,353) size 200x19 - text run at (0,353) width 200: "dynamic insert of selected option:" - LayoutBR {BR} at (200,368) size 0x0 - LayoutMenuList {SELECT} at (0,373) size 156x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] - LayoutBlockFlow (anonymous) at (1,1) size 154x18 - LayoutText (anonymous) at (4,1) size 134x16 - text run at (4,1) width 134: "this should be selected" - LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,0) size 784x393 + LayoutText {#text} at (0,0) size 86x19 + text run at (0,0) width 86: "initial selected:" + LayoutBR {BR} at (86,15) size 0x0 + LayoutText {#text} at (155,71) size 4x19 + text run at (155,71) width 4: " " + LayoutBR {BR} at (159,86) size 0x0 + LayoutText {#text} at (0,91) size 152x19 + text run at (0,91) width 152: "dynamic selected change:" + LayoutBR {BR} at (152,106) size 0x0 + LayoutText {#text} at (155,162) size 4x19 + text run at (155,162) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,182) size 200x19 + text run at (0,182) width 200: "dynamic insert of selected option:" + LayoutBR {BR} at (200,197) size 0x0 + LayoutText {#text} at (155,253) size 4x19 + text run at (155,253) width 4: " " + LayoutBR {BR} at (159,268) size 0x0 + LayoutText {#text} at (0,273) size 86x19 + text run at (0,273) width 86: "initial selected:" + LayoutBR {BR} at (86,288) size 0x0 + LayoutMenuList {SELECT} at (0,293) size 156x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] + LayoutBlockFlow (anonymous) at (1,1) size 154x18 + LayoutText (anonymous) at (4,1) size 134x16 + text run at (4,1) width 134: "this should be selected" + LayoutText {#text} at (156,293) size 4x19 + text run at (156,293) width 4: " " + LayoutBR {BR} at (160,308) size 0x0 + LayoutText {#text} at (0,313) size 152x19 + text run at (0,313) width 152: "dynamic selected change:" + LayoutBR {BR} at (152,328) size 0x0 + LayoutMenuList {SELECT} at (0,333) size 156x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] + LayoutBlockFlow (anonymous) at (1,1) size 154x18 + LayoutText (anonymous) at (4,1) size 134x16 + text run at (4,1) width 134: "this should be selected" + LayoutText {#text} at (156,333) size 4x19 + text run at (156,333) width 4: " " + LayoutText {#text} at (0,0) size 0x0 + LayoutBR {BR} at (0,0) size 0x0 + LayoutText {#text} at (0,353) size 200x19 + text run at (0,353) width 200: "dynamic insert of selected option:" + LayoutBR {BR} at (200,368) size 0x0 + LayoutMenuList {SELECT} at (0,373) size 156x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] + LayoutBlockFlow (anonymous) at (1,1) size 154x18 + LayoutText (anonymous) at (4,1) size 134x16 + text run at (4,1) width 134: "this should be selected" + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,409) size 784x20 + LayoutText {#text} at (0,0) size 180x19 + text run at (0,0) width 180: "Display 'none' to 'inline-block'" + LayoutBlockFlow (anonymous) at (0,445) size 784x70 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 layer at (8,28) size 155x70 clip at (9,29) size 138x68 scrollY 119.00 scrollHeight 238 LayoutListBox {SELECT} at (0,20) size 155x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] LayoutBlockFlow {OPTION} at (1,1) size 138x17 @@ -165,3 +172,26 @@ LayoutBlockFlow {OPTION} at (1,120) size 138x17 LayoutText {#text} at (2,0) size 18x16 text run at (2,0) width 18: "opt" +layer at (8,453) size 226x70 clip at (9,454) size 209x68 scrollY 51.00 scrollHeight 119 + LayoutListBox {SELECT} at (0,0) size 226x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] + LayoutBlockFlow {OPTION} at (1,1) size 209x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option1" + LayoutBlockFlow {OPTION} at (1,18) size 209x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option2" + LayoutBlockFlow {OPTION} at (1,35) size 209x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option3" + LayoutBlockFlow {OPTION} at (1,52) size 209x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option4" + LayoutBlockFlow {OPTION} at (1,69) size 209x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option5" + LayoutBlockFlow {OPTION} at (1,86) size 209x17 + LayoutText {#text} at (2,0) size 42x16 + text run at (2,0) width 42: "option6" + LayoutBlockFlow {OPTION} at (1,103) size 209x17 [color=#FFFFFF] [bgcolor=#999999] + LayoutText {#text} at (2,0) size 205x16 + text run at (2,0) width 205: "This should be selected and visible."
diff --git a/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp b/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp index d107c76..88325d25 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp +++ b/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp
@@ -56,11 +56,6 @@ isolate, world, v8::Local<v8::Object>(), prototype_object, interface_object); } - if (OriginTrials::webShareEnabled(execution_context)) { - V8NavigatorPartial::installWebShare(isolate, world, - v8::Local<v8::Object>(), - prototype_object, interface_object); - } if (OriginTrials::webVREnabled(execution_context)) { V8NavigatorPartial::installWebVR(isolate, world, v8::Local<v8::Object>(), prototype_object, interface_object); @@ -168,16 +163,6 @@ } return; } - if (feature == "WebShare") { - if (context_data->GetExistingConstructorAndPrototypeForType( - &V8Navigator::wrapperTypeInfo, &prototype_object, - &interface_object)) { - V8NavigatorPartial::installWebShare(isolate, world, - v8::Local<v8::Object>(), - prototype_object, interface_object); - } - return; - } if (feature == "WebVR1.1") { global_instance_object = script_state->GetContext()->Global(); V8WindowPartial::installGamepadExtensions(
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 49fc092..5b8dff27 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2381,6 +2381,7 @@ if (run_post_layout_tasks == kRunPostLayoutTasksSynchronously && View()) View()->FlushAnyPendingPostLayoutTasks(); + ++force_layout_count_; } PassRefPtr<ComputedStyle> Document::StyleForElementIgnoringPendingStylesheets( @@ -2575,6 +2576,8 @@ lifecycle_.AdvanceTo(DocumentLifecycle::kStopping); View()->Dispose(); + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. + CHECK(!View()->IsAttached()); // If the EmbeddedContentView of the document's frame owner doesn't match // view() then LocalFrameView::Dispose() didn't clear the owner's @@ -2635,6 +2638,8 @@ layout_view_ = nullptr; ContainerNode::DetachLayoutTree(); + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. + CHECK(!View()->IsAttached()); if (this != &AxObjectCacheOwner()) { if (AXObjectCache* cache = ExistingAXObjectCache()) { @@ -2678,6 +2683,8 @@ media_query_matcher_->DocumentDetached(); lifecycle_.AdvanceTo(DocumentLifecycle::kStopped); + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. + CHECK(!View()->IsAttached()); // TODO(haraken): Call contextDestroyed() before we start any disruptive // operations. @@ -2688,6 +2695,8 @@ // a contextDestroyed() notification. This can happen for a document // created by DOMImplementation::createDocument(). ExecutionContext::NotifyContextDestroyed(); + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. + CHECK(!View()->IsAttached()); // This is required, as our LocalFrame might delete itself as soon as it // detaches us. However, this violates Node::detachLayoutTree() semantics, as
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index 731c536..31b2524a 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -967,6 +967,7 @@ uint64_t DomTreeVersion() const { return dom_tree_version_; } uint64_t StyleVersion() const { return style_version_; } + unsigned ForceLayoutCountForTesting() const { return force_layout_count_; } enum PendingSheetLayout { kNoLayoutWithPendingSheets, @@ -1511,6 +1512,7 @@ static uint64_t global_tree_version_; uint64_t style_version_; + unsigned force_layout_count_ = 0; HeapHashSet<WeakMember<NodeIterator>> node_iterators_; using AttachedRangeSet = HeapHashSet<WeakMember<Range>>;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp index 46f5a7d..c2975ee 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -299,6 +299,16 @@ loader_.StopAllLoaders(); loader_.Detach(); GetDocument()->Shutdown(); + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. + // It seems to crash because Frame is detached before LocalFrameView. + // Verify here that any LocalFrameView has been detached by now. + if (view_ && view_->IsAttached()) { + CHECK(DeprecatedLocalOwner()); + CHECK(DeprecatedLocalOwner()->OwnedEmbeddedContentView()); + CHECK_EQ(view_, DeprecatedLocalOwner()->OwnedEmbeddedContentView()); + } + CHECK(!view_ || !view_->IsAttached()); + // This is the earliest that scripting can be disabled: // - FrameLoader::Detach() can fire XHR abort events // - Document::Shutdown() can dispose plugins which can run script. @@ -306,21 +316,15 @@ if (!Client()) return; + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. + CHECK(!view_->IsAttached()); Client()->WillBeDetached(); // Notify ScriptController that the frame is closing, since its cleanup ends // up calling back to LocalFrameClient via WindowProxy. GetScriptController().ClearForClose(); // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. - // It seems to crash because Frame is detached before LocalFrameView. - // Verify here that any LocalFrameView has been detached by now. - if (view_->IsAttached()) { - CHECK(DeprecatedLocalOwner()); - CHECK(DeprecatedLocalOwner()->OwnedEmbeddedContentView()); - CHECK_EQ(view_, DeprecatedLocalOwner()->OwnedEmbeddedContentView()); - } CHECK(!view_->IsAttached()); - SetView(nullptr); page_->GetEventHandlerRegistry().DidRemoveAllEventHandlers(*DomWindow());
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index a816e48d..77dd70be 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -3907,7 +3907,10 @@ } void LocalFrameView::AttachToLayout() { + // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes. CHECK(!is_attached_); + if (frame_->GetDocument()) + CHECK_NE(Lifecycle().GetState(), DocumentLifecycle::kStopping); is_attached_ = true; parent_ = ParentFrameView(); if (!parent_) {
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp index ae72a44..6548714f 100644 --- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp +++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -114,6 +114,7 @@ if (inner_viewport_container_layer_) { inner_viewport_container_layer_->SetSize(FloatSize(size_)); + inner_viewport_scroll_layer_->PlatformLayer()->SetScrollable(size_); // Need to re-compute sizes for the overlay scrollbars. InitializeScrollbars(); @@ -369,8 +370,7 @@ GetPage().GetSettings().GetMainFrameClipsContent()); inner_viewport_container_layer_->SetSize(FloatSize(size_)); - inner_viewport_scroll_layer_->PlatformLayer()->SetScrollClipLayer( - inner_viewport_container_layer_->PlatformLayer()); + inner_viewport_scroll_layer_->PlatformLayer()->SetScrollable(size_); if (MainFrame()) { if (Document* document = MainFrame()->GetDocument()) { inner_viewport_scroll_layer_->SetElementId(
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp index 0b1bc9b1..31bc4f73 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -44,7 +44,6 @@ #include "core/dom/NodeComputedStyle.h" #include "core/dom/NodeListsNodeData.h" #include "core/dom/NodeTraversal.h" -#include "core/dom/TaskRunnerHelper.h" #include "core/events/GestureEvent.h" #include "core/events/KeyboardEvent.h" #include "core/events/MouseEvent.h" @@ -70,6 +69,7 @@ #include "core/page/ChromeClient.h" #include "core/page/Page.h" #include "core/page/SpatialNavigation.h" +#include "core/paint/PaintLayerScrollableArea.h" #include "platform/instrumentation/tracing/TraceEvent.h" #include "platform/text/PlatformLocale.h" @@ -891,30 +891,43 @@ return; if (UsesMenuList()) return; - bool has_pending_task = option_to_scroll_to_; - // We'd like to keep an HTMLOptionElement reference rather than the index of - // the option because the task should work even if unselected option is - // inserted before executing scrollToOptionTask(). + if (GetLayoutObject()) { + if (GetDocument().Lifecycle().GetState() >= + DocumentLifecycle::kLayoutClean) { + ToLayoutListBox(GetLayoutObject())->ScrollToRect(option->BoundingBox()); + return; + } + // Make sure the LayoutObject will be laid out. + GetLayoutObject()->SetNeedsLayout( + LayoutInvalidationReason::kMenuOptionsChanged); + } option_to_scroll_to_ = option; - if (!has_pending_task) - TaskRunnerHelper::Get(TaskType::kUserInteraction, &GetDocument()) - ->PostTask(BLINK_FROM_HERE, - WTF::Bind(&HTMLSelectElement::ScrollToOptionTask, - WrapPersistent(this))); + // ScrollToOptionAfterLayout() should be called if this element is rendered. } -void HTMLSelectElement::ScrollToOptionTask() { +void HTMLSelectElement::ScrollToOptionAfterLayout( + PaintLayerScrollableArea& scrollable_area) { HTMLOptionElement* option = option_to_scroll_to_.Release(); - if (!option || !isConnected()) + if (!option || UsesMenuList()) return; - // optionRemoved() makes sure m_optionToScrollTo doesn't have an option with - // another owner. - DCHECK_EQ(option->OwnerSelectElement(), this); - GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (!GetLayoutObject() || !GetLayoutObject()->IsListBox()) + LayoutBox* option_box = option->GetLayoutBox(); + if (!option_box) return; - LayoutRect bounds = option->BoundingBox(); - ToLayoutListBox(GetLayoutObject())->ScrollToRect(bounds); + + // We can't use PaintLayerScrollableArea::ScrollIntoView(), which needs + // absolute coordinate. We are unable to compute absolute positions because + // ancestors' layout aren't fixed yet. + LayoutObject* container = option_box->Container(); + LayoutSize option_offset = option_box->OffsetFromContainer(container); + for (; container && container != GetLayoutObject(); + container = container->Container()) + option_offset += container->OffsetFromContainer(container->Container()); + if (!container) + return; + scrollable_area.ScrollLocalRectIntoView( + LayoutRect(LayoutPoint() + option_offset, option_box->Size()), + ScrollAlignment::kAlignToEdgeIfNeeded, + ScrollAlignment::kAlignToEdgeIfNeeded, false); } void HTMLSelectElement::OptionSelectionStateChanged(HTMLOptionElement* option,
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.h b/third_party/WebKit/Source/core/html/HTMLSelectElement.h index 8814387..59f94d0e 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.h +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.h
@@ -45,6 +45,7 @@ class HTMLOptionElement; class HTMLOptionElementOrHTMLOptGroupElement; class HTMLElementOrLong; +class PaintLayerScrollableArea; class PopupMenu; class CORE_EXPORT HTMLSelectElement final @@ -118,6 +119,7 @@ void ScrollToSelection(); void ScrollToOption(HTMLOptionElement*); + void ScrollToOptionAfterLayout(PaintLayerScrollableArea&); bool CanSelectAll() const; void SelectAll(); @@ -267,7 +269,6 @@ SkipDirection) const; HTMLOptionElement* EventTargetOption(const Event&); AutoscrollController* GetAutoscrollController() const; - void ScrollToOptionTask(); bool AreAuthorShadowsAllowed() const override { return false; } void FinishParsingChildren() override;
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp index 977dbc96..de26df74 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -487,7 +487,7 @@ WebLayer* web_layer = toWebLayer(scrollable_area->LayerForScrolling()); WebLayer* container_layer = toWebLayer(scrollable_area->LayerForContainer()); if (web_layer) { - web_layer->SetScrollClipLayer(container_layer); + web_layer->SetScrollable(container_layer->Bounds()); FloatPoint scroll_position(scrollable_area->ScrollOrigin() + scrollable_area->GetScrollOffset()); web_layer->SetScrollPosition(scroll_position);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp index 6f8b3ff9..6f3abea9 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -60,6 +60,7 @@ #include "core/frame/Settings.h" #include "core/frame/VisualViewport.h" #include "core/html/HTMLFrameOwnerElement.h" +#include "core/html/HTMLSelectElement.h" #include "core/input/EventHandler.h" #include "core/layout/LayoutEmbeddedContent.h" #include "core/layout/LayoutFlexibleBox.h" @@ -916,6 +917,10 @@ DisableCompositingQueryAsserts disabler; PositionOverflowControls(); + + Node* node = Box().GetNode(); + if (isHTMLSelectElement(node)) + toHTMLSelectElement(node)->ScrollToOptionAfterLayout(*this); } void PaintLayerScrollableArea::ClampScrollOffsetAfterOverflowChange() { @@ -1775,16 +1780,13 @@ // keep the point under the cursor in view. } -LayoutRect PaintLayerScrollableArea::ScrollIntoView( +LayoutRect PaintLayerScrollableArea::ScrollLocalRectIntoView( const LayoutRect& rect, const ScrollAlignment& align_x, const ScrollAlignment& align_y, bool is_smooth, ScrollType scroll_type) { - LayoutRect local_expose_rect( - Box() - .AbsoluteToLocalQuad(FloatQuad(FloatRect(rect)), kUseTransforms) - .BoundingBox()); + LayoutRect local_expose_rect(rect); local_expose_rect.Move(-Box().BorderLeft(), -Box().BorderTop()); LayoutRect visible_rect(LayoutPoint(), ClientSize()); LayoutRect r = ScrollAlignment::GetRectToExpose( @@ -1802,7 +1804,22 @@ ScrollOffset scroll_offset_difference = ClampScrollOffset(new_scroll_offset) - old_scroll_offset; local_expose_rect.Move(-LayoutSize(scroll_offset_difference)); + return local_expose_rect; +} +LayoutRect PaintLayerScrollableArea::ScrollIntoView( + const LayoutRect& rect, + const ScrollAlignment& align_x, + const ScrollAlignment& align_y, + bool is_smooth, + ScrollType scroll_type) { + LayoutRect local_expose_rect( + Box() + .AbsoluteToLocalQuad(FloatQuad(FloatRect(rect)), kUseTransforms) + .BoundingBox()); + local_expose_rect = ScrollLocalRectIntoView(local_expose_rect, align_x, + align_y, is_smooth, scroll_type); + LayoutRect visible_rect(LayoutPoint(), ClientSize()); LayoutRect intersect = LocalToAbsolute(Box(), Intersection(visible_rect, local_expose_rect)); if (intersect.IsEmpty() && !visible_rect.IsEmpty() &&
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h index 10c6f8b7..74f24dc 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h +++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
@@ -386,6 +386,13 @@ bool HitTestResizerInFragments(const PaintLayerFragments&, const HitTestLocation&) const; + // Returns the new offset, after scrolling, of the given rect in parents + // coordinates. + LayoutRect ScrollLocalRectIntoView(const LayoutRect&, + const ScrollAlignment& align_x, + const ScrollAlignment& align_y, + bool is_smooth, + ScrollType = kProgrammaticScroll); // Returns the new offset, after scrolling, of the given rect in absolute // coordinates, clipped by the parent's client rect. LayoutRect ScrollIntoView(const LayoutRect&,
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index a05e0b2..4ad93814 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -335,6 +335,14 @@ return needs_layout_objects; } +unsigned Internals::forceLayoutCount(ExceptionState& exception_state) const { + if (document_) + return document_->ForceLayoutCountForTesting(); + exception_state.ThrowDOMException(kInvalidAccessError, + "No context document is available."); + return 0; +} + unsigned Internals::hitTestCount(Document* doc, ExceptionState& exception_state) const { if (!doc) {
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index d31c67a..fddaaf23c 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -151,6 +151,7 @@ unsigned updateStyleAndReturnAffectedElementCount(ExceptionState&) const; unsigned needsLayoutCount(ExceptionState&) const; + unsigned forceLayoutCount(ExceptionState&) const; unsigned hitTestCount(Document*, ExceptionState&) const; unsigned hitTestCacheHits(Document*, ExceptionState&) const; Element* elementFromPoint(Document*,
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl index bacd7d84..597afb4 100644 --- a/third_party/WebKit/Source/core/testing/Internals.idl +++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -65,7 +65,10 @@ Node parentTreeScope(Node node); [RaisesException] unsigned short compareTreeScopePosition(Node treeScope1, Node treeScope2); [RaisesException] unsigned long updateStyleAndReturnAffectedElementCount(); + // Returns the number of LayoutObjects with needs-layout flag. [RaisesException] unsigned long needsLayoutCount(); + // The number of force layout since Document creation. + [RaisesException] readonly attribute unsigned long forceLayoutCount; [RaisesException] unsigned long hitTestCount(Document document); [RaisesException] unsigned long hitTestCacheHits(Document document); [RaisesException] Element? elementFromPoint(Document document, double x, double y, boolean ignoreClipping, boolean allowChildFrameContent);
diff --git a/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl b/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl index a5c4b308..7cf20fe9 100644 --- a/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl +++ b/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl
@@ -5,7 +5,7 @@ // https://wicg.github.io/web-share/ [ - OriginTrialEnabled=WebShare + RuntimeEnabled=WebShare ] partial interface Navigator { [SecureContext, CallWith=ScriptState, MeasureAs=WebShareShare] Promise<void> share(ShareData data);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index 4c7dbb6..34cb29c 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -1103,10 +1103,9 @@ name: "WebNFC", status: "experimental", }, + // WebShare is enabled by default on Android. { name: "WebShare", - origin_trial_feature_name: "WebShare", - origin_trial_os: ["android"], status: "experimental", }, {
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp index f618395..2eedb74 100644 --- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp +++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -308,6 +308,10 @@ RuntimeEnabledFeatures::SetPushMessagingEnabled(enable); } +void WebRuntimeFeatures::EnableWebShare(bool enable) { + RuntimeEnabledFeatures::SetWebShareEnabled(enable); +} + void WebRuntimeFeatures::EnableWebVR(bool enable) { RuntimeEnabledFeatures::SetWebVREnabled(enable); }
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp index 846be66..2e354e6 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -63,8 +63,8 @@ clip_layer_->AddChild(scroll_elasticity_layer_.get()); scroll_elasticity_layer_->AddChild(page_scale_layer_.get()); page_scale_layer_->AddChild(graphics_layer_.get()); - graphics_layer_->PlatformLayer()->SetScrollClipLayer( - clip_layer_->PlatformLayer()); + graphics_layer_->PlatformLayer()->SetScrollable( + clip_layer_->PlatformLayer()->Bounds()); platform_layer_ = graphics_layer_->PlatformLayer(); layer_tree_view_ = WTF::WrapUnique(new WebLayerTreeViewImplForTesting); DCHECK(layer_tree_view_);
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index b3e8164..153cb71a 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -780,9 +780,9 @@ EXPECT_EQ(transform_node_index, transform_node.id); EXPECT_EQ(0u, scroll_client.did_scroll_count); - // TODO(pdr): The PaintArtifactCompositor should set the scroll clip layer id - // so the Layer is scrollable. This call should be removed. - layer->SetScrollClipLayerId(layer->id()); + // TODO(pdr): The PaintArtifactCompositor should set the scrolling content + // bounds so the Layer is scrollable. This call should be removed. + layer->SetScrollable(gfx::Size(1, 1)); layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(1, 2)); EXPECT_EQ(1u, scroll_client.did_scroll_count); EXPECT_EQ(gfx::ScrollOffset(1, 2), scroll_client.last_scroll_offset);
diff --git a/third_party/WebKit/public/platform/WebLayer.h b/third_party/WebKit/public/platform/WebLayer.h index 12a7329..07ef4a6b 100644 --- a/third_party/WebKit/public/platform/WebLayer.h +++ b/third_party/WebKit/public/platform/WebLayer.h
@@ -169,9 +169,9 @@ virtual void SetScrollPosition(WebFloatPoint) = 0; virtual WebFloatPoint ScrollPosition() const = 0; - // To set a WebLayer as scrollable we must specify the corresponding clip - // layer. - virtual void SetScrollClipLayer(WebLayer*) = 0; + // To set a WebLayer as scrollable we must specify the scrolling container + // bounds. + virtual void SetScrollable(const WebSize& scroll_container_bounds) = 0; virtual bool Scrollable() const = 0; virtual void SetUserScrollable(bool horizontal, bool vertical) = 0; virtual bool UserScrollableHorizontal() const = 0;
diff --git a/third_party/WebKit/public/platform/WebLocalizedString.h b/third_party/WebKit/public/platform/WebLocalizedString.h index 9ae231a..ac53b8a 100644 --- a/third_party/WebKit/public/platform/WebLocalizedString.h +++ b/third_party/WebKit/public/platform/WebLocalizedString.h
@@ -41,11 +41,7 @@ kAXCalendarShowPreviousMonth, kAXCalendarWeekDescription, kAXDayOfMonthFieldText, - kAXHeadingText, // Deprecated. kAXHourFieldText, - kAXImageMapText, // Deprecated. - kAXLinkText, // Deprecated. - kAXListMarkerText, // Deprecated. kAXMediaAudioElement, kAXMediaAudioElementHelp, kAXMediaAudioSliderHelp, @@ -73,11 +69,6 @@ kAXMediaPlayButtonHelp, kAXMediaShowClosedCaptionsButton, kAXMediaShowClosedCaptionsButtonHelp, - kAXMediaSlider, // Deprecated. - kAXMediaSliderThumb, // Deprecated. - kAXMediaSliderThumbHelp, // Deprecated. - kAXMediaStatusDisplay, - kAXMediaStatusDisplayHelp, kAXMediaTimeRemainingDisplay, kAXMediaTimeRemainingDisplayHelp, kAXMediaUnMuteButton, @@ -89,15 +80,11 @@ kAXMinuteFieldText, kAXMonthFieldText, kAXSecondFieldText, - kAXWebAreaText, // Deprecated. kAXWeekOfYearFieldText, kAXYearFieldText, kBlockedPluginText, kCalendarClear, kCalendarToday, - kDateFormatDayInMonthLabel, - kDateFormatMonthLabel, - kDateFormatYearLabel, kDetailsLabel, kDownloadButtonLabel, kFileButtonChooseFileLabel, @@ -111,7 +98,6 @@ kOtherColorLabel, kOtherDateLabel, kOtherMonthLabel, - kOtherTimeLabel, kOtherWeekLabel, kOverflowMenuCaptions, kOverflowMenuCast, @@ -136,10 +122,6 @@ // "datetime-local" input UI instead of "----". kPlaceholderForYearField, kResetButtonDefaultLabel, - kSearchableIndexIntroduction, - kSearchMenuClearRecentSearchesText, // Deprecated. - kSearchMenuNoRecentSearchesText, // Deprecated. - kSearchMenuRecentSearchesText, // Deprecated. kSelectMenuListText, kSubmitButtonDefaultLabel, kTextTracksNoLabel,
diff --git a/third_party/WebKit/public/platform/WebRuntimeFeatures.h b/third_party/WebKit/public/platform/WebRuntimeFeatures.h index c78c7a1a..e67bf35 100644 --- a/third_party/WebKit/public/platform/WebRuntimeFeatures.h +++ b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
@@ -135,6 +135,7 @@ BLINK_PLATFORM_EXPORT static void EnableWebGLDraftExtensions(bool); BLINK_PLATFORM_EXPORT static void EnableWebGLImageChromium(bool); BLINK_PLATFORM_EXPORT static void EnableWebNfc(bool); + BLINK_PLATFORM_EXPORT static void EnableWebShare(bool); BLINK_PLATFORM_EXPORT static void EnableWebUsb(bool); BLINK_PLATFORM_EXPORT static void EnableWebVR(bool); BLINK_PLATFORM_EXPORT static void EnableWebVRExperimentalRendering(bool);
diff --git a/tools/grit/grit/format/chrome_messages_json.py b/tools/grit/grit/format/chrome_messages_json.py old mode 100755 new mode 100644 index 27ac361..61d718e --- a/tools/grit/grit/format/chrome_messages_json.py +++ b/tools/grit/grit/format/chrome_messages_json.py
@@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (c) 2012 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. @@ -31,6 +30,12 @@ if id.startswith('IDR_') or id.startswith('IDS_'): id = id[4:] + translation_missing = child.GetCliques()[0].clique.get(lang) is None; + if child.ShouldFallbackToEnglish() and translation_missing: + # Skip the string if it's not translated. Chrome will fallback + # to English automatically. + continue + loc_message = encoder.encode(child.ws_at_start + child.Translate(lang) + child.ws_at_end)
diff --git a/tools/grit/grit/format/chrome_messages_json_unittest.py b/tools/grit/grit/format/chrome_messages_json_unittest.py index ec188cc..0a3ae2e 100755 --- a/tools/grit/grit/format/chrome_messages_json_unittest.py +++ b/tools/grit/grit/format/chrome_messages_json_unittest.py
@@ -108,7 +108,8 @@ """) buf = StringIO.StringIO() - build.RcBuilder.ProcessNode(root, DummyOutput('chrome_messages_json', 'fr'), buf) + build.RcBuilder.ProcessNode(root, DummyOutput('chrome_messages_json', 'fr'), + buf) output = buf.getvalue() test = u""" { @@ -122,6 +123,31 @@ """ self.assertEqual(test.strip(), output.strip()) + def testSkipMissingTranslations(self): + grd = """<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="2" current_release="3" source_lang_id="en" + base_dir="%s"> + <outputs> + </outputs> + <release seq="3" allow_pseudo="False"> + <messages fallback_to_english="true"> + <message name="ID_HELLO_NO_TRANSLATION">Hello not translated</message> + </messages> + </release> +</grit>""" + root = grd_reader.Parse(StringIO.StringIO(grd), dir=".") + + buf = StringIO.StringIO() + build.RcBuilder.ProcessNode(root, DummyOutput('chrome_messages_json', 'fr'), + buf) + output = buf.getvalue() + test = u""" +{ + +} +""" + self.assertEqual(test.strip(), output.strip()) + class DummyOutput(object):
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c6d8e48..b7ba56a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -36497,6 +36497,8 @@ <int value="11" label="Disabled by Key"/> <int value="12" label="Language in ULP"/> <int value="13" label="Aborted by translate ranker"/> + <int value="14" label="Aborted by too often denied rule"/> + <int value="15" label="Aborted by matches previous language"/> </enum> <enum name="TranslateLanguage">
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index aa712fa..0d7d03c 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -32,4 +32,56 @@ } } +bool IsCellOrTableHeaderRole(ui::AXRole role) { + switch (role) { + case ui::AX_ROLE_CELL: + case ui::AX_ROLE_COLUMN_HEADER: + case ui::AX_ROLE_ROW_HEADER: + return true; + default: + return false; + } +} + +bool IsTableLikeRole(ui::AXRole role) { + switch (role) { + case ui::AX_ROLE_TABLE: + case ui::AX_ROLE_GRID: + case ui::AX_ROLE_TREE_GRID: + return true; + default: + return false; + } +} + +bool IsContainerWithSelectableChildrenRole(ui::AXRole role) { + switch (role) { + case ui::AX_ROLE_COMBO_BOX: + case ui::AX_ROLE_GRID: + case ui::AX_ROLE_LIST_BOX: + case ui::AX_ROLE_MENU: + case ui::AX_ROLE_MENU_BAR: + case ui::AX_ROLE_RADIO_GROUP: + case ui::AX_ROLE_TAB_LIST: + case ui::AX_ROLE_TOOLBAR: + case ui::AX_ROLE_TREE: + case ui::AX_ROLE_TREE_GRID: + return true; + default: + return false; + } +} + +bool IsRowContainer(ui::AXRole role) { + switch (role) { + case ui::AX_ROLE_TREE: + case ui::AX_ROLE_TREE_GRID: + case ui::AX_ROLE_GRID: + case ui::AX_ROLE_TABLE: + return true; + default: + return false; + } +} + } // namespace ui
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index 7d9ab796..6ee8234 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -14,6 +14,18 @@ // clicks. AX_EXPORT bool IsRoleClickable(AXRole role); +// Returns true if this node is a cell or a table header. +AX_EXPORT bool IsCellOrTableHeaderRole(AXRole role); + +// Returns true if this node is a table, a grid or a treegrid. +AX_EXPORT bool IsTableLikeRole(AXRole role); + +// Returns true if this node is a container with selectable children. +AX_EXPORT bool IsContainerWithSelectableChildrenRole(ui::AXRole role); + +// Returns true if this node is a row container. +AX_EXPORT bool IsRowContainer(ui::AXRole role); + } // namespace ui #endif // UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_
diff --git a/ui/android/java/src/org/chromium/ui/UiUtils.java b/ui/android/java/src/org/chromium/ui/UiUtils.java index 861320d..3a55ab9 100644 --- a/ui/android/java/src/org/chromium/ui/UiUtils.java +++ b/ui/android/java/src/org/chromium/ui/UiUtils.java
@@ -8,6 +8,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; +import android.graphics.Typeface; import android.os.Build; import android.os.Environment; import android.os.Handler; @@ -395,4 +396,19 @@ if (parent == null) return; parent.removeView(view); } + + /** + * Creates a {@link Typeface} that represents medium-weighted text. This function returns + * Roboto Medium when it is available (Lollipop and up) and Roboto Bold where it isn't. + * + * @return Typeface that can be applied to a View. + */ + public static Typeface createRobotoMediumTypeface() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + // Roboto Medium, regular. + return Typeface.create("sans-serif-medium", Typeface.NORMAL); + } else { + return Typeface.create("sans-serif", Typeface.BOLD); + } + } }
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn index 330928c..979cde4 100644 --- a/ui/app_list/BUILD.gn +++ b/ui/app_list/BUILD.gn
@@ -124,6 +124,8 @@ "views/contents_view.h", "views/custom_launcher_page_view.cc", "views/custom_launcher_page_view.h", + "views/expand_arrow_view.cc", + "views/expand_arrow_view.h", "views/folder_background_view.cc", "views/folder_background_view.h", "views/folder_header_view.cc",
diff --git a/ui/app_list/vector_icons/BUILD.gn b/ui/app_list/vector_icons/BUILD.gn index 3c49259..3a1fd24 100644 --- a/ui/app_list/vector_icons/BUILD.gn +++ b/ui/app_list/vector_icons/BUILD.gn
@@ -8,6 +8,8 @@ icon_directory = "." icons = [ + "ic_arrow_up.1x.icon", + "ic_arrow_up.icon", "ic_badge_instant.1x.icon", "ic_badge_instant.icon", "ic_badge_play.1x.icon",
diff --git a/ui/app_list/vector_icons/ic_arrow_up.1x.icon b/ui/app_list/vector_icons/ic_arrow_up.1x.icon new file mode 100644 index 0000000..d28822f --- /dev/null +++ b/ui/app_list/vector_icons/ic_arrow_up.1x.icon
@@ -0,0 +1,13 @@ +// Copyright 2017 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. + +CANVAS_DIMENSIONS, 12, +MOVE_TO, 10.59f, 9, +LINE_TO, 6, 4.67f, +LINE_TO, 1.42f, 9, +LINE_TO, 0, 7.66f, +LINE_TO, 6, 2, +R_LINE_TO, 6, 5.66f, +CLOSE, +END
diff --git a/ui/app_list/vector_icons/ic_arrow_up.icon b/ui/app_list/vector_icons/ic_arrow_up.icon new file mode 100644 index 0000000..5f8b186 --- /dev/null +++ b/ui/app_list/vector_icons/ic_arrow_up.icon
@@ -0,0 +1,13 @@ +// Copyright 2017 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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 21.17f, 19, +LINE_TO, 12, 10.34f, +LINE_TO, 2.83f, 19, +LINE_TO, 0, 16.33f, +LINE_TO, 12, 5, +R_LINE_TO, 12, 11.33f, +CLOSE, +END
diff --git a/ui/app_list/views/expand_arrow_view.cc b/ui/app_list/views/expand_arrow_view.cc new file mode 100644 index 0000000..632d3e18 --- /dev/null +++ b/ui/app_list/views/expand_arrow_view.cc
@@ -0,0 +1,108 @@ +// Copyright 2017 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 "ui/app_list/views/expand_arrow_view.h" + +#include "base/metrics/histogram_macros.h" +#include "ui/app_list/app_list_constants.h" +#include "ui/app_list/vector_icons/vector_icons.h" +#include "ui/app_list/views/app_list_view.h" +#include "ui/app_list/views/contents_view.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/animation/flood_fill_ink_drop_ripple.h" +#include "ui/views/animation/ink_drop_highlight.h" +#include "ui/views/animation/ink_drop_impl.h" +#include "ui/views/animation/ink_drop_mask.h" +#include "ui/views/animation/ink_drop_painted_layer_delegates.h" +#include "ui/views/controls/image_view.h" + +namespace app_list { + +namespace { + +constexpr int kExpandArrowTileSize = 36; +constexpr int kExpandArrowIconSize = 12; +constexpr int kInkDropRadius = 18; + +constexpr SkColor kExpandArrowColor = SK_ColorWHITE; +constexpr SkColor kInkDropRippleColor = + SkColorSetARGBMacro(0x14, 0xFF, 0xFF, 0xFF); +constexpr SkColor kInkDropHighlightColor = + SkColorSetARGBMacro(0xF, 0xFF, 0xFF, 0xFF); + +} // namespace + +ExpandArrowView::ExpandArrowView(ContentsView* contents_view, + AppListView* app_list_view) + : views::CustomButton(this), + contents_view_(contents_view), + app_list_view_(app_list_view) { + icon_ = new views::ImageView; + icon_->SetVerticalAlignment(views::ImageView::CENTER); + icon_->SetImage(gfx::CreateVectorIcon(kIcArrowUpIcon, kExpandArrowIconSize, + kExpandArrowColor)); + AddChildView(icon_); + + SetInkDropMode(InkDropHostView::InkDropMode::ON); +} + +ExpandArrowView::~ExpandArrowView() {} + +void ExpandArrowView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + UMA_HISTOGRAM_ENUMERATION(kPageOpenedHistogram, AppListModel::STATE_APPS, + AppListModel::STATE_LAST); + + contents_view_->SetActiveState(AppListModel::STATE_APPS); + app_list_view_->SetState(AppListView::FULLSCREEN_ALL_APPS); + GetInkDrop()->AnimateToState(views::InkDropState::ACTION_TRIGGERED); +} + +gfx::Size ExpandArrowView::CalculatePreferredSize() const { + return gfx::Size(kExpandArrowTileSize, kExpandArrowTileSize); +} + +void ExpandArrowView::Layout() { + gfx::Rect rect(GetContentsBounds()); + gfx::Point center = rect.CenterPoint(); + rect.SetRect(center.x() - kExpandArrowIconSize / 2, + center.y() - kExpandArrowIconSize / 2, kExpandArrowIconSize, + kExpandArrowIconSize); + icon_->SetBoundsRect(rect); +} + +std::unique_ptr<views::InkDrop> ExpandArrowView::CreateInkDrop() { + std::unique_ptr<views::InkDropImpl> ink_drop = + CustomButton::CreateDefaultInkDropImpl(); + ink_drop->SetShowHighlightOnHover(false); + ink_drop->SetShowHighlightOnFocus(true); + ink_drop->SetAutoHighlightMode( + views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE); + return std::move(ink_drop); +} + +std::unique_ptr<views::InkDropMask> ExpandArrowView::CreateInkDropMask() const { + return base::MakeUnique<views::CircleInkDropMask>( + size(), GetLocalBounds().CenterPoint(), kInkDropRadius); +} + +std::unique_ptr<views::InkDropRipple> ExpandArrowView::CreateInkDropRipple() + const { + gfx::Point center = GetLocalBounds().CenterPoint(); + gfx::Rect bounds(center.x() - kInkDropRadius, center.y() - kInkDropRadius, + 2 * kInkDropRadius, 2 * kInkDropRadius); + return base::MakeUnique<views::FloodFillInkDropRipple>( + size(), GetLocalBounds().InsetsFrom(bounds), + GetInkDropCenterBasedOnLastEvent(), kInkDropRippleColor, 1.0f); +} + +std::unique_ptr<views::InkDropHighlight> +ExpandArrowView::CreateInkDropHighlight() const { + return base::MakeUnique<views::InkDropHighlight>( + gfx::PointF(GetLocalBounds().CenterPoint()), + base::MakeUnique<views::CircleLayerDelegate>(kInkDropHighlightColor, + kInkDropRadius)); +} + +} // namespace app_list
diff --git a/ui/app_list/views/expand_arrow_view.h b/ui/app_list/views/expand_arrow_view.h new file mode 100644 index 0000000..b1064ad4 --- /dev/null +++ b/ui/app_list/views/expand_arrow_view.h
@@ -0,0 +1,56 @@ +// Copyright 2017 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_APP_LIST_VIEWS_EXPAND_ARROW_VIEW_H_ +#define UI_APP_LIST_VIEWS_EXPAND_ARROW_VIEW_H_ + +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/custom_button.h" + +namespace views { +class ImageView; +class InkDrop; +class InkDropMask; +class InkDropRipple; +class InkDropHighlight; +} // namespace views + +namespace app_list { + +class AppListView; +class ContentsView; + +// A tile item for the expand arrow on the start page. +class ExpandArrowView : public views::CustomButton, + public views::ButtonListener { + public: + ExpandArrowView(ContentsView* contents_view, AppListView* app_list_view); + ~ExpandArrowView() override; + + // Overridden from views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + // Overridden from views::View: + gfx::Size CalculatePreferredSize() const override; + void Layout() override; + + // Overridden from views::InkDropHost: + std::unique_ptr<views::InkDrop> CreateInkDrop() override; + std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; + std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; + std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() + const override; + + private: + ContentsView* const contents_view_; + AppListView* const app_list_view_; // Owned by the views hierarchy. + + views::ImageView* icon_; + + DISALLOW_COPY_AND_ASSIGN(ExpandArrowView); +}; + +} // namespace app_list + +#endif // UI_APP_LIST_VIEWS_EXPAND_ARROW_VIEW_H_
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index ad3b9b8..fb4e24f 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -23,6 +23,7 @@ #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/custom_launcher_page_view.h" +#include "ui/app_list/views/expand_arrow_view.h" #include "ui/app_list/views/indicator_chip_view.h" #include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/search_result_container_view.h" @@ -56,6 +57,7 @@ constexpr int kWebViewWidth = 700; constexpr int kWebViewHeight = 224; +constexpr int kExpandArrowTopPadding = 28; constexpr int kLauncherPageBackgroundWidth = 400; } // namespace @@ -125,6 +127,11 @@ // The view containing the start page tiles. AddChildView(suggestions_container_); + if (is_fullscreen_app_list_enabled_) { + expand_arrow_view_ = new ExpandArrowView( + app_list_main_view_->contents_view(), app_list_view); + AddChildView(expand_arrow_view_); + } AddChildView(custom_launcher_page_background_); suggestions_container_->SetResults(view_delegate_->GetModel()->results()); @@ -245,6 +252,18 @@ } suggestions_container_->SetBoundsRect(bounds); + if (expand_arrow_view_) { + gfx::Rect expand_arrow_rect(GetContentsBounds()); + int left_right_padding = + (bounds.width() - expand_arrow_view_->GetPreferredSize().width()) / 2; + + expand_arrow_rect.Inset(left_right_padding, 0, left_right_padding, 0); + expand_arrow_rect.set_y(bounds.bottom() + kExpandArrowTopPadding); + expand_arrow_rect.set_height( + expand_arrow_view_->GetPreferredSize().height()); + expand_arrow_view_->SetBoundsRect(expand_arrow_rect); + } + CustomLauncherPageView* custom_launcher_page_view = app_list_main_view_->contents_view()->custom_page_view(); if (!custom_launcher_page_view)
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h index 0c4aef3c..e1df339 100644 --- a/ui/app_list/views/start_page_view.h +++ b/ui/app_list/views/start_page_view.h
@@ -19,6 +19,7 @@ class AppListView; class AppListViewDelegate; class CustomLauncherPageBackgroundView; +class ExpandArrowView; class IndicatorChipView; class SearchResultTileItemView; class SuggestionsContainerView; @@ -79,6 +80,7 @@ IndicatorChipView* indicator_ = nullptr; // Owned by views hierarchy. SuggestionsContainerView* suggestions_container_; // Owned by views hierarchy. + ExpandArrowView* expand_arrow_view_ = nullptr; // Owned by views hierarchy. const bool is_fullscreen_app_list_enabled_;
diff --git a/ui/app_list/views/suggestions_container_view.cc b/ui/app_list/views/suggestions_container_view.cc index b3d2ca6..fef2d86 100644 --- a/ui/app_list/views/suggestions_container_view.cc +++ b/ui/app_list/views/suggestions_container_view.cc
@@ -20,7 +20,6 @@ constexpr int kTileSpacing = 7; constexpr int kNumTilesCols = 5; constexpr int kTilesHorizontalMarginLeft = 145; -constexpr int kCenterColumnOfStartPageAppGrid = 3; } // namespace @@ -148,21 +147,14 @@ search_result_tile_views_.emplace_back(tile_item); } - if (all_apps_button_) + if (all_apps_button_ && !is_fullscreen_app_list_enabled_) { all_apps_button_->UpdateIcon(); - if (is_fullscreen_app_list_enabled_) { - // Also add a special "all apps" button to the middle of the next row of the - // container. - tiles_layout_manager->StartRow(0, 0); - tiles_layout_manager->SkipColumns(kCenterColumnOfStartPageAppGrid); - } else { + // Also add a special "all apps" button to the end of the next row of the // container. if (i % kNumTilesCols == 0) tiles_layout_manager->StartRow(0, 0); - } - if (all_apps_button_) { tiles_layout_manager->AddView(all_apps_button_); AddChildView(all_apps_button_); }
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 3a2aa4fc..b48c8a3 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -872,11 +872,13 @@ delegate_->OnDelegatedFrameDamage(damage_rect_in_dip); } -void Layer::SetScrollable( - Layer* parent_clip_layer, - const base::Callback<void(const gfx::ScrollOffset&)>& on_scroll) { - cc_layer_->SetScrollClipLayerId(parent_clip_layer->cc_layer_->id()); - cc_layer_->set_did_scroll_callback(on_scroll); +void Layer::SetDidScrollCallback( + base::Callback<void(const gfx::ScrollOffset&)> callback) { + cc_layer_->set_did_scroll_callback(std::move(callback)); +} + +void Layer::SetScrollable(const gfx::Size& container_bounds) { + cc_layer_->SetScrollable(container_bounds); cc_layer_->SetUserScrollable(true, true); }
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index a439bbdf1..0c2a0e8 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -366,11 +366,15 @@ // Requets a copy of the layer's output as a texture or bitmap. void RequestCopyOfOutput(std::unique_ptr<cc::CopyOutputRequest> request); - // Makes this Layer scrollable, clipping to |parent_clip_layer|. |on_scroll| - // is invoked when scrolling performed by the cc::InputHandler is committed. - void SetScrollable( - Layer* parent_clip_layer, - const base::Callback<void(const gfx::ScrollOffset&)>& on_scroll); + // Invoked when scrolling performed by the cc::InputHandler is committed. This + // will only occur if the Layer has set scroll container bounds. + void SetDidScrollCallback( + base::Callback<void(const gfx::ScrollOffset&)> callback); + + // Marks this layer as scrollable inside the provided bounds. This size only + // affects scrolling so if clipping is desired, a separate clipping layer + // needs to be created. + void SetScrollable(const gfx::Size& container_bounds); // Gets and sets the current scroll offset of the layer. gfx::ScrollOffset CurrentScrollOffset() const;
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.h b/ui/ozone/platform/drm/host/drm_overlay_manager.h index 89f8b41..6e5a0ac 100644 --- a/ui/ozone/platform/drm/host/drm_overlay_manager.h +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.h
@@ -28,6 +28,8 @@ std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates( gfx::AcceleratedWidget w) override; + // Invoked on changes to the window (aka display) that require re-populating + // the cache from the DRM thread. void ResetCache(); // Communication-free implementations of actions performed in response to
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc index 539d23e..61f853fe 100644 --- a/ui/views/controls/scroll_view.cc +++ b/ui/views/controls/scroll_view.cc
@@ -237,9 +237,9 @@ a_view->SetBackground(CreateSolidBackground(GetBackgroundColor())); } a_view->SetPaintToLayer(); - a_view->layer()->SetScrollable( - contents_viewport_->layer(), + a_view->layer()->SetDidScrollCallback( base::Bind(&ScrollView::OnLayerScrolled, base::Unretained(this))); + a_view->layer()->SetScrollable(contents_viewport_->bounds().size()); } SetHeaderOrContents(contents_viewport_, a_view, &contents_); } @@ -474,6 +474,7 @@ gfx::Size container_size = contents_ ? contents_->size() : gfx::Size(); container_size.SetToMax(viewport_bounds.size()); contents_->SetBoundsRect(gfx::Rect(container_size)); + contents_->layer()->SetScrollable(viewport_bounds.size()); } header_viewport_->SetBounds(contents_x, contents_y,