diff --git a/DEPS b/DEPS index 19502f1a1..e8ebf9a 100644 --- a/DEPS +++ b/DEPS
@@ -82,11 +82,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '485dc868fff73073a40509186e4e33fbcfb0edd2', + 'skia_revision': '0cfd547b465a3611506dc4c4c0ba973ccb2e7f30', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '3e5f91d2931572b1baeff5f29a5e8bd45cb1c4ef', + 'v8_revision': 'c0df24c4d4d91ab742b647ae5df1938c01eb92f2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -94,7 +94,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'c3755fc56611eeeed712e5decc3a2f8670fac55a', + 'angle_revision': 'd2488aba58e91483b3b7afc72ce013ac7d0f912b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -106,7 +106,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': '4862705090a7469115ae7e3c80143b6f8b6b527a', + 'pdfium_revision': 'ace80b32dab5c6eaa32cc2f23c4540a5313879a1', # 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. @@ -142,7 +142,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': 'aaeb23e97cd16d8795cf73dd5d9ed8cd2cd1e00f', + 'catapult_revision': '5361d68fa6f7e637841187ffc915e233b403f881', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -224,7 +224,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '3ac6d0ff2ac59613b12f3278a2ca36f43692ad8c', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8c8aad6dc245a6682544952e9d47c44149bffb33', 'condition': 'checkout_ios', }, @@ -411,7 +411,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '46d83879919cc77d6dbcfb07b8aa8cd95af2f0ef', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0f0cab3eae122da42bc872926d720fc68193ecb7', 'condition': 'checkout_linux', }, @@ -436,7 +436,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1118a2193b8f7b77c0e2336fa9528645ae70e804', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '3f277fc747b51e6637c88f660e781a1c401a9913', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -655,7 +655,7 @@ Var('chromium_git') + '/external/github.com/google/libprotobuf-mutator.git' + '@' + Var('libprotobuf-mutator'), 'src/third_party/libsrtp': - Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + '1d45b8e599dc2db6ea3ae22dbc94a8c504652423', + Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + 'fc2345089a6b3c5aca9ecd2e1941871a78a13e9c', # Android Explicit Synchronization. 'src/third_party/libsync/src': { @@ -910,7 +910,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ecf6e8e622df1050b4e74695930ee99958c839b5', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b59810f75793af13e75f3bc7b0ca8e2101323d3b', 'condition': 'checkout_src_internal', }, @@ -1259,10 +1259,9 @@ ], }, { - # Ensure that while generating dependencies lists in .gyp files we don't - # accidentally reference any .pyc files whose corresponding .py files have - # already been deleted. - # We should actually try to avoid generating .pyc files, crbug.com/500078. + # Ensure that we don't accidentally reference any .pyc files whose + # corresponding .py files have since been deleted. + # We could actually try to avoid generating .pyc files, crbug.com/500078. 'name': 'remove_stale_pyc_files', 'pattern': '.', 'action': [ @@ -1927,7 +1926,7 @@ 'action': [ 'src/third_party/chromite/bin/cros', 'chrome-sdk', - '--nostart-goma', + '--nogoma', '--use-external-config', '--nogn-gen', '--download-vm',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index cbcaff69..50253eb 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1585,10 +1585,41 @@ black_list=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST), white_list=(file_inclusion_pattern,)) - return_construct_pattern = input_api.re.compile( - r'(=|\breturn|^)\s*std::unique_ptr<.*?(?<!])>\(([^)]|$)') + + # Pattern to capture a single "<...>" block of template arguments. It can + # handle linearly nested blocks, such as "<std::vector<std::set<T>>>", but + # cannot handle branching structures, such as "<pair<set<T>,set<U>>". The + # latter would likely require counting that < and > match, which is not + # expressible in regular languages. Should the need arise, one can introduce + # limited counting (matching up to a total number of nesting depth), which + # should cover all practical cases for already a low nesting limit. + template_arg_pattern = ( + r'<[^>]*' # Opening block of <. + r'>([^<]*>)?') # Closing block of >. + # Prefix expressing that whatever follows is not already inside a <...> + # block. + not_inside_template_arg_pattern = r'(^|[^<,\s]\s*)' null_construct_pattern = input_api.re.compile( - r'\b(?<!<)std::unique_ptr<[^>]*>([^(<]*>)?\(\)') + not_inside_template_arg_pattern + + r'\bstd::unique_ptr' + + template_arg_pattern + + r'\(\)') + + # Same as template_arg_pattern, but excluding type arrays, e.g., <T[]>. + template_arg_no_array_pattern = ( + r'<[^>]*[^]]' # Opening block of <. + r'>([^(<]*[^]]>)?') # Closing block of >. + # Prefix saying that what follows is the start of an expression. + start_of_expr_pattern = r'(=|\breturn|^)\s*' + # Suffix saying that what follows are call parentheses with a non-empty list + # of arguments. + nonempty_arg_list_pattern = r'\(([^)]|$)' + return_construct_pattern = input_api.re.compile( + start_of_expr_pattern + + r'std::unique_ptr' + + template_arg_no_array_pattern + + nonempty_arg_list_pattern) + problems_constructor = [] problems_nullptr = [] for f in input_api.AffectedSourceFiles(sources): @@ -1610,15 +1641,15 @@ '%s:%d\n %s' % (local_path, line_number, line.strip())) errors = [] - if problems_constructor: + if problems_nullptr: errors.append(output_api.PresubmitError( 'The following files use std::unique_ptr<T>(). Use nullptr instead.', - problems_constructor)) - if problems_nullptr: + problems_nullptr)) + if problems_constructor: errors.append(output_api.PresubmitError( 'The following files use explicit std::unique_ptr constructor.' 'Use std::make_unique<T>() instead.', - problems_nullptr)) + problems_constructor)) return errors
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 7d21f84..997625b7 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -1642,12 +1642,13 @@ def testTruePositivesNullptr(self): mock_input_api = MockInputApi() mock_input_api.files = [ - MockFile('dir/java/src/baz.cc', ['std::unique_ptr<T>()']), - MockFile('dir/java/src/baz-p.cc', ['std::unique_ptr<T<P>>()']), + MockFile('dir/baz.cc', ['std::unique_ptr<T>()']), + MockFile('dir/baz-p.cc', ['std::unique_ptr<T<P>>()']), ] results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi()) self.assertEqual(1, len(results)) + self.assertTrue('nullptr' in results[0].message) self.assertEqual(2, len(results[0].items)) self.assertTrue('baz.cc' in results[0].items[0]) self.assertTrue('baz-p.cc' in results[0].items[1]) @@ -1655,17 +1656,17 @@ def testTruePositivesConstructor(self): mock_input_api = MockInputApi() mock_input_api.files = [ - MockFile('dir/java/src/foo.cc', ['return std::unique_ptr<T>(foo);']), - MockFile('dir/java/src/bar.mm', ['bar = std::unique_ptr<T>(foo)']), - MockFile('dir/java/src/mult.cc', [ + MockFile('dir/foo.cc', ['return std::unique_ptr<T>(foo);']), + MockFile('dir/bar.mm', ['bar = std::unique_ptr<T>(foo)']), + MockFile('dir/mult.cc', [ 'return', ' std::unique_ptr<T>(barVeryVeryLongFooSoThatItWouldNotFitAbove);' ]), - MockFile('dir/java/src/mult2.cc', [ + MockFile('dir/mult2.cc', [ 'barVeryVeryLongLongBaaaaaarSoThatTheLineLimitIsAlmostReached =', ' std::unique_ptr<T>(foo);' ]), - MockFile('dir/java/src/mult3.cc', [ + MockFile('dir/mult3.cc', [ 'bar = std::unique_ptr<T>(', ' fooVeryVeryVeryLongStillGoingWellThisWillTakeAWhileFinallyThere);' ]), @@ -1673,6 +1674,7 @@ results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi()) self.assertEqual(1, len(results)) + self.assertTrue('std::make_unique' in results[0].message) self.assertEqual(5, len(results[0].items)) self.assertTrue('foo.cc' in results[0].items[0]) self.assertTrue('bar.mm' in results[0].items[1]) @@ -1683,12 +1685,17 @@ def testFalsePositives(self): mock_input_api = MockInputApi() mock_input_api.files = [ - MockFile('dir/java/src/foo.cc', ['return std::unique_ptr<T[]>(foo);']), - MockFile('dir/java/src/bar.mm', ['bar = std::unique_ptr<T[]>(foo)']), - MockFile('dir/java/src/file.cc', ['std::unique_ptr<T> p = Foo();']), - MockFile('dir/java/src/baz.cc', [ + MockFile('dir/foo.cc', ['return std::unique_ptr<T[]>(foo);']), + MockFile('dir/bar.mm', ['bar = std::unique_ptr<T[]>(foo)']), + MockFile('dir/file.cc', ['std::unique_ptr<T> p = Foo();']), + MockFile('dir/baz.cc', [ 'std::unique_ptr<T> result = std::make_unique<T>();' ]), + MockFile('dir/baz2.cc', [ + 'std::unique_ptr<T> result = std::make_unique<T>(' + ]), + MockFile('dir/nested.cc', ['set<std::unique_ptr<T>>();']), + MockFile('dir/nested2.cc', ['map<U, std::unique_ptr<T>>();']), ] results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
diff --git a/android_webview/java/src/org/chromium/android_webview/FindAddress.java b/android_webview/java/src/org/chromium/android_webview/FindAddress.java index 963a59c..781f1ec 100644 --- a/android_webview/java/src/org/chromium/android_webview/FindAddress.java +++ b/android_webview/java/src/org/chromium/android_webview/FindAddress.java
@@ -444,20 +444,21 @@ // At this point we've matched a state; try to match a zip code after it. Matcher zipMatcher = sWordRe.matcher(content); - if (zipMatcher.find(stateMatch.end()) - && isValidZipCode(zipMatcher.group(0), stateMatch)) { - return zipMatcher.end(); + if (zipMatcher.find(stateMatch.end())) { + if (isValidZipCode(zipMatcher.group(0), stateMatch)) { + return zipMatcher.end(); + } + } else { + // The content ends with a state but no zip + // code. This is a legal match according to the + // documentation. N.B. This is equivalent to the + // original c++ implementation, which only allowed + // the zip code to be optional at the end of the + // string, which presumably is a bug. We tried + // relaxing this to work in other places but it + // caused too many false positives. + nonZipMatch = stateMatch.end(); } - // The content ends with a state but no zip - // code. This is a legal match according to the - // documentation. N.B. This differs from the - // original c++ implementation, which only allowed - // the zip code to be optional at the end of the - // string, which presumably is a bug. Now we - // prefer to find a match with a zip code, but - // remember non-zip matches and return them if - // necessary. - nonZipMatch = stateMatch.end(); } } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/FindAddressTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/FindAddressTest.java index 5bf6c045..e3314b4 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/FindAddressTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/FindAddressTest.java
@@ -128,6 +128,15 @@ public void testFullAddressWithoutZipCode() { assertIsAddress("1600 Amphitheatre Parkway Mountain View, CA"); assertIsAddress("201 S. Division St. Suite 500 Ann Arbor, MI"); + + // Check that addresses without a zip code are only accepted at the end of the string. + // This isn't implied by the documentation but was the case in the old implementation + // and fixing this bug creates a lot of false positives while fixing relatively few + // false negatives. In these examples, "one point" is parsed as a street and "as" is a + // state abbreviation (this is taken from a false positive reported in a bug). + Assert.assertTrue(containsAddress("one point I was as")); + Assert.assertTrue(containsAddress("At one point I was as ignorant as")); + Assert.assertFalse(containsAddress("At one point I was as ignorant as them")); } @Test
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java index e4d04b46..262c9167 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
@@ -28,4 +28,52 @@ // WebViewClientCompat#shouldOverrideUrlLoading public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS"; + + // WebSettingsCompat.getOffscreenPreRaster + // WebSettingsCompat.setOffscreenPreRaster + public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER"; + + // WebSettingsCompat.getSafeBrowsingEnabled + // WebSettingsCompat.setSafeBrowsingEnabled + public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE"; + + // WebSettingsCompat.getDisabledActionModeMenuItems + // WebSettingsCompat.setDisabledActionModeMenuItems + public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS"; + + // WebViewCompat.startSafeBrowsing + public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING"; + + // WebViewCompat.setSafeBrowsingWhitelist + public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST"; + + // WebViewCompat.getSafeBrowsingPrivacyPolicyUrl + public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = + "SAFE_BROWSING_PRIVACY_POLICY_URL"; + + // ServiceWorkerControllerCompat.getInstance + // ServiceWorkerControllerCompat.getServiceWorkerWebSettings + // ServiceWorkerControllerCompat.setServiceWorkerClient + public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE"; + + // ServiceWorkerClientCompat.shouldInterceptRequest + public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = + "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST"; + + // ServiceWorkerWebSettingsCompat.getCacheMode + // ServiceWorkerWebSettingsCompat.setCacheMode + public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE"; + + // ServiceWorkerWebSettingsCompat.getAllowContentAccess + // ServiceWorkerWebSettingsCompat.setAllowContentAccess + public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS"; + + // ServiceWorkerWebSettingsCompat.getAllowFileAccess + // ServiceWorkerWebSettingsCompat.setAllowFileAccess + public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS"; + + // ServiceWorkerWebSettingsCompat.getBlockNetworkLoads + // ServiceWorkerWebSettingsCompat.setBlockNetworkLoads + public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = + "SERVICE_WORKER_BLOCK_NETWORK_LOADS"; }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java index e8db97b1..a3277a58 100644 --- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java +++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
@@ -29,8 +29,23 @@ // SupportLibWebkitToCompatConverterAdapter private final InvocationHandler mCompatConverterAdapter; private final WebViewChromiumAwInit mAwInit; + // clang-format off private final String[] mWebViewSupportedFeatures = - new String[] {Features.VISUAL_STATE_CALLBACK}; + new String[] { + Features.VISUAL_STATE_CALLBACK, + Features.OFF_SCREEN_PRERASTER, + Features.SAFE_BROWSING_ENABLE, + Features.DISABLED_ACTION_MODE_MENU_ITEMS, + Features.START_SAFE_BROWSING, + Features.SAFE_BROWSING_WHITELIST, + Features.SAFE_BROWSING_PRIVACY_POLICY_URL, + Features.SERVICE_WORKER_BASIC_USAGE, + Features.SERVICE_WORKER_CACHE_MODE, + Features.SERVICE_WORKER_CONTENT_ACCESS, + Features.SERVICE_WORKER_FILE_ACCESS, + Features.SERVICE_WORKER_BLOCK_NETWORK_LOADS + }; + // clang-format on // Initialization guarded by mAwInit.getLock() private InvocationHandler mStatics;
diff --git a/android_webview/tools/apk_merger.py b/android_webview/tools/apk_merger.py index 9893191..2545e81 100755 --- a/android_webview/tools/apk_merger.py +++ b/android_webview/tools/apk_merger.py
@@ -176,7 +176,7 @@ # TODO(ssid): unwind file should be included in monochrome apk once all the # official builds start including the file. https://crbug.com/819888. - ignores = ['META-INF', 'AndroidManifest.xml', 'unwind_cfi'] + ignores = ['META-INF', 'AndroidManifest.xml', 'unwind_cfi_32'] if args.ignore_classes_dex: ignores += ['classes.dex', 'classes2.dex'] if args.debug:
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index e60b6f1..e8d514f 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -792,6 +792,8 @@ "system/unified/top_shortcut_button.h", "system/unified/top_shortcuts_view.cc", "system/unified/top_shortcuts_view.h", + "system/unified/unified_message_center_view.cc", + "system/unified/unified_message_center_view.h", "system/unified/unified_slider_view.cc", "system/unified/unified_slider_view.h", "system/unified/unified_system_info_view.cc",
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 3ce0566..499e4cc 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -61,6 +61,7 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/optional.h" +#include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" @@ -1018,6 +1019,8 @@ } for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i) actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]); + for (size_t i = 0; i < kActionsAllowedAtPowerMenuLength; ++i) + actions_allowed_at_power_menu_.insert(kActionsAllowedAtPowerMenu[i]); for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i) actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]); for (size_t i = 0; i < kPreferredActionsLength; ++i) @@ -1574,6 +1577,10 @@ actions_allowed_at_lock_screen_.end()) { return RESTRICTION_PREVENT_PROCESSING; } + if (Shell::Get()->power_button_controller()->IsMenuOpened() && + !base::ContainsKey(actions_allowed_at_power_menu_, action)) { + return RESTRICTION_PREVENT_PROCESSING; + } if (Shell::Get()->shell_delegate()->IsRunningInForcedAppMode() && actions_allowed_in_app_mode_.find(action) == actions_allowed_in_app_mode_.end()) {
diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h index a481d7c..15fd8568 100644 --- a/ash/accelerators/accelerator_controller.h +++ b/ash/accelerators/accelerator_controller.h
@@ -205,6 +205,8 @@ std::set<int> actions_allowed_at_login_screen_; // Actions allowed when the screen is locked. std::set<int> actions_allowed_at_lock_screen_; + // Actions allowed when the power menu is opened. + std::set<int> actions_allowed_at_power_menu_; // Actions allowed when a modal window is up. std::set<int> actions_allowed_at_modal_window_; // Preferred actions. See accelerator_table.h for details.
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc index 85138ae2..8838299 100644 --- a/ash/accelerators/accelerator_table.cc +++ b/ash/accelerators/accelerator_table.cc
@@ -354,6 +354,13 @@ const size_t kActionsAllowedAtLockScreenLength = arraysize(kActionsAllowedAtLockScreen); +const AcceleratorAction kActionsAllowedAtPowerMenu[] = { + BRIGHTNESS_DOWN, BRIGHTNESS_UP, VOLUME_DOWN, VOLUME_UP, VOLUME_MUTE, +}; + +const size_t kActionsAllowedAtPowerMenuLength = + arraysize(kActionsAllowedAtPowerMenu); + const AcceleratorAction kActionsAllowedAtModalWindow[] = { BRIGHTNESS_DOWN, BRIGHTNESS_UP,
diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h index 4834f07..9ce4ca2e 100644 --- a/ash/accelerators/accelerator_table.h +++ b/ash/accelerators/accelerator_table.h
@@ -233,6 +233,10 @@ ASH_EXPORT extern const AcceleratorAction kActionsAllowedAtLockScreen[]; ASH_EXPORT extern const size_t kActionsAllowedAtLockScreenLength; +// Actions allowed while power menu is opened. +ASH_EXPORT extern const AcceleratorAction kActionsAllowedAtPowerMenu[]; +ASH_EXPORT extern const size_t kActionsAllowedAtPowerMenuLength; + // Actions allowed while a modal window is up. ASH_EXPORT extern const AcceleratorAction kActionsAllowedAtModalWindow[]; ASH_EXPORT extern const size_t kActionsAllowedAtModalWindowLength;
diff --git a/ash/accelerators/accelerator_table_unittest.cc b/ash/accelerators/accelerator_table_unittest.cc index 8876bc6..24c1b75 100644 --- a/ash/accelerators/accelerator_table_unittest.cc +++ b/ash/accelerators/accelerator_table_unittest.cc
@@ -90,6 +90,14 @@ } } +TEST(AcceleratorTableTest, CheckDuplicatedActionsAllowedAtPowerMenu) { + std::set<AcceleratorAction> actions; + for (size_t i = 0; i < kActionsAllowedAtPowerMenuLength; ++i) { + EXPECT_TRUE(actions.insert(kActionsAllowedAtPowerMenu[i]).second) + << "Duplicated action: " << kActionsAllowedAtPowerMenu[i]; + } +} + TEST(AcceleratorTableTest, CheckDuplicatedActionsAllowedAtModalWindow) { std::set<AcceleratorAction> actions; for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i) {
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc index 8acd924..7b0cdd9 100644 --- a/ash/accessibility/accessibility_controller.cc +++ b/ash/accessibility/accessibility_controller.cc
@@ -41,8 +41,94 @@ namespace ash { namespace { -PrefService* GetActivePrefService() { - return Shell::Get()->session_controller()->GetActivePrefService(); +// List of accessibility prefs that are to be copied (if changed by the user) on +// signin screen profile to a newly created user profile or a guest session. +constexpr const char* const kCopiedOnSigninAccessibilityPrefs[]{ + prefs::kAccessibilityAutoclickDelayMs, + prefs::kAccessibilityAutoclickEnabled, + prefs::kAccessibilityCaretHighlightEnabled, + prefs::kAccessibilityCursorHighlightEnabled, + prefs::kAccessibilityFocusHighlightEnabled, + prefs::kAccessibilityHighContrastEnabled, + prefs::kAccessibilityLargeCursorEnabled, + prefs::kAccessibilityMonoAudioEnabled, + prefs::kAccessibilityScreenMagnifierEnabled, + prefs::kAccessibilityScreenMagnifierScale, + prefs::kAccessibilitySelectToSpeakEnabled, + prefs::kAccessibilitySpokenFeedbackEnabled, + prefs::kAccessibilityStickyKeysEnabled, + prefs::kAccessibilitySwitchAccessEnabled, + prefs::kAccessibilityVirtualKeyboardEnabled, + prefs::kDockedMagnifierEnabled, + prefs::kDockedMagnifierScale, +}; + +// Returns true if |pref_service| is the one used for the signin screen. +bool IsSigninPrefService(PrefService* pref_service) { + const PrefService* signin_pref_service = + Shell::Get()->session_controller()->GetSigninScreenPrefService(); + DCHECK(signin_pref_service); + return pref_service == signin_pref_service; +} + +// Returns true if the current session is the guest session. +bool IsCurrentSessionGuest() { + const base::Optional<user_manager::UserType> user_type = + Shell::Get()->session_controller()->GetUserType(); + return user_type && *user_type == user_manager::USER_TYPE_GUEST; +} + +bool IsUserFirstLogin() { + return Shell::Get()->session_controller()->IsUserFirstLogin(); +} + +// The copying of any modified accessibility prefs on the signin prefs happens +// when the |previous_pref_service| is of the signin profile, and the +// |current_pref_service| is of a newly created profile first logged in, or if +// the current session is the guest session. +bool ShouldCopySigninPrefs(PrefService* previous_pref_service, + PrefService* current_pref_service) { + DCHECK(previous_pref_service); + if (IsUserFirstLogin() && IsSigninPrefService(previous_pref_service) && + !IsSigninPrefService(current_pref_service)) { + // If the user set a pref value on the login screen and is now starting a + // session with a new profile, copy the pref value to the profile. + return true; + } + + if (IsCurrentSessionGuest()) { + // Guest sessions don't have their own prefs, so always copy. + return true; + } + + return false; +} + +// On a user's first login into a device, any a11y features enabled/disabled +// by the user on the login screen are enabled/disabled in the user's profile. +// This function copies settings from the signin prefs into the user's prefs +// when it detects a login with a newly created profile. +void CopySigninPrefsIfNeeded(PrefService* previous_pref_service, + PrefService* current_pref_service) { + DCHECK(current_pref_service); + if (!ShouldCopySigninPrefs(previous_pref_service, current_pref_service)) + return; + + PrefService* signin_prefs = + Shell::Get()->session_controller()->GetSigninScreenPrefService(); + DCHECK(signin_prefs); + for (const auto* pref_path : kCopiedOnSigninAccessibilityPrefs) { + const PrefService::Preference* pref = + signin_prefs->FindPreference(pref_path); + + // Ignore if the pref has not been set by the user. + if (!pref || !pref->IsUserControlled()) + continue; + + // Copy the pref value from the signin profile. + const base::Value* value_on_login = pref->GetValue(); + current_pref_service->Set(pref_path, *value_on_login); + } } } // namespace @@ -129,11 +215,11 @@ } void AccessibilityController::SetAutoclickEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityAutoclickEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityAutoclickEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsAutoclickEnabled() const { @@ -141,11 +227,11 @@ } void AccessibilityController::SetCaretHighlightEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityCaretHighlightEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityCaretHighlightEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsCaretHighlightEnabled() const { @@ -153,11 +239,11 @@ } void AccessibilityController::SetCursorHighlightEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityCursorHighlightEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityCursorHighlightEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsCursorHighlightEnabled() const { @@ -165,11 +251,11 @@ } void AccessibilityController::SetFocusHighlightEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityFocusHighlightEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityFocusHighlightEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsFocusHighlightEnabled() const { @@ -177,11 +263,11 @@ } void AccessibilityController::SetHighContrastEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityHighContrastEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsHighContrastEnabled() const { @@ -189,11 +275,11 @@ } void AccessibilityController::SetLargeCursorEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsLargeCursorEnabled() const { @@ -201,11 +287,11 @@ } void AccessibilityController::SetMonoAudioEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityMonoAudioEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityMonoAudioEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsMonoAudioEnabled() const { @@ -215,12 +301,12 @@ void AccessibilityController::SetSpokenFeedbackEnabled( bool enabled, AccessibilityNotificationVisibility notify) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; spoken_feedback_notification_ = notify; - prefs->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsSpokenFeedbackEnabled() const { @@ -228,11 +314,11 @@ } void AccessibilityController::SetSelectToSpeakEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilitySelectToSpeakEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilitySelectToSpeakEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsSelectToSpeakEnabled() const { @@ -240,11 +326,11 @@ } void AccessibilityController::SetStickyKeysEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityStickyKeysEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityStickyKeysEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsStickyKeysEnabled() const { @@ -252,11 +338,11 @@ } void AccessibilityController::SetVirtualKeyboardEnabled(bool enabled) { - PrefService* prefs = GetActivePrefService(); - if (!prefs) + if (!active_user_prefs_) return; - prefs->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled, enabled); - prefs->CommitPendingWrite(); + active_user_prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled, + enabled); + active_user_prefs_->CommitPendingWrite(); } bool AccessibilityController::IsVirtualKeyboardEnabled() const { @@ -372,6 +458,10 @@ void AccessibilityController::OnActiveUserPrefServiceChanged( PrefService* prefs) { + // This is guaranteed to be received after + // OnSigninScreenPrefServiceInitialized() so only copy the signin prefs if + // needed here. + CopySigninPrefsIfNeeded(active_user_prefs_, prefs); ObservePrefs(prefs); } @@ -380,6 +470,10 @@ } void AccessibilityController::ObservePrefs(PrefService* prefs) { + DCHECK(prefs); + + active_user_prefs_ = prefs; + // Watch for pref updates from webui settings and policy. pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); pref_change_registrar_->Init(prefs); @@ -458,8 +552,9 @@ } void AccessibilityController::UpdateAutoclickFromPref() { - PrefService* prefs = GetActivePrefService(); - const bool enabled = prefs->GetBoolean(prefs::kAccessibilityAutoclickEnabled); + DCHECK(active_user_prefs_); + const bool enabled = + active_user_prefs_->GetBoolean(prefs::kAccessibilityAutoclickEnabled); if (autoclick_enabled_ == enabled) return; @@ -481,9 +576,9 @@ } void AccessibilityController::UpdateAutoclickDelayFromPref() { - PrefService* prefs = GetActivePrefService(); - base::TimeDelta autoclick_delay = base::TimeDelta::FromMilliseconds( - int64_t{prefs->GetInteger(prefs::kAccessibilityAutoclickDelayMs)}); + DCHECK(active_user_prefs_); + base::TimeDelta autoclick_delay = base::TimeDelta::FromMilliseconds(int64_t{ + active_user_prefs_->GetInteger(prefs::kAccessibilityAutoclickDelayMs)}); if (autoclick_delay_ == autoclick_delay) return; @@ -502,9 +597,9 @@ } void AccessibilityController::UpdateCaretHighlightFromPref() { - PrefService* prefs = GetActivePrefService(); - const bool enabled = - prefs->GetBoolean(prefs::kAccessibilityCaretHighlightEnabled); + DCHECK(active_user_prefs_); + const bool enabled = active_user_prefs_->GetBoolean( + prefs::kAccessibilityCaretHighlightEnabled); if (caret_highlight_enabled_ == enabled) return; @@ -516,9 +611,9 @@ } void AccessibilityController::UpdateCursorHighlightFromPref() { - PrefService* prefs = GetActivePrefService(); - const bool enabled = - prefs->GetBoolean(prefs::kAccessibilityCursorHighlightEnabled); + DCHECK(active_user_prefs_); + const bool enabled = active_user_prefs_->GetBoolean( + prefs::kAccessibilityCursorHighlightEnabled); if (cursor_highlight_enabled_ == enabled) return; @@ -530,8 +625,9 @@ } void AccessibilityController::UpdateFocusHighlightFromPref() { - PrefService* prefs = GetActivePrefService(); - bool enabled = prefs->GetBoolean(prefs::kAccessibilityFocusHighlightEnabled); + DCHECK(active_user_prefs_); + bool enabled = active_user_prefs_->GetBoolean( + prefs::kAccessibilityFocusHighlightEnabled); // Focus highlighting can't be on when spoken feedback is on, because // ChromeVox does its own focus highlighting. @@ -548,9 +644,9 @@ } void AccessibilityController::UpdateHighContrastFromPref() { - PrefService* prefs = GetActivePrefService(); + DCHECK(active_user_prefs_); const bool enabled = - prefs->GetBoolean(prefs::kAccessibilityHighContrastEnabled); + active_user_prefs_->GetBoolean(prefs::kAccessibilityHighContrastEnabled); if (high_contrast_enabled_ == enabled) return; @@ -575,13 +671,14 @@ } void AccessibilityController::UpdateLargeCursorFromPref() { - PrefService* prefs = GetActivePrefService(); + DCHECK(active_user_prefs_); const bool enabled = - prefs->GetBoolean(prefs::kAccessibilityLargeCursorEnabled); + active_user_prefs_->GetBoolean(prefs::kAccessibilityLargeCursorEnabled); // Reset large cursor size to the default size when large cursor is disabled. if (!enabled) - prefs->ClearPref(prefs::kAccessibilityLargeCursorDipSize); - const int size = prefs->GetInteger(prefs::kAccessibilityLargeCursorDipSize); + active_user_prefs_->ClearPref(prefs::kAccessibilityLargeCursorDipSize); + const int size = + active_user_prefs_->GetInteger(prefs::kAccessibilityLargeCursorDipSize); if (large_cursor_enabled_ == enabled && large_cursor_size_in_dip_ == size) return; @@ -598,8 +695,9 @@ } void AccessibilityController::UpdateMonoAudioFromPref() { - PrefService* prefs = GetActivePrefService(); - const bool enabled = prefs->GetBoolean(prefs::kAccessibilityMonoAudioEnabled); + DCHECK(active_user_prefs_); + const bool enabled = + active_user_prefs_->GetBoolean(prefs::kAccessibilityMonoAudioEnabled); if (mono_audio_enabled_ == enabled) return; @@ -611,9 +709,9 @@ } void AccessibilityController::UpdateSpokenFeedbackFromPref() { - PrefService* prefs = GetActivePrefService(); - const bool enabled = - prefs->GetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled); + DCHECK(active_user_prefs_); + const bool enabled = active_user_prefs_->GetBoolean( + prefs::kAccessibilitySpokenFeedbackEnabled); if (spoken_feedback_enabled_ == enabled) return; @@ -651,9 +749,9 @@ } void AccessibilityController::UpdateSelectToSpeakFromPref() { - PrefService* prefs = GetActivePrefService(); + DCHECK(active_user_prefs_); const bool enabled = - prefs->GetBoolean(prefs::kAccessibilitySelectToSpeakEnabled); + active_user_prefs_->GetBoolean(prefs::kAccessibilitySelectToSpeakEnabled); if (select_to_speak_enabled_ == enabled) return; @@ -664,9 +762,9 @@ } void AccessibilityController::UpdateStickyKeysFromPref() { - PrefService* prefs = GetActivePrefService(); + DCHECK(active_user_prefs_); const bool enabled = - prefs->GetBoolean(prefs::kAccessibilityStickyKeysEnabled); + active_user_prefs_->GetBoolean(prefs::kAccessibilityStickyKeysEnabled); if (sticky_keys_enabled_ == enabled) return; @@ -679,9 +777,9 @@ } void AccessibilityController::UpdateVirtualKeyboardFromPref() { - PrefService* prefs = GetActivePrefService(); - const bool enabled = - prefs->GetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled); + DCHECK(active_user_prefs_); + const bool enabled = active_user_prefs_->GetBoolean( + prefs::kAccessibilityVirtualKeyboardEnabled); if (virtual_keyboard_enabled_ == enabled) return;
diff --git a/ash/accessibility/accessibility_controller.h b/ash/accessibility/accessibility_controller.h index d9797ecd..984512e 100644 --- a/ash/accessibility/accessibility_controller.h +++ b/ash/accessibility/accessibility_controller.h
@@ -170,6 +170,11 @@ void NotifyShowAccessibilityNotification(); service_manager::Connector* connector_ = nullptr; + + // The pref service of the currently active user or the signin profile before + // user logs in. Can be null in ash_unittests. + PrefService* active_user_prefs_ = nullptr; + std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; // Binding for mojom::AccessibilityController interface.
diff --git a/ash/accessibility/accessibility_controller_unittest.cc b/ash/accessibility/accessibility_controller_unittest.cc index 40f1a4b..8c5e9a135 100644 --- a/ash/accessibility/accessibility_controller_unittest.cc +++ b/ash/accessibility/accessibility_controller_unittest.cc
@@ -7,12 +7,15 @@ #include "ash/accessibility/accessibility_observer.h" #include "ash/accessibility/test_accessibility_controller_client.h" #include "ash/ash_constants.h" +#include "ash/magnifier/docked_magnifier_controller.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/config.h" #include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/sticky_keys/sticky_keys_controller.h" #include "ash/test/ash_test_base.h" +#include "base/test/scoped_feature_list.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_power_manager_client.h" #include "components/prefs/pref_service.h" @@ -355,34 +358,151 @@ EXPECT_FALSE(power_manager_client_->backlights_forced_off()); } -using AccessibilityControllerSigninTest = NoSessionAshTestBase; +namespace { -TEST_F(AccessibilityControllerSigninTest, SigninScreenPrefs) { +enum class TestUserLoginType { + kNewUser, + kGuest, + kExistingUser, +}; + +class AccessibilityControllerSigninTest + : public NoSessionAshTestBase, + public testing::WithParamInterface<TestUserLoginType> { + public: + AccessibilityControllerSigninTest() = default; + ~AccessibilityControllerSigninTest() = default; + + // AshTestBase: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(features::kDockedMagnifier); + NoSessionAshTestBase::SetUp(); + } + + void SimulateLogin() { + constexpr char kUserEmail[] = "user1@test.com"; + switch (GetParam()) { + case TestUserLoginType::kNewUser: + SimulateNewUserFirstLogin(kUserEmail); + break; + + case TestUserLoginType::kGuest: + SimulateGuestLogin(); + break; + + case TestUserLoginType::kExistingUser: + SimulateUserLogin(kUserEmail); + break; + } + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(AccessibilityControllerSigninTest); +}; + +} // namespace + +INSTANTIATE_TEST_CASE_P(, + AccessibilityControllerSigninTest, + ::testing::Values(TestUserLoginType::kNewUser, + TestUserLoginType::kGuest, + TestUserLoginType::kExistingUser)); + +TEST_P(AccessibilityControllerSigninTest, EnableOnLoginScreenAndLogin) { + constexpr float kMagnifierScale = 4.3f; + AccessibilityController* accessibility = Shell::Get()->accessibility_controller(); + DockedMagnifierController* docked_magnifier = + Shell::Get()->docked_magnifier_controller(); SessionController* session = Shell::Get()->session_controller(); EXPECT_EQ(session_manager::SessionState::LOGIN_PRIMARY, session->GetSessionState()); EXPECT_FALSE(accessibility->IsLargeCursorEnabled()); + EXPECT_FALSE(accessibility->IsSpokenFeedbackEnabled()); + EXPECT_FALSE(accessibility->IsHighContrastEnabled()); + EXPECT_FALSE(accessibility->IsAutoclickEnabled()); + EXPECT_FALSE(accessibility->IsMonoAudioEnabled()); + EXPECT_FALSE(docked_magnifier->GetEnabled()); + using prefs::kAccessibilityLargeCursorEnabled; + using prefs::kAccessibilitySpokenFeedbackEnabled; + using prefs::kAccessibilityHighContrastEnabled; + using prefs::kAccessibilityAutoclickEnabled; + using prefs::kAccessibilityMonoAudioEnabled; + using prefs::kDockedMagnifierEnabled; + PrefService* signin_prefs = session->GetSigninScreenPrefService(); + EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); + EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled)); + EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityHighContrastEnabled)); + EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityAutoclickEnabled)); + EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityMonoAudioEnabled)); + EXPECT_FALSE(signin_prefs->GetBoolean(kDockedMagnifierEnabled)); // Verify that toggling prefs at the signin screen changes the signin setting. - PrefService* signin_prefs = session->GetSigninScreenPrefService(); - using prefs::kAccessibilityLargeCursorEnabled; - EXPECT_FALSE(signin_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); accessibility->SetLargeCursorEnabled(true); + accessibility->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_NONE); + accessibility->SetHighContrastEnabled(true); + accessibility->SetAutoclickEnabled(true); + accessibility->SetMonoAudioEnabled(true); + docked_magnifier->SetEnabled(true); + docked_magnifier->SetScale(kMagnifierScale); + // TODO(afakhry): Test the Fullscreen magnifier prefs once the + // ash::MagnificationController handles all the prefs work itself inside ash + // without needing magnification manager in Chrome. EXPECT_TRUE(accessibility->IsLargeCursorEnabled()); + EXPECT_TRUE(accessibility->IsSpokenFeedbackEnabled()); + EXPECT_TRUE(accessibility->IsHighContrastEnabled()); + EXPECT_TRUE(accessibility->IsAutoclickEnabled()); + EXPECT_TRUE(accessibility->IsMonoAudioEnabled()); + EXPECT_TRUE(docked_magnifier->GetEnabled()); + EXPECT_FLOAT_EQ(kMagnifierScale, docked_magnifier->GetScale()); EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); + EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled)); + EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityHighContrastEnabled)); + EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityAutoclickEnabled)); + EXPECT_TRUE(signin_prefs->GetBoolean(kAccessibilityMonoAudioEnabled)); + EXPECT_TRUE(signin_prefs->GetBoolean(kDockedMagnifierEnabled)); - // Verify that toggling prefs after signin changes the user setting. - SimulateUserLogin("user1@test.com"); + SimulateLogin(); + + // Verify that prefs values are copied if they should. PrefService* user_prefs = session->GetLastActiveUserPrefService(); EXPECT_NE(signin_prefs, user_prefs); - EXPECT_FALSE(accessibility->IsLargeCursorEnabled()); - EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); - accessibility->SetLargeCursorEnabled(true); - EXPECT_TRUE(accessibility->IsLargeCursorEnabled()); - EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); + const bool should_signin_prefs_be_copied = + GetParam() == TestUserLoginType::kNewUser || + GetParam() == TestUserLoginType::kGuest; + if (should_signin_prefs_be_copied) { + EXPECT_TRUE(accessibility->IsLargeCursorEnabled()); + EXPECT_TRUE(accessibility->IsSpokenFeedbackEnabled()); + EXPECT_TRUE(accessibility->IsHighContrastEnabled()); + EXPECT_TRUE(accessibility->IsAutoclickEnabled()); + EXPECT_TRUE(accessibility->IsMonoAudioEnabled()); + EXPECT_TRUE(docked_magnifier->GetEnabled()); + EXPECT_FLOAT_EQ(kMagnifierScale, docked_magnifier->GetScale()); + EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); + EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled)); + EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityHighContrastEnabled)); + EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityAutoclickEnabled)); + EXPECT_TRUE(user_prefs->GetBoolean(kAccessibilityMonoAudioEnabled)); + EXPECT_TRUE(user_prefs->GetBoolean(kDockedMagnifierEnabled)); + } else { + EXPECT_FALSE(accessibility->IsLargeCursorEnabled()); + EXPECT_FALSE(accessibility->IsSpokenFeedbackEnabled()); + EXPECT_FALSE(accessibility->IsHighContrastEnabled()); + EXPECT_FALSE(accessibility->IsAutoclickEnabled()); + EXPECT_FALSE(accessibility->IsMonoAudioEnabled()); + EXPECT_FALSE(docked_magnifier->GetEnabled()); + EXPECT_NE(kMagnifierScale, docked_magnifier->GetScale()); + EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityLargeCursorEnabled)); + EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilitySpokenFeedbackEnabled)); + EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityHighContrastEnabled)); + EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityAutoclickEnabled)); + EXPECT_FALSE(user_prefs->GetBoolean(kAccessibilityMonoAudioEnabled)); + EXPECT_FALSE(user_prefs->GetBoolean(kDockedMagnifierEnabled)); + } } } // namespace ash
diff --git a/ash/components/resources/ash_components_resources.grd b/ash/components/resources/ash_components_resources.grd index cda8305f..02db092 100644 --- a/ash/components/resources/ash_components_resources.grd +++ b/ash/components/resources/ash_components_resources.grd
@@ -12,6 +12,7 @@ <release seq="1"> <structures fallback_to_low_resolution="true"> <!-- Keyboard Shortcut Viewer icons. --> + <!-- TODO(wutao): This structures cannot be empty. Delete this resource when possible. --> <structure type="chrome_scaled_image" name="IDR_KEYBOARD_SHORTCUT_VIEWER_APP_ICON" file="shortcut_viewer/ksv_app_icon.png" /> </structures>
diff --git a/ash/components/shortcut_viewer/BUILD.gn b/ash/components/shortcut_viewer/BUILD.gn index c51c79ad..6d7136e 100644 --- a/ash/components/shortcut_viewer/BUILD.gn +++ b/ash/components/shortcut_viewer/BUILD.gn
@@ -30,6 +30,7 @@ "//ash/components/shortcut_viewer/vector_icons", "//ash/components/strings", "//ash/public/cpp", + "//ash/resources", "//cc/paint", "//ui/accessibility", "//ui/aura",
diff --git a/ash/components/shortcut_viewer/DEPS b/ash/components/shortcut_viewer/DEPS index bb6465e7..3df4fbf0 100644 --- a/ash/components/shortcut_viewer/DEPS +++ b/ash/components/shortcut_viewer/DEPS
@@ -4,6 +4,7 @@ "+ash/components/resources", "+ash/components/shortcut_viewer", "+ash/components/strings", + "+ash/resources", "+base", "+cc/paint", "+testing/gtest",
diff --git a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc index a0a0bae..8e84794 100644 --- a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc +++ b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -13,8 +13,10 @@ #include "ash/components/shortcut_viewer/views/keyboard_shortcut_item_view.h" #include "ash/components/shortcut_viewer/views/ksv_search_box_view.h" #include "ash/components/strings/grit/ash_components_strings.h" +#include "ash/public/cpp/app_list/internal_app_id_constants.h" #include "ash/public/cpp/shelf_item.h" #include "ash/public/cpp/window_properties.h" +#include "ash/resources/grit/ash_resources.h" #include "base/bind.h" #include "base/i18n/string_search.h" #include "base/metrics/user_metrics.h" @@ -117,12 +119,7 @@ window->SetProperty(ash::kFrameInactiveColorKey, SK_ColorWHITE); // Set shelf icon. - // An app id for keyboard shortcut viewer window, also used to identify the - // shelf item. Generated as - // crx_file::id_util::GenerateId("org.chromium.keyboardshortcutviewer") - static constexpr char kKeyboardShortcutViewerId[] = - "dieikdblbimmfmfinbibdlalidbnbchd"; - const ash::ShelfID shelf_id(kKeyboardShortcutViewerId); + const ash::ShelfID shelf_id(app_list::kInternalAppIdKeyboardShortcutViewer); window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize())); window->SetProperty<int>(ash::kShelfItemTypeKey, ash::TYPE_DIALOG); @@ -134,7 +131,7 @@ window->SetTitle(l10n_util::GetStringUTF16(IDS_KSV_TITLE)); gfx::ImageSkia* icon = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_KEYBOARD_SHORTCUT_VIEWER_APP_ICON); + IDR_KEYBOARD_SHORTCUT_VIEWER_LOGO_192); // The new gfx::ImageSkia instance is owned by the window itself. window->SetProperty(aura::client::kWindowIconKey, new gfx::ImageSkia(*icon));
diff --git a/ash/components/strings/ash_components_strings_en-GB.xtb b/ash/components/strings/ash_components_strings_en-GB.xtb index fa843f9..f34ef33 100644 --- a/ash/components/strings/ash_components_strings_en-GB.xtb +++ b/ash/components/strings/ash_components_strings_en-GB.xtb
@@ -6,6 +6,7 @@ <translation id="1134347825771908369">Mute volume</translation> <translation id="1195667586424773550">Drag the link to the tab's address bar</translation> <translation id="1204450209689312104">Open a new window in incognito mode</translation> +<translation id="1290373024480130896"><ph name="MODIFIER1" /><ph name="SEPARATOR1" /><ph name="MODIFIER2" /><ph name="SEPARATOR2" /><ph name="MODIFIER3" /><ph name="SEPARATOR3" /><ph name="KEY" /></translation> <translation id="1293699935367580298">Esc</translation> <translation id="1299858300159559687">Print your current page</translation> <translation id="1383876407941801731">Search</translation> @@ -22,7 +23,10 @@ <translation id="1920446759863417809"><ph name="SHIFT1" /><ph name="SEPARATOR1" /><ph name="ALT" /><ph name="SEPARATOR2" /><ph name="L" />, then <ph name="SHIFT2" /><ph name="SEPARATOR3" /><ph name="TAB" /> or <ph name="LEFT" /></translation> <translation id="1996162290124031907">Go to next tab</translation> <translation id="2010818616644390445">Go to the last tab in the window</translation> +<translation id="2040706009561734834">Open/close the launcher</translation> +<translation id="2045117674524495717">Keyboard Shortcut Helper</translation> <translation id="2088054208777350526">Search for keyboard shortcuts</translation> +<translation id="2125211348069077981"><ph name="ALT" /><ph name="SEPARATOR" /><ph name="E" /> or <ph name="F" /></translation> <translation id="2145908266289632567">Text Editing</translation> <translation id="215292019801409139"><ph name="SEARCH" /><ph name="SEPARATOR" /> 1 through =</translation> <translation id="2181097965834437145">Show or hide the bookmarks bar</translation> @@ -35,9 +39,11 @@ <translation id="2515586267016047495">Alt</translation> <translation id="2530339807289914946">Scroll down the web page</translation> <translation id="2568632782096378307">Reset screen resolution to default</translation> +<translation id="2596078834055697711">Take window screenshot</translation> <translation id="2685170433750953446"><ph name="SHIFT" /><ph name="SEPARATOR1" /><ph name="ALT" /><ph name="SEPARATOR2" /><ph name="L" />, then <ph name="TAB" /> or <ph name="RIGHT" /></translation> <translation id="2699509451653686398">Save your current web page as a bookmark</translation> <translation id="2750942583782703988">Reload your current page</translation> +<translation id="2764005613199379871">Place focus in search address bar</translation> <translation id="2789868185375229787">Zoom out on the page</translation> <translation id="2804480015716812239">Press <ph name="ALT" /> and click a link</translation> <translation id="2830827904629746450">Dock a window on the right</translation> @@ -49,6 +55,7 @@ <translation id="3105917916468784889">Take screenshot</translation> <translation id="3126026824346185272">Ctrl</translation> <translation id="3140353188828248647">Focus address bar</translation> +<translation id="3256109297135787951">Remove the highlight from an item on your shelf</translation> <translation id="3288816184963444640">Close the current window</translation> <translation id="3407560819924487926">Bring up task manager</translation> <translation id="3422679037938588196">Go to the previous match for your search</translation> @@ -59,9 +66,11 @@ <translation id="3649256019230929621">Minimise window</translation> <translation id="3655154169297074232">Tabs & Windows</translation> <translation id="3668361878347172356">Redo your last action</translation> +<translation id="3710784500737332588">Open Help Centre</translation> <translation id="3720939646656082033">Open the link in a new tab and switch to the new tab</translation> <translation id="3725795051337497754">Close the current tab</translation> <translation id="3751033133896282964">Undo your last action</translation> +<translation id="3792178297143798024">Open the highlighted item on your shelf</translation> <translation id="379295446891231126"><ph name="CTRL" /><ph name="SEPARATOR" /> 1 to 8</translation> <translation id="3837047332182291558">Make keyboard brighter (for backlit keyboards only)</translation> <translation id="3976863468609830880">Click the last icon on your shelf</translation> @@ -76,11 +85,15 @@ <translation id="4148761611071495477"><ph name="CTRL" /><ph name="SEPARATOR" /><ph name="G" /> or <ph name="ENTER" /></translation> <translation id="4240486403425279990">Overview mode</translation> <translation id="4472417192667361414">System & Display Settings</translation> +<translation id="4484292984055789039">Switch to the previous language input method</translation> <translation id="4556221320735744018">See Keyboard Shortcut Helper</translation> <translation id="4628718545549558538">Open the status area (where your account picture appears)</translation> <translation id="4642092649622328492">Take partial screenshot</translation> +<translation id="4698850295812410683">Show stylus tools</translation> <translation id="4801989101741319327">Move to the end of the next word</translation> <translation id="4916163929714267752">Open the link in a new window</translation> +<translation id="5002047168347153398">Focus inactive pop-up for accessibility</translation> +<translation id="5030659775136592441">Show bookmark manager</translation> <translation id="5034421018520995080">Go to top of page</translation> <translation id="5042305953558921026">Overview mode key</translation> <translation id="5104462712192763270">Save your current page</translation> @@ -97,12 +110,14 @@ <translation id="5757111373163288447">Open the link in the tab</translation> <translation id="5757474750054631686">Dim keyboard (for backlit keyboards only)</translation> <translation id="587531134027443617">Delete the previous word</translation> +<translation id="5899919361772749550">Show or hide the Developer Tools console</translation> <translation id="5921745308587794300">Rotate window</translation> <translation id="5975083100439434680">Zoom out</translation> <translation id="6022924867608035986">Clear search box text</translation> <translation id="6045998054441862242">Turn on high contrast mode</translation> <translation id="6052614013050385269">Right-click a link</translation> <translation id="6129953537138746214">Space</translation> +<translation id="613146727819833328">Move window to centre</translation> <translation id="6143669479988153888">Zoom in on the page</translation> <translation id="6185696379715117369">Page up</translation> <translation id="6228457605945141550">Turn brightness down</translation> @@ -115,30 +130,42 @@ <translation id="6435207348963613811">Highlight the previous item on your shelf</translation> <translation id="6445033640292336367">Return the tab to its original position</translation> <translation id="649811797655257835">Select the file, then press <ph name="SPACE" /></translation> +<translation id="6556040137485212400">Open the window that has not been used for the longest time</translation> <translation id="666343722268997814">Open right-click menu for highlighted item</translation> <translation id="6671538777808758331">Go to the next match for your search</translation> +<translation id="6681606577947445973"><ph name="REFRESH" /> or <ph name="CTRL" /><ph name="SEPARATOR" /><ph name="R" /></translation> <translation id="6690765639083431875">Dock a window on the left</translation> <translation id="6692847073476874842">Preview a file in the Files app</translation> <translation id="671928215901716392">Lock screen</translation> <translation id="6727005317916125192">Previous pane</translation> <translation id="6740781404993465795">Select the next word or letter</translation> <translation id="6760706756348334449">Volume down</translation> +<translation id="6941333068993625698">Submit feedback</translation> <translation id="6981982820502123353">Accessibility</translation> <translation id="7020813747703216897">No matching results found</translation> <translation id="7025325401470358758">Next pane</translation> +<translation id="7077383985738259936">Focus on or Highlight the bookmarks bar (if shown)</translation> <translation id="7237562915163138771">Type a web address in the address bar, then press <ph name="ALT" /><ph name="SEPARATOR" /><ph name="ENTER" /></translation> +<translation id="7254764037241667478">Put device in sleep mode (suspend)</translation> <translation id="7379254767514753910"><ph name="ALT" /> or <ph name="SEARCH" /><ph name="SEPARATOR" /><ph name="UP" /></translation> +<translation id="743754632698445141">Unpin an app</translation> <translation id="7439718573248533901">Delete the next letter (forward delete)</translation> +<translation id="7449669175878568981">Starts or stops dictation (type what you speak)</translation> <translation id="766326951329901120">Paste content from the clipboard as plain text</translation> <translation id="7724603315864178912">Cut</translation> <translation id="7730490981846175479"><ph name="SHIFT" /><ph name="SEPARATOR1" /><ph name="ALT" /><ph name="SEPARATOR2" /><ph name="L" />, then <ph name="SPACE" /> or <ph name="ENTER" /></translation> <translation id="7787242579016742662">Open a file in the browser</translation> +<translation id="7822267121073044318">Switch to the next language input method</translation> <translation id="7917881398263220094">Stop the loading of your current page</translation> +<translation id="7952165122793773711">Go to tabs one to eight</translation> <translation id="8025696740288105292"><ph name="CTRL" /><ph name="SEPARATOR1" /><ph name="SHIFT" /><ph name="SEPARATOR2" /><ph name="PLUS" /> or <ph name="MINUS" /></translation> <translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8104889575691864804">Show app menu</translation> <translation id="8130528849632411619">Go to beginning of document</translation> <translation id="8147954207400281792"><ph name="CTRL" /><ph name="SEPARATOR" /><ph name="K" /> or <ph name="E" /></translation> +<translation id="8232835244134740473">Switch focus between: Status area (where your account picture appears), Launcher, Address bar, Bookmarks bar (if visible), the web page that's open and Downloads bar (if visible).</translation> <translation id="8234414138295101081">Rotate screen 90 degrees</translation> +<translation id="8264941229485248811">Show or hide the Developer Tools inspector</translation> <translation id="836869401750819675">Open the Downloads page</translation> <translation id="8388247778047144397">Drag the link to a blank area on the tab strip</translation> <translation id="8389638407792712197">Open new window</translation> @@ -153,8 +180,11 @@ <translation id="88986195241502842">Page down</translation> <translation id="8903921497873541725">Zoom in</translation> <translation id="8924883688469390268">Switch to the previous user</translation> +<translation id="8951768610999698672">Make items on your screen larger or smaller</translation> <translation id="8977648847395357314">Select the content in the address bar</translation> +<translation id="8982190978301344584">Show the menu displaying a list of available IMEs</translation> <translation id="8990356943438003669"><ph name="ALT" /><ph name="SEPARATOR" /> 1 to 8</translation> +<translation id="9005984960510803406">Open Crosh window</translation> <translation id="9041599225465145264">Paste content from the clipboard</translation> <translation id="9052808072970550123">Switch to the next user</translation> <translation id="906458777597946297">Maximise window</translation> @@ -163,5 +193,6 @@ <translation id="9179672198516322668">Popular Shortcuts</translation> <translation id="93603345341560814">Press <ph name="SHIFT" /> and click a link</translation> <translation id="945383118875625837">Drag link to bookmarks bar</translation> +<translation id="969054500339500113">Place focus on menu bar</translation> <translation id="98120814841227350">Go to end of document</translation> </translationbundle> \ No newline at end of file
diff --git a/ash/magnifier/docked_magnifier_controller.cc b/ash/magnifier/docked_magnifier_controller.cc index 7458953a..cef485e 100644 --- a/ash/magnifier/docked_magnifier_controller.cc +++ b/ash/magnifier/docked_magnifier_controller.cc
@@ -201,8 +201,14 @@ auto* screen = display::Screen::GetScreen(); auto* window = screen->GetWindowAtScreenPoint(point_in_screen); - if (!window) - return; + if (!window) { + // In tests and sometimes initially on signin screen, |point_in_screen| + // maybe invalid and doesn't belong to any existing root window. However, we + // are here because the Docked Magnifier is enabled. We need to create the + // viewport widget somewhere, so we'll use the primary root window until we + // get a valid cursor event. + window = Shell::GetPrimaryRootWindow(); + } auto* root_window = window->GetRootWindow(); DCHECK(root_window); @@ -279,6 +285,11 @@ InitFromUserPrefs(); } +void DockedMagnifierController::OnSigninScreenPrefServiceInitialized( + PrefService* prefs) { + OnActiveUserPrefServiceChanged(prefs); +} + void DockedMagnifierController::OnMouseEvent(ui::MouseEvent* event) { DCHECK(GetEnabled()); CenterOnPoint(GetCursorScreenPoint()); @@ -501,7 +512,18 @@ void DockedMagnifierController::OnEnabledPrefChanged() { Shell* shell = Shell::Get(); - if (GetEnabled()) { + // When switching from the signin screen to a newly created profile while the + // Docked Magnifier is enabled, the prefs will copied from the signin profile + // to the user profile, and the Docked Magnifier will remain enabled. We don't + // want to redo the below operations if the status doesn't change, for example + // readding the same observer to the WindowTreeHostManager will cause a crash + // on DCHECK on debug builds. + const bool current_enabled = !!current_source_root_window_; + const bool new_enabled = GetEnabled(); + if (current_enabled == new_enabled) + return; + + if (new_enabled) { // Enabling the Docked Magnifier disables the Fullscreen Magnifier. SetFullscreenMagnifierEnabled(false); // Calling refresh will result in the creation of the magnifier viewport and
diff --git a/ash/magnifier/docked_magnifier_controller.h b/ash/magnifier/docked_magnifier_controller.h index a7d7ee3..095a185 100644 --- a/ash/magnifier/docked_magnifier_controller.h +++ b/ash/magnifier/docked_magnifier_controller.h
@@ -84,6 +84,7 @@ // ash::SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; + void OnSigninScreenPrefServiceInitialized(PrefService* prefs) override; // ui::EventHandler: void OnMouseEvent(ui::MouseEvent* event) override;
diff --git a/ash/magnifier/docked_magnifier_controller_unittest.cc b/ash/magnifier/docked_magnifier_controller_unittest.cc index 95316948..9d9b10f 100644 --- a/ash/magnifier/docked_magnifier_controller_unittest.cc +++ b/ash/magnifier/docked_magnifier_controller_unittest.cc
@@ -110,6 +110,9 @@ GetSessionControllerClient()->AddUserSession(kUser2Email); test_client_.Start(); + + // Place the cursor in the first display. + GetEventGenerator().MoveMouseTo(gfx::Point(0, 0)); } void SwitchActiveUser(const std::string& email) {
diff --git a/ash/message_center/message_list_view.cc b/ash/message_center/message_list_view.cc index 87984220..17f53b4 100644 --- a/ash/message_center/message_list_view.cc +++ b/ash/message_center/message_list_view.cc
@@ -6,6 +6,7 @@ #include "ash/message_center/message_center_style.h" #include "ash/message_center/message_center_view.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_switches.h" #include "base/command_line.h" #include "base/location.h" @@ -30,10 +31,13 @@ namespace { const int kAnimateClearingNextNotificationDelayMS = 40; +bool HasBorderPadding() { + return !switches::IsSidebarEnabled() && + !features::IsSystemTrayUnifiedEnabled(); +} + int GetMarginBetweenItems() { - return switches::IsSidebarEnabled() - ? 0 - : message_center::kMarginBetweenItemsInList; + return HasBorderPadding() ? message_center::kMarginBetweenItemsInList : 0; } } // namespace @@ -50,7 +54,7 @@ layout->SetDefaultFlex(1); SetLayoutManager(std::move(layout)); - if (!switches::IsSidebarEnabled()) { + if (HasBorderPadding()) { SetBorder(views::CreateEmptyBorder( gfx::Insets(message_center::kMarginBetweenItemsInList))); }
diff --git a/ash/public/cpp/app_list/internal_app_id_constants.h b/ash/public/cpp/app_list/internal_app_id_constants.h new file mode 100644 index 0000000..521fa058 --- /dev/null +++ b/ash/public/cpp/app_list/internal_app_id_constants.h
@@ -0,0 +1,21 @@ +// Copyright 2018 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 ASH_PUBLIC_CPP_APP_LIST_INTERNAL_APP_ID_CONSTANTS_H_ +#define ASH_PUBLIC_CPP_APP_LIST_INTERNAL_APP_ID_CONSTANTS_H_ + +namespace app_list { + +// App ids for internal apps, also used to identify the shelf item. +// Generated as +// crx_file::id_util::GenerateId("org.chromium.keyboardshortcuthelper"). +constexpr char kInternalAppIdKeyboardShortcutViewer[] = + "bhbpmkoclkgbgaefijcdgkfjghcmiijm"; + +// Generated as crx_file::id_util::GenerateId("org.chromium.settings_ui"). +constexpr char kInternalAppIdSettings[] = "dhnmfjegnohoakobpikffnelcemaplkm"; + +} // namespace app_list + +#endif // ASH_PUBLIC_CPP_APP_LIST_INTERNAL_APP_ID_CONSTANTS_H_
diff --git a/ash/public/cpp/shell_window_ids.cc b/ash/public/cpp/shell_window_ids.cc index de623e1..a1216fc 100644 --- a/ash/public/cpp/shell_window_ids.cc +++ b/ash/public/cpp/shell_window_ids.cc
@@ -14,7 +14,7 @@ const int32_t kActivatableShellWindowIds[] = { kShellWindowId_OverlayContainer, kShellWindowId_LockSystemModalContainer, kShellWindowId_AccessibilityPanelContainer, - kShellWindowId_SettingBubbleContainer, + kShellWindowId_SettingBubbleContainer, kShellWindowId_PowerMenuContainer, kShellWindowId_LockActionHandlerContainer, kShellWindowId_LockScreenContainer, kShellWindowId_SystemModalContainer, kShellWindowId_AlwaysOnTopContainer, kShellWindowId_AppListContainer,
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h index 0152d24..4537c73 100644 --- a/ash/public/cpp/shell_window_ids.h +++ b/ash/public/cpp/shell_window_ids.h
@@ -104,6 +104,9 @@ // The container for drag/drop images and tooltips. kShellWindowId_DragImageAndTooltipContainer, + // The container for the fullscreen power button menu. + kShellWindowId_PowerMenuContainer, + // The container for bubbles briefly overlaid onscreen to show settings // changes (volume, brightness, input method bubbles, etc.). kShellWindowId_SettingBubbleContainer, @@ -161,6 +164,7 @@ kShellWindowId_ImeWindowParentContainer, kShellWindowId_MenuContainer, kShellWindowId_DragImageAndTooltipContainer, + kShellWindowId_PowerMenuContainer, kShellWindowId_SettingBubbleContainer, kShellWindowId_AccessibilityPanelContainer, kShellWindowId_OverlayContainer,
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd index b0b2c0a..7a9a1a3 100644 --- a/ash/resources/ash_resources.grd +++ b/ash/resources/ash_resources.grd
@@ -14,7 +14,6 @@ SAME CONDITIONALS. --> <structure type="chrome_scaled_image" name="IDR_ASH_SHELF_LIST_BROWSER" file="common/shelf/window_switcher_icon_normal.png" /> <structure type="chrome_scaled_image" name="IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER" file="common/shelf/window_switcher_icon_incognito.png" /> - <structure type="chrome_scaled_image" name="IDR_ASH_SHELF_ICON_SETTINGS" file="common/shelf/settings_app_icon.png" /> <structure type="chrome_scaled_image" name="IDR_ASH_SHELF_ICON_TASK_MANAGER" file="common/shelf/task_manager.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_FAILED" file="cros/network/status_network_failed.png" /> @@ -36,6 +35,10 @@ <!-- Crostini terminal images --> <structure type="chrome_scaled_image" name="IDR_LOGO_CROSTINI_TERMINAL" file="cros/crostini/logo_crostini_terminal.png" /> + <!-- CrOS internal apps images --> + <structure type="chrome_scaled_image" name="IDR_KEYBOARD_SHORTCUT_VIEWER_LOGO_192" file="cros/keyboard_shortcut_viewer_logo_192.png" /> + <structure type="chrome_scaled_image" name="IDR_SETTINGS_LOGO_192" file="cros/settings_logo_192.png" /> + </structures> </release> </grit>
diff --git a/ash/resources/default_100_percent/common/shelf/settings_app_icon.png b/ash/resources/default_100_percent/common/shelf/settings_app_icon.png deleted file mode 100644 index 5445c4c..0000000 --- a/ash/resources/default_100_percent/common/shelf/settings_app_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/cros/keyboard_shortcut_viewer_logo_192.png b/ash/resources/default_100_percent/cros/keyboard_shortcut_viewer_logo_192.png similarity index 100% rename from chrome/app/theme/cros/keyboard_shortcut_viewer_logo_192.png rename to ash/resources/default_100_percent/cros/keyboard_shortcut_viewer_logo_192.png Binary files differ
diff --git a/ash/resources/default_100_percent/cros/settings_logo_192.png b/ash/resources/default_100_percent/cros/settings_logo_192.png new file mode 100644 index 0000000..be98c3ce --- /dev/null +++ b/ash/resources/default_100_percent/cros/settings_logo_192.png Binary files differ
diff --git a/ash/resources/default_200_percent/common/shelf/settings_app_icon.png b/ash/resources/default_200_percent/common/shelf/settings_app_icon.png deleted file mode 100644 index b240bfb..0000000 --- a/ash/resources/default_200_percent/common/shelf/settings_app_icon.png +++ /dev/null Binary files differ
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index a34b699..87b4da0 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -923,6 +923,12 @@ status_container->SetProperty(kUsesScreenCoordinatesKey, true); status_container->SetProperty(kLockedToRootKey, true); + aura::Window* power_menu_container = + CreateContainer(kShellWindowId_PowerMenuContainer, "PowerMenuContainer", + lock_screen_related_containers); + wm::SetSnapsChildrenToPhysicalPixelBoundary(power_menu_container); + power_menu_container->SetProperty(kUsesScreenCoordinatesKey, true); + aura::Window* settings_bubble_container = CreateContainer(kShellWindowId_SettingBubbleContainer, "SettingBubbleContainer", lock_screen_related_containers);
diff --git a/ash/session/session_controller.cc b/ash/session/session_controller.cc index 3f078bc..2c2e730 100644 --- a/ash/session/session_controller.cc +++ b/ash/session/session_controller.cc
@@ -346,10 +346,9 @@ observer.OnActiveUserSessionChanged( user_sessions_[0]->user_info->account_id); } - if (it != per_user_prefs_.end()) { - for (auto& observer : observers_) - observer.OnActiveUserPrefServiceChanged(last_active_user_prefs_); - } + + if (it != per_user_prefs_.end()) + MaybeNotifyOnActiveUserPrefServiceChanged(); UpdateLoginStatus(); } @@ -498,10 +497,8 @@ session_activation_observer_holder_.NotifyLockStateChanged(locked); } - // Signin profile prefs are needed at OOBE and login screen, but don't request - // them twice. - if (!signin_screen_prefs_requested_ && - (state_ == SessionState::OOBE || state_ == SessionState::LOGIN_PRIMARY)) { + // Request signin profile prefs only once. + if (!signin_screen_prefs_requested_) { ConnectToSigninScreenPrefService(); signin_screen_prefs_requested_ = true; } @@ -639,11 +636,18 @@ DCHECK(!signin_screen_prefs_); signin_screen_prefs_ = std::move(pref_service); - // The signin profile should be initialized before any user profile. - DCHECK(!last_active_user_prefs_); - - for (auto& observer : observers_) + for (auto& observer : observers_) { observer.OnSigninScreenPrefServiceInitialized(signin_screen_prefs_.get()); + } + + if (on_active_user_prefs_changed_notify_deferred_) { + // Notify obsevers with the deferred OnActiveUserPrefServiceChanged(). Do + // this in a separate loop from the above since observers might depend on + // each other and we want to avoid having inconsistent states. + for (auto& observer : observers_) + observer.OnActiveUserPrefServiceChanged(last_active_user_prefs_); + on_active_user_prefs_changed_notify_deferred_ = false; + } } void SessionController::OnProfilePrefServiceInitialized( @@ -660,9 +664,24 @@ DCHECK(!user_sessions_.empty()); if (account_id == user_sessions_[0]->user_info->account_id) { last_active_user_prefs_ = pref_service_ptr; - for (auto& observer : observers_) - observer.OnActiveUserPrefServiceChanged(pref_service_ptr); + + MaybeNotifyOnActiveUserPrefServiceChanged(); } } +void SessionController::MaybeNotifyOnActiveUserPrefServiceChanged() { + DCHECK(last_active_user_prefs_); + + if (!signin_screen_prefs_) { + // We must guarantee that OnSigninScreenPrefServiceInitialized() is called + // before OnActiveUserPrefServiceChanged(), so defer notifying the + // observers until the sign in prefs are received. + on_active_user_prefs_changed_notify_deferred_ = true; + return; + } + + for (auto& observer : observers_) + observer.OnActiveUserPrefServiceChanged(last_active_user_prefs_); +} + } // namespace ash
diff --git a/ash/session/session_controller.h b/ash/session/session_controller.h index 6fe48f3..b862cf0 100644 --- a/ash/session/session_controller.h +++ b/ash/session/session_controller.h
@@ -227,6 +227,12 @@ const AccountId& account_id, std::unique_ptr<PrefService> pref_service); + // Notifies observers that the active user pref service changed only if the + // signin profile pref service has been connected and observers were notified + // via OnSigninScreenPrefServiceInitialized(). Otherwise, defer the + // notification until that happens. + void MaybeNotifyOnActiveUserPrefServiceChanged(); + // Bindings for users of the mojom::SessionController interface. mojo::BindingSet<mojom::SessionController> bindings_; @@ -272,6 +278,12 @@ // pref in case of a crash during the session. base::TimeTicks session_start_time_; + // Set to true if the active user's pref is received before the signin prefs. + // This is so that we can guarantee that observers are notified with + // OnActiveUserPrefServiceChanged() after + // OnSigninScreenPrefServiceInitialized(). + bool on_active_user_prefs_changed_notify_deferred_ = false; + base::ObserverList<ash::SessionObserver> observers_; service_manager::Connector* const connector_;
diff --git a/ash/shell.cc b/ash/shell.cc index 0009b18..84ed5d4 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -395,7 +395,7 @@ PaletteTray::RegisterProfilePrefs(registry); PaletteWelcomeBubble::RegisterProfilePrefs(registry); ShelfController::RegisterProfilePrefs(registry); - TouchDevicesController::RegisterProfilePrefs(registry, for_test); + TouchDevicesController::RegisterProfilePrefs(registry); CapsLockNotificationController::RegisterProfilePrefs(registry, for_test); }
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb index a9fe06a..90dc6901 100644 --- a/ash/strings/ash_strings_en-GB.xtb +++ b/ash/strings/ash_strings_en-GB.xtb
@@ -32,6 +32,7 @@ <translation id="1658406695958299976">Sorry, your password still couldn't be verified. Note: If you changed your password recently, your new password will be applied once you sign out. Please use the old password here.</translation> <translation id="1677472565718498478"><ph name="TIME" /> left</translation> <translation id="1698760176351776263">IPv6 address: <ph name="ADDRESS" /></translation> +<translation id="170389796989115980">The device admin may be able to monitor your activity.</translation> <translation id="1734367976349034509">This device is enterprise managed</translation> <translation id="1746730358044914197">Input methods are configured by your administrator.</translation> <translation id="1747827819627189109">On-screen keyboard enabled</translation> @@ -46,6 +47,7 @@ <translation id="1942830294380034169">Overflow button</translation> <translation id="1951012854035635156">Assistant</translation> <translation id="1957803754585243749">0°</translation> +<translation id="1957958912175573503">Set your language</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> <translation id="1995660704900986789">Power off</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> @@ -81,6 +83,8 @@ <translation id="2653659639078652383">Submit</translation> <translation id="2675319268637823299">An administrator has dismissed multiple sign-ins for <ph name="USER_EMAIL" />. All users must sign out to continue.</translation> +<translation id="2696763960464195425">Your information will be removed when you sign out. <ph name="LEARN_MORE" /></translation> +<translation id="2700493154570097719">Set your keyboard</translation> <translation id="2718395828230677721">Night Light</translation> <translation id="2727977024730340865">Plugged in to a low-power charger. Battery charging may not be reliable.</translation> <translation id="2761704814324807722">Status tray, time <ph name="TIME" />, <ph name="BATTERY" /></translation> @@ -269,6 +273,7 @@ <translation id="7098389117866926363">USB-C device (left port in the back)</translation> <translation id="7131634465328662194">You will automatically be signed out.</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> +<translation id="7165511658052620796">(TEMP) Show webui login; if used file bug (crbug.com) or feedback (alt+shift+i)</translation> <translation id="7168224885072002358">Reverting to old resolution in <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Rear microphone</translation> <translation id="726276584504105859">Drag here to use split screen</translation> @@ -329,6 +334,7 @@ <translation id="8673028979667498656">270°</translation> <translation id="8676770494376880701">Low-power charger connected</translation> <translation id="8734991477317290293">It may be attempting to steal your keystrokes</translation> +<translation id="8809737090443522491">Type the name of an app or document</translation> <translation id="8814190375133053267">Wi-Fi</translation> <translation id="8814715559352963456">Moving windows to another desktop may result in unexpected behaviour.
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb index f3ea989..5cc50abd 100644 --- a/ash/strings/ash_strings_id.xtb +++ b/ash/strings/ash_strings_id.xtb
@@ -186,7 +186,7 @@ <translation id="5430931332414098647">Tethering Instan</translation> <translation id="5431825016875453137">OpenVPN / L2TP</translation> <translation id="544691375626129091">Semua pengguna yang tersedia telah ditambahkan ke sesi ini.</translation> -<translation id="5457599981699367932">Jelajahi sebagai Tamu</translation> +<translation id="5457599981699367932">Login sebagai Tamu</translation> <translation id="54609108002486618">Terkelola</translation> <translation id="553675580533261935">Keluar dari sesi</translation> <translation id="5548285847212963613">Ekstensi "<ph name="EXTENSION_NAME" />" dapat membantu menyambungkan ke jaringan ini.</translation>
diff --git a/ash/system/power/power_button_controller.cc b/ash/system/power/power_button_controller.cc index 757eb23..1069ea4 100644 --- a/ash/system/power/power_button_controller.cc +++ b/ash/system/power/power_button_controller.cc
@@ -62,7 +62,7 @@ params.name = "PowerButtonMenuWindow"; params.layer_type = ui::LAYER_SOLID_COLOR; params.parent = Shell::GetPrimaryRootWindow()->GetChildById( - kShellWindowId_OverlayContainer); + kShellWindowId_PowerMenuContainer); menu_widget->Init(params); gfx::Rect widget_bounds = @@ -286,7 +286,6 @@ return; } - DismissMenu(); if (down) lock_state_controller_->StartLockAnimation(); else @@ -490,8 +489,7 @@ // Focus on 'Power off' when menu is shown. static_cast<PowerButtonMenuScreenView*>(menu_widget_->GetContentsView()) ->power_button_menu_view() - ->power_off_item() - ->RequestFocus(); + ->FocusPowerOffButton(); pre_shutdown_timer_.Start( FROM_HERE, kStartShutdownAnimationTimeout,
diff --git a/ash/system/power/power_button_controller_test_api.cc b/ash/system/power/power_button_controller_test_api.cc index b69f4ca..bb50db71 100644 --- a/ash/system/power/power_button_controller_test_api.cc +++ b/ash/system/power/power_button_controller_test_api.cc
@@ -70,8 +70,7 @@ } bool PowerButtonControllerTestApi::MenuHasSignOutItem() const { - return IsMenuOpened() && - GetPowerButtonMenuView()->sign_out_item_for_testing(); + return IsMenuOpened() && GetPowerButtonMenuView()->sign_out_item_for_test(); } PowerButtonScreenshotController*
diff --git a/ash/system/power/power_button_controller_unittest.cc b/ash/system/power/power_button_controller_unittest.cc index f8e50a6..0bce0123 100644 --- a/ash/system/power/power_button_controller_unittest.cc +++ b/ash/system/power/power_button_controller_unittest.cc
@@ -132,7 +132,7 @@ ASSERT_TRUE(power_button_test_api_->IsMenuOpened()); // "Power off" item has focus after menu is opened. EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView() - ->power_off_item() + ->power_off_item_for_test() ->HasFocus()); } @@ -309,18 +309,6 @@ EXPECT_FALSE(power_manager_client_->backlights_forced_off()); } -// Should dismiss the menu if locking screen when menu is opened. -TEST_F(PowerButtonControllerTest, LockScreenIfMenuIsOpened) { - Initialize(ButtonType::NORMAL, LoginStatus::USER); - OpenPowerButtonMenu(); - EXPECT_TRUE(power_button_test_api_->IsMenuOpened()); - PressLockButton(); - ReleaseLockButton(); - EXPECT_TRUE(lock_state_test_api_->is_animating_lock()); - EXPECT_EQ(1, session_manager_client_->request_lock_screen_call_count()); - EXPECT_FALSE(power_button_test_api_->IsMenuOpened()); -} - // Tests press lock button and power button in sequence. TEST_F(PowerButtonControllerTest, PressAfterAnotherReleased) { // Tap power button after press lock button should still turn screen off. @@ -948,6 +936,52 @@ EXPECT_TRUE(cursor_manager->IsCursorVisible()); } +// Tests that press VKEY_ESCAPE should dismiss the opened menu. +TEST_F(PowerButtonControllerTest, ESCDismissMenu) { + OpenPowerButtonMenu(); + + PressKey(ui::VKEY_VOLUME_DOWN); + EXPECT_TRUE(power_button_test_api_->IsMenuOpened()); + + PressKey(ui::VKEY_BRIGHTNESS_UP); + EXPECT_TRUE(power_button_test_api_->IsMenuOpened()); + + PressKey(ui::VKEY_BROWSER_SEARCH); + EXPECT_TRUE(power_button_test_api_->IsMenuOpened()); + + PressKey(ui::VKEY_ESCAPE); + EXPECT_FALSE(power_button_test_api_->IsMenuOpened()); +} + +// Tests the navigation of the menu. +TEST_F(PowerButtonControllerTest, MenuNavigation) { + OpenPowerButtonMenu(); + PressKey(ui::VKEY_TAB); + EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView() + ->sign_out_item_for_test() + ->HasFocus()); + + PressKey(ui::VKEY_LEFT); + EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView() + ->power_off_item_for_test() + ->HasFocus()); + + PressKey(ui::VKEY_RIGHT); + EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView() + ->sign_out_item_for_test() + ->HasFocus()); + + PressKey(ui::VKEY_UP); + EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView() + ->power_off_item_for_test() + ->HasFocus()); + + PressKey(ui::VKEY_DOWN); + EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView() + ->sign_out_item_for_test() + ->HasFocus()); +} + class PowerButtonControllerWithPositionTest : public PowerButtonControllerTest, public testing::WithParamInterface<PowerButtonPosition> {
diff --git a/ash/system/power/power_button_menu_view.cc b/ash/system/power/power_button_menu_view.cc index fb4a3c2..c06ac2a7 100644 --- a/ash/system/power/power_button_menu_view.cc +++ b/ash/system/power/power_button_menu_view.cc
@@ -48,6 +48,10 @@ PowerButtonMenuView::~PowerButtonMenuView() = default; +void PowerButtonMenuView::FocusPowerOffButton() { + power_off_item_->RequestFocus(); +} + void PowerButtonMenuView::ScheduleShowHideAnimation(bool show) { // Cancel any previous animation. layer()->GetAnimator()->AbortAllAnimations(); @@ -192,6 +196,20 @@ return menu_size; } +bool PowerButtonMenuView::OnKeyPressed(const ui::KeyEvent& event) { + const ui::KeyboardCode key = event.key_code(); + if (key == ui::VKEY_ESCAPE) { + Shell::Get()->power_button_controller()->DismissMenu(); + } else if (sign_out_item_ && (key == ui::VKEY_TAB || key == ui::VKEY_LEFT || + key == ui::VKEY_RIGHT || key == ui::VKEY_UP || + key == ui::VKEY_DOWN)) { + sign_out_item_->HasFocus() ? power_off_item_->RequestFocus() + : sign_out_item_->RequestFocus(); + } + + return true; +} + void PowerButtonMenuView::ButtonPressed(views::Button* sender, const ui::Event& event) { DCHECK(sender);
diff --git a/ash/system/power/power_button_menu_view.h b/ash/system/power/power_button_menu_view.h index 6566d09..f0366e0 100644 --- a/ash/system/power/power_button_menu_view.h +++ b/ash/system/power/power_button_menu_view.h
@@ -42,9 +42,15 @@ PowerButtonController::PowerButtonPosition power_button_position); ~PowerButtonMenuView() override; - bool sign_out_item_for_testing() const { return sign_out_item_; } + PowerButtonMenuItemView* sign_out_item_for_test() const { + return sign_out_item_; + } + PowerButtonMenuItemView* power_off_item_for_test() const { + return power_off_item_; + } - PowerButtonMenuItemView* power_off_item() const { return power_off_item_; } + // Requests focus for |power_off_item_|. + void FocusPowerOffButton(); // Schedules an animation to show or hide the view. void ScheduleShowHideAnimation(bool show); @@ -60,6 +66,7 @@ void Layout() override; void OnPaint(gfx::Canvas* canvas) override; gfx::Size CalculatePreferredSize() const override; + bool OnKeyPressed(const ui::KeyEvent& event) override; // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc index 3db767db..1e00e24 100644 --- a/ash/system/status_area_widget.cc +++ b/ash/system/status_area_widget.cc
@@ -56,9 +56,11 @@ } // Must happen after the widget is initialized so the native window exists. - web_notification_tray_ = - std::make_unique<WebNotificationTray>(shelf_, GetNativeWindow()); - status_area_widget_delegate_->AddChildView(web_notification_tray_.get()); + if (!features::IsSystemTrayUnifiedEnabled()) { + web_notification_tray_ = + std::make_unique<WebNotificationTray>(shelf_, GetNativeWindow()); + status_area_widget_delegate_->AddChildView(web_notification_tray_.get()); + } palette_tray_ = std::make_unique<PaletteTray>(shelf_); status_area_widget_delegate_->AddChildView(palette_tray_.get()); @@ -85,8 +87,12 @@ status_area_widget_delegate_->UpdateLayout(); // Initialize after all trays have been created. - system_tray_->InitializeTrayItems(web_notification_tray_.get()); - web_notification_tray_->Initialize(); + if (web_notification_tray_) { + system_tray_->InitializeTrayItems(web_notification_tray_.get()); + web_notification_tray_->Initialize(); + } else { + system_tray_->InitializeTrayItems(nullptr); + } palette_tray_->Initialize(); virtual_keyboard_tray_->Initialize(); ime_menu_tray_->Initialize(); @@ -119,7 +125,8 @@ void StatusAreaWidget::UpdateAfterShelfAlignmentChange() { system_tray_->UpdateAfterShelfAlignmentChange(); - web_notification_tray_->UpdateAfterShelfAlignmentChange(); + if (web_notification_tray_) + web_notification_tray_->UpdateAfterShelfAlignmentChange(); logout_button_tray_->UpdateAfterShelfAlignmentChange(); virtual_keyboard_tray_->UpdateAfterShelfAlignmentChange(); ime_menu_tray_->UpdateAfterShelfAlignmentChange(); @@ -171,12 +178,14 @@ bool StatusAreaWidget::IsMessageBubbleShown() const { return system_tray_->IsSystemBubbleVisible() || - web_notification_tray_->IsMessageCenterVisible(); + (web_notification_tray_ && + web_notification_tray_->IsMessageCenterVisible()); } void StatusAreaWidget::SchedulePaint() { status_area_widget_delegate_->SchedulePaint(); - web_notification_tray_->SchedulePaint(); + if (web_notification_tray_) + web_notification_tray_->SchedulePaint(); system_tray_->SchedulePaint(); virtual_keyboard_tray_->SchedulePaint(); logout_button_tray_->SchedulePaint(); @@ -200,7 +209,8 @@ } void StatusAreaWidget::UpdateShelfItemBackground(SkColor color) { - web_notification_tray_->UpdateShelfItemBackground(color); + if (web_notification_tray_) + web_notification_tray_->UpdateShelfItemBackground(color); system_tray_->UpdateShelfItemBackground(color); virtual_keyboard_tray_->UpdateShelfItemBackground(color); ime_menu_tray_->UpdateShelfItemBackground(color);
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 847d6a29..63c2216 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc
@@ -238,14 +238,14 @@ void SystemTray::InitializeTrayItems( WebNotificationTray* web_notification_tray) { - DCHECK(web_notification_tray); + DCHECK(web_notification_tray || features::IsSystemTrayUnifiedEnabled()); web_notification_tray_ = web_notification_tray; TrayBackgroundView::Initialize(); CreateItems(); } void SystemTray::Shutdown() { - DCHECK(web_notification_tray_); + DCHECK(web_notification_tray_ || features::IsSystemTrayUnifiedEnabled()); web_notification_tray_ = nullptr; }
diff --git a/ash/system/unified/feature_pods_container_view.cc b/ash/system/unified/feature_pods_container_view.cc index faaf977..7a0247f 100644 --- a/ash/system/unified/feature_pods_container_view.cc +++ b/ash/system/unified/feature_pods_container_view.cc
@@ -45,16 +45,13 @@ PreferredSizeChanged(); - if (expanded_amount == 0.0 || expanded_amount == 1.0) { - expanded_ = expanded_amount == 1.0; - for (int i = 0; i < child_count(); ++i) { - auto* child = static_cast<FeaturePodButton*>(child_at(i)); - child->SetExpanded(expanded_); - } - UpdateChildVisibility(); - // We have to call Layout() explicitly here. - Layout(); + for (int i = 0; i < child_count(); ++i) { + auto* child = static_cast<FeaturePodButton*>(child_at(i)); + child->SetExpanded(expanded_amount_ > 0.0); } + UpdateChildVisibility(); + // We have to call Layout() explicitly here. + Layout(); } void FeaturePodsContainerView::ChildVisibilityChanged(View* child) { @@ -69,79 +66,22 @@ } void FeaturePodsContainerView::Layout() { - if (expanded_) - LayoutExpanded(); - else - LayoutCollapsed(); -} + UpdateCollapsedSidePadding(); -void FeaturePodsContainerView::LayoutExpanded() { - DCHECK(expanded_); - int x = kUnifiedFeaturePodHorizontalSidePadding; - int y = kUnifiedFeaturePodVerticalPadding; int visible_count = 0; for (int i = 0; i < child_count(); ++i) { views::View* child = child_at(i); if (!child->visible()) continue; - ++visible_count; - child->SetBounds(x, y, kUnifiedFeaturePodSize.width(), - kUnifiedFeaturePodSize.height()); + child->SetBoundsRect(gfx::Rect(GetButtonPosition(visible_count++), + expanded_amount_ > 0.0 + ? kUnifiedFeaturePodSize + : kUnifiedFeaturePodCollapsedSize)); child->Layout(); - - x += kUnifiedFeaturePodSize.width() + - kUnifiedFeaturePodHorizontalMiddlePadding; - // Go to the next line if the number of items exceeds - // kUnifiedFeaturePodItemsInRow. - if (visible_count % kUnifiedFeaturePodItemsInRow == 0) { - // Check if the total width fits into the menu width. - DCHECK(x - kUnifiedFeaturePodHorizontalMiddlePadding + - kUnifiedFeaturePodHorizontalSidePadding == - kTrayMenuWidth); - x = kUnifiedFeaturePodHorizontalSidePadding; - y += kUnifiedFeaturePodSize.height() + kUnifiedFeaturePodVerticalPadding; - } } } -void FeaturePodsContainerView::LayoutCollapsed() { - DCHECK(!expanded_); - - int visible_count = 0; - for (int i = 0; i < child_count(); ++i) { - if (child_at(i)->visible()) - ++visible_count; - } - - DCHECK(visible_count > 0 && - visible_count <= kUnifiedFeaturePodMaxItemsInCollapsed); - - int contents_width = - visible_count * kUnifiedFeaturePodCollapsedSize.width() + - (visible_count - 1) * kUnifiedFeaturePodCollapsedHorizontalPadding; - - int side_padding = (width() - contents_width) / 2; - DCHECK(side_padding > 0); - - int x = side_padding; - for (int i = 0; i < child_count(); ++i) { - views::View* child = child_at(i); - if (!child->visible()) - continue; - - child->SetBounds(x, kUnifiedFeaturePodCollapsedVerticalPadding, - kUnifiedFeaturePodCollapsedSize.width(), - kUnifiedFeaturePodCollapsedSize.height()); - - x += kUnifiedFeaturePodCollapsedSize.width() + - kUnifiedFeaturePodCollapsedHorizontalPadding; - } - - DCHECK(x - kUnifiedFeaturePodCollapsedHorizontalPadding + side_padding == - kTrayMenuWidth); -} - void FeaturePodsContainerView::UpdateChildVisibility() { DCHECK(!changing_visibility_); changing_visibility_ = true; @@ -149,14 +89,72 @@ int visible_count = 0; for (int i = 0; i < child_count(); ++i) { auto* child = static_cast<FeaturePodButton*>(child_at(i)); - child->SetVisibleByContainer( - child->visible_preferred() && - (expanded_ || visible_count < kUnifiedFeaturePodMaxItemsInCollapsed)); - if (child->visible()) + bool visible = child->visible_preferred() && + (expanded_amount_ > 0.0 || + visible_count < kUnifiedFeaturePodMaxItemsInCollapsed); + child->SetVisibleByContainer(visible); + if (visible) ++visible_count; } changing_visibility_ = false; } +gfx::Point FeaturePodsContainerView::GetButtonPosition( + int visible_index) const { + int row = visible_index / kUnifiedFeaturePodItemsInRow; + int column = visible_index % kUnifiedFeaturePodItemsInRow; + int x = kUnifiedFeaturePodHorizontalSidePadding + + (kUnifiedFeaturePodSize.width() + + kUnifiedFeaturePodHorizontalMiddlePadding) * + column; + int y = + kUnifiedFeaturePodVerticalPadding + + (kUnifiedFeaturePodSize.height() + kUnifiedFeaturePodVerticalPadding) * + row; + + // When fully expanded, or below the second row, always return the same + // position. + if (expanded_amount_ == 1.0 || row > 2) + return gfx::Point(x, y); + + int collapsed_x = + collapsed_side_padding_ + (kUnifiedFeaturePodCollapsedSize.width() + + kUnifiedFeaturePodCollapsedHorizontalPadding) * + visible_index; + int collapsed_y = kUnifiedFeaturePodCollapsedVerticalPadding; + + // When fully collapsed, just return the collapsed position. + if (expanded_amount_ == 0.0) + return gfx::Point(collapsed_x, collapsed_y); + + // Button width is different between expanded and collapsed states. + // During the transition, expanded width is used, so it should be adjusted. + collapsed_x -= (kUnifiedFeaturePodSize.width() - + kUnifiedFeaturePodCollapsedSize.width()) / + 2; + + return gfx::Point( + x * expanded_amount_ + collapsed_x * (1.0 - expanded_amount_), + y * expanded_amount_ + collapsed_y * (1.0 - expanded_amount_)); +} + +void FeaturePodsContainerView::UpdateCollapsedSidePadding() { + int visible_count = 0; + for (int i = 0; i < child_count(); ++i) { + if (static_cast<const FeaturePodButton*>(child_at(i))->visible_preferred()) + ++visible_count; + } + + visible_count = + std::min(visible_count, kUnifiedFeaturePodMaxItemsInCollapsed); + + int contents_width = + visible_count * kUnifiedFeaturePodCollapsedSize.width() + + (visible_count - 1) * kUnifiedFeaturePodCollapsedHorizontalPadding; + + collapsed_side_padding_ = (kTrayMenuWidth - contents_width) / 2; + DCHECK(collapsed_side_padding_ > 0); +} + } // namespace ash
diff --git a/ash/system/unified/feature_pods_container_view.h b/ash/system/unified/feature_pods_container_view.h index c781f465..75f4ccd 100644 --- a/ash/system/unified/feature_pods_container_view.h +++ b/ash/system/unified/feature_pods_container_view.h
@@ -31,18 +31,20 @@ void Layout() override; private: - void LayoutExpanded(); - void LayoutCollapsed(); void UpdateChildVisibility(); + // Calculate the current position of the button from |visible_index| and + // |expanded_amount_|. + gfx::Point GetButtonPosition(int visible_index) const; + + // Update |collapsed_state_padding_|. + void UpdateCollapsedSidePadding(); + // The last |expanded_amount| passed to SetExpandedAmount(). double expanded_amount_ = 1.0; - // True if the last state was expanded or collapsed. Changes when - // SetExpandedAmount is called with 0.0 or 1.0. - // TODO(tetsui): Remove this flag when the animation for this view is - // implemented. - bool expanded_ = true; + // Horizontal side padding in dip for collapsed state. + int collapsed_side_padding_ = 0; bool changing_visibility_ = false;
diff --git a/ash/system/unified/unified_message_center_view.cc b/ash/system/unified/unified_message_center_view.cc new file mode 100644 index 0000000..c5521a7 --- /dev/null +++ b/ash/system/unified/unified_message_center_view.cc
@@ -0,0 +1,167 @@ +// Copyright 2018 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 "ash/system/unified/unified_message_center_view.h" + +#include "ui/message_center/message_center.h" +#include "ui/message_center/message_center_types.h" +#include "ui/message_center/views/message_view.h" +#include "ui/message_center/views/message_view_factory.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/controls/scrollbar/overlay_scroll_bar.h" + +using message_center::MessageCenter; +using message_center::MessageView; +using message_center::Notification; +using message_center::NotificationList; + +namespace ash { + +namespace { + +const int kMaxVisibleNotifications = 100; + +} // namespace + +// UnifiedMessageCenterView +// /////////////////////////////////////////////////////////// + +UnifiedMessageCenterView::UnifiedMessageCenterView( + MessageCenter* message_center) + : message_center_(message_center), + scroller_(new views::ScrollView()), + message_list_view_(new MessageListView()) { + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + + message_center_->AddObserver(this); + set_notify_enter_exit_on_child(true); + SetFocusBehavior(views::View::FocusBehavior::NEVER); + + // Need to set the transparent background explicitly, since ScrollView has + // set the default opaque background color. + scroller_->SetBackgroundColor(SK_ColorTRANSPARENT); + scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false)); + scroller_->SetHorizontalScrollBar(new views::OverlayScrollBar(true)); + AddChildView(scroller_); + + message_list_view_->set_scroller(scroller_); + scroller_->SetContents(message_list_view_); + + MessageView::SetSidebarEnabled(); + + SetNotifications(message_center_->GetVisibleNotifications()); +} + +UnifiedMessageCenterView::~UnifiedMessageCenterView() { + message_center_->RemoveObserver(this); +} + +void UnifiedMessageCenterView::SetMaxHeight(int max_height) { + scroller_->ClipHeightTo(0, max_height); + Update(); +} + +void UnifiedMessageCenterView::SetNotifications( + const NotificationList::Notifications& notifications) { + int index = message_list_view_->GetNotificationCount(); + for (const Notification* notification : notifications) { + if (index >= kMaxVisibleNotifications) { + break; + } + + AddNotificationAt(*notification, index++); + message_center_->DisplayedNotification( + notification->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER); + } + + Update(); +} + +void UnifiedMessageCenterView::Layout() { + scroller_->SetBounds(0, 0, width(), height()); +} + +gfx::Size UnifiedMessageCenterView::CalculatePreferredSize() const { + return scroller_->GetPreferredSize(); +} + +void UnifiedMessageCenterView::OnNotificationAdded(const std::string& id) { + if (message_list_view_->GetNotificationCount() >= kMaxVisibleNotifications) + return; + + int index = 0; + const NotificationList::Notifications& notifications = + message_center_->GetVisibleNotifications(); + for (const Notification* notification : notifications) { + if (notification->id() == id) { + AddNotificationAt(*notification, index); + break; + } + ++index; + } + Update(); +} + +void UnifiedMessageCenterView::OnNotificationRemoved(const std::string& id, + bool by_user) { + auto view_pair = message_list_view_->GetNotificationById(id); + MessageView* view = view_pair.second; + if (!view) + return; + + message_list_view_->RemoveNotification(view); + Update(); +} + +void UnifiedMessageCenterView::OnNotificationUpdated(const std::string& id) { + UpdateNotification(id); +} + +void UnifiedMessageCenterView::OnViewPreferredSizeChanged( + views::View* observed_view) { + DCHECK_EQ(std::string(MessageView::kViewClassName), + observed_view->GetClassName()); + UpdateNotification( + static_cast<MessageView*>(observed_view)->notification_id()); +} + +void UnifiedMessageCenterView::Update() { + SetVisible(message_list_view_->GetNotificationCount() > 0); + + scroller_->InvalidateLayout(); + PreferredSizeChanged(); + Layout(); +} + +void UnifiedMessageCenterView::AddNotificationAt( + const Notification& notification, + int index) { + MessageView* view = message_center::MessageViewFactory::Create( + notification, /*top-level=*/false); + view->AddObserver(this); + view->set_scroller(scroller_); + message_list_view_->AddNotificationAt(view, index); +} + +void UnifiedMessageCenterView::UpdateNotification(const std::string& id) { + MessageView* view = message_list_view_->GetNotificationById(id).second; + if (!view) + return; + + Notification* notification = message_center_->FindVisibleNotificationById(id); + if (!notification) + return; + + int old_width = view->width(); + int old_height = view->height(); + bool old_pinned = view->GetPinned(); + message_list_view_->UpdateNotification(view, *notification); + if (view->GetHeightForWidth(old_width) != old_height || + view->GetPinned() != old_pinned) { + Update(); + } +} + +} // namespace ash
diff --git a/ash/system/unified/unified_message_center_view.h b/ash/system/unified/unified_message_center_view.h new file mode 100644 index 0000000..af214d0 --- /dev/null +++ b/ash/system/unified/unified_message_center_view.h
@@ -0,0 +1,72 @@ +// Copyright 2018 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 ASH_SYSTEM_UNIFIED_UNIFIED_MESSAGE_CENTER_VIEW_H_ +#define ASH_SYSTEM_UNIFIED_UNIFIED_MESSAGE_CENTER_VIEW_H_ + +#include <stddef.h> + +#include "ash/ash_export.h" +#include "ash/message_center/message_list_view.h" +#include "base/macros.h" +#include "ui/message_center/message_center_observer.h" +#include "ui/message_center/notification_list.h" +#include "ui/views/focus/focus_manager.h" +#include "ui/views/view.h" + +namespace message_center { + +class MessageCenter; + +} // namespace message_center + +namespace ash { + +// Container for message list view. Acts as a controller/delegate of message +// list view, passing data back and forth to message center. +class ASH_EXPORT UnifiedMessageCenterView + : public views::View, + public message_center::MessageCenterObserver, + public views::ViewObserver { + public: + explicit UnifiedMessageCenterView( + message_center::MessageCenter* message_center); + ~UnifiedMessageCenterView() override; + + // Set the maximum height that the view can take. + void SetMaxHeight(int max_height); + + protected: + void SetNotifications( + const message_center::NotificationList::Notifications& notifications); + + // views::View: + void Layout() override; + gfx::Size CalculatePreferredSize() const override; + + // message_center::MessageCenterObserver: + void OnNotificationAdded(const std::string& id) override; + void OnNotificationRemoved(const std::string& id, bool by_user) override; + void OnNotificationUpdated(const std::string& id) override; + + // views::ViewObserver: + void OnViewPreferredSizeChanged(views::View* observed_view) override; + + private: + void Update(); + void AddNotificationAt(const message_center::Notification& notification, + int index); + void UpdateNotification(const std::string& notification_id); + + message_center::MessageCenter* message_center_; + + views::ScrollView* const scroller_; + MessageListView* const message_list_view_; + + DISALLOW_COPY_AND_ASSIGN(UnifiedMessageCenterView); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_UNIFIED_UNIFIED_MESSAGE_CENTER_VIEW_H_
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc index 8a1ff06..a5fbbd0 100644 --- a/ash/system/unified/unified_system_tray.cc +++ b/ash/system/unified/unified_system_tray.cc
@@ -7,10 +7,93 @@ #include "ash/system/status_area_widget.h" #include "ash/system/tray/system_tray.h" #include "ash/system/unified/unified_system_tray_bubble.h" +#include "ash/system/web_notification/ash_popup_alignment_delegate.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" +#include "ui/message_center/message_center.h" +#include "ui/message_center/ui_controller.h" +#include "ui/message_center/ui_delegate.h" +#include "ui/message_center/views/message_popup_collection.h" namespace ash { -UnifiedSystemTray::UnifiedSystemTray(Shelf* shelf) : TrayBackgroundView(shelf) { +class UnifiedSystemTray::UiDelegate : public message_center::UiDelegate { + public: + explicit UiDelegate(UnifiedSystemTray* owner); + ~UiDelegate() override; + + // message_center::UiDelegate: + void OnMessageCenterContentsChanged() override; + bool ShowPopups() override; + void HidePopups() override; + bool ShowMessageCenter(bool show_by_click) override; + void HideMessageCenter() override; + bool ShowNotifierSettings() override; + + message_center::UiController* ui_controller() { return ui_controller_.get(); } + + private: + std::unique_ptr<message_center::UiController> ui_controller_; + std::unique_ptr<AshPopupAlignmentDelegate> popup_alignment_delegate_; + std::unique_ptr<message_center::MessagePopupCollection> + message_popup_collection_; + + UnifiedSystemTray* const owner_; + + DISALLOW_COPY_AND_ASSIGN(UiDelegate); +}; + +UnifiedSystemTray::UiDelegate::UiDelegate(UnifiedSystemTray* owner) + : owner_(owner) { + ui_controller_ = std::make_unique<message_center::UiController>(this); + popup_alignment_delegate_ = + std::make_unique<AshPopupAlignmentDelegate>(owner->shelf()); + message_popup_collection_ = + std::make_unique<message_center::MessagePopupCollection>( + message_center::MessageCenter::Get(), ui_controller_.get(), + popup_alignment_delegate_.get()); + display::Screen* screen = display::Screen::GetScreen(); + popup_alignment_delegate_->StartObserving( + screen, screen->GetDisplayNearestWindow( + owner->shelf()->GetStatusAreaWidget()->GetNativeWindow())); +} + +UnifiedSystemTray::UiDelegate::~UiDelegate() = default; + +void UnifiedSystemTray::UiDelegate::OnMessageCenterContentsChanged() { + // TODO(tetsui): Implement. +} + +bool UnifiedSystemTray::UiDelegate::ShowPopups() { + if (owner_->IsBubbleShown()) + return false; + message_popup_collection_->DoUpdate(); + return true; +} + +void UnifiedSystemTray::UiDelegate::HidePopups() { + message_popup_collection_->MarkAllPopupsShown(); +} + +bool UnifiedSystemTray::UiDelegate::ShowMessageCenter(bool show_by_click) { + if (owner_->IsBubbleShown()) + return false; + + owner_->ShowBubbleInternal(); + return true; +} + +void UnifiedSystemTray::UiDelegate::HideMessageCenter() { + owner_->HideBubbleInternal(); +} + +bool UnifiedSystemTray::UiDelegate::ShowNotifierSettings() { + return false; +} + +UnifiedSystemTray::UnifiedSystemTray(Shelf* shelf) + : TrayBackgroundView(shelf), + ui_delegate_(std::make_unique<UiDelegate>(this)) { // On the first step, features in the status area button are still provided by // TrayViews in SystemTray. // TODO(tetsui): Remove SystemTray from StatusAreaWidget and provide these @@ -33,15 +116,14 @@ } void UnifiedSystemTray::ShowBubble(bool show_by_click) { - bubble_ = std::make_unique<UnifiedSystemTrayBubble>(this); - // TODO(tetsui): Call its own SetIsActive. See the comment in the ctor. - shelf()->GetStatusAreaWidget()->system_tray()->SetIsActive(true); + // ShowBubbleInternal will be called from UiDelegate. + if (!bubble_) + ui_delegate_->ui_controller()->ShowMessageCenterBubble(show_by_click); } void UnifiedSystemTray::CloseBubble() { - bubble_.reset(); - // TODO(tetsui): Call its own SetIsActive. See the comment in the ctor. - shelf()->GetStatusAreaWidget()->system_tray()->SetIsActive(false); + // HideBubbleInternal will be called from UiDelegate. + ui_delegate_->ui_controller()->HideMessageCenterBubble(); } base::string16 UnifiedSystemTray::GetAccessibleNameForTray() { @@ -54,4 +136,16 @@ void UnifiedSystemTray::ClickedOutsideBubble() {} +void UnifiedSystemTray::ShowBubbleInternal() { + bubble_ = std::make_unique<UnifiedSystemTrayBubble>(this); + // TODO(tetsui): Call its own SetIsActive. See the comment in the ctor. + shelf()->GetStatusAreaWidget()->system_tray()->SetIsActive(true); +} + +void UnifiedSystemTray::HideBubbleInternal() { + bubble_.reset(); + // TODO(tetsui): Call its own SetIsActive. See the comment in the ctor. + shelf()->GetStatusAreaWidget()->system_tray()->SetIsActive(false); +} + } // namespace ash
diff --git a/ash/system/unified/unified_system_tray.h b/ash/system/unified/unified_system_tray.h index 5da9c8c..48dc0b54 100644 --- a/ash/system/unified/unified_system_tray.h +++ b/ash/system/unified/unified_system_tray.h
@@ -44,6 +44,15 @@ void ClickedOutsideBubble() override; private: + // Private class implements message_center::UiDelegate. + class UiDelegate; + + // Forwarded from UiDelegate. + void ShowBubbleInternal(); + void HideBubbleInternal(); + + std::unique_ptr<UiDelegate> ui_delegate_; + std::unique_ptr<UnifiedSystemTrayBubble> bubble_; DISALLOW_COPY_AND_ASSIGN(UnifiedSystemTray);
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc index b317c6d..c9237b3 100644 --- a/ash/system/unified/unified_system_tray_bubble.cc +++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -13,6 +13,12 @@ namespace ash { +namespace { + +constexpr int kPaddingFromScreenTop = 8; + +} // namespace + UnifiedSystemTrayBubble::UnifiedSystemTrayBubble(UnifiedSystemTray* tray) : controller_(std::make_unique<UnifiedSystemTrayController>( tray->shelf()->GetStatusAreaWidget()->system_tray())), @@ -27,7 +33,12 @@ tray->shelf()->GetSystemTrayAnchor()->GetBubbleAnchor(); auto* bubble_view = new views::TrayBubbleView(init_params); - bubble_view->AddChildView(controller_->CreateView()); + int max_height = + tray->shelf()->GetUserWorkAreaBounds().height() - kPaddingFromScreenTop; + auto* unified_view = controller_->CreateView(); + unified_view->SetMaxHeight(max_height); + bubble_view->SetMaxHeight(max_height); + bubble_view->AddChildView(unified_view); bubble_view->set_anchor_view_insets( tray->shelf()->GetSystemTrayAnchor()->GetBubbleAnchorInsets()); bubble_view->set_color(SK_ColorTRANSPARENT);
diff --git a/ash/system/unified/unified_system_tray_view.cc b/ash/system/unified/unified_system_tray_view.cc index 92c83a8..49cc7733 100644 --- a/ash/system/unified/unified_system_tray_view.cc +++ b/ash/system/unified/unified_system_tray_view.cc
@@ -8,9 +8,11 @@ #include "ash/system/unified/feature_pod_button.h" #include "ash/system/unified/feature_pods_container_view.h" #include "ash/system/unified/top_shortcuts_view.h" +#include "ash/system/unified/unified_message_center_view.h" #include "ash/system/unified/unified_system_info_view.h" #include "ash/system/unified/unified_system_tray_controller.h" #include "ui/app_list/app_list_features.h" +#include "ui/message_center/message_center.h" #include "ui/views/background.h" #include "ui/views/layout/box_layout.h" @@ -62,13 +64,15 @@ UnifiedSystemTrayView::UnifiedSystemTrayView( UnifiedSystemTrayController* controller) : controller_(controller), + message_center_view_( + new UnifiedMessageCenterView(message_center::MessageCenter::Get())), top_shortcuts_view_(new TopShortcutsView(controller_)), feature_pods_container_(new FeaturePodsContainerView()), sliders_container_(new UnifiedSlidersContainerView()), system_info_view_(new UnifiedSystemInfoView()) { DCHECK(controller_); - SetLayoutManager( + auto* layout = SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); SetBackground( @@ -78,14 +82,20 @@ SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); + AddChildView(message_center_view_); AddChildView(top_shortcuts_view_); AddChildView(feature_pods_container_); AddChildView(sliders_container_); AddChildView(system_info_view_); + layout->SetFlexForView(message_center_view_, 1); } UnifiedSystemTrayView::~UnifiedSystemTrayView() = default; +void UnifiedSystemTrayView::SetMaxHeight(int max_height) { + message_center_view_->SetMaxHeight(max_height); +} + void UnifiedSystemTrayView::AddFeaturePodButton(FeaturePodButton* button) { feature_pods_container_->AddChildView(button); } @@ -103,6 +113,9 @@ feature_pods_container_->SetExpandedAmount(expanded_amount); sliders_container_->SetExpandedAmount(expanded_amount); PreferredSizeChanged(); + // It is possible that the ratio between |message_center_view_| and others + // can change while the bubble size remain unchanged. + Layout(); } void UnifiedSystemTrayView::OnGestureEvent(ui::GestureEvent* event) {
diff --git a/ash/system/unified/unified_system_tray_view.h b/ash/system/unified/unified_system_tray_view.h index 8cefd69..6fce556 100644 --- a/ash/system/unified/unified_system_tray_view.h +++ b/ash/system/unified/unified_system_tray_view.h
@@ -12,6 +12,7 @@ class FeaturePodButton; class FeaturePodsContainerView; class TopShortcutsView; +class UnifiedMessageCenterView; class UnifiedSystemInfoView; class UnifiedSystemTrayController; @@ -46,6 +47,9 @@ explicit UnifiedSystemTrayView(UnifiedSystemTrayController* controller); ~UnifiedSystemTrayView() override; + // Set the maximum height that the view can take. + void SetMaxHeight(int max_height); + // Add feature pod button to |feature_pods_|. void AddFeaturePodButton(FeaturePodButton* button); @@ -64,6 +68,7 @@ UnifiedSystemTrayController* controller_; // Owned by views hierarchy. + UnifiedMessageCenterView* message_center_view_; TopShortcutsView* top_shortcuts_view_; FeaturePodsContainerView* feature_pods_container_; UnifiedSlidersContainerView* sliders_container_;
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 9112db8..5f82389 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -409,6 +409,18 @@ session_controller_client->SetSessionState(SessionState::ACTIVE); } +void AshTestBase::SimulateNewUserFirstLogin(const std::string& user_email) { + TestSessionControllerClient* const session_controller_client = + GetSessionControllerClient(); + session_controller_client->AddUserSession( + user_email, user_manager::USER_TYPE_REGULAR, true /* enable_settings */, + true /* provide_pref_service */, true /* is_new_profile */); + session_controller_client->SwitchActiveUser( + AccountId::FromUserEmail(user_email)); + session_controller_client->SetSessionState( + session_manager::SessionState::ACTIVE); +} + void AshTestBase::SimulateGuestLogin() { const std::string guest = user_manager::kGuestUserName; TestSessionControllerClient* session = GetSessionControllerClient();
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index b88122a..141af950 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h
@@ -189,6 +189,9 @@ // existing user sessions and makes it the active user session. void SimulateUserLogin(const std::string& user_email); + // Simular to SimulateUserLogin but for a newly created user first ever login. + void SimulateNewUserFirstLogin(const std::string& user_email); + // Similar to SimulateUserLogin but for a guest user. void SimulateGuestLogin();
diff --git a/ash/touch/touch_devices_controller.cc b/ash/touch/touch_devices_controller.cc index 36c2a75..8ad098d 100644 --- a/ash/touch/touch_devices_controller.cc +++ b/ash/touch/touch_devices_controller.cc
@@ -52,20 +52,12 @@ } // namespace // static -void TouchDevicesController::RegisterProfilePrefs(PrefRegistrySimple* registry, - bool for_test) { - if (for_test) { - // In tests there is no remote pref service. Make ash own the prefs. - registry->RegisterBooleanPref( - prefs::kTapDraggingEnabled, false, - user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF | - PrefRegistry::PUBLIC); - } else { - // In production the prefs are owned by chrome. - // TODO: Move ownership to ash. - registry->RegisterForeignPref(prefs::kTapDraggingEnabled); - } - +void TouchDevicesController::RegisterProfilePrefs( + PrefRegistrySimple* registry) { + registry->RegisterBooleanPref( + prefs::kTapDraggingEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF | + PrefRegistry::PUBLIC); registry->RegisterBooleanPref(prefs::kTouchpadEnabled, PrefRegistry::PUBLIC); registry->RegisterBooleanPref(prefs::kTouchscreenEnabled, PrefRegistry::PUBLIC);
diff --git a/ash/touch/touch_devices_controller.h b/ash/touch/touch_devices_controller.h index 131dc537..0bbe4590 100644 --- a/ash/touch/touch_devices_controller.h +++ b/ash/touch/touch_devices_controller.h
@@ -33,7 +33,7 @@ TouchDevicesController(); ~TouchDevicesController() override; - static void RegisterProfilePrefs(PrefRegistrySimple* registry, bool for_test); + static void RegisterProfilePrefs(PrefRegistrySimple* registry); // Toggles the status of touchpad between enabled and disabled. void ToggleTouchpad();
diff --git a/base/BUILD.gn b/base/BUILD.gn index d235a66..463fa3e3 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -21,7 +21,6 @@ import("//build/config/allocator.gni") import("//build/config/arm.gni") import("//build/config/chromecast_build.gni") -import("//build/config/clang/clang.gni") import("//build/config/compiler/compiler.gni") import("//build/config/dcheck_always_on.gni") import("//build/config/jumbo.gni") @@ -1162,6 +1161,7 @@ all_dependent_configs = [] defines = [] data = [] + data_deps = [] configs += [ ":base_flags", @@ -1486,79 +1486,12 @@ "//base/win:base_win_buildflags", ] + data_deps += [ "//build/win:runtime_libs" ] + if (com_init_check_hook_disabled) { defines += [ "COM_INIT_CHECK_HOOK_DISABLED" ] } - if (is_component_build) { - # Copy the VS runtime DLLs into the isolate so that they don't have to be - # preinstalled on the target machine. The debug runtimes have a "d" at - # the end. - if (is_debug) { - vcrt_suffix = "d" - } else { - vcrt_suffix = "" - } - - # These runtime files are copied to the output directory by the - # vs_toolchain script that runs as part of toolchain configuration. - data += [ - "$root_out_dir/msvcp140${vcrt_suffix}.dll", - "$root_out_dir/vccorlib140${vcrt_suffix}.dll", - "$root_out_dir/vcruntime140${vcrt_suffix}.dll", - - # Universal Windows 10 CRT files - "$root_out_dir/api-ms-win-core-console-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-datetime-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-debug-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-errorhandling-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-file-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-file-l1-2-0.dll", - "$root_out_dir/api-ms-win-core-file-l2-1-0.dll", - "$root_out_dir/api-ms-win-core-handle-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-heap-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-interlocked-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-libraryloader-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-localization-l1-2-0.dll", - "$root_out_dir/api-ms-win-core-memory-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-namedpipe-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-processenvironment-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-processthreads-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-processthreads-l1-1-1.dll", - "$root_out_dir/api-ms-win-core-profile-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-rtlsupport-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-string-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-synch-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-synch-l1-2-0.dll", - "$root_out_dir/api-ms-win-core-sysinfo-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-timezone-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-util-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-conio-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-convert-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-environment-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-filesystem-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-heap-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-locale-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-math-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-multibyte-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-private-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-process-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-runtime-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-stdio-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-string-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-time-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-utility-l1-1-0.dll", - "$root_out_dir/ucrtbase${vcrt_suffix}.dll", - ] - if (is_asan) { - if (current_cpu == "x64") { - data += [ "$clang_base_path/lib/clang/$clang_version/lib/windows/clang_rt.asan_dynamic-x86_64.dll" ] - } else { - data += [ "$clang_base_path/lib/clang/$clang_version/lib/windows/clang_rt.asan_dynamic-i386.dll" ] - } - } - } - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
diff --git a/base/files/file_descriptor_watcher_posix.h b/base/files/file_descriptor_watcher_posix.h index 6cc011bb..5a8a4dc5 100644 --- a/base/files/file_descriptor_watcher_posix.h +++ b/base/files/file_descriptor_watcher_posix.h
@@ -79,12 +79,13 @@ FileDescriptorWatcher(MessageLoopForIO* message_loop_for_io); ~FileDescriptorWatcher(); - // Registers |callback| to be invoked on the current sequence when |fd| is + // Registers |callback| to be posted on the current sequence when |fd| is // readable or writable without blocking. |callback| is unregistered when the // returned Controller is deleted (deletion must happen on the current // sequence). To call these methods, a FileDescriptorWatcher must have been // instantiated on the current thread and SequencedTaskRunnerHandle::IsSet() - // must return true. + // must return true (these conditions are met at least on all TaskScheduler + // threads as well as on threads backed by a MessageLoopForIO). static std::unique_ptr<Controller> WatchReadable(int fd, const Closure& callback); static std::unique_ptr<Controller> WatchWritable(int fd,
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index 2a348182..3cdff60 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -103,14 +103,12 @@ } if (S_ISLNK(stat_info.st_mode)) { - DLOG(ERROR) << "Path " << path.value() - << " is a symbolic link."; + DLOG(ERROR) << "Path " << path.value() << " is a symbolic link."; return false; } if (stat_info.st_uid != owner_uid) { - DLOG(ERROR) << "Path " << path.value() - << " is owned by the wrong user."; + DLOG(ERROR) << "Path " << path.value() << " is owned by the wrong user."; return false; } @@ -122,8 +120,7 @@ } if (stat_info.st_mode & S_IWOTH) { - DLOG(ERROR) << "Path " << path.value() - << " is writable by any user."; + DLOG(ERROR) << "Path " << path.value() << " is writable by any user."; return false; } @@ -227,15 +224,13 @@ // This function does not properly handle destinations within the source FilePath real_to_path = to_path; - if (PathExists(real_to_path)) { + if (PathExists(real_to_path)) real_to_path = MakeAbsoluteFilePath(real_to_path); - if (real_to_path.empty()) - return false; - } else { + else real_to_path = MakeAbsoluteFilePath(real_to_path.DirName()); - if (real_to_path.empty()) - return false; - } + if (real_to_path.empty()) + return false; + FilePath real_from_path = MakeAbsoluteFilePath(from_path); if (real_from_path.empty()) return false; @@ -1064,17 +1059,15 @@ bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { AssertBlockingAllowed(); - // Windows compatibility: if to_path exists, from_path and to_path + // Windows compatibility: if |to_path| exists, |from_path| and |to_path| // must be the same type, either both files, or both directories. stat_wrapper_t to_file_info; if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { stat_wrapper_t from_file_info; - if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { - if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) - return false; - } else { + if (CallStat(from_path.value().c_str(), &from_file_info) != 0) return false; - } + if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) + return false; } if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
diff --git a/base/metrics/OWNERS b/base/metrics/OWNERS index 2f98bde4..4cc69ff 100644 --- a/base/metrics/OWNERS +++ b/base/metrics/OWNERS
@@ -1,4 +1,5 @@ asvitkine@chromium.org +bcwhite@chromium.org gayane@chromium.org holte@chromium.org isherman@chromium.org
diff --git a/base/metrics/persistent_histogram_storage.cc b/base/metrics/persistent_histogram_storage.cc index 20922888..0676e47 100644 --- a/base/metrics/persistent_histogram_storage.cc +++ b/base/metrics/persistent_histogram_storage.cc
@@ -24,8 +24,8 @@ PersistentHistogramStorage::PersistentHistogramStorage( StringPiece allocator_name, - StorageDirCreation storage_dir_create_action) - : storage_dir_create_action_(storage_dir_create_action) { + StorageDirManagement storage_dir_management) + : storage_dir_management_(storage_dir_management) { DCHECK(!allocator_name.empty()); DCHECK(IsStringASCII(allocator_name)); @@ -53,8 +53,8 @@ FilePath storage_dir = storage_base_dir_.AppendASCII(allocator->Name()); - switch (storage_dir_create_action_) { - case StorageDirCreation::kEnable: + switch (storage_dir_management_) { + case StorageDirManagement::kCreate: if (!CreateDirectory(storage_dir)) { LOG(ERROR) << "Could not write \"" << allocator->Name() @@ -63,11 +63,11 @@ return; } break; - case StorageDirCreation::kDisable: + case StorageDirManagement::kUseExisting: if (!DirectoryExists(storage_dir)) { - // When the consumer of this class disables storage directory creation - // by the class instance, it should ensure the directory's existence if - // it's essential. + // When the consumer of this class decides to use an existing storage + // directory, it should ensure the directory's existence if it's + // essential. LOG(ERROR) << "Could not write \"" << allocator->Name() << "\" persistent histograms to file as the storage directory "
diff --git a/base/metrics/persistent_histogram_storage.h b/base/metrics/persistent_histogram_storage.h index e101a2605..397236dd 100644 --- a/base/metrics/persistent_histogram_storage.h +++ b/base/metrics/persistent_histogram_storage.h
@@ -22,7 +22,7 @@ // Persisted histograms will eventually be reported by Chrome. class BASE_EXPORT PersistentHistogramStorage { public: - enum class StorageDirCreation { kEnable, kDisable }; + enum class StorageDirManagement { kCreate, kUseExisting }; // Creates a process-wide storage location for histograms that will be written // to a file within a directory provided by |set_storage_base_dir()| on @@ -30,11 +30,10 @@ // The |allocator_name| is used both as an internal name for the allocator, // well as the leaf directory name for the file to which the histograms are // persisted. The string must be ASCII. - // |storage_dir_create_action| determines that if this instance is - // responsible for creating the storage directory. If kDisable is supplied, - // it's the consumer's responsibility to create the storage directory. + // |storage_dir_management| specifies if this instance reuses an existing + // storage directory, or is responsible for creating one. PersistentHistogramStorage(StringPiece allocator_name, - StorageDirCreation storage_dir_create_action); + StorageDirManagement storage_dir_management); ~PersistentHistogramStorage(); @@ -53,9 +52,8 @@ // |storage_base_dir_|/|allocator_name| (see the ctor for allocator_name). FilePath storage_base_dir_; - // A flag indicating if the class instance is responsible for creating the - // storage directory. - const StorageDirCreation storage_dir_create_action_; + // The setting of the storage directory management. + const StorageDirManagement storage_dir_management_; // A flag indicating if histogram storage is disabled. It starts with false, // but can be set to true by the caller who decides to throw away its
diff --git a/base/metrics/persistent_histogram_storage_unittest.cc b/base/metrics/persistent_histogram_storage_unittest.cc index 4a9b34b..adbcdfc 100644 --- a/base/metrics/persistent_histogram_storage_unittest.cc +++ b/base/metrics/persistent_histogram_storage_unittest.cc
@@ -55,7 +55,7 @@ auto persistent_histogram_storage = std::make_unique<PersistentHistogramStorage>( kTestHistogramAllocatorName, - PersistentHistogramStorage::StorageDirCreation::kEnable); + PersistentHistogramStorage::StorageDirManagement::kCreate); persistent_histogram_storage->set_storage_base_dir(temp_dir_path());
diff --git a/base/threading/post_task_and_reply_impl.cc b/base/threading/post_task_and_reply_impl.cc index 4eba45a..7a85d180 100644 --- a/base/threading/post_task_and_reply_impl.cc +++ b/base/threading/post_task_and_reply_impl.cc
@@ -10,7 +10,6 @@ #include "base/debug/leak_annotations.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" @@ -18,56 +17,87 @@ namespace { -// This relay class remembers the sequence that it was created on, and ensures -// that both the |task| and |reply| Closures are deleted on this same sequence. -// Also, |task| is guaranteed to be deleted before |reply| is run or deleted. -// -// If RunReplyAndSelfDestruct() doesn't run because the originating execution -// context is no longer available, then the |task| and |reply| Closures are -// leaked. Leaking is considered preferable to having a thread-safetey -// violations caused by invoking the Closure destructor on the wrong sequence. class PostTaskAndReplyRelay { public: PostTaskAndReplyRelay(const Location& from_here, OnceClosure task, OnceClosure reply) - : sequence_checker_(), - from_here_(from_here), - origin_task_runner_(SequencedTaskRunnerHandle::Get()), - reply_(std::move(reply)), - task_(std::move(task)) {} + : from_here_(from_here), + task_(std::move(task)), + reply_(std::move(reply)) {} + PostTaskAndReplyRelay(PostTaskAndReplyRelay&&) = default; ~PostTaskAndReplyRelay() { - DCHECK(sequence_checker_.CalledOnValidSequence()); + // This destructor can run: + // 1) On origin sequence, when: + // 1a) Posting |task_| fails. + // 1b) |reply_| is cancelled before running. + // 1c) |reply_| completes. + // 2) On destination sequence, when: + // 2a) |task_| is cancelled before running. + // 2b) Posting |reply_| fails. + + // |task_| can still be alive if the destination task runner was no longer + // accepting tasks or if it was cancelled before being run. Destroy it ahead + // of |reply_| to keep happens-before expectations sane. |task_| can be + // safely destroyed on origin or destination sequence per being constructed + // on the former and designed to be ran on the latter. + DCHECK(task_.is_null() || !reply_.is_null()); + task_.Reset(); + + if (reply_) { + if (reply_task_runner_->RunsTasksInCurrentSequence()) { + // Case 1a) or 1b). + reply_.Reset(); + } else { + // Case 2a) or 2b). + // Destroy |reply_| asynchronously on |reply_task_runner_| since it can + // rightfully be affine to it. As always, DeleteSoon() might leak its + // argument if the target execution environment is shutdown (e.g. + // MessageLoop deleted, TaskScheduler shutdown). + auto reply_to_delete = std::make_unique<OnceClosure>(std::move(reply_)); + ANNOTATE_LEAKING_OBJECT_PTR(reply_to_delete.get()); + reply_task_runner_->DeleteSoon(from_here_, std::move(reply_to_delete)); + } + } } - void RunTaskAndPostReply() { - std::move(task_).Run(); - origin_task_runner_->PostTask( - from_here_, BindOnce(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct, - base::Unretained(this))); + // No assignment operator because of const members. + PostTaskAndReplyRelay& operator=(PostTaskAndReplyRelay&&) = delete; + + // Static function is used because it is not possible to bind a method call to + // a non-pointer type. + static void RunTaskAndPostReply(PostTaskAndReplyRelay relay) { + DCHECK(relay.task_); + std::move(relay.task_).Run(); + + // Keep a reference to the reply TaskRunner for the PostTask() call before + // |relay| is moved into a callback. + scoped_refptr<SequencedTaskRunner> reply_task_runner = + relay.reply_task_runner_; + + reply_task_runner->PostTask( + relay.from_here_, + BindOnce(&PostTaskAndReplyRelay::RunReply, std::move(relay))); } private: - void RunReplyAndSelfDestruct() { - DCHECK(sequence_checker_.CalledOnValidSequence()); - - // Ensure |task_| has already been released before |reply_| to ensure that - // no one accidentally depends on |task_| keeping one of its arguments alive - // while |reply_| is executing. - DCHECK(!task_); - - std::move(reply_).Run(); - - // Cue mission impossible theme. - delete this; + // Static function is used because it is not possible to bind a method call to + // a non-pointer type. + static void RunReply(PostTaskAndReplyRelay relay) { + DCHECK(!relay.task_); + DCHECK(relay.reply_); + // Case 1c). + std::move(relay.reply_).Run(); } - const SequenceChecker sequence_checker_; const Location from_here_; - const scoped_refptr<SequencedTaskRunner> origin_task_runner_; - OnceClosure reply_; OnceClosure task_; + OnceClosure reply_; + const scoped_refptr<SequencedTaskRunner> reply_task_runner_ = + SequencedTaskRunnerHandle::Get(); + + DISALLOW_COPY_AND_ASSIGN(PostTaskAndReplyRelay); }; } // namespace @@ -77,23 +107,13 @@ bool PostTaskAndReplyImpl::PostTaskAndReply(const Location& from_here, OnceClosure task, OnceClosure reply) { - DCHECK(!task.is_null()) << from_here.ToString(); - DCHECK(!reply.is_null()) << from_here.ToString(); - PostTaskAndReplyRelay* relay = - new PostTaskAndReplyRelay(from_here, std::move(task), std::move(reply)); - // PostTaskAndReplyRelay self-destructs after executing |reply|. On the flip - // side though, it is intentionally leaked if the |task| doesn't complete - // before the origin sequence stops executing tasks. Annotate |relay| as leaky - // to avoid having to suppress every callsite which happens to flakily trigger - // this race. - ANNOTATE_LEAKING_OBJECT_PTR(relay); - if (!PostTask(from_here, BindOnce(&PostTaskAndReplyRelay::RunTaskAndPostReply, - Unretained(relay)))) { - delete relay; - return false; - } + DCHECK(task) << from_here.ToString(); + DCHECK(reply) << from_here.ToString(); - return true; + return PostTask(from_here, + BindOnce(&PostTaskAndReplyRelay::RunTaskAndPostReply, + PostTaskAndReplyRelay(from_here, std::move(task), + std::move(reply)))); } } // namespace internal
diff --git a/base/threading/post_task_and_reply_impl.h b/base/threading/post_task_and_reply_impl.h index 696a655..02eb27bd 100644 --- a/base/threading/post_task_and_reply_impl.h +++ b/base/threading/post_task_and_reply_impl.h
@@ -18,17 +18,17 @@ // custom execution context. // // If you're looking for a concrete implementation of PostTaskAndReply, you -// probably want base::TaskRunner. -// -// TODO(fdoray): Move this to the anonymous namespace of base/task_runner.cc. +// probably want base::TaskRunner or base/task_scheduler/post_task.h class BASE_EXPORT PostTaskAndReplyImpl { public: virtual ~PostTaskAndReplyImpl() = default; - // Posts |task| by calling PostTask(). On completion, |reply| is posted to the - // sequence or thread that called this. Can only be called when - // SequencedTaskRunnerHandle::IsSet(). Both |task| and |reply| are guaranteed - // to be deleted on the sequence or thread that called this. + // Posts |task| by calling PostTask(). On completion, posts |reply| to the + // sequence that called this. Can only be called when + // SequencedTaskRunnerHandle::IsSet(). |task| is deleted on the target + // TaskRunner or on the sequence that called this. |reply| is deleted on the + // sequence that called this, or leaked if it can't be deleted before the + // sequence stops accepting tasks. bool PostTaskAndReply(const Location& from_here, OnceClosure task, OnceClosure reply);
diff --git a/base/threading/post_task_and_reply_impl_unittest.cc b/base/threading/post_task_and_reply_impl_unittest.cc index 6678c95..a0edfd6 100644 --- a/base/threading/post_task_and_reply_impl_unittest.cc +++ b/base/threading/post_task_and_reply_impl_unittest.cc
@@ -10,8 +10,7 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/test/test_mock_time_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -57,53 +56,94 @@ MockObject() = default; MOCK_METHOD1(Task, void(scoped_refptr<ObjectToDelete>)); - MOCK_METHOD0(Reply, void()); + MOCK_METHOD1(Reply, void(scoped_refptr<ObjectToDelete>)); private: DISALLOW_COPY_AND_ASSIGN(MockObject); }; +class PostTaskAndReplyImplTest : public testing::Test { + protected: + PostTaskAndReplyImplTest() = default; + + void PostTaskAndReplyToMockObject() { + // Expect the post to succeed. + EXPECT_TRUE( + PostTaskAndReplyTaskRunner(post_runner_.get()) + .PostTaskAndReply( + FROM_HERE, + BindOnce(&MockObject::Task, Unretained(&mock_object_), + MakeRefCounted<ObjectToDelete>(&delete_task_flag_)), + BindOnce(&MockObject::Reply, Unretained(&mock_object_), + MakeRefCounted<ObjectToDelete>(&delete_reply_flag_)))); + + // Expect the first task to be posted to |post_runner_|. + EXPECT_TRUE(post_runner_->HasPendingTask()); + EXPECT_FALSE(reply_runner_->HasPendingTask()); + EXPECT_FALSE(delete_task_flag_); + EXPECT_FALSE(delete_reply_flag_); + } + + scoped_refptr<TestMockTimeTaskRunner> post_runner_ = + MakeRefCounted<TestMockTimeTaskRunner>(); + scoped_refptr<TestMockTimeTaskRunner> reply_runner_ = + MakeRefCounted<TestMockTimeTaskRunner>( + TestMockTimeTaskRunner::Type::kBoundToThread); + testing::StrictMock<MockObject> mock_object_; + bool delete_task_flag_ = false; + bool delete_reply_flag_ = false; + + private: + DISALLOW_COPY_AND_ASSIGN(PostTaskAndReplyImplTest); +}; + } // namespace -TEST(PostTaskAndReplyImplTest, PostTaskAndReply) { - scoped_refptr<TestSimpleTaskRunner> post_runner(new TestSimpleTaskRunner); - scoped_refptr<TestSimpleTaskRunner> reply_runner(new TestSimpleTaskRunner); - ThreadTaskRunnerHandle task_runner_handle(reply_runner); +TEST_F(PostTaskAndReplyImplTest, PostTaskAndReply) { + PostTaskAndReplyToMockObject(); - testing::StrictMock<MockObject> mock_object; - bool delete_flag = false; + EXPECT_CALL(mock_object_, Task(_)); + post_runner_->RunUntilIdle(); + testing::Mock::VerifyAndClear(&mock_object_); + // The task should have been deleted right after being run. + EXPECT_TRUE(delete_task_flag_); + EXPECT_FALSE(delete_reply_flag_); - EXPECT_TRUE(PostTaskAndReplyTaskRunner(post_runner.get()) - .PostTaskAndReply( - FROM_HERE, - BindOnce(&MockObject::Task, Unretained(&mock_object), - MakeRefCounted<ObjectToDelete>(&delete_flag)), - BindOnce(&MockObject::Reply, Unretained(&mock_object)))); + // Expect the reply to be posted to |reply_runner_|. + EXPECT_FALSE(post_runner_->HasPendingTask()); + EXPECT_TRUE(reply_runner_->HasPendingTask()); - // Expect the task to be posted to |post_runner|. - EXPECT_TRUE(post_runner->HasPendingTask()); - EXPECT_FALSE(reply_runner->HasPendingTask()); - EXPECT_FALSE(delete_flag); + EXPECT_CALL(mock_object_, Reply(_)); + reply_runner_->RunUntilIdle(); + testing::Mock::VerifyAndClear(&mock_object_); + EXPECT_TRUE(delete_task_flag_); + // The reply should have been deleted right after being run. + EXPECT_TRUE(delete_reply_flag_); - EXPECT_CALL(mock_object, Task(_)); - post_runner->RunUntilIdle(); - testing::Mock::VerifyAndClear(&mock_object); + // Expect no pending task in |post_runner_| and |reply_runner_|. + EXPECT_FALSE(post_runner_->HasPendingTask()); + EXPECT_FALSE(reply_runner_->HasPendingTask()); +} - // |task| should have been deleted right after being run. - EXPECT_TRUE(delete_flag); +TEST_F(PostTaskAndReplyImplTest, PostTaskAndReplyDoesNotRun) { + PostTaskAndReplyToMockObject(); - // Expect the reply to be posted to |reply_runner|. - EXPECT_FALSE(post_runner->HasPendingTask()); - EXPECT_TRUE(reply_runner->HasPendingTask()); + EXPECT_CALL(mock_object_, Task(_)); + post_runner_->RunUntilIdle(); + testing::Mock::VerifyAndClear(&mock_object_); + // The task should have been deleted right after being run. + EXPECT_TRUE(delete_task_flag_); + EXPECT_FALSE(delete_reply_flag_); - EXPECT_CALL(mock_object, Reply()); - reply_runner->RunUntilIdle(); - testing::Mock::VerifyAndClear(&mock_object); - EXPECT_TRUE(delete_flag); + // Expect the reply to be posted to |reply_runner_|. + EXPECT_FALSE(post_runner_->HasPendingTask()); + EXPECT_TRUE(reply_runner_->HasPendingTask()); - // Expect no pending task in |post_runner| and |reply_runner|. - EXPECT_FALSE(post_runner->HasPendingTask()); - EXPECT_FALSE(reply_runner->HasPendingTask()); + // Clear the |reply_runner_| queue without running tasks. The reply callback + // should be deleted. + reply_runner_->ClearPendingTasks(); + EXPECT_TRUE(delete_task_flag_); + EXPECT_TRUE(delete_reply_flag_); } } // namespace internal
diff --git a/base/trace_event/cfi_backtrace_android.cc b/base/trace_event/cfi_backtrace_android.cc index 3859eb1..8fd8b955 100644 --- a/base/trace_event/cfi_backtrace_android.cc +++ b/base/trace_event/cfi_backtrace_android.cc
@@ -114,7 +114,7 @@ } // namespace // static -CFIBacktraceAndroid* CFIBacktraceAndroid::GetInstance() { +CFIBacktraceAndroid* CFIBacktraceAndroid::GetInitializedInstance() { static CFIBacktraceAndroid* instance = new CFIBacktraceAndroid(); return instance; } @@ -138,7 +138,7 @@ executable_start_addr_ = reinterpret_cast<uintptr_t>(&__executable_start); // This file name is defined by extract_unwind_tables.gni. - static constexpr char kCfiFileName[] = "assets/unwind_cfi"; + static constexpr char kCfiFileName[] = "assets/unwind_cfi_32"; MemoryMappedFile::Region cfi_region; int fd = base::android::OpenApkAsset(kCfiFileName, &cfi_region); if (fd < 0)
diff --git a/base/trace_event/cfi_backtrace_android.h b/base/trace_event/cfi_backtrace_android.h index 5e969787..0c513321 100644 --- a/base/trace_event/cfi_backtrace_android.h +++ b/base/trace_event/cfi_backtrace_android.h
@@ -31,8 +31,9 @@ // data. class BASE_EXPORT CFIBacktraceAndroid { public: - // Creates and initializes the unwinder on first call. - static CFIBacktraceAndroid* GetInstance(); + // Creates and initializes by memory mapping the unwind tables from apk assets + // on first call. + static CFIBacktraceAndroid* GetInitializedInstance(); // Returns true if stack unwinding is possible using CFI unwind tables in apk. // There is no need to check this before each unwind call. Will always return
diff --git a/base/trace_event/cfi_backtrace_android_unittest.cc b/base/trace_event/cfi_backtrace_android_unittest.cc index 365749a..b3a0d81 100644 --- a/base/trace_event/cfi_backtrace_android_unittest.cc +++ b/base/trace_event/cfi_backtrace_android_unittest.cc
@@ -19,7 +19,7 @@ } // namespace TEST(CFIBacktraceAndroidTest, TestUnwinding) { - auto* unwinder = CFIBacktraceAndroid::GetInstance(); + auto* unwinder = CFIBacktraceAndroid::GetInitializedInstance(); EXPECT_TRUE(unwinder->can_unwind_stack_frames()); EXPECT_GT(unwinder->executable_start_addr_, 0u); EXPECT_GT(unwinder->executable_end_addr_, unwinder->executable_start_addr_); @@ -46,7 +46,7 @@ } TEST(CFIBacktraceAndroidTest, TestFindCFIRow) { - auto* unwinder = CFIBacktraceAndroid::GetInstance(); + auto* unwinder = CFIBacktraceAndroid::GetInitializedInstance(); /* Input is generated from the CFI file: STACK CFI INIT 1000 500 STACK CFI 1002 .cfa: sp 272 + .ra: .cfa -4 + ^ r4: .cfa -16 +
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc index eb5f128..556719e 100644 --- a/base/trace_event/heap_profiler_allocation_context_tracker.cc +++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc
@@ -223,8 +223,9 @@ const void* frames[Backtrace::kMaxFrameCount + 1]; static_assert(arraysize(frames) >= Backtrace::kMaxFrameCount, "not requesting enough frames to fill Backtrace"); - size_t frame_count = CFIBacktraceAndroid::GetInstance()->Unwind( - frames, arraysize(frames)); + size_t frame_count = + CFIBacktraceAndroid::GetInitializedInstance()->Unwind( + frames, arraysize(frames)); #elif BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) const void* frames[Backtrace::kMaxFrameCount + 1]; static_assert(arraysize(frames) >= Backtrace::kMaxFrameCount,
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 2514536..dfea78a 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -280,8 +280,8 @@ case kHeapProfilingModeNative: #if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) { - bool can_unwind = - CFIBacktraceAndroid::GetInstance()->can_unwind_stack_frames(); + bool can_unwind = CFIBacktraceAndroid::GetInitializedInstance() + ->can_unwind_stack_frames(); DCHECK(can_unwind); } #endif
diff --git a/build/config/android/extract_unwind_tables.gni b/build/config/android/extract_unwind_tables.gni index 8c34f91b..d0b0532 100644 --- a/build/config/android/extract_unwind_tables.gni +++ b/build/config/android/extract_unwind_tables.gni
@@ -5,8 +5,9 @@ import("//build/config/android/rules.gni") template("unwind_table_asset") { + # Note: This file name is used in multiple monochrome build scripts. + _asset_path = "${target_gen_dir}/${target_name}/unwind_cfi_32" _unwind_action = "${target_name}__extract" - _asset_path = "${target_gen_dir}/${target_name}/unwind_cfi" action(_unwind_action) { if (defined(invoker.testonly)) {
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 11f099d9..9c7bc781 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -221,10 +221,20 @@ # In general, Windows is totally different, but all the other builds share # some common GCC configuration. if (!is_win) { - # Common GCC compiler flags setup. + # Common POSIX compiler flags setup. # -------------------------------- cflags += [ "-fno-strict-aliasing" ] # See http://crbug.com/32204 + if (is_clang) { + # Enable -fmerge-all-constants. This used to be the default in clang + # for over a decade. It makes clang non-conforming, but is fairly safe + # in practice and saves some binary size. We might want to consider + # disabling this (https://bugs.llvm.org/show_bug.cgi?id=18538#c13), + # but for now it looks like our build might rely on it + # (https://crbug.com/829795). + cflags += [ "-fmerge-all-constants" ] + } + # Stack protection. if (is_mac) { # The strong variant of the stack protector significantly increases @@ -1525,9 +1535,9 @@ # thin_archive ----------------------------------------------------------------- # # Enables thin archives on posix. Regular archives directly include the object -# fiels used to generate it. Thin archives merely reference the object files. -# This makes building them faster since it requires less disk IO, but is in -# appropriate if you wish to redistribute your static library. +# files used to generate it. Thin archives merely reference the object files. +# This makes building them faster since it requires less disk IO, but is +# inappropriate if you wish to redistribute your static library. # This config is added to the global config, so thin archives should already be # enabled. If you want to make a distributable static library, you need to do 2 # things: @@ -1537,12 +1547,10 @@ # .o files, instead of just references to .o files in the build directoy config("thin_archive") { if (is_posix && !is_nacl) { - # TODO(thomasanderson): Remove !is_clang conditional once llvm-ar supports - # multiple dashed flags. - if (!is_clang) { - # TODO(thomasanderson): Introduce -T once :thin_archive is removed from - # all third_party repos where appropriate. - # arflags = [ "-T" ] + # TODO(thomasanderson): Enable on ChromeOS builds once + # https://crbug.com/829956 is fixed. + if (default_toolchain != "//build/toolchain/cros:target") { + arflags = [ "-T" ] } } }
diff --git a/build/toolchain/gcc_ar_wrapper.py b/build/toolchain/gcc_ar_wrapper.py index 893b859f..5977f44 100755 --- a/build/toolchain/gcc_ar_wrapper.py +++ b/build/toolchain/gcc_ar_wrapper.py
@@ -57,7 +57,7 @@ wrapper_utils.CombineResourceWhitelists( whitelist_candidates, args.resource_whitelist) - command = [args.ar] + object_mode + [args.operation] + command = [args.ar] + object_mode + args.operation.split() if args.plugin is not None: command += ['--plugin', args.plugin] command.append(args.output)
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 89d5969..48fbf699 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -334,13 +334,21 @@ # POSIX-like toolchains such as NaCl on Windows). ar_wrapper = rebase_path("//build/toolchain/gcc_ar_wrapper.py", root_build_dir) - if (current_os == "aix") { - # We use slightly different arflags for AIX. - extra_arflags = "rcsT" - } else { + + # TODO(thomasanderson): Remove the special ChromeOS case once + # https://crbug.com/829956 is fixed. + if (default_toolchain == "//build/toolchain/cros:target") { extra_arflags = "rcsD" + } else if (current_os == "aix") { + # We use slightly different arflags for AIX. + extra_arflags = "-r -c -s" + } else { + extra_arflags = "-r -c -s -D" } - command = "$python_path \"$ar_wrapper\"$whitelist_flag --output={{output}} --ar=\"$ar\" {{arflags}} $extra_arflags @\"$rspfile\"" + + # Almost all targets build with //build/config/compiler:thin_archive which + # adds -T to arflags. + command = "$python_path \"$ar_wrapper\"$whitelist_flag --output={{output}} --ar=\"$ar\" \"{{arflags}} $extra_arflags\" @\"$rspfile\"" description = "AR {{output}}" rspfile_content = "{{inputs}}" outputs = [
diff --git a/build/win/BUILD.gn b/build/win/BUILD.gn index 20a555d..320ee7a 100644 --- a/build/win/BUILD.gn +++ b/build/win/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/clang/clang.gni") +import("//build/config/sanitizers/sanitizers.gni") import("//build/config/win/manifest.gni") # Depending on this target will cause the manifests for Chrome's default @@ -77,4 +79,75 @@ current_cpu, ] } + + group("runtime_libs") { + if (is_component_build) { + # Copy the VS runtime DLLs into the isolate so that they don't have to be + # preinstalled on the target machine. The debug runtimes have a "d" at + # the end. + if (is_debug) { + vcrt_suffix = "d" + } else { + vcrt_suffix = "" + } + + # These runtime files are copied to the output directory by the + # vs_toolchain script that runs as part of toolchain configuration. + data = [ + "$root_out_dir/msvcp140${vcrt_suffix}.dll", + "$root_out_dir/vccorlib140${vcrt_suffix}.dll", + "$root_out_dir/vcruntime140${vcrt_suffix}.dll", + + # Universal Windows 10 CRT files + "$root_out_dir/api-ms-win-core-console-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-datetime-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-debug-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-errorhandling-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-file-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-file-l1-2-0.dll", + "$root_out_dir/api-ms-win-core-file-l2-1-0.dll", + "$root_out_dir/api-ms-win-core-handle-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-heap-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-interlocked-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-libraryloader-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-localization-l1-2-0.dll", + "$root_out_dir/api-ms-win-core-memory-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-namedpipe-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-processenvironment-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-processthreads-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-processthreads-l1-1-1.dll", + "$root_out_dir/api-ms-win-core-profile-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-rtlsupport-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-string-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-synch-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-synch-l1-2-0.dll", + "$root_out_dir/api-ms-win-core-sysinfo-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-timezone-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-util-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-conio-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-convert-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-environment-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-filesystem-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-heap-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-locale-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-math-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-multibyte-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-private-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-process-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-runtime-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-stdio-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-string-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-time-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-utility-l1-1-0.dll", + "$root_out_dir/ucrtbase${vcrt_suffix}.dll", + ] + if (is_asan) { + if (current_cpu == "x64") { + data += [ "$clang_base_path/lib/clang/$clang_version/lib/windows/clang_rt.asan_dynamic-x86_64.dll" ] + } else { + data += [ "$clang_base_path/lib/clang/$clang_version/lib/windows/clang_rt.asan_dynamic-i386.dll" ] + } + } + } + } }
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 2d9b4a88..24463ef1 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -1807,7 +1807,8 @@ void* first_frame_sink_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerLoseFrameSinkTest); +// TODO(crbug.com/829923): Flaky with a heap-use-after-free. +// SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerLoseFrameSinkTest); class SoftwareTextureLayerUnregisterRegisterTest : public SoftwareTextureLayerTest {
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index bc50d30..329e9cd4 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <memory> #include <set> +#include <tuple> #include <vector> #include "base/memory/ptr_util.h" @@ -4489,7 +4490,7 @@ active_child->effect_tree_index())); } -using LCDTextTestParam = std::tr1::tuple<bool, bool, bool>; +using LCDTextTestParam = std::tuple<bool, bool, bool>; class LCDTextTest : public LayerTreeHostCommonTestBase, public testing::TestWithParam<LCDTextTestParam> { public: @@ -4505,8 +4506,8 @@ LayerTreeSettings LCDTextTestLayerTreeSettings() { LayerTreeSettings settings = VerifyTreeCalcsLayerTreeSettings(); - can_use_lcd_text_ = std::tr1::get<0>(GetParam()); - layers_always_allowed_lcd_text_ = std::tr1::get<1>(GetParam()); + can_use_lcd_text_ = std::get<0>(GetParam()); + layers_always_allowed_lcd_text_ = std::get<1>(GetParam()); settings.can_use_lcd_text = can_use_lcd_text_; settings.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text_; return settings; @@ -4547,8 +4548,7 @@ child_->SetBounds(gfx::Size(1, 1)); grand_child_->SetBounds(gfx::Size(1, 1)); - child_->test_properties()->force_render_surface = - std::tr1::get<2>(GetParam()); + child_->test_properties()->force_render_surface = std::get<2>(GetParam()); } bool can_use_lcd_text_;
diff --git a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml index dc470a5a..6be1029 100644 --- a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml +++ b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml
@@ -19,9 +19,9 @@ <!-- Use 48dp width and 16dp end/start padding to produce a 16dp, centered icon. --> <ImageView android:layout_height="match_parent" - android:layout_width="48dp" + android:layout_width="wrap_content" android:src="@drawable/ic_logo_googleg_24dp" - android:scaleType="centerInside" + android:scaleType="center" android:paddingStart="16dp" android:paddingEnd="16dp" android:contentDescription="@null" /> @@ -31,18 +31,17 @@ android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1" - android:gravity="center" android:singleLine="true" android:ellipsize="end" - android:textAppearance="@style/BlackBodyDefault" /> + android:textAppearance="@style/BlackTitle1" /> <!-- Use 50dp width and 16dp end/start padding to produce an 18dp, centered icon. --> <ImageView android:id="@+id/close_button" android:layout_height="match_parent" - android:layout_width="50dp" + android:layout_width="wrap_content" android:src="@drawable/btn_close" - android:scaleType="centerInside" + android:scaleType="center" android:paddingStart="16dp" android:paddingEnd="16dp" android:contentDescription="@string/close" />
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 6c9b45a..38046322 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -216,7 +216,7 @@ <!-- Full Screen Dimensions --> <!-- Should match toolbar_height_no_shadow --> <dimen name="control_container_height">56dp</dimen> - <dimen name="bottom_control_container_peek_height">40dp</dimen> + <dimen name="bottom_control_container_peek_height">48dp</dimen> <dimen name="custom_tabs_control_container_height">56dp</dimen> <dimen name="fullscreen_activity_control_container_height">0dp</dimen> @@ -298,7 +298,7 @@ <dimen name="omnibox_suggestion_answer_image_vertical_spacing">5dp</dimen> <dimen name="omnibox_suggestion_answer_image_horizontal_spacing">4dp</dimen> <dimen name="omnibox_suggestion_phone_url_bar_left_offset">10dp</dimen> - <dimen name="omnibox_suggestion_phone_url_bar_left_offset_rtl">10dp</dimen> + <dimen name="omnibox_suggestion_phone_url_bar_left_offset_rtl">40dp</dimen> <dimen name="omnibox_suggestion_refine_width">48dp</dimen> <dimen name="omnibox_suggestion_text_vertical_padding">5dp</dimen> <dimen name="omnibox_suggestion_multiline_text_vertical_padding">10dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 6fa99d6..82dbcbb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -850,8 +850,15 @@ if (getActivityTab() != null) { LaunchMetrics.commitLaunchMetrics(getActivityTab().getWebContents()); } - ContentViewCore cvc = getContentViewCore(); - if (cvc != null) cvc.onResume(); + + for (TabModel model : getTabModelSelector().getModels()) { + int count = model.getCount(); + for (int i = 0; i < count; ++i) { + ContentViewCore cvc = model.getTabAt(i).getActiveContentViewCore(); + if (cvc != null) cvc.onResume(); + } + } + FeatureUtilities.setCustomTabVisible(isCustomTab()); FeatureUtilities.setIsInMultiWindowMode( MultiWindowUtils.getInstance().isInMultiWindowMode(this)); @@ -882,8 +889,13 @@ RecordUserAction.record("MobileGoToBackground"); Tab tab = getActivityTab(); if (tab != null) getTabContentManager().cacheTabThumbnail(tab); - ContentViewCore cvc = getContentViewCore(); - if (cvc != null) cvc.onPause(); + for (TabModel model : getTabModelSelector().getModels()) { + int count = model.getCount(); + for (int i = 0; i < count; ++i) { + ContentViewCore cvc = model.getTabAt(i).getActiveContentViewCore(); + if (cvc != null) cvc.onPause(); + } + } VrShellDelegate.maybeUnregisterVrEntryHook(this); markSessionEnd(); super.onPauseWithNative(); @@ -1288,7 +1300,7 @@ mFadingBackgroundView = (FadingBackgroundView) findViewById(R.id.fading_focus_target); mBottomSheetController = new BottomSheetController(this, getTabModelSelector(), getCompositorViewHolder().getLayoutManager(), mFadingBackgroundView, - mBottomSheet); + getContextualSearchManager(), mBottomSheet); mContextualSuggestionsCoordinator = new ContextualSuggestionsCoordinator( this, mBottomSheetController, getTabModelSelector());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java index 817d4dd..a4cb840 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -214,11 +214,6 @@ return Action.FINISH_ACTIVITY; } - // Ignore this VR intent if we can't handle it in Chrome. - if (mIsVrIntent && !VrIntentUtils.canHandleVrIntent(mActivity)) { - return Action.FINISH_ACTIVITY; - } - // Check if we should push the user through First Run. if (FirstRunFlowSequencer.launch(mActivity, mIntent, false /* requiresBroadcast */, false /* preferLightweightFre */)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java index 2280d62..2df472b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java
@@ -172,6 +172,11 @@ } @Override + public boolean isCurrentModel(TabModel model) { + return false; + } + + @Override public boolean isInOverviewMode() { return false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index 733e144..2b19c42 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -668,12 +668,14 @@ tab.getContentViewCore() != null && !tab.isShowingSadTab() && !isNativePage; boolean isNtp = tab.getNativePage() instanceof NewTabPage; + boolean isLocationBarShownInNtp = + isNtp ? ((NewTabPage) tab.getNativePage()).isLocationBarShownInNTP() : false; boolean useModernDesign = FeatureUtilities.isChromeModernDesignEnabled() && tab.getActivity() != null && tab.getActivity().supportsModernDesign(); boolean needsUpdate = layoutTab.initFromHost(tab.getBackgroundColor(), tab.shouldStall(), canUseLiveTexture, themeColor, - ColorUtils.getTextBoxColorForToolbarBackground( - mContext.getResources(), isNtp, themeColor, useModernDesign), + ColorUtils.getTextBoxColorForToolbarBackground(mContext.getResources(), + isLocationBarShownInNtp, themeColor, useModernDesign), ColorUtils.getTextBoxAlphaForToolbarBackground(tab)); if (needsUpdate) requestUpdate();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java index 838984e4..5fb023e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java
@@ -98,18 +98,23 @@ int textBoxColor = Color.WHITE; int textBoxResourceId = R.drawable.card_single; - boolean isNtp = false; + boolean isLocationBarShownInNtp = false; boolean useModern = false; Tab currentTab = fullscreenManager.getTab(); if (currentTab != null) { - isNtp = currentTab != null ? NewTabPage.isNTPUrl(currentTab.getUrl()) : false; + boolean isNtp = + currentTab != null ? currentTab.getNativePage() instanceof NewTabPage : false; + if (isNtp) { + isLocationBarShownInNtp = + ((NewTabPage) currentTab.getNativePage()).isLocationBarShownInNTP(); + } useModern = currentTab.getActivity().supportsModernDesign() && FeatureUtilities.isChromeModernDesignEnabled(); } if (useModern) { - textBoxColor = ColorUtils.getTextBoxColorForToolbarBackground( - mContext.getResources(), isNtp, browserControlsBackgroundColor, true); + textBoxColor = ColorUtils.getTextBoxColorForToolbarBackground(mContext.getResources(), + isLocationBarShownInNtp, browserControlsBackgroundColor, true); textBoxResourceId = R.drawable.modern_location_bar; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java index 47cae4a..158a0ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java
@@ -9,9 +9,11 @@ import java.util.List; /** - * A node in a tree containing a list of {@link ContextualSuggestionCluster}s. + * A node in a tree containing a list of {@link ContextualSuggestionsCluster}s. */ class ClusterList extends InnerNode { + private boolean mIsDestroyed; + /** * Construct a new {@link ClusterList}. * @param clusters The list of clusters held by this ClusterList. @@ -21,4 +23,12 @@ addChild(cluster); } } + + /** Remove all clusters and detach itself from its parent. */ + void destroy() { + assert !mIsDestroyed; + mIsDestroyed = true; + removeChildren(); + detach(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java index 82d4347..f8aa7e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java
@@ -20,6 +20,8 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import java.util.List; + /** * An adapter that contains the view binder for the content component. */ @@ -103,4 +105,16 @@ public void onViewRecycled(NewTabPageViewHolder holder) { holder.recycle(); } + + @Override + public void onBindViewHolder(NewTabPageViewHolder holder, int position, List<Object> payloads) { + if (payloads.isEmpty()) { + onBindViewHolder(holder, position); + return; + } + + for (Object payload : payloads) { + ((NewTabPageViewHolder.PartialBindCallback) payload).onResult(holder); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java index 524002d..6c367dc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.contextual_suggestions; +import android.support.annotation.NonNull; import android.text.TextUtils; import org.chromium.base.Callback; @@ -17,9 +18,15 @@ import org.chromium.chrome.browser.ntp.snippets.KnownCategories; import org.chromium.chrome.browser.ntp.snippets.SectionHeader; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; +import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; +import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.offlinepages.OfflinePageItem; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.ContentSuggestionsAdditionalAction; +import org.chromium.chrome.browser.suggestions.SuggestionsOfflineModelObserver; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -30,6 +37,8 @@ private final List<SnippetArticle> mSuggestions = new ArrayList<>(); private SectionHeader mHeader; + private SuggestionsList mSuggestionsList; + private OfflineModelObserver mOfflineModelObserver; /** Creates a new contextual suggestions cluster with provided title. */ ContextualSuggestionsCluster(String title) { @@ -57,13 +66,25 @@ addChild(mHeader); } - SuggestionsList suggestionsList = new SuggestionsList(); - suggestionsList.addAll(mSuggestions); - addChild(suggestionsList); + mSuggestionsList = new SuggestionsList(); + mSuggestionsList.addAll(mSuggestions); + addChild(mSuggestionsList); + + // Only add observer after suggestions have been added to the cluster node to avoid + // OfflineModelObserver requesting a null list. + mOfflineModelObserver = new OfflineModelObserver( + OfflinePageBridge.getForProfile(Profile.getLastUsedProfile().getOriginalProfile())); + mOfflineModelObserver.updateAllSuggestionsOfflineAvailability(false); + } + + @Override + public void detach() { + super.detach(); + if (mOfflineModelObserver != null) mOfflineModelObserver.onDestroy(); } /** A tree node that holds a list of suggestions. */ - private static class SuggestionsList extends ChildNode { + private static class SuggestionsList extends ChildNode implements Iterable<SnippetArticle> { private final List<SnippetArticle> mSuggestions = new ArrayList<>(); private final SuggestionsCategoryInfo mCategoryInfo; @@ -126,5 +147,42 @@ // Contextual suggestions are not dismissible. assert false; } + + @NonNull + @Override + public Iterator<SnippetArticle> iterator() { + return mSuggestions.iterator(); + } + + // TODO(huayinz): Look at a way to share this with SuggestionsSection. + void updateSuggestionOfflineId(SnippetArticle article, Long newId) { + int index = mSuggestions.indexOf(article); + // The suggestions could have been removed / replaced in the meantime. + if (index == -1) return; + + Long oldId = article.getOfflinePageOfflineId(); + article.setOfflinePageOfflineId(newId); + + if ((oldId == null) == (newId == null)) return; + notifyItemChanged(index, SnippetArticleViewHolder::refreshOfflineBadgeVisibility); + } + } + + /** An observer to offline changes on suggestions. */ + private class OfflineModelObserver extends SuggestionsOfflineModelObserver<SnippetArticle> { + OfflineModelObserver(OfflinePageBridge bridge) { + super(bridge); + } + + @Override + public void onSuggestionOfflineIdChanged(SnippetArticle suggestion, OfflinePageItem item) { + mSuggestionsList.updateSuggestionOfflineId( + suggestion, item == null ? null : item.getOfflineId()); + } + + @Override + public Iterable<SnippetArticle> getOfflinableSuggestions() { + return mSuggestionsList; + } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java index 6aeb6b02..22b8e8d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java
@@ -52,7 +52,8 @@ mModel = new ContextualSuggestionsModel(); mMediator = new ContextualSuggestionsMediator(mActivity, mProfile, tabModelSelector, - activity.getFullscreenManager(), this, mModel); + activity.getFullscreenManager(), this, mModel, + mBottomSheetController.getBottomSheet()); } /** Called when the containing activity is destroyed. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java index 5f08094..d46f017 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java
@@ -7,8 +7,11 @@ import android.content.Context; import android.support.annotation.Nullable; import android.text.TextUtils; +import android.view.View; import org.chromium.base.ContextUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; @@ -18,7 +21,12 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.StateChangeReason; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.chrome.browser.widget.textbubble.TextBubble; +import org.chromium.components.feature_engagement.EventConstants; +import org.chromium.components.feature_engagement.FeatureConstants; +import org.chromium.components.feature_engagement.Tracker; import org.chromium.ui.widget.Toast; +import org.chromium.ui.widget.ViewRectProvider; import java.util.ArrayList; import java.util.Collections; @@ -30,20 +38,22 @@ * with the component coordinator(s). */ class ContextualSuggestionsMediator implements EnabledStateMonitor.Observer, FetchHelper.Delegate { - private final Context mContext; private final Profile mProfile; private final TabModelSelector mTabModelSelector; private final ContextualSuggestionsCoordinator mCoordinator; private final ContextualSuggestionsModel mModel; - private final EnabledStateMonitor mEnabledStateMonitor; private final ChromeFullscreenManager mFullscreenManager; + private final View mIphParentView; + private final EnabledStateMonitor mEnabledStateMonitor; private @Nullable ContextualSuggestionsSource mSuggestionsSource; private @Nullable FetchHelper mFetchHelper; private @Nullable String mCurrentRequestUrl; private @Nullable BottomSheetObserver mSheetObserver; + private @Nullable TextBubble mHelpBubble; private boolean mDidSuggestionsShowForTab; + private boolean mHasRecordedPeekEventForTab; /** * Construct a new {@link ContextualSuggestionsMediator}. @@ -54,16 +64,18 @@ * events. * @param coordinator The {@link ContextualSuggestionsCoordinator} for the component. * @param model The {@link ContextualSuggestionsModel} for the component. + * @param iphParentView The parent {@link View} used to anchor an in-product help bubble. */ ContextualSuggestionsMediator(Context context, Profile profile, TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager, - ContextualSuggestionsCoordinator coordinator, ContextualSuggestionsModel model) { - mContext = context; + ContextualSuggestionsCoordinator coordinator, ContextualSuggestionsModel model, + View iphParentView) { mProfile = profile; mTabModelSelector = tabModelSelector; mCoordinator = coordinator; mModel = model; mFullscreenManager = fullscreenManager; + mIphParentView = iphParentView; // Create a state monitor that will alert this mediator if the enabled state for contextual // suggestions changes. @@ -106,6 +118,8 @@ mSuggestionsSource.destroy(); mSuggestionsSource = null; } + + if (mHelpBubble != null) mHelpBubble.dismiss(); } /** @@ -178,6 +192,7 @@ private void clearSuggestions() { // TODO(twellington): Does this signal need to go back to FetchHelper? mDidSuggestionsShowForTab = false; + mHasRecordedPeekEventForTab = false; mModel.setClusterList(new ClusterList(Collections.emptyList())); mModel.setCloseButtonOnClickListener(null); mModel.setTitle(null); @@ -187,13 +202,19 @@ if (mSheetObserver != null) { mCoordinator.removeBottomSheetObserver(mSheetObserver); } + + if (mHelpBubble != null) mHelpBubble.dismiss(); } private void preloadContentInSheet(ClusterList clusters, String title) { if (mSuggestionsSource == null) return; mModel.setClusterList(clusters); - mModel.setCloseButtonOnClickListener(view -> { clearSuggestions(); }); + mModel.setCloseButtonOnClickListener(view -> { + clearSuggestions(); + TrackerFactory.getTrackerForProfile(mProfile).notifyEvent( + EventConstants.CONTEXTUAL_SUGGESTIONS_DISMISSED); + }); mModel.setTitle(title); mCoordinator.preloadContentInSheet(); } @@ -203,7 +224,25 @@ mSheetObserver = new EmptyBottomSheetObserver() { @Override + public void onSheetFullyPeeked() { + if (mHasRecordedPeekEventForTab) return; + + mHasRecordedPeekEventForTab = true; + TrackerFactory.getTrackerForProfile(mProfile).notifyEvent( + EventConstants.CONTEXTUAL_SUGGESTIONS_PEEKED); + maybeShowHelpBubble(); + } + + @Override + public void onSheetOffsetChanged(float heightFraction) { + if (mHelpBubble != null) mHelpBubble.dismiss(); + } + + @Override public void onSheetOpened(@StateChangeReason int reason) { + TrackerFactory.getTrackerForProfile(mProfile).notifyEvent( + EventConstants.CONTEXTUAL_SUGGESTIONS_OPENED); + mCoordinator.showSuggestions(mSuggestionsSource); mCoordinator.removeBottomSheetObserver(this); mSheetObserver = null; @@ -214,6 +253,29 @@ mCoordinator.showContentInSheet(); } + private void maybeShowHelpBubble() { + Tracker tracker = TrackerFactory.getTrackerForProfile(mProfile); + if (!tracker.shouldTriggerHelpUI(FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE)) { + return; + } + + ViewRectProvider rectProvider = new ViewRectProvider(mIphParentView); + rectProvider.setInsetPx(0, + mIphParentView.getResources().getDimensionPixelSize(R.dimen.toolbar_shadow_height), + 0, 0); + mHelpBubble = new TextBubble(mIphParentView.getContext(), mIphParentView, + R.string.contextual_suggestions_in_product_help, + R.string.contextual_suggestions_in_product_help, rectProvider); + + mHelpBubble.setDismissOnTouchInteraction(true); + mHelpBubble.addOnDismissListener(() -> { + tracker.dismissed(FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE); + mHelpBubble = null; + }); + + mHelpBubble.show(); + } + // TODO(twellington): Remove after clusters are returned from the backend. private ClusterList generateClusterList(List<ContextualSuggestionsCluster> clusters) { if (clusters.size() != 1) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java index 2ab3bab3..3aa5bdd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java
@@ -4,10 +4,14 @@ package org.chromium.chrome.browser.contextual_suggestions; +import android.support.annotation.Nullable; import android.view.View.OnClickListener; import org.chromium.chrome.browser.modelutil.ListObservable; import org.chromium.chrome.browser.modelutil.PropertyObservable; +import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; +import org.chromium.chrome.browser.ntp.cards.NodeParent; +import org.chromium.chrome.browser.ntp.cards.TreeNode; import java.util.Collections; @@ -24,16 +28,23 @@ } /** A {@link ListObservable} containing the current cluster list. */ - class ClusterListObservable extends ListObservable { + class ClusterListObservable extends ListObservable implements NodeParent { ClusterList mClusterList = new ClusterList(Collections.emptyList()); + /** Constructor to initialize parent of cluster list. */ + ClusterListObservable() { + mClusterList.setParent(this); + } + private void setClusterList(ClusterList clusterList) { assert clusterList != null; - int oldLength = getItemCount(); - mClusterList = clusterList; + // Destroy the old cluster list. + mClusterList.destroy(); - if (oldLength != 0) notifyItemRangeRemoved(0, oldLength); + mClusterList = clusterList; + mClusterList.setParent(this); + if (getItemCount() != 0) notifyItemRangeInserted(0, getItemCount()); } @@ -41,6 +52,26 @@ public int getItemCount() { return mClusterList.getItemCount(); } + + // NodeParent implementations. + @Override + public void onItemRangeChanged(TreeNode child, int index, int count, + @Nullable NewTabPageViewHolder.PartialBindCallback callback) { + assert child == mClusterList; + notifyItemRangeChanged(index, count, callback); + } + + @Override + public void onItemRangeInserted(TreeNode child, int index, int count) { + assert child == mClusterList; + notifyItemRangeInserted(index, count); + } + + @Override + public void onItemRangeRemoved(TreeNode child, int index, int count) { + assert child == mClusterList; + notifyItemRangeRemoved(index, count); + } } ClusterListObservable mClusterListObservable = new ClusterListObservable(); @@ -48,7 +79,7 @@ private String mTitle; private boolean mToolbarShadowVisibility; - /** @param suggestions The current list of clusters. */ + /** @param clusterList The current list of clusters. */ void setClusterList(ClusterList clusterList) { mClusterListObservable.setClusterList(clusterList); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java index b8e7ae31..30541d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
@@ -21,11 +21,7 @@ private final TabObserver mTabObserver = new EmptyTabObserver() { @Override public void onInteractabilityChanged(boolean isInteractable) { - if (!isInteractable) { - mManager.suspendType(ModalDialogManager.TAB_MODAL); - } else { - mManager.resumeType(ModalDialogManager.TAB_MODAL); - } + updateSuspensionState(); } @Override @@ -58,16 +54,16 @@ mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) { @Override public void didSelectTab(Tab tab, TabModel.TabSelectionType type, int lastId) { - if (tab == null || tab.getId() != lastId) { + // Do not use lastId here since it can be the selected tab's ID if model is switched + // inside tab switcher. + if (tab != mActiveTab) { mManager.cancelAllDialogs(ModalDialogManager.TAB_MODAL); if (mActiveTab != null) mActiveTab.removeObserver(mTabObserver); mActiveTab = tab; if (mActiveTab != null) { mActiveTab.addObserver(mTabObserver); - if (mActiveTab.isUserInteractable()) { - mManager.resumeType(ModalDialogManager.TAB_MODAL); - } + updateSuspensionState(); } } } @@ -100,4 +96,14 @@ public void destroy() { mTabModelObserver.destroy(); } + + /** Update whether the {@link ModalDialogManager} should suspend tab modal dialogs. */ + private void updateSuspensionState() { + assert mActiveTab != null; + if (mActiveTab.isUserInteractable()) { + mManager.resumeType(ModalDialogManager.TAB_MODAL); + } else { + mManager.suspendType(ModalDialogManager.TAB_MODAL); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index a282644..d0e293d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -49,6 +49,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.chrome.browser.vr_shell.VrShellDelegate; @@ -283,8 +284,8 @@ mBackgroundColor = ApiCompatibilityUtils.getColor(activity.getResources(), SuggestionsConfig.useModernLayout() ? R.color.modern_primary_color : R.color.ntp_bg); - mThemeColor = ApiCompatibilityUtils.getColor( - activity.getResources(), R.color.default_primary_color); + mThemeColor = ColorUtils.getDefaultThemeColor( + activity.getResources(), FeatureUtilities.isChromeModernDesignEnabled(), false); mIsTablet = activity.isTablet(); TemplateUrlService.getInstance().addObserver(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index 93005c1..4783c994 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -470,14 +470,12 @@ public static void sharePublishedPage(OfflinePageItem page, final Activity activity, final Callback<ShareParams> shareCallback) { if (page == null) { - // Set the source component name to null to indicate failure, causing ShareHelper.share - // to return. - ShareParams shareParams = - new ShareParams.Builder(activity, page.getTitle(), page.getUrl()) - .setShareDirectly(false) - .setOfflineUri(Uri.parse(page.getUrl())) - .setSourcePackageName(null) - .build(); + // Set share directly to true and the source component name to null to indicate failure, + // causing ShareHelper.share() to return. + ShareParams shareParams = new ShareParams.Builder(activity, "", "") + .setShareDirectly(true) + .setSourcePackageName(null) + .build(); shareCallback.onResult(shareParams); return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 7ff4f32..05e3f63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -560,8 +560,10 @@ int availableViewportHeight = Math.min(mTempRect.height(), decorHeight) + additionalHeightForBottomNavMenu; int availableListHeight = availableViewportHeight - anchorBottomRelativeToContent; - // If the bottom sheet is used, the suggestions should consume all available space. - int desiredHeight = Math.min(availableListHeight, getIdealHeight()); + // The suggestions should consume all available space in Modern on phone. + int desiredHeight = useModernDesign() && !mIsTablet + ? availableListHeight + : Math.min(availableListHeight, getIdealHeight()); if (layoutParams.height != desiredHeight) { layoutParams.height = desiredHeight; updateLayout = true; @@ -1001,7 +1003,7 @@ private void updateFocusedUrlBarSelection() { if (!mUrlBar.hasFocus()) return; - if (mToolbarDataProvider.isDisplayingQueryTerms()) { + if (mToolbarDataProvider.shouldDisplaySearchTerms()) { mUrlBar.setSelection(mUrlBar.getText().length()); } else { selectAll(); @@ -1315,9 +1317,9 @@ } else { // For the default toolbar color, use a green or red icon. if (securityLevel == ConnectionSecurityLevel.DANGEROUS) { - assert !provider.isDisplayingQueryTerms(); + assert !provider.shouldDisplaySearchTerms(); list = ApiCompatibilityUtils.getColorStateList(resources, R.color.google_red_700); - } else if (!provider.isDisplayingQueryTerms() + } else if (!provider.shouldDisplaySearchTerms() && (securityLevel == ConnectionSecurityLevel.SECURE || securityLevel == ConnectionSecurityLevel.EV_SECURE)) { list = ApiCompatibilityUtils.getColorStateList(resources, R.color.google_green_700); @@ -1361,7 +1363,7 @@ } private void emphasizeUrl() { - if (mToolbarDataProvider.isDisplayingQueryTerms()) return; + if (mToolbarDataProvider.shouldDisplaySearchTerms()) return; mUrlBar.emphasizeUrl(); } @@ -2073,14 +2075,14 @@ @Override public boolean shouldForceLTR() { - return !mToolbarDataProvider.isDisplayingQueryTerms(); + return !mToolbarDataProvider.shouldDisplaySearchTerms(); } @Override @UrlBar.ScrollType public int getScrollType() { - return mToolbarDataProvider.isDisplayingQueryTerms() ? UrlBar.SCROLL_TO_BEGINNING - : UrlBar.SCROLL_TO_TLD; + return mToolbarDataProvider.shouldDisplaySearchTerms() ? UrlBar.SCROLL_TO_BEGINNING + : UrlBar.SCROLL_TO_TLD; } /** @@ -2140,12 +2142,12 @@ */ @Override public void setUrlToPageUrl() { - String url = mToolbarDataProvider.getCurrentUrl(); + String currentUrl = mToolbarDataProvider.getCurrentUrl(); // If the URL is currently focused, do not replace the text they have entered with the URL. // Once they stop editing the URL, the current tab's URL will automatically be filled in. if (mUrlBar.hasFocus()) { - if (mUrlFocusedWithoutAnimations && !NewTabPage.isNTPUrl(url)) { + if (mUrlFocusedWithoutAnimations && !NewTabPage.isNTPUrl(currentUrl)) { // If we did not run the focus animations, then the user has not typed any text. // So, clear the focus and accept whatever URL the page is currently attempting to // display. If the NTP is showing, the current page's URL should not be displayed. @@ -2155,12 +2157,12 @@ } } - mOriginalUrl = url; + mOriginalUrl = currentUrl; String displayText = getDisplayText(); if (TextUtils.isEmpty(displayText)) { setUrlBarText("", null); } else { - if (setUrlBarText(url, displayText)) { + if (setUrlBarText(currentUrl, displayText)) { emphasizeUrl(); } } @@ -2276,17 +2278,11 @@ } else { currentTab.loadUrl(loadUrlParams); } - - setUrlToPageUrl(); RecordUserAction.record("MobileOmniboxUse"); - } else { - setUrlToPageUrl(); } - LocaleManager.getInstance().recordLocaleBasedSearchMetrics(false, url, transition); focusCurrentTab(); - // Prevent any upcoming omnibox suggestions from showing. We have to do this after we load // the URL as this will hide the suggestions and trigger a cancel of the prerendered page. stopAutocomplete(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java index b0e61db..19451c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -707,12 +707,20 @@ } private void scrollToBeginning() { - int scrollX = 0; - if (BidiFormatter.getInstance().isRtl(getTextWithAutocomplete())) { - int textWidth = (int) getLayout().getPaint().measureText(getTextWithAutocomplete()); - scrollX = textWidth - getMeasuredWidth(); + if (mFocused) return; + + setSelection(0); + + Editable text = getText(); + float scrollPos = 0f; + if (BidiFormatter.getInstance().isRtl(text)) { + // RTL. + float endPointX = getLayout().getPrimaryHorizontal(text.length()); + int measuredWidth = getMeasuredWidth(); + float width = getLayout().getPaint().measureText(text.toString()); + scrollPos = Math.max(0, endPointX - measuredWidth + width); } - scrollTo(scrollX, getScrollY()); + scrollTo((int) scrollPos, getScrollY()); } public void scrollToTLD() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java index 8fc14aa..b550e0d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java
@@ -111,7 +111,7 @@ } @Override - public boolean isDisplayingQueryTerms() { + public boolean shouldDisplaySearchTerms() { return false; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java index 52f7bdd..5a2b2e13 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
@@ -86,6 +86,11 @@ public void setIndex(int i, TabSelectionType type) {} @Override + public boolean isCurrentModel() { + return false; + } + + @Override public void moveTab(int id, int newIndex) {} @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java index d3eeb369..bcbb43d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java
@@ -165,6 +165,11 @@ } @Override + public boolean isCurrentModel() { + return mDelegateModel.isCurrentModel(); + } + + @Override public void moveTab(int id, int newIndex) { mDelegateModel.moveTab(id, newIndex); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java index ab007e1..b690fff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java
@@ -125,6 +125,11 @@ } @Override + public boolean isCurrentModel() { + return true; + } + + @Override public void moveTab(int id, int newIndex) { assert false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java index 2c39204b..3f3c532 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
@@ -182,6 +182,12 @@ public void setIndex(int i, final TabSelectionType type); /** + * @return Whether this tab model is currently selected in the correspond + * {@link TabModelSelector}. + */ + boolean isCurrentModel(); + + /** * Moves a tab to a new index. * @param id The id of the tab to move. * @param newIndex The new place to put the tab.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelDelegate.java index 336cdb6..475056d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelDelegate.java
@@ -8,8 +8,8 @@ import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; /** - * This class serves as a callback from TabModel to TabModelSelector. The number of methods in this - * class should be reduced to a minimum. http://crbug.com/263579 + * This class serves as a callback from TabModel to TabModelSelector. Avoid adding unnecessary + * methods that expose too much access to TabModel. http://crbug.com/263579 */ public interface TabModelDelegate { @@ -27,6 +27,12 @@ */ boolean closeAllTabsRequest(boolean incognito); + /** + * @param model The specified model. + * @return Whether the specified model is currently selected. + */ + boolean isCurrentModel(TabModel model); + // TODO(aurimas): clean these methods up. TabModel getCurrentModel(); TabModel getModel(boolean incognito);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java index 5c9670a..4559336 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -443,13 +443,6 @@ return retVal == -1 ? INVALID_TAB_INDEX : retVal; } - /** - * @return true if this is the current model according to the model selector - */ - private boolean isCurrentModel() { - return mModelDelegate.getCurrentModel().isIncognito() == isIncognito(); - } - // TODO(aurimas): Move this method to TabModelSelector when notifications move there. private int getLastId(TabSelectionType type) { if (type == TabSelectionType.FROM_CLOSE || type == TabSelectionType.FROM_EXIT) { @@ -505,6 +498,11 @@ } } + @Override + public boolean isCurrentModel() { + return mModelDelegate.isCurrentModel(this); + } + /** * Performs the necessary actions to remove this {@link Tab} from this {@link TabModel}. * This does not actually destroy the {@link Tab} (see
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java index c58c459..d09e7354 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -145,6 +145,10 @@ @CalledByNative protected abstract boolean isSessionRestoreInProgress(); + @CalledByNative + @Override + public abstract boolean isCurrentModel(); + /** * Register the start of tab switch latency timing. Called when setIndex() indicates a tab * switch event.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java index 4b6aee61..0b2d8f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
@@ -259,6 +259,11 @@ return mCloseAllTabsDelegate.closeAllTabsRequest(incognito); } + @Override + public boolean isCurrentModel(TabModel model) { + return isIncognitoSelected() == model.isIncognito(); + } + public void saveState() { commitAllTabClosures(); mTabSaver.saveState();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java index 49d64b6b..c39e4a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java
@@ -28,6 +28,15 @@ * Maintains a list of Tabs displayed when Chrome is running in document-mode. */ public class DocumentTabModelImpl extends TabModelJniBridge implements DocumentTabModel { + /** Serves as a callback from DocumentTabModelImpl to DocumentTabModelSelector. */ + public interface TabModelDelegate { + /** + * @param model The specified model. + * @return Whether the specified model is currently selected. + */ + boolean isCurrentModel(TabModel model); + } + private static final String TAG = "DocumentTabModel"; public static final String PREF_PACKAGE = "com.google.android.apps.chrome.document"; @@ -94,6 +103,8 @@ /** Context to use. */ private final Context mContext; + private final TabModelDelegate mTabModelDelegate; + /** Current loading status. */ private int mCurrentState; @@ -119,11 +130,12 @@ */ public DocumentTabModelImpl(ActivityDelegate activityDelegate, StorageDelegate storageDelegate, TabCreatorManager tabCreatorManager, boolean isIncognito, int prioritizedTabId, - Context context) { + Context context, TabModelDelegate tabModelDelegate) { super(isIncognito, false); mActivityDelegate = activityDelegate; mStorageDelegate = storageDelegate; mContext = context; + mTabModelDelegate = tabModelDelegate; mCurrentState = STATE_UNINITIALIZED; mTabIdList = new ArrayList<Integer>(); @@ -267,6 +279,11 @@ } @Override + public boolean isCurrentModel() { + return mTabModelDelegate.isCurrentModel(this); + } + + @Override public String getInitialUrlForDocument(int tabId) { Entry entry = mEntryMap.get(tabId); return entry == null ? null : entry.initialUrl;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java index e69d43c..84b15e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java
@@ -31,7 +31,8 @@ * created by one Activity but need to be loaded in another Tab. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class DocumentTabModelSelector extends TabModelSelectorBase implements TabCreatorManager { +public class DocumentTabModelSelector extends TabModelSelectorBase + implements TabCreatorManager, DocumentTabModelImpl.TabModelDelegate { public static final String PREF_PACKAGE = "com.google.android.apps.chrome.document"; public static final String PREF_IS_INCOGNITO_SELECTED = "is_incognito_selected"; @@ -91,13 +92,13 @@ final Context context = ContextUtils.getApplicationContext(); mRegularTabModel = new DocumentTabModelImpl( - mActivityDelegate, mStorageDelegate, this, false, sPrioritizedTabId, context); + mActivityDelegate, mStorageDelegate, this, false, sPrioritizedTabId, context, this); mIncognitoTabModel = new IncognitoDocumentTabModel(new IncognitoTabModelDelegate() { @Override public TabModel createTabModel() { DocumentTabModel incognitoModel = new DocumentTabModelImpl(mActivityDelegate, mStorageDelegate, DocumentTabModelSelector.this, true, sPrioritizedTabId, - context); + context, DocumentTabModelSelector.this); return incognitoModel; } @@ -179,6 +180,11 @@ return (DocumentTabModel) super.getModelForTabId(id); } + @Override + public boolean isCurrentModel(TabModel model) { + return isIncognitoSelected() == model.isIncognito(); + } + /** * Overrides the regular StorageDelegate in the constructor. MUST be called before the * DocumentTabModelSelector instance is created to take effect.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java index b02ded4..e10b814 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java
@@ -109,7 +109,7 @@ int getSecurityIconResource(boolean isTablet); /** - * @return Whether or not we're currently showing a search query instead of a URL. + * @return Whether or not we should display search terms instead of a URL for query in omnibox. */ - boolean isDisplayingQueryTerms(); + boolean shouldDisplaySearchTerms(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java index c1baf5e..d4f7f48a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
@@ -234,7 +234,7 @@ } @Override - public boolean isDisplayingQueryTerms() { + public boolean shouldDisplaySearchTerms() { return false; } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index ac9d914..c86ea88 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -25,7 +25,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.NativePage; import org.chromium.chrome.browser.TabLoadStatus; @@ -176,8 +175,6 @@ private boolean mShouldUpdateToolbarPrimaryColor = true; private int mCurrentThemeColor; - private boolean mQueryInOmniboxEnabled; - /** * Creates a ToolbarManager object. * @@ -307,20 +304,12 @@ mTabObserver = new EmptyTabObserver() { @Override public void onSSLStateUpdated(Tab tab) { + setModelShouldIgnoreSecurityLevelForSearchTerms(false); if (mToolbarModel.getTab() == null) return; assert tab == mToolbarModel.getTab(); mLocationBar.updateSecurityIcon(); - - // If the SSL state was updated while the location bar is display a DSE URL and - // the query in omnibox feature is enabled, update the URL to be on the safe side, - // as we may be showing query terms when we should now be showing the full URL for - // security. - if (mQueryInOmniboxEnabled - && TemplateUrlService.getInstance() - .isSearchResultsPageFromDefaultSearchProvider(tab.getUrl())) { - mLocationBar.setUrlToPageUrl(); - } + mLocationBar.setUrlToPageUrl(); } @Override @@ -353,7 +342,13 @@ } @Override + public void onPageLoadStarted(Tab tab, String url) { + mToolbarModel.setIgnoreSecurityLevelForSearchTerms(true); + } + + @Override public void onPageLoadFinished(Tab tab) { + mToolbarModel.setIgnoreSecurityLevelForSearchTerms(false); if (tab.isShowingErrorPage()) { handleIPHForErrorPageShown(tab); return; @@ -365,6 +360,7 @@ @Override public void onLoadStarted(Tab tab, boolean toDifferentDocument) { if (!toDifferentDocument) return; + mToolbarModel.setIgnoreSecurityLevelForSearchTerms(true); updateButtonStatus(); updateTabLoadingState(true); } @@ -372,6 +368,7 @@ @Override public void onLoadStopped(Tab tab, boolean toDifferentDocument) { if (!toDifferentDocument) return; + mToolbarModel.setIgnoreSecurityLevelForSearchTerms(false); updateTabLoadingState(true); // If we made some progress, fast-forward to complete, otherwise just dismiss any @@ -408,8 +405,7 @@ @Override public void onWebContentsSwapped(Tab tab, boolean didStartLoad, boolean didFinishLoad) { if (!didStartLoad) return; - mLocationBar.setUrlToPageUrl(); - mLocationBar.updateSecurityIcon(); + mLocationBar.updateLoadingState(true); if (didFinishLoad) { mLoadProgressSimulator.start(); } @@ -883,8 +879,6 @@ refreshSelectedTab(); if (mTabModelSelector.isTabStateInitialized()) mTabRestoreCompleted = true; handleTabRestoreCompleted(); - - mQueryInOmniboxEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.QUERY_IN_OMNIBOX); } private void handleTabRestoreCompleted() { @@ -1375,6 +1369,22 @@ == Configuration.KEYBOARD_QWERTY; } + /** + * Notifies the toolbar model that it should ignore the security level when determining whether + * or not to display search terms in the URL bar. This is useful for the interim period between + * loading a new page and getting proper security info, to avoid having the full URL flicker + * before displaying search terms. + * + * @param shouldIgnore Whether or not the toolbar model should ignore the security level. + */ + private void setModelShouldIgnoreSecurityLevelForSearchTerms(boolean shouldIgnore) { + boolean wasShowingSearchTerms = mToolbarModel.shouldDisplaySearchTerms(); + mToolbarModel.setIgnoreSecurityLevelForSearchTerms(shouldIgnore); + if (wasShowingSearchTerms != mToolbarModel.shouldDisplaySearchTerms()) { + mLocationBar.setUrlToPageUrl(); + } + } + private static class LoadProgressSimulator { private static final int MSG_ID_UPDATE_PROGRESS = 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java index b4c96475..9678a2a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java
@@ -55,6 +55,8 @@ private int mPreviousSecurityLevel; private String mCachedSearchTerms; + private boolean mIgnoreSecurityLevelForSearchTerms; + /** * Default constructor for this class. * @param bottomSheet The {@link BottomSheet} for the activity displaying this toolbar. @@ -141,7 +143,7 @@ String url = getCurrentUrl(); if (DomDistillerUrlUtils.isDistilledPage(url)) return false; if (isOfflinePage()) return false; - if (isDisplayingQueryTerms()) return false; + if (shouldDisplaySearchTerms()) return false; if (NativePageFactory.isNativePageUrl(url, isIncognito()) || NewTabPage.isNTPUrl(url)) { return false; } @@ -201,10 +203,9 @@ String originalUrl = mTab.getOriginalUrl(); editingText = OfflinePageUtils.stripSchemeFromOnlineUrl( DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl)); - } else { - String searchTerms = extractSearchTermsFromUrl(url); + } else if (shouldDisplaySearchTerms()) { // Show the search terms in the omnibox instead of the URL if this is a DSE search URL. - if (searchTerms != null) editingText = searchTerms; + editingText = getDisplaySearchTerms(url); } return editingText; @@ -318,7 +319,7 @@ public int getSecurityIconResource(boolean isTablet) { // If we're showing a query in the omnibox, and the security level is high enough to show // the search icon, return that instead of the security icon. - if (isDisplayingQueryTerms()) { + if (shouldDisplaySearchTerms()) { return R.drawable.ic_search; } return getSecurityIconResource(getSecurityLevel(), !isTablet, isOfflinePage()); @@ -367,8 +368,16 @@ } @Override - public boolean isDisplayingQueryTerms() { - return extractSearchTermsFromUrl(getCurrentUrl()) != null; + public boolean shouldDisplaySearchTerms() { + return (mIgnoreSecurityLevelForSearchTerms || securityLevelSafeForQueryInOmnibox()) + && isUrlApplicableToDisplaySearchTerms(getCurrentUrl()); + } + + private boolean isUrlApplicableToDisplaySearchTerms(String url) { + if (!mQueryInOmniboxEnabled) return false; + if (mTab != null && !(mTab.getActivity() instanceof ChromeTabbedActivity)) return false; + if (TextUtils.isEmpty(getDisplaySearchTerms(url))) return false; + return true; } private boolean securityLevelSafeForQueryInOmnibox() { @@ -379,21 +388,23 @@ /** * Extracts query terms from a URL if it's a SRP URL from the default search engine, caching - * the result of the more expensive call to {@link #extractSearchTermsFromUrlInternal}. + * the result of the more expensive call to {@link #getDisplaySearchTermsInternal}. * * @param url The URL to extract search terms from. * @return The search terms. Returns null if not a DSE SRP URL or there are no search terms to * extract, if query in omnibox is disabled, or if the security level is insufficient to - * display search terms in place of SRP URL. + * display search terms in place of SRP URL. This will also return nothing if the search + * terms look too much like a URL, since we don't want to display URL look-a-likes with + * "Query in Omnibox" to avoid confusion. */ - private String extractSearchTermsFromUrl(String url) { + private String getDisplaySearchTerms(String url) { if (url == null) { mCachedSearchTerms = null; } else { @ConnectionSecurityLevel int securityLevel = getSecurityLevel(); if (!url.equals(mPreviousUrl) || securityLevel != mPreviousSecurityLevel) { - mCachedSearchTerms = extractSearchTermsFromUrlInternal(url); + mCachedSearchTerms = getDisplaySearchTermsInternal(url); mPreviousUrl = url; mPreviousSecurityLevel = securityLevel; } @@ -411,19 +422,35 @@ * extract, if query in omnibox is disabled, or if the security level is insufficient to * display search terms in place of SRP URL. */ - private String extractSearchTermsFromUrlInternal(String url) { - if (mTab != null && !(mTab.getActivity() instanceof ChromeTabbedActivity)) return null; - if (!mQueryInOmniboxEnabled || !securityLevelSafeForQueryInOmnibox()) return null; + private String getDisplaySearchTermsInternal(String url) { + TemplateUrlService templateUrlService = TemplateUrlService.getInstance(); + if (!templateUrlService.isSearchResultsPageFromDefaultSearchProvider(url)) return null; - String searchTerms = TemplateUrlService.getInstance().extractSearchTermsFromUrl(url); - if (!TextUtils.isEmpty(searchTerms)) { - // Avoid showing search terms that would be interpreted as a URL if typed into the - // omnibox. - if (TextUtils.isEmpty( - AutocompleteController.nativeQualifyPartialURLQuery(searchTerms))) { - return searchTerms; - } - } - return null; + String searchTerms = templateUrlService.extractSearchTermsFromUrl(url); + // Avoid showing search terms that would be interpreted as a URL if typed into the + // omnibox. + return looksLikeUrl(searchTerms) ? null : searchTerms; + } + + /** + * Checks if the provided {@link String} look like a URL. + * + * @param input The {@link String} to check. + * @return Whether or not the {@link String} appeared to be a URL. + */ + private boolean looksLikeUrl(String input) { + return !TextUtils.isEmpty(input) + && !TextUtils.isEmpty(AutocompleteController.nativeQualifyPartialURLQuery(input)); + } + + /** + * Sets a flag telling the model to ignore the security level in its check for whether to + * display search terms or not. This is useful for avoiding the flicker that occurs when loading + * a SRP URL before our SSL state updates. + * + * @param ignore Whether or not we should ignore the security level. + */ + protected void setIgnoreSecurityLevelForSearchTerms(boolean ignore) { + mIgnoreSecurityLevelForSearchTerms = ignore; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java index 6c2a01c..8d7baef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -1066,12 +1066,10 @@ mLocationBarNtpOffsetLeft = 0; mLocationBarNtpOffsetRight = 0; - boolean isNtp = false; Tab currentTab = getToolbarDataProvider().getTab(); if (currentTab != null) { NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab(); if (ntp != null) { - isNtp = true; ntp.setUrlFocusChangeAnimationPercent(mUrlFocusChangePercent); } @@ -1102,7 +1100,8 @@ // Only transition theme colors if in static tab mode that is not the NTP. In practice this // only runs when you focus the omnibox on a web page. - if (mLocationBar.useModernDesign() && !isNtp && mTabSwitcherState == STATIC_TAB) { + if (mLocationBar.useModernDesign() && !isLocationBarShownInNTP() + && mTabSwitcherState == STATIC_TAB) { int defaultColor = ColorUtils.getDefaultThemeColor(getResources(), true, isIncognito()); int defaultLocationBarColor = getLocationBarColorForToolbarColor(defaultColor); int primaryColor = getToolbarDataProvider().getPrimaryColor();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/ColorUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/util/ColorUtils.java index 1fc47912..dd30d899bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/ColorUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/ColorUtils.java
@@ -71,10 +71,15 @@ } /** - * @return The base color for the textbox given a toolbar background color. + * Determine the text box color based on the current toolbar background color. + * @param res {@link Resources} used to retrieve colors. + * @param isLocationBarShownInNtp Whether the location bar is currently shown in an NTP. + * @param color The color of the toolbar background. + * @param useModernDesign Whether to use the "modern" visual design. + @return The base color for the textbox given a toolbar background color. */ public static int getTextBoxColorForToolbarBackground( - Resources res, boolean isNtp, int color, boolean useModernDesign) { + Resources res, boolean isLocationBarShownInNtp, int color, boolean useModernDesign) { // If modern is enabled, it is a special case. It's toolbar is white with a darker text box // background. boolean usingDefaultThemeColor = @@ -83,14 +88,16 @@ // In modern, the default theme color is white, so the text box uses a darker color // which is different from all other cases. In the case of the NTP, the location bar is // not visible by default, so we make it white to appear as part of the background. - return isNtp ? Color.WHITE - : ApiCompatibilityUtils.getColor(res, R.color.modern_light_grey); + return isLocationBarShownInNtp + ? Color.WHITE + : ApiCompatibilityUtils.getColor(res, R.color.modern_light_grey); } if (shouldUseOpaqueTextboxBackground(color)) { // NTP should have no visible textbox in the toolbar, so just return the toolbar's // background color. - return isNtp ? ApiCompatibilityUtils.getColor(res, R.color.ntp_bg) : Color.WHITE; + return isLocationBarShownInNtp ? ApiCompatibilityUtils.getColor(res, R.color.ntp_bg) + : Color.WHITE; } return getColorWithOverlay(color, Color.WHITE, LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java index 34115b1..94255c4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
@@ -55,13 +55,6 @@ * @return Whether the intent should be allowed to auto-present. */ boolean isTrustedAutopresentIntent(Intent intent); - - /** - * Determines whether the installed version of Chrome can handle VR intents. - * @param context The context for the caller. - * @return Whether VR intents can be handled. - */ - boolean canHandleVrIntent(Context context); } private static VrIntentHandler createInternalVrIntentHandler() { @@ -82,16 +75,6 @@ return isTrustedDaydreamIntent(intent) && IntentUtils.safeGetBooleanExtra(intent, AUTOPRESENT_WEVBVR_EXTRA, false); } - - @Override - public boolean canHandleVrIntent(Context context) { - VrClassesWrapper wrapper = VrShellDelegate.getVrClassesWrapper(); - if (wrapper == null) return false; - int supportLevel = - VrShellDelegate.getVrSupportLevel(wrapper.createVrDaydreamApi(context), - wrapper.createVrCoreVersionChecker(), null); - return supportLevel == VrSupportLevel.VR_DAYDREAM; - } }; } @@ -137,13 +120,6 @@ } /** - * @return whether the installed version of Chrome can handle VR intents. - */ - public static boolean canHandleVrIntent(Context context) { - return getHandlerInstance().canHandleVrIntent(context); - } - - /** * This function returns an intent that will launch a VR activity that will prompt the * user to take off their headset and forward the freIntent to the standard * 2D FRE activity.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index b2f3f84a..43c6099 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -185,6 +185,8 @@ // the URL bar security icon. private OnExitVrRequestListener mOnExitVrRequestListener; private Runnable mPendingExitVrRequest; + private Boolean mShowVrServicesUpdatePrompt; + private boolean mShowingDoffForGvrUpdate; private boolean mExitedDueToUnsupportedMode; private boolean mExitingCct; private boolean mPaused; @@ -672,8 +674,7 @@ // Enable VR mode and hide system UI. We do this here so we don't get kicked out of // VR mode and to prevent seeing a flash of system UI. setVrModeEnabled(activity, true); - activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - activity.getWindow().getDecorView().setSystemUiVisibility(VR_SYSTEM_UI_FLAGS); + setSystemUiVisibilityForVr(activity); } /** @@ -809,13 +810,17 @@ sRegisteredDaydreamHook = false; } + private static boolean isVrBrowsingSupported(ChromeActivity activity, VrDaydreamApi api) { + return activitySupportsVrBrowsing(activity) && !willChangeDensityInVr(activity) + && isDaydreamCurrentViewer(api); + } + /** * @return Whether or not VR Browsing is currently enabled for the given Activity. */ /* package */ static boolean isVrBrowsingEnabled( ChromeActivity activity, int vrSupportLevel, VrDaydreamApi api) { - return vrSupportLevel == VrSupportLevel.VR_DAYDREAM && activitySupportsVrBrowsing(activity) - && !willChangeDensityInVr(activity) && isDaydreamCurrentViewer(api); + return isVrBrowsingSupported(activity, api) && vrSupportLevel == VrSupportLevel.VR_DAYDREAM; } /* package */ static boolean isDaydreamCurrentViewer(VrDaydreamApi api) { @@ -1083,7 +1088,10 @@ if (getVrClassesWrapper() == null) return; int version = getVrCorePackageVersion(); // If VrCore package hasn't changed, no need to update. - if (version == mCachedVrCorePackageVersion) return; + if (version == mCachedVrCorePackageVersion + && !(mShowVrServicesUpdatePrompt != null && mShowVrServicesUpdatePrompt)) { + return; + } updateVrSupportLevel(version); } @@ -1171,9 +1179,7 @@ // If the page is listening for vrdisplayactivate we assume it wants to request // presentation. Go into WebVR mode tentatively. If the page doesn't request presentation - // in the vrdisplayactivate handler we will exit presentation later. Note that in the - // case of autopresentation, we don't want to enter WebVR mode so that we can show the - // splash screen. In this case, we enter WebVR mode when the site requests presentation. + // in the vrdisplayactivate handler we will exit presentation later. // Note that we don't want to dispatch vrdisplayactivate for auto-present and vr intents. boolean tentativeWebVrMode = mListeningForWebVrActivateBeforePause && !mRequestedWebVr && !mEnterVrOnStartup; @@ -1282,7 +1288,9 @@ // it's a reasonable assumption. mDonSucceeded = true; mEnterVrOnStartup = true; - if (!mPaused) enterVrAfterDon(); + mInVrAtChromeLaunch = true; + + nativeRecordVrStartAction(mNativeVrShellDelegate, VrStartAction.INTENT_LAUNCH); } private void onAutopresentIntent() { @@ -1291,6 +1299,7 @@ assert !mInVr; if (USE_HIDE_ANIMATION) mNeedsAnimationCancel = true; mAutopresentWebVr = true; + mEnterVrOnStartup = true; // We assume that the user is already in VR mode when launched for auto-presentation. mDonSucceeded = true; @@ -1340,7 +1349,6 @@ if (VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(intent)) { if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: autopresent"); assert activitySupportsAutopresentation(activity); - assert mVrSupportLevel == VrSupportLevel.VR_DAYDREAM; // TODO(mthiesse): This needs to be set here to correctly close the CCT when we early // exit here. We should use a different variable or refactor or something to make this @@ -1351,7 +1359,7 @@ return; } onAutopresentIntent(); - } else if (isVrBrowsingEnabled()) { + } else if (isVrBrowsingSupported(mActivity, mVrDaydreamApi)) { if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: vr"); onVrIntent(); } else { @@ -1434,6 +1442,12 @@ && orientation == Configuration.ORIENTATION_LANDSCAPE; } + private static void setSystemUiVisibilityForVr(Activity activity) { + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + int flags = activity.getWindow().getDecorView().getSystemUiVisibility(); + activity.getWindow().getDecorView().setSystemUiVisibility(flags | VR_SYSTEM_UI_FLAGS); + } + private void setWindowModeForVr() { // Decouple the compositor size from the view size, or we'll get an unnecessary resize due // to the orientation change when entering VR, then another resize once VR has settled on @@ -1442,7 +1456,6 @@ mActivity.getCompositorViewHolder().onEnterVr(); } ScreenOrientationDelegateManager.setOrientationDelegate(this); - mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // Set correct orientation. if (mRestoreOrientation == null) { @@ -1451,8 +1464,7 @@ mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // Hide system UI. - int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility(); - mActivity.getWindow().getDecorView().setSystemUiVisibility(flags | VR_SYSTEM_UI_FLAGS); + setSystemUiVisibilityForVr(mActivity); mRestoreSystemUiVisibility = true; } @@ -1596,6 +1608,17 @@ return true; } + private boolean maybeExitVrToUpdateVrServices() { + if (!mEnterVrOnStartup || mVrSupportLevel != VrSupportLevel.VR_NOT_AVAILABLE) return false; + // This means that we were started in VR mode but the vr services may be out of date. We + // should exit VR and prompt the user to update. + if (DEBUG_LOGS) Log.i(TAG, "VR services update needed"); + mShowingDoffForGvrUpdate = true; + showDoff(false /* optional */); + mEnterVrOnStartup = false; + return true; + } + protected void onResume() { if (DEBUG_LOGS) Log.i(TAG, "onResume"); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return; @@ -1640,7 +1663,9 @@ StrictMode.setThreadPolicy(oldPolicy); } - if (mVrSupportLevel != VrSupportLevel.VR_DAYDREAM) return; + // If mEnterVrOnStartup is set, we show DOFF in handleDonFlowSuccess below. + if (mVrSupportLevel != VrSupportLevel.VR_DAYDREAM && !mEnterVrOnStartup) return; + if (isVrBrowsingEnabled()) { // Perform slow initialization asynchronously. new Handler().post(new Runnable() { @@ -1662,12 +1687,7 @@ mCancellingEntryAnimation = false; } - if (mEnterVrOnStartup) { - // This means that Chrome was started with a VR intent, so we should enter VR. - assert !mProbablyInDon; - if (DEBUG_LOGS) Log.i(TAG, "onResume: entering VR mode for VR intent"); - enterVrAfterDon(); - } else if (mDonSucceeded) { + if (mDonSucceeded || mEnterVrOnStartup) { handleDonFlowSuccess(); } else { if (mProbablyInDon) { @@ -1685,6 +1705,7 @@ } mProbablyInDon = false; + mShowVrServicesUpdatePrompt = null; } private void handleDonFlowSuccess() { @@ -1694,8 +1715,9 @@ mDonSucceeded = false; return; } + if (maybeExitVrToUpdateVrServices()) return; // If we fail to enter VR when we should have entered VR, return to the home screen. - if (!mInVr && !enterVrAfterDon()) { + if (!enterVrAfterDon()) { cancelPendingVrEntry(); mVrDaydreamApi.launchVrHomescreen(); } @@ -1781,8 +1803,9 @@ if (!isDaydreamCurrentViewer()) return false; // To avoid taking the user out of VR mode when started for auto-presentation, never show - // DOFF and bail to Daydream if we're forced to leave Chrome. - if (!mAutopresentWebVr) { + // DOFF and bail to Daydream if we're forced to leave Chrome. We still show DOFF if VR + // services are out of date though. + if (!mAutopresentWebVr || mShowingDoffForGvrUpdate) { try { if (mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) { mShowingDaydreamDoff = true; @@ -1799,7 +1822,7 @@ } private void onExitVrResult(boolean success) { - assert mVrSupportLevel != VrSupportLevel.VR_NOT_AVAILABLE; + if (DEBUG_LOGS) Log.i(TAG, "returned from DOFF, success: " + success); // We may have manually handled the exit early by swapping to another Chrome activity that // supports VR while in the DOFF activity. If that happens we want to exit early when the @@ -1812,12 +1835,20 @@ if (!mDoffOptional && !success) mVrDaydreamApi.launchVrHomescreen(); mShowingDaydreamDoff = false; + + if (mShowingDoffForGvrUpdate) { + mShowVrServicesUpdatePrompt = success; + handleFinishAutopresentation(); + } + if (success) { shutdownVr(true /* disableVrMode */, !mExitingCct /* stayingInChrome */); if (mExitingCct) ((CustomTabActivity) mActivity).finishAndClose(false); } + mExitingCct = false; callOnExitVrRequestListener(success); + mShowingDoffForGvrUpdate = false; } private boolean isDaydreamCurrentViewer() { @@ -1851,6 +1882,7 @@ } private void cancelPendingVrEntry() { + if (DEBUG_LOGS) Log.i(TAG, "cancelPendingVrEntry"); removeBlackOverlayView(mActivity); mDonSucceeded = false; maybeSetPresentResult(false, false); @@ -1864,6 +1896,7 @@ * Exits VR Shell, performing all necessary cleanup. */ protected void shutdownVr(boolean disableVrMode, boolean stayingInChrome) { + if (DEBUG_LOGS) Log.i(TAG, "shuttdown VR"); cancelPendingVrEntry(); // Ensure shutdownVr runs if we're stopping. if (handleFinishAutopresentation() && !mStopped) return; @@ -1990,7 +2023,12 @@ * Returns true if finishing auto-presentation was handled. */ private boolean handleFinishAutopresentation() { - if (!mAutopresentWebVr) return false; + // We keep the activity alive when we're returning from DOFF and need to show the GVR update + // infobar. + boolean willPromptForUpdateOnVrExit = mShowingDoffForGvrUpdate + && mShowVrServicesUpdatePrompt != null && mShowVrServicesUpdatePrompt; + if (!mAutopresentWebVr || willPromptForUpdateOnVrExit) return false; + if (DEBUG_LOGS) Log.i(TAG, "killing activity started for auto-presentation"); // Should only autopresent CustomTabActivity for now. assert mActivity instanceof CustomTabActivity; ((CustomTabActivity) mActivity).finishAndClose(false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 1ce0485..0e3f8ba5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -85,7 +85,8 @@ /** The different reasons that the sheet's state can change. */ @IntDef({StateChangeReason.NONE, StateChangeReason.SWIPE, StateChangeReason.BACK_PRESS, - StateChangeReason.TAP_SCRIM, StateChangeReason.NAVIGATION}) + StateChangeReason.TAP_SCRIM, StateChangeReason.NAVIGATION, + StateChangeReason.COMPOSITED_UI}) @Retention(RetentionPolicy.SOURCE) public @interface StateChangeReason { int NONE = 0; @@ -93,6 +94,7 @@ int BACK_PRESS = 2; int TAP_SCRIM = 3; int NAVIGATION = 4; + int COMPOSITED_UI = 5; } /** The different priorities that the sheet's content can have. */ @@ -1158,6 +1160,11 @@ for (BottomSheetObserver o : mObservers) o.onSheetOffsetChanged(mLastOffsetRatioSent); + if (MathUtils.areFloatsEqual( + offsetWithBrowserControls, getSheetHeightForState(SHEET_STATE_PEEK))) { + for (BottomSheetObserver o : mObservers) o.onSheetFullyPeeked(); + } + // This ratio is relative to the peek and half positions of the sheet. float peekHalfRatio = MathUtils.clamp( (screenRatio - getPeekRatio()) / (getHalfRatio() - getPeekRatio()), 0, 1);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java index 1d6bd600..5c5fc7b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java
@@ -14,6 +14,9 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.StaticLayout; +import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; +import org.chromium.chrome.browser.contextualsearch.ContextualSearchObserver; +import org.chromium.chrome.browser.gsa.GSAContextDisplaySelection; import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -26,6 +29,8 @@ import java.util.PriorityQueue; +import javax.annotation.Nullable; + /** * This class is responsible for managing the content shown by the {@link BottomSheet}. Features * wishing to show content in the {@link BottomSheet} UI must implement {@link BottomSheetContent} @@ -54,16 +59,20 @@ /** Track whether the sheet was shown for the current tab. */ private boolean mWasShownForCurrentTab; + /** Whether composited UI is currently showing (such as Contextual Search). */ + private boolean mIsCompositedUIShowing; + /** * Build a new controller of the bottom sheet. * @param tabModelSelector A tab model selector to track events on tabs open in the browser. * @param layoutManager A layout manager for detecting changes in the active layout. * @param fadingBackgroundView The scrim that shows when the bottom sheet is opened. + * @param contextualSearchManager The manager for Contextual Search to attach listeners to. * @param bottomSheet The bottom sheet that this class will be controlling. */ public BottomSheetController(final Activity activity, final TabModelSelector tabModelSelector, final LayoutManager layoutManager, final FadingBackgroundView fadingBackgroundView, - BottomSheet bottomSheet) { + ContextualSearchManager contextualSearchManager, BottomSheet bottomSheet) { mBottomSheet = bottomSheet; mLayoutManager = layoutManager; mSnackbarManager = new SnackbarManager( @@ -151,6 +160,34 @@ } }); + // TODO(mdjones): This should be changed to a generic OverlayPanel observer. + if (contextualSearchManager != null) { + contextualSearchManager.addObserver(new ContextualSearchObserver() { + /** Whether the bottom sheet was showing prior to contextual search appearing. */ + private boolean mWasSheetShowing; + + @Override + public void onShowContextualSearch( + @Nullable GSAContextDisplaySelection selectionContext) { + mWasSheetShowing = mBottomSheet.getSheetState() == BottomSheet.SHEET_STATE_PEEK; + mIsCompositedUIShowing = true; + mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_HIDDEN, false, + BottomSheet.StateChangeReason.COMPOSITED_UI); + } + + @Override + public void onHideContextualSearch() { + mIsCompositedUIShowing = false; + if (mBottomSheet.getCurrentSheetContent() != null && mWasSheetShowing) { + mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true); + } else { + showNextContent(); + } + mWasSheetShowing = false; + } + }); + } + // Initialize the queue with a comparator that checks content priority. mContentQueue = new PriorityQueue<>(INITIAL_QUEUE_CAPACITY, (content1, content2) -> content2.getPriority() - content1.getPriority()); @@ -181,7 +218,7 @@ public boolean requestShowContent(BottomSheetContent content, boolean animate) { // If pre-load failed, do nothing. The content will automatically be queued. if (!requestContentPreload(content)) return false; - if (!mBottomSheet.isSheetOpen()) { + if (!mBottomSheet.isSheetOpen() && !isOtherUIObscuring()) { mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, animate); } mWasShownForCurrentTab = true; @@ -304,6 +341,13 @@ } /** + * @return Whether some other UI is preventing the sheet from showing. + */ + protected boolean isOtherUIObscuring() { + return mIsCompositedUIShowing; + } + + /** * @return Whether the sheet currently supports switching its content. */ protected boolean canBottomSheetSwitchContent() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserver.java index 0077e86..85637b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserver.java
@@ -69,6 +69,13 @@ void onSheetStateChanged(@SheetState int newState); /** + * An event for when the sheet reaches its full peeking height. This is called when the sheet + * is finished being scrolled back on-screen or finishes animating to its peeking state. This + * is also called when going back to the peeking state after the sheet has been opened. + */ + void onSheetFullyPeeked(); + + /** * An event for when the sheet content changes. * @param newContent The new {@link BottomSheetContent}, or null if the sheet has no content. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/EmptyBottomSheetObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/EmptyBottomSheetObserver.java index d37e0b30..452800f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/EmptyBottomSheetObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/EmptyBottomSheetObserver.java
@@ -33,5 +33,8 @@ public void onSheetStateChanged(int newState) {} @Override + public void onSheetFullyPeeked() {} + + @Override public void onSheetContentChanged(BottomSheetContent newContent) {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java index 0d9aadb4..24c749b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
@@ -122,6 +122,8 @@ private int mModernToolbarSearchIconOffsetPx; private boolean mIsDestroyed; + private boolean mShowInfoItem; + private boolean mInfoShowing; /** * Constructor for inflating from XML. @@ -200,6 +202,9 @@ if (!FeatureUtilities.isChromeModernDesignEnabled()) { setTitleTextAppearance(getContext(), R.style.BlackHeadline2); } + + VrShellDelegate.registerVrModeObserver(this); + if (VrShellDelegate.isInVr()) onEnterVr(); } @Override @@ -208,12 +213,14 @@ // searching. mIsVrEnabled = true; if (mHasSearchView) updateSearchMenuItem(); + updateInfoMenuItem(mShowInfoItem, mInfoShowing); } @Override public void onExitVr() { mIsVrEnabled = false; if (mHasSearchView) updateSearchMenuItem(); + updateInfoMenuItem(mShowInfoItem, mInfoShowing); } /** @@ -268,9 +275,6 @@ getResources().getDimensionPixelSize(R.dimen.clear_text_button_end_padding), mClearTextButton.getPaddingBottom()); } - - VrShellDelegate.registerVrModeObserver(this); - if (VrShellDelegate.isInVr()) onEnterVr(); } @Override @@ -637,6 +641,8 @@ * @param infoShowing Whether or not info header is currently showing. */ public void updateInfoMenuItem(boolean showItem, boolean infoShowing) { + mShowInfoItem = showItem; + mInfoShowing = infoShowing; MenuItem infoMenuItem = getMenu().findItem(mInfoMenuItemId); if (infoMenuItem != null) { Drawable iconDrawable = @@ -644,7 +650,16 @@ infoShowing ? R.color.light_active_color : R.color.light_normal_color); infoMenuItem.setIcon(iconDrawable); - infoMenuItem.setTitle(infoShowing ? R.string.hide_info : R.string.show_info); + if (VrShellDelegate.isInVr()) { + // There seems to be a bug with the support library, only on Android N, where the + // toast showing the title shows up every time the info menu item is clicked or + // scrolled on, even if its long press handler is overridden. VR on N doesn't + // support toasts, which render monocularly over top of VR content, so we need to + // disable it. + infoMenuItem.setTitle(""); + } else { + infoMenuItem.setTitle(infoShowing ? R.string.hide_info : R.string.show_info); + } infoMenuItem.setVisible(showItem); } }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 66d5c2c..7b819a03 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2448,6 +2448,11 @@ Refresh </message> + <!-- Contextual suggestions strings --> + <message name="IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP" desc="The string displayed in an in-product help bubble when contextual suggestions are displayed for the first time. The bubble points to a swipeable panel containing suggestions related to the webpage the user is currently viewing."> + See more like this from Google + </message> + <!-- Toolbar button strings --> <message name="IDS_OPEN_TABS" desc="Text for button to enter the tab switcher and show tabs that are open on this device"> Open tabs
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb b/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb index 43593d73..64ad3b6 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb
@@ -284,6 +284,7 @@ <translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> <translation id="3662546969139119822">No history here</translation> <translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> <translation id="3712575778697986964">Reset Data Saver?</translation> <translation id="3714981814255182093">Open the Find Bar</translation> <translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> @@ -320,6 +321,7 @@ <translation id="4056223980640387499">Sepia</translation> <translation id="4062305924942672200">Legal information</translation> <translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> <translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> <translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> <translation id="4095146165863963773">Delete app data?</translation> @@ -369,6 +371,7 @@ <translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> <translation id="4558311620361989323">Web page shortcuts</translation> <translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> <translation id="4572422548854449519">Sign in to managed account</translation> <translation id="4581964774250883625">You’ve gone incognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> @@ -545,6 +548,7 @@ <translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> <translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> <translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> <translation id="6112702117600201073">Refreshing page</translation> <translation id="6127379762771434464">Item removed</translation> <translation id="6138140242378429169">Make page mobile-friendly</translation> @@ -697,6 +701,7 @@ <translation id="748127970106343339">Confirm device credential deletion</translation> <translation id="7481312909269577407">Forward</translation> <translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494974237137038751">data saved</translation> <translation id="7498271377022651285">Please wait…</translation> <translation id="7514365320538308">Download</translation> <translation id="751961395872307827">Can't connect to the site</translation>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarVoiceRecognitionHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarVoiceRecognitionHandlerTest.java index 5f6d994..c48f120e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarVoiceRecognitionHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarVoiceRecognitionHandlerTest.java
@@ -215,7 +215,7 @@ } @Override - public boolean isDisplayingQueryTerms() { + public boolean shouldDisplaySearchTerms() { return false; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserverTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserverTestRule.java index 1d3945a..a6316be 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserverTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserverTestRule.java
@@ -104,6 +104,11 @@ } @Override + public boolean isCurrentModel(TabModel model) { + return false; + } + + @Override public boolean isInOverviewMode() { return false; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java index 4d6a39e6..41256d6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
@@ -223,6 +223,11 @@ public boolean isSessionRestoreInProgress() { return false; } + + @Override + public boolean isCurrentModel(TabModel model) { + return false; + } } static class MockTabPersistentStoreObserver extends TabPersistentStoreObserver {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/MockDocumentTabModel.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/MockDocumentTabModel.java index d6de382..1b9bb87 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/MockDocumentTabModel.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/MockDocumentTabModel.java
@@ -123,6 +123,11 @@ } @Override + public boolean isCurrentModel() { + return false; + } + + @Override public int index() { Assert.fail(); return 0;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java index 7054b85b..a87dae8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.vr_shell.mock; -import android.content.Context; import android.content.Intent; import org.chromium.chrome.browser.vr_shell.VrIntentUtils; @@ -34,11 +33,6 @@ return false; } - @Override - public boolean canHandleVrIntent(Context context) { - return true; - } - public void setUseMockImplementation(boolean enabled) { mUseMockImplementation = enabled; }
diff --git a/chrome/android/monochrome/scripts/monochrome_apk_checker.py b/chrome/android/monochrome/scripts/monochrome_apk_checker.py index 2e2ddfc9..c1e60920 100755 --- a/chrome/android/monochrome/scripts/monochrome_apk_checker.py +++ b/chrome/android/monochrome/scripts/monochrome_apk_checker.py
@@ -54,7 +54,7 @@ r'resources\.arsc', r'classes\.dex', r'res/.*\.xml', # Resource id isn't same - r'assets/unwind_cfi', # Generated from apk's shared library + r'assets/unwind_cfi_32', # Generated from apk's shared library # All pak files except chrome_100_percent.pak are different r'assets/resources\.pak', r'assets/am\.pak',
diff --git a/chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json b/chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json index b72c69d..1d8aedbe 100644 --- a/chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json +++ b/chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json
@@ -9,7 +9,7 @@ "VrDeviceParams": "CgZHb29nbGUSCUNhcmRib2FyZB0J-SA9JQHegj0qEAAAcEIAAHBCAABwQgAAcEI1KVwPPToIV_GrPmKxDT9QAFgAYAM", "UseAutomatedController": false, "GvrPlatformLibraryPref": false, - "EnableVrCoreHeadTracking": true + "EnableVrCoreHeadTracking": false } } ]
diff --git a/chrome/android/shared_preference_files/test/vr_ddview_don_setupcomplete.json b/chrome/android/shared_preference_files/test/vr_ddview_don_setupcomplete.json index 9e1e2b4..ecfb927 100644 --- a/chrome/android/shared_preference_files/test/vr_ddview_don_setupcomplete.json +++ b/chrome/android/shared_preference_files/test/vr_ddview_don_setupcomplete.json
@@ -2,13 +2,15 @@ { "package": "com.google.vr.vrcore", "filename": "VrCoreSettings.xml", + "supports_encrypted_path": true, "set": { "VrSkipDon": false, "DaydreamSetupComplete": true, "VrDeviceParams": "CgxHb29nbGUsIEluYy4SDURheWRyZWFtIFZpZXcdCfkgPSUB3oI9KhAAAFxCAABcQgAAXEIAAFxCNd9PDT06CLgexT7Zzhc_WABgAJqRYBoIARIKDQAAAAAV9P3UPBIKDQAAAAAV9P3UvA", "UseAutomatedController": false, "PairedControllerDriver": "DRIVER_P6", - "PairedControllerAddress": "AA:AA:AA:AA:AA:AA" + "PairedControllerAddress": "AA:AA:AA:AA:AA:AA", + "EnableVrCoreHeadTracking": false } } ]
diff --git a/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json b/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json index 11dd340..1c27f12 100644 --- a/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json +++ b/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json
@@ -11,7 +11,7 @@ "PairedControllerDriver": "DRIVER_AUTOMATED", "PairedControllerAddress": "FOO", "GvrPlatformLibraryPref": false, - "EnableVrCoreHeadTracking": true + "EnableVrCoreHeadTracking": false } } ]
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 4b47f0e..56779c4 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -4864,10 +4864,13 @@ Lock screen notes are automatically saved to <ph name="LOCK_SCREEN_APP_NAME">$1<ex>Lock Screen Enabled App</ex></ph>. Your most recent note will remain on the lock screen. </message> - <!-- Launcher Searchable Chrome OS apps --> - <message name="IDS_LAUNCHER_SEARCHABLE_APP_KEYBOARD_SHORTCUT_VIEWER" desc="The string can be used to search keyboard shortcut viewer app."> + <!-- Launcher Searchable Chrome OS internal apps --> + <message name="IDS_INTERNAL_APP_KEYBOARD_SHORTCUT_VIEWER" desc="The string can be used to search keyboard shortcut viewer app."> Keyboard Shortcut Helper </message> + <message name="IDS_INTERNAL_APP_SETTINGS" desc="The string can be used to search Settings."> + Settings + </message> <message name="IDS_CROSTINI_INSTALLER_TITLE" desc="Title of the Crostini installer, a dialog for installing the 'Terminal'."> <ph name="APP_NAME">$1<ex>Terminal</ex></ph> for <ph name="DEVICE_TYPE">$2<ex>Chromebook</ex></ph>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 4c92453..df36eee 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8200,7 +8200,7 @@ </message> <if expr="not chromeos"> <message name="IDS_SYNC_RELOGIN_ERROR" desc="The text to display on in the hyperlink when the user needs to sign in again to use sync."> - Sign in again to start sync + Sign in again to resume sync </message> </if> <if expr="chromeos">
diff --git a/chrome/app/nibs/BUILD.gn b/chrome/app/nibs/BUILD.gn index 46f24f4..0010724 100644 --- a/chrome/app/nibs/BUILD.gn +++ b/chrome/app/nibs/BUILD.gn
@@ -14,11 +14,6 @@ "CookieDetailsView.xib", "DownloadItem.xib", "DownloadShelf.xib", - "ExtensionInstallPrompt.xib", - "ExtensionInstallPromptNoWarnings.xib", - "ExtensionInstallPromptWebstoreData.xib", - "ExtensionInstalledBubble.xib", - "HttpAuthLoginSheet.xib", "HungRendererDialog.xib", "MainMenu.xib", "OneClickSigninBubble.xib", @@ -42,6 +37,11 @@ "ContentBlockedPopups.xib", "ContentBlockedSimple.xib", "ContentProtocolHandlers.xib", + "ExtensionInstallPrompt.xib", + "ExtensionInstallPromptNoWarnings.xib", + "ExtensionInstallPromptWebstoreData.xib", + "ExtensionInstalledBubble.xib", + "HttpAuthLoginSheet.xib", ] }
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index 971bf3f6..13d62464 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -5030,7 +5030,7 @@ <translation id="8977811652087512276">Contrasenya incorrecta o fitxer malmès</translation> <translation id="8978154919215542464">Activat: se sincronitza tot</translation> <translation id="8980951173413349704"><ph name="WINDOW_TITLE" />: ha fallat</translation> -<translation id="8986362086234534611">Esborra</translation> +<translation id="8986362086234534611">Oblida</translation> <translation id="8986494364107987395">Envia automàticament estadístiques d'ús i informes d'error a Google</translation> <translation id="8987927404178983737">Mes</translation> <translation id="8991520179165052608">El lloc web pot utilitzar el micròfon</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index 53165b5..45c19f4 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -70,6 +70,7 @@ <translation id="1108164192735968833">SMS Connect</translation> <translation id="1108600514891325577">&Stop</translation> <translation id="1110155001042129815">Wait</translation> +<translation id="1112420131909513020">Background tab is using Bluetooth</translation> <translation id="1114102982691049955"><ph name="PRINTER_MANUFACTURER" /> <ph name="PRINTER_MODEL" /> (USB)</translation> <translation id="1114202307280046356">Diamond</translation> <translation id="1114335938027186412">Your computer contains a Trusted Platform Module (TPM) security device, which is used to implement many critical security features in Chrome OS. Visit the Chromebook Help Centre to find out more: https://support.google.com/chromebook/?p=tpm</translation> @@ -153,6 +154,7 @@ <ph name="BR" /> On the next screen, please send feedback to help us fix the issue.</translation> <translation id="121783623783282548">Passwords do not match.</translation> +<translation id="1218860753635451122">By clicking the 'I Agree' button, you agree to the processing described above for these Google services.</translation> <translation id="122082903575839559">Certificate Signature Algorithm</translation> <translation id="1221024147024329929">PKCS #1 MD2 With RSA Encryption</translation> <translation id="1221825588892235038">Selection only</translation> @@ -192,6 +194,7 @@ <translation id="1285320974508926690">Never translate this site</translation> <translation id="1285484354230578868">Store data in your Google Drive account</translation> <translation id="1288037062697528143">Night Light will turn on automatically at sunset</translation> +<translation id="1288300545283011870">Speech Properties</translation> <translation id="1293177648337752319">Unmute Site</translation> <translation id="1293509594570842875">The new supervised user couldn't be created. Please check your network connection and try again later.</translation> <translation id="1293556467332435079">Files</translation> @@ -419,6 +422,7 @@ <translation id="1624026626836496796">This will only happen once, and your credentials will not be stored.</translation> <translation id="1627276047960621195">File Descriptors</translation> <translation id="1627408615528139100">Already downloaded</translation> +<translation id="1632551555529177478">ERROR: Failed to start Concierge client.</translation> <translation id="1632803087685957583">Allows you to adjust your keyboard repeat rate, word prediction and more</translation> <translation id="1635033183663317347">Installed by your custodian.</translation> <translation id="1637224376458524414">Get this bookmark on your iPhone</translation> @@ -517,6 +521,7 @@ <translation id="177336675152937177">Hosted app data</translation> <translation id="1774349594977710164">Your phone also unlocks your other <ph name="DEVICE_TYPE" />s because they are automatically synced.</translation> <translation id="1774833706453699074">Bookmark open pages...</translation> +<translation id="1775381402323441512">Video info</translation> <translation id="1776883657531386793"><ph name="OID" />: <ph name="INFO" /></translation> <translation id="177694132944350798">Your data was encrypted with your Google password as of <ph name="TIME" />. Enter it to start sync.</translation> <translation id="1779652936965200207">Please enter this passkey on "<ph name="DEVICE_NAME" />":</translation> @@ -536,6 +541,7 @@ <translation id="180035236176489073">You must be online to access these files.</translation> <translation id="1802687198411089702">The page isn't responding. You can wait for it or exit.</translation> <translation id="1802931390041703523">Flash was blocked on this page</translation> +<translation id="1805738995123446102">Background tab is using your microphone</translation> <translation id="1805822111539868586">Inspect views</translation> <translation id="1807938677607439181">All files</translation> <translation id="1809734401532861917">Add my bookmarks, history, passwords and other settings to <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -558,6 +564,7 @@ <translation id="1829192082282182671">Zoom &Out</translation> <translation id="1830550083491357902">Not signed in</translation> <translation id="1832511806131704864">Phone change updated</translation> +<translation id="1834503245783133039">Download unsuccessful: <ph name="FILE_NAME" /></translation> <translation id="1838374766361614909">Clear search</translation> <translation id="1838709767668011582">Google site</translation> <translation id="1839704667838141620">Change how this file is shared</translation> @@ -672,6 +679,7 @@ <translation id="2040460856718599782">Oops! Something went wrong when trying to authenticate you. Please double-check your sign-in credentials and try again.</translation> <translation id="2043818754674261542">Distance needed for phone to unlock this <ph name="DEVICE_TYPE" /></translation> <translation id="204497730941176055">Microsoft Certificate Template Name</translation> +<translation id="2045117674524495717">Keyboard Shortcut Helper</translation> <translation id="2045969484888636535">Continue blocking cookies</translation> <translation id="204622017488417136">Your device will be returned to the previously installed version of Chrome. All user accounts and local data will be removed. This cannot be undone.</translation> <translation id="2048182445208425546">Access your network traffic</translation> @@ -693,6 +701,7 @@ <translation id="2079053412993822885">If you delete one of your own certificates, you can no longer use it to identify yourself.</translation> <translation id="2079545284768500474">Undo</translation> <translation id="2080070583977670716">More settings</translation> +<translation id="2084108471225856927">Device settings</translation> <translation id="2085470240340828803">A file named "<ph name="FILENAME" />" already exists. What do you want to do?</translation> <translation id="2087822576218954668">Print: <ph name="PRINT_NAME" /></translation> <translation id="2089566709556890888">Browse safely with Google Chrome</translation> @@ -806,6 +815,7 @@ <translation id="2239921694246509981">Add supervised person</translation> <translation id="2241053333139545397">Read and change your data on a number of websites</translation> <translation id="2242687258748107519">File Info</translation> +<translation id="2243194103992005307">To remove apps, go to Settings > Apps or Application manager. Then tap the app that you want to uninstall (you may need to swipe right or left to find the app). Then tap Uninstall or Disable.</translation> <translation id="2245240762616536227">Control how your browsing history personalises Search, ads and other Google services</translation> <translation id="2249605167705922988">e.g. 1-5, 8, 11-13</translation> <translation id="2251218783371366160">Open with system viewer</translation> @@ -824,6 +834,7 @@ <translation id="2270627217422354837">Exchange data with any device in the domains: <ph name="DOMAINS" /></translation> <translation id="2271088077909873520">Manage your synced data on <ph name="BEGIN_LINK" />Google Dashboard<ph name="END_LINK" />.</translation> <translation id="2272570998639520080">Martini glass</translation> +<translation id="2275685295206198038">Finished installing <ph name="APP_NAME" />.</translation> <translation id="2276503375879033601">Add More Apps</translation> <translation id="2277255602909579701">All cookies and site data</translation> <translation id="2277769717710009150">{COUNT,plural, =1{1 item copied}other{# items copied}}</translation> @@ -863,6 +874,7 @@ <translation id="2335122562899522968">This page has set cookies.</translation> <translation id="2336228925368920074">Bookmark All Tabs...</translation> <translation id="2336381494582898602">Powerwash</translation> +<translation id="2338776671779155318">ERROR: Failed to create disk image.</translation> <translation id="2339120501444485379">Enter new name</translation> <translation id="2339641773402824483">Checking for updates...</translation> <translation id="2340263603246777781"><ph name="ORIGIN" /> wants to pair</translation> @@ -882,6 +894,7 @@ <translation id="2359808026110333948">Continue</translation> <translation id="236141728043665931">Always block microphone access</translation> <translation id="2365507699358342471">This site can see text and images copied to the clipboard.</translation> +<translation id="2367199180085172140">Add File Share</translation> <translation id="2367972762794486313">Show apps</translation> <translation id="2371076942591664043">Open when &done</translation> <translation id="2377319039870049694">Switch to list view</translation> @@ -1061,10 +1074,12 @@ <translation id="264810637653812429">No compatible devices found.</translation> <translation id="2648831393319960979">Adding the device to your account – this may take a moment...</translation> <translation id="2649045351178520408">Base64-encoded ASCII, certificate chain</translation> +<translation id="2651353619134567122">Send system data. This device currently automatically sends diagnostic and device and app usage data to Google. You can change this at any time in your device <ph name="BEGIN_LINK1" />settings<ph name="END_LINK1" />. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK2" />Learn More<ph name="END_LINK2" /></translation> <translation id="2653033005692233957">Search failed</translation> <translation id="2653266418988778031">If you delete a Certification Authority (CA) certificate, your browser will no longer trust any certificates issued by that CA.</translation> <translation id="2653659639078652383">Submit</translation> <translation id="265390580714150011">Field Value</translation> +<translation id="2654166010170466751">Allow sites to install payment handlers</translation> <translation id="2655386581175833247">User certificate:</translation> <translation id="2660779039299703961">Event</translation> <translation id="266079277508604648">Can’t connect to printer. Check that the printer is turned on and is connected to your Chromebook by Wi-Fi or USB.</translation> @@ -1301,6 +1316,7 @@ <translation id="2986010903908656993">This page has been blocked from having full control of MIDI devices.</translation> <translation id="2989474696604907455">not attached</translation> <translation id="2989786307324390836">DER-encoded binary, single certificate</translation> +<translation id="2993165626813508977">ERROR: Failed to start container inside Termina VM.</translation> <translation id="2993517869960930405">App Info</translation> <translation id="2994669386200004489">Couldn't back up <ph name="FILE_NAME" /></translation> <translation id="299483336428448530">Installed by your parent.</translation> @@ -1353,6 +1369,7 @@ <translation id="3045447014237878114">This site downloaded multiple files automatically</translation> <translation id="304567287000691532">Sharing screen</translation> <translation id="3046910703532196514">Web Page, Complete</translation> +<translation id="304747341537320566">Speech Engines</translation> <translation id="304826556400666995">Unmute Tabs</translation> <translation id="3053013834507634016">Certificate Key Usage</translation> <translation id="3057861065630527966">Backup your photos and videos</translation> @@ -1361,6 +1378,7 @@ <translation id="3064410671692449875">Insufficient data</translation> <translation id="3065041951436100775">Tab killed feedback.</translation> <translation id="3066642396596108483">Sync your bookmarks, passwords and history on all your devices</translation> +<translation id="3067198179881736288">Install app?</translation> <translation id="3067198360141518313">Run this plug-in</translation> <translation id="3071624960923923138">You can click here to open a new tab</translation> <translation id="3074037959626057712">You've signed in and turned on Sync</translation> @@ -1406,10 +1424,13 @@ <translation id="3130528281680948470">Your device will be reset and all user accounts and local data will be removed. This cannot be undone.</translation> <translation id="313205617302240621">Forgot password?</translation> <translation id="3135204511829026971">Rotate screen</translation> +<translation id="313963229645891001">Downloading, <ph name="STATUS" /></translation> <translation id="3139925690611372679">Default yellow avatar</translation> <translation id="3140353188828248647">Focus address bar</translation> <translation id="3141318088920353606">Listening...</translation> <translation id="3141917231319778873">The given request is not supported to: "<ph name="DEVICE_NAME" />".</translation> +<translation id="3143515551205905069">Cancel sync</translation> +<translation id="3143695347784622594">Send system data. Automatically send diagnostic and device and app usage data to Google. You can change this at any time in your device <ph name="BEGIN_LINK1" />settings<ph name="END_LINK1" />. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK2" />Learn More<ph name="END_LINK2" /></translation> <translation id="3144126448740580210">DONE</translation> <translation id="3144647712221361880">Open link as</translation> <translation id="3149510190863420837">Chrome Apps</translation> @@ -1448,6 +1469,7 @@ <translation id="3206175707080061730">A file named "$1" already exists. Do you want to replace it?</translation> <translation id="3208703785962634733">Unconfirmed</translation> <translation id="3213187967168344806">Can’t add printer. Restart your computer and try again.</translation> +<translation id="3217843140356091325">Create shortcut?</translation> <translation id="321799795901478485">Zip Archiver</translation> <translation id="3220586366024592812">The <ph name="CLOUD_PRINT_NAME" /> connector process has crashed. Restart?</translation> <translation id="3221634914176615296">Explore the device's content in the Files app.</translation> @@ -1530,6 +1552,7 @@ <translation id="3326821416087822643">Zipping <ph name="FILE_NAME" />...</translation> <translation id="3331321258768829690">(<ph name="UTCOFFSET" />) <ph name="LONGTZNAME" /> (<ph name="EXEMPLARCITY" />)</translation> <translation id="3331974543021145906">App info</translation> +<translation id="3335337277364016868">Year recorded</translation> <translation id="3335947283844343239">Re-open Closed Tab</translation> <translation id="3340978935015468852">settings</translation> <translation id="3341703758641437857">Allow access to file URLs</translation> @@ -1592,6 +1615,7 @@ <translation id="3435738964857648380">Security</translation> <translation id="3435896845095436175">Enable</translation> <translation id="3436038974659740746">Customised spelling</translation> +<translation id="3437801641691368414">Created time</translation> <translation id="3438633801274389918">Ninja</translation> <translation id="3439153939049640737">Always allow <ph name="HOST" /> to access your microphone</translation> <translation id="3439970425423980614">Opening PDF in Preview</translation> @@ -1635,6 +1659,7 @@ <translation id="3487007233252413104">anonymous function</translation> <translation id="348780365869651045">Waiting for AppCache...</translation> <translation id="3488065109653206955">Partially activated</translation> +<translation id="348999362308956431">Download complete: <ph name="FILE_NAME" /></translation> <translation id="3492788708641132712">Sync isn’t working. Try signing in again.</translation> <translation id="3493881266323043047">Validity</translation> <translation id="3494769164076977169">Ask when a site tries to download files automatically after the first file (recommended)</translation> @@ -1724,6 +1749,7 @@ <translation id="3627320433825461852">Less than 1 minute left</translation> <translation id="3627588569887975815">Open link in inco&gnito window</translation> <translation id="3627671146180677314">Netscape Certificate Renewal Time</translation> +<translation id="3627879631695760395">Install <ph name="APP" />…</translation> <translation id="3630995161997703415">Add this site to your shelf to use it at any time</translation> <translation id="3635030235490426869">Tab 1</translation> <translation id="3636096452488277381">Hi, <ph name="USER_GIVEN_NAME" />.</translation> @@ -1736,6 +1762,7 @@ <translation id="3646789916214779970">Reset to default theme</translation> <translation id="3648348069317717750"><ph name="USB_DEVICE_NAME" /> detected</translation> <translation id="3649138363871392317">Photo was captured</translation> +<translation id="3650952250015018111">Allow '<ph name="APP_NAME" />' to access:</translation> <translation id="3651488188562686558">Disconnect from Wi-Fi</translation> <translation id="3652817283076144888">Initialising</translation> <translation id="3653999333232393305">Continue allowing <ph name="HOST" /> to access your microphone</translation> @@ -1848,6 +1875,7 @@ <translation id="381202950560906753">Add another</translation> <translation id="3812525830114410218">Bad certificate</translation> <translation id="3813296892522778813">Go to <ph name="BEGIN_LINK_CHROMIUM" />Google Chrome help<ph name="END_LINK_CHROMIUM" /> if you can't find what you're looking for</translation> +<translation id="3817579325494460411">Not provided</translation> <translation id="3819007103695653773">Allow all sites to send background push messages</translation> <translation id="3819752733757735746">Switch access (control the computer with just one or two switches)</translation> <translation id="3819800052061700452">&Full screen</translation> @@ -1941,6 +1969,7 @@ <translation id="394984172568887996">Imported From IE</translation> <translation id="3950820424414687140">Sign in</translation> <translation id="3954354850384043518">In progress</translation> +<translation id="3954469006674843813"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (<ph name="REFRESH_RATE" /> Hertz)</translation> <translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> <translation id="3956702100721821638">Couldn't reach Google Play</translation> <translation id="3958088479270651626">Import bookmarks and settings</translation> @@ -1961,6 +1990,7 @@ <translation id="3979748722126423326">Enable <ph name="NETWORKDEVICE" /></translation> <translation id="3981760180856053153">Invalid save type entered.</translation> <translation id="3983586614702900908">devices from an unknown vendor</translation> +<translation id="3985261842049607969">Back up to Google Drive. Easily restore your data or switch device at any time. Your backup includes app data. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="3987348946546879621">Saved data</translation> <translation id="3987938432087324095">Sorry, didn't catch that.</translation> <translation id="3988996860813292272">Select Time Zone</translation> @@ -1986,6 +2016,7 @@ <translation id="4033471457476425443">Add new folder</translation> <translation id="4034042927394659004">Decrease key brightness</translation> <translation id="4035758313003622889">&Task manager</translation> +<translation id="4036758022112812315">Highlight what you want to hear, then press Search + S. Or, press and hold Search, then click or drag to select content.</translation> <translation id="4037084878352560732">Horse</translation> <translation id="4037889604535939429">Edit person</translation> <translation id="4042264909745389898">Google Chrome OS terms</translation> @@ -2018,6 +2049,7 @@ <ph name="EXTENSION_FILE" /></translation> <translation id="4087470595660267445">Install apps and games from Google Play on your Chromebook. <a target='_blank' href='<ph name="URL" />'>Learn more</a></translation> <translation id="4088095054444612037">Accept for group</translation> +<translation id="4089235344645910861">Settings saved. Sync started.</translation> <translation id="4090103403438682346">Enable Verified Access</translation> <translation id="4090535558450035482">(This extension is managed and cannot be removed.)</translation> <translation id="4091434297613116013">sheets of paper</translation> @@ -2028,6 +2060,7 @@ <translation id="4096824249111507322">Secure module is being prepared, please wait (this may take a few minutes)...</translation> <translation id="4099060993766194518">Restore default search engine?</translation> <translation id="4100733287846229632">Device space critically low</translation> +<translation id="4103091233824664032">Enter your password to configure screen lock and sign-in</translation> <translation id="4104163789986725820">E&xport...</translation> <translation id="4105563239298244027">Get 1 TB free with Google Drive</translation> <translation id="4107048419833779140">Identify and eject storage devices</translation> @@ -2090,11 +2123,13 @@ <translation id="4235200303672858594">Entire screen</translation> <translation id="4235813040357936597">Add Account for <ph name="PROFILE_NAME" /></translation> <translation id="4235965441080806197">Cancel sign in</translation> +<translation id="4239107879884489787">ERROR: Failed to load Termina component.</translation> <translation id="4242533952199664413">Open settings</translation> <translation id="4242577469625748426">Failed to install policy settings on the device: <ph name="VALIDATION_ERROR" />.</translation> <translation id="4244238649050961491">Find more stylus apps</translation> <translation id="424546999567421758">High disk usage detected</translation> <translation id="424726838611654458">Always open in Adobe Reader</translation> +<translation id="4247901771970415646">Can't sync to <ph name="USERNAME" /></translation> <translation id="4249248555939881673">Waiting for network connection...</translation> <translation id="4249373718504745892">This page has been blocked from accessing your camera and microphone.</translation> <translation id="424963718355121712">Apps must be served from the host they affect</translation> @@ -2115,6 +2150,7 @@ <translation id="4271396100647220620">No matches</translation> <translation id="4275830172053184480">Restart your device</translation> <translation id="4278390842282768270">Allowed</translation> +<translation id="4280864916190672950">Stop loading</translation> <translation id="4281844954008187215">Terms of Service</translation> <translation id="4282196459431406533">Smart Lock is turned on</translation> <translation id="4284105660453474798">Are you sure that you want to delete "$1"?</translation> @@ -2131,6 +2167,7 @@ <translation id="4305227814872083840">long (2s)</translation> <translation id="4306119971288449206">Apps must be served with content-type '<ph name="CONTENT_TYPE" />'</translation> <translation id="4309420042698375243"><ph name="NUM_KILOBYTES" />K (<ph name="NUM_KILOBYTES_LIVE" />K live)</translation> +<translation id="4309915981827077375">General info</translation> <translation id="4310139701823742692">File is in the wrong format. Check the PPD file and try again.</translation> <translation id="431076611119798497">&Details</translation> <translation id="4312866146174492540">Block (default)</translation> @@ -2179,11 +2216,13 @@ <translation id="4409697491990005945">Margins</translation> <translation id="4411578466613447185">Code Signer</translation> <translation id="4412698727486357573">Help Centre</translation> +<translation id="44141919652824029">Allow '<ph name="APP_NAME" />' to get the list of your attached USB devices?</translation> <translation id="4414232939543644979">New &Incognito Window</translation> <translation id="4415748029120993980">SECG elliptic curve secp384r1 (aka NIST P-384)</translation> <translation id="4419409365248380979">Always allow <ph name="HOST" /> to set cookies</translation> <translation id="4421932782753506458">Fluffy</translation> <translation id="4422347585044846479">Edit bookmark for this page</translation> +<translation id="4423104065312875417">Install additional speech engines</translation> <translation id="4423376891418188461">Restore Settings</translation> <translation id="4423482519432579560">&Spellcheck</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, your administrator requires you to change your password.</translation> @@ -2271,6 +2310,7 @@ <translation id="4565377596337484307">Hide password</translation> <translation id="4567772783389002344">Add word</translation> <translation id="4568213207643490790">Sorry, Google accounts are not allowed on this device.</translation> +<translation id="4568854179928172494">Modified time</translation> <translation id="4569747168316751899">When idle</translation> <translation id="4572659312570518089">Authentication cancelled while connecting to "<ph name="DEVICE_NAME" />".</translation> <translation id="4572815280350369984"><ph name="FILE_TYPE" /> file</translation> @@ -2314,6 +2354,7 @@ <translation id="4640525840053037973">Sign in with your Google Account</translation> <translation id="4641539339823703554">Chrome was unable to set the system time. Please check the time below and correct it if needed.</translation> <translation id="4643612240819915418">&Open Video in New Tab</translation> +<translation id="4644818355646995778">Downloading, <ph name="PERCENT_REMAINING" /></translation> <translation id="4645676300727003670">&Keep</translation> <translation id="4647090755847581616">&Close Tab</translation> <translation id="4647697156028544508">Please enter the PIN for "<ph name="DEVICE_NAME" />":</translation> @@ -2471,6 +2512,11 @@ <translation id="4883178195103750615">Export bookmarks to HTML file...</translation> <translation id="4883436287898674711">All <ph name="WEBSITE_1" /> sites</translation> <translation id="48838266408104654">&Task Manager</translation> +<translation id="4883898390143004266">Help apps find location. Use Google’s Location service to help improve location for apps. Google may collect location data periodically and use this data anonymously to improve location accuracy and location-based services. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> +<translation id="4884740091792292473"><ph name="BEGIN_PARAGRAPH1" />Back up to Google Drive. Easily restore your data or switch device at any time. Your backup includes app data.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />App data can be any data that an app has saved (based on developer settings), including potentially sensitive data such as contacts, messages and photos.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />Backup data will not count toward your Drive storage quota.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />You can turn this service off in Settings.<ph name="END_PARAGRAPH4" /></translation> <translation id="4884987973312178454">6x</translation> <translation id="4885705234041587624">MSCHAPv2</translation> <translation id="4887424188275796356">Open With System Viewer</translation> @@ -2697,6 +2743,7 @@ <translation id="5250372599208556903"><ph name="SEARCH_ENGINE_NAME" /> uses your location to give you local content. You can change this in <ph name="SETTINGS_LINK" />.</translation> <translation id="5252456968953390977">Roaming</translation> <translation id="5252653240322147470">PIN must be less than <ph name="MAXIMUM" /> digits</translation> +<translation id="5253070652067921974">Created by</translation> <translation id="5254368820972107711">Show files to be removed</translation> <translation id="52550593576409946">Kiosk application could not be launched.</translation> <translation id="5255315797444241226">The passphrase that you've entered is incorrect.</translation> @@ -2719,6 +2766,7 @@ <translation id="5275973617553375938">Recovered files from Google Drive</translation> <translation id="527605719918376753">Mute tab</translation> <translation id="527605982717517565">Always allow JavaScript on <ph name="HOST" /></translation> +<translation id="5280426389926346830">Create Shortcut?</translation> <translation id="5282733140964383898">Enabling 'Do Not Track' means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request, and how the request is interpreted. For example, some websites may respond to this request by showing you ads that aren't based on other websites you've visited. Many websites will still collect and use your browsing data – for example, to improve security, to provide content, services, ads and recommendations on their websites, and to generate reporting statistics. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> <translation id="5283677936944177147">Oops! The system failed to determine device model or serial number.</translation> <translation id="5284445933715251131">Continue Downloading</translation> @@ -2751,6 +2799,7 @@ <translation id="532360961509278431">Unable to open "$1": $2</translation> <translation id="5324780743567488672">Set time zone automatically using your location</translation> <translation id="5327248766486351172">Name</translation> +<translation id="532776649628038357">I Agree</translation> <translation id="532943162177641444">Tap the notification on your <ph name="PHONE_NAME" /> to set up the mobile hotspot that can be used by this device.</translation> <translation id="5329858601952122676">&Delete</translation> <translation id="5330145655348521461">These files opened on a different desktop. Move to <ph name="USER_NAME" /> (<ph name="MAIL_ADDRESS" />) to view it.</translation> @@ -2764,6 +2813,7 @@ <translation id="5337771866151525739">Installed by a third party.</translation> <translation id="5338503421962489998">Local storage</translation> <translation id="5340217413897845242">Shelf item 6</translation> +<translation id="5340638867532133571">Allow sites to install payment handlers (recommended)</translation> <translation id="5341793073192892252">The following cookies were blocked (third-party cookies are being blocked without exception)</translation> <translation id="5341980496415249280">Please wait, packing…</translation> <translation id="5342091991439452114">PIN must be at least <ph name="MINIMUM" /> digits</translation> @@ -2772,6 +2822,7 @@ <translation id="5353252989841766347">Export Passwords From Chrome</translation> <translation id="5355097969896547230">Find again</translation> <translation id="5355926466126177564">The extension "<ph name="EXTENSION_NAME" />" has changed the page that is shown when you search from the Omnibox.</translation> +<translation id="5358764674931277">Frame rate</translation> <translation id="5360150013186312835">Show in Toolbar</translation> <translation id="5362741141255528695">Select private key file.</translation> <translation id="5363109466694494651">Powerwash and Revert</translation> @@ -2808,6 +2859,7 @@ <translation id="5414566801737831689">Read the icons of the websites that you visit</translation> <translation id="5417312524372586921">Browser themes</translation> <translation id="5419294236999569767">System time</translation> +<translation id="5420438158931847627">Determines sharpness of text and images</translation> <translation id="5422221874247253874">Access Point</translation> <translation id="5422781158178868512">Sorry, your external storage device could not be recognised.</translation> <translation id="5423849171846380976">Activated</translation> @@ -2863,6 +2915,7 @@ <translation id="5487521232677179737">Clear data</translation> <translation id="5488093641312826914">'<ph name="COPIED_ITEM_NAME" />' copied</translation> <translation id="5488468185303821006">Allow in incognito</translation> +<translation id="5491110079163012109">Send system data. Automatically send diagnostic and device and app usage data to Google. This setting is enforced by the owner. The owner may choose to send diagnostic and usage data for this device to Google. You may view this in settings. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="5493792505296048976">screen on</translation> <translation id="5494362494988149300">Open When &Finished</translation> <translation id="5494920125229734069">Select all</translation> @@ -2923,6 +2976,7 @@ <translation id="5568069709869097550">Can't sign in</translation> <translation id="5568144734023334204">Android storage</translation> <translation id="5569544776448152862">Enrolling in <ph name="BEGIN_BOLD" /><ph name="DOMAIN_NAME" /><ph name="END_BOLD" />...</translation> +<translation id="5572572070321843880">ERROR: Failed to start Termina VM.</translation> <translation id="5575473780076478375">Incognito Extension: <ph name="EXTENSION_NAME" /></translation> <translation id="557722062034137776">Resetting your device will not affect your Google accounts or any data synced to these accounts. However, all files saved locally on your device will be deleted.</translation> <translation id="5578059481725149024">Auto sign-in</translation> @@ -2991,6 +3045,9 @@ <translation id="5678550637669481956">Read and write access to <ph name="VOLUME_NAME" /> has been granted.</translation> <translation id="5678955352098267522">Read your data on <ph name="WEBSITE_1" /></translation> <translation id="5684661240348539843">Asset Identifier</translation> +<translation id="5686799162999241776"><ph name="BEGIN_BOLD" />Can't disconnect from an archive or virtual disk<ph name="END_BOLD" /> + <ph name="LINE_BREAKS" /> + Close all files on the archive or virtual disk, then try again.</translation> <translation id="5687326903064479980">Time Zone</translation> <translation id="5689516760719285838">Location</translation> <translation id="56907980372820799">Link data</translation> @@ -2999,6 +3056,8 @@ <translation id="5694501201003948907">Zipping $1 items...</translation> <translation id="5696143504434933566">Report abuse from '<ph name="EXTENSION_NAME" />'</translation> <translation id="5699533844376998780">The extension "<ph name="EXTENSION_NAME" />" has been installed.</translation> +<translation id="5700087501958648444">Audio info</translation> +<translation id="570043786759263127">Google Play apps and services</translation> <translation id="5700836101007545240">Add connection is disabled by your administrator</translation> <translation id="5701381305118179107">Centre</translation> <translation id="5702898740348134351">&Edit Search Engines...</translation> @@ -3023,6 +3082,7 @@ <translation id="5739458112391494395">Very large</translation> <translation id="5740331643563157105"><ph name="LANGUAGE_1" />, <ph name="LANGUAGE_2" />, and <ph name="NUM_ADDITIONAL_LANGUAGES" /> others</translation> <translation id="5741245087700236983"><ph name="PROFILE_NAME" />: select to edit</translation> +<translation id="574209121243317957">Pitch</translation> <translation id="5746169159649715125">Save as PDF</translation> <translation id="5747552184818312860">Expires</translation> <translation id="5747785204778348146">Developer - unstable</translation> @@ -3182,6 +3242,7 @@ <translation id="5991049340509704927">Magnify</translation> <translation id="599131315899248751">{NUM_APPLICATIONS,plural, =1{To ensure that you can keep browsing the web, ask your administrator to remove this application.}other{To ensure that you can keep browsing the web, ask your administrator to remove these applications.}}</translation> <translation id="5993332328670040093">Your data use will no longer be measured.</translation> +<translation id="6002458620803359783">Preferred Voices</translation> <translation id="600424552813877586">Invalid application.</translation> <translation id="6005695835120147974">Media Router</translation> <translation id="6006484371116297560">Classic</translation> @@ -3198,6 +3259,7 @@ <translation id="602251597322198729">This site is attempting to download multiple files. Do you want to allow this?</translation> <translation id="6022526133015258832">Open Full Screen</translation> <translation id="6025215716629925253">Stack Trace</translation> +<translation id="6026047032548434446">Install App?</translation> <translation id="6026819612896463875"><ph name="WINDOW_TITLE" /> – USB device connected</translation> <translation id="6032912588568283682">File system</translation> <translation id="6034662038931255275">OS update successful</translation> @@ -3283,6 +3345,7 @@ <translation id="6151771661215463137">The file already exists in your download folder.</translation> <translation id="615436196126345398">Protocol</translation> <translation id="6154697846084421647">Currently signed in</translation> +<translation id="6155141482566063812">Background tab is sharing your screen</translation> <translation id="6156323911414505561">Show bookmarks bar</translation> <translation id="6156863943908443225">Script cache</translation> <translation id="6156960295318603523">Language Settings</translation> @@ -3301,6 +3364,7 @@ <translation id="6181431612547969857">Download blocked</translation> <translation id="6185132558746749656">Device Location</translation> <translation id="6185696379715117369">Page up</translation> +<translation id="6189273858858366896">Set up or manage Network File Shares.</translation> <translation id="6189412234224385711">Open with <ph name="EXTENSION_NAME" /></translation> <translation id="6196640612572343990">Block third-party cookies</translation> <translation id="6196854373336333322">The extension "<ph name="EXTENSION_NAME" />" has taken control of your proxy settings, which means it can change, break or eavesdrop on anything you do online. If you aren't sure why this change happened, you probably don't want it.</translation> @@ -3523,6 +3587,7 @@ <translation id="6528513914570774834">Allow other users of this device to use this network</translation> <translation id="652948702951888897">Chrome history</translation> <translation id="653019979737152879">Syncing <ph name="FILE_NAME" />...</translation> +<translation id="6530681427077572136">Send system data. This device currently automatically sends diagnostic and device and app usage data to Google. You can change this at any time in your device settings. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="6531282281159901044">Keep dangerous file</translation> <translation id="6534583978616527129">Initialise the connection</translation> <translation id="654039047105555694"><ph name="BEGIN_BOLD" />Note:<ph name="END_BOLD" /> Only enable if you know what you are doing or if you have been asked to do so, as collection of data may reduce performance.</translation> @@ -3549,6 +3614,7 @@ <translation id="656398493051028875">Deleting "<ph name="FILENAME" />"...</translation> <translation id="6567688344210276845">Could not load icon '<ph name="ICON" />' for page action.</translation> <translation id="657402800789773160">&Reload This Page</translation> +<translation id="6577284282025554716">Download cancelled: <ph name="FILE_NAME" /></translation> <translation id="6578664922716508575">Encrypt synced passwords with your Google username and password</translation> <translation id="6580151766480067746">ARC Version</translation> <translation id="6581162200855843583">Google Drive link</translation> @@ -3564,6 +3630,7 @@ <translation id="6596745167571172521">Disable caps lock</translation> <translation id="6596816719288285829">IP Address</translation> <translation id="6597017209724497268">Samples</translation> +<translation id="659934686219830168">Sync will start once you leave this page</translation> <translation id="6602353599068390226">move window to another display</translation> <translation id="6602956230557165253">Use left and right arrow keys to navigate.</translation> <translation id="660380282187945520">F9</translation> @@ -3573,6 +3640,7 @@ <translation id="6607831829715835317">More too&ls</translation> <translation id="6612358246767739896">Protected content</translation> <translation id="6613452264606394692">Get back here fast by bookmarking this page</translation> +<translation id="6614893213975402384">Install updates & apps. By continuing, you agree that this device may also automatically download and install updates and apps from Google, your operator and your device's manufacturer, possibly using mobile data. Some of these apps may offer in-app purchases. You can remove these apps at any time. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="6615455863669487791">Show me</translation> <translation id="661719348160586794">Your saved passwords will appear here.</translation> <translation id="6618097958368085618">Keep Anyway</translation> @@ -3588,6 +3656,7 @@ <translation id="6628328486509726751">Uploaded <ph name="WEBRTC_LOG_UPLOAD_TIME" /></translation> <translation id="6629841649550503054">All backed up to <ph name="BEGIN_LINK" />Google Drive!<ph name="END_LINK" /></translation> <translation id="6630752851777525409"><ph name="EXTENSION_NAME" /> wants permanent access to a certificate to authenticate itself on your behalf.</translation> +<translation id="6635956300022133031">Select and customise text-to-speech voices</translation> <translation id="6639554308659482635">SQLite memory</translation> <translation id="6641138807883536517">The randomly generated secure module password is not available. This is normal after a Powerwash.</translation> <translation id="6643016212128521049">Clear</translation> @@ -3595,6 +3664,7 @@ <translation id="6644846457769259194">Updating your device (<ph name="PROGRESS_PERCENT" />)</translation> <translation id="6647228709620733774">Netscape Certification Authority Revocation URL</translation> <translation id="6647838571840953560">Currently on <ph name="CHANNEL_NAME" /></translation> +<translation id="6648911618876616409">A critical update is ready to install. Sign in to get started.</translation> <translation id="6649018507441623493">Just a sec...</translation> <translation id="6649563841575838401">The archive format is not supported, or the file is broken.</translation> <translation id="665061930738760572">Open in &New Window</translation> @@ -3614,6 +3684,7 @@ <translation id="6678717876183468697">Query URL</translation> <translation id="6680028776254050810">Change Users</translation> <translation id="6680442031740878064">Available: <ph name="AVAILABLE_SPACE" /></translation> +<translation id="6680650203439190394">Rate</translation> <translation id="6681668084120808868">Take photo</translation> <translation id="6681964764822470072">"<ph name="APP_NAME" />" will be uninstalled.</translation> <translation id="668599234725812620">Open Google Play</translation> @@ -3630,6 +3701,7 @@ <translation id="6702639462873609204">&Edit...</translation> <translation id="6706210727756204531">Scope</translation> <translation id="6707389671160270963">SSL Client Certificate</translation> +<translation id="6708029444764748914">Re-enter your PIN to use it to sign in to your device.</translation> <translation id="6708242697268981054">Origin:</translation> <translation id="6709357832553498500">Connect using <ph name="EXTENSIONNAME" /></translation> <translation id="6710213216561001401">Previous</translation> @@ -3710,6 +3782,7 @@ <translation id="6829250331733125857">Get help with your <ph name="DEVICE_TYPE" />.</translation> <translation id="6829270497922309893">Enrol in your organisation</translation> <translation id="682971198310367122">Google Privacy Policy</translation> +<translation id="6829772336900667075">Open <ph name="APP_NAME" /></translation> <translation id="6831043979455480757">Translate</translation> <translation id="683373380308365518">Switch to a smart and secure browser</translation> <translation id="6835762382653651563">Please connect to the Internet to update your <ph name="DEVICE_TYPE" />.</translation> @@ -3759,6 +3832,7 @@ <translation id="6922128026973287222">Save data and browse faster using Google Data Saver. Click to learn more.</translation> <translation id="6923132443355966645">Scroll/Click</translation> <translation id="6929555043669117778">Continue blocking pop-ups</translation> +<translation id="6929835486583850209">Error installing <ph name="APP_NAME" />…</translation> <translation id="6930242544192836755">Duration</translation> <translation id="6934241953272494177">Scanning your media device… <ph name="LINE_BREAK1" /> @@ -3770,6 +3844,7 @@ <translation id="6945221475159498467">Select</translation> <translation id="694592694773692225">Redirect blocked on this page.</translation> <translation id="6949306908218145636">Bookmark Open Pages...</translation> +<translation id="6951153907720526401">Payment Handlers</translation> <translation id="6955446738988643816">Inspect Pop-up</translation> <translation id="6957231940976260713">Service name</translation> <translation id="696203921837389374">Enable syncing over mobile data</translation> @@ -3862,6 +3937,7 @@ <translation id="7077829361966535409">The sign-in page failed to load using the current proxy settings. Please <ph name="GAIA_RELOAD_LINK_START" />try to sign in again<ph name="GAIA_RELOAD_LINK_END" /> or use different <ph name="PROXY_SETTINGS_LINK_START" />proxy settings<ph name="PROXY_SETTINGS_LINK_END" />.</translation> <translation id="7078120482318506217">All networks</translation> <translation id="708060913198414444">C&opy audio address</translation> +<translation id="7081952801286122383">You're incognito</translation> <translation id="708278670402572152">Disconnect to enable scanning</translation> <translation id="7084192839369222683">Run only important content</translation> <translation id="7085389578340536476">Allow Chrome to record audio?</translation> @@ -3929,6 +4005,9 @@ <translation id="7191454237977785534">Save file as</translation> <translation id="7193374945610105795">No passwords saved for <ph name="ORIGIN" /></translation> <translation id="7196835305346730603">Searching for nearby Chromeboxes...</translation> +<translation id="7197160646667308890"><ph name="BEGIN_PARAGRAPH1" />This is general information about your device and how you use it (such as battery level, app usage and network connectivity). The data will be used to improve Google's products and services for everyone. Some aggregated information will help partners, such as Android developers, make their apps and products better, too.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Turning off this feature doesn't affect your device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />You can control this feature from Settings > Google. Select Usage & diagnostics from the menu.<ph name="END_PARAGRAPH3" /></translation> <translation id="7199158086730159431">Get H&elp</translation> <translation id="720110658997053098">Permanently keep this device in kiosk mode</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' deleted</translation> @@ -3947,9 +4026,11 @@ <translation id="7223775956298141902">Oh dear... You have no extensions :-(</translation> <translation id="7225179976675429563">Network type missing</translation> <translation id="7228479291753472782">Manipulate settings that specify whether websites can use features such as geo-location, microphone, camera, etc.</translation> +<translation id="7228523857728654909">Screen lock and sign-in</translation> <translation id="7229570126336867161">Need EVDO</translation> <translation id="7230787553283372882">Customise your text size</translation> <translation id="7232750842195536390">Renaming failed</translation> +<translation id="7233309214676155451">Sync and personalise Chrome across your device</translation> <translation id="7238585580608191973">SHA-256 Fingerprint</translation> <translation id="7240120331469437312">Certificate Subject Alternative Name</translation> <translation id="7240339475467890413">Connect to new hotspot?</translation> @@ -3980,6 +4061,7 @@ <translation id="727952162645687754">Download error</translation> <translation id="7279701417129455881">Manage cookie blocking...</translation> <translation id="7280041992884344566">An error occurred while Chrome was searching for harmful software</translation> +<translation id="7280649757394340890">Text-to-Speech voice settings</translation> <translation id="7280877790564589615">Permission requested</translation> <translation id="7282992757463864530">Infobar</translation> <translation id="7283041136720745563">Your Google Drive quota isn't large enough.</translation> @@ -3995,12 +4077,14 @@ <translation id="7297443947353982503">Username/password incorrect or EAP-auth failed</translation> <translation id="729761647156315797">Choose your language & keyboard</translation> <translation id="7299337219131431707">Enable Guest browsing</translation> +<translation id="730289542559375723">{NUM_APPLICATIONS,plural, =1{This application could prevent Chrome from working properly.}other{These applications could prevent Chrome from working properly.}}</translation> <translation id="7303900363563182677">This site has been blocked from seeing text and images copied to the clipboard</translation> <translation id="730515362922783851">Exchange data with any device on the local network or Internet</translation> <translation id="7308002049209013926">Use the Launcher to quickly get to new apps and activities. To get here by keyboard, press Alt + Shift + L.</translation> <translation id="7309257895202129721">Show &controls</translation> <translation id="7311079019872751559">Unsandboxed plug-in access</translation> <translation id="7311891583377621132">Move slightly to capture a different part of the fingerprint</translation> +<translation id="7317680720589234980">Screen lock and sign-in options</translation> <translation id="7317938878466090505"><ph name="PROFILE_NAME" /> (current)</translation> <translation id="7321545336522791733">Server unreachable</translation> <translation id="7324297612904500502">Beta forum</translation> @@ -4130,6 +4214,9 @@ <translation id="7507930499305566459">Status Responder Certificate</translation> <translation id="7508545000531937079">Slideshow</translation> <translation id="7513029293694390567">Automatically sign in to websites using stored credentials. If disabled, you will be asked for confirmation every time before signing in to a website.</translation> +<translation id="7515154058529101840"><ph name="BEGIN_PARAGRAPH1" />Help apps find location. Use Google’s Location service to help improve location for apps. Google may collect location data periodically and use this data in anonymously to improve location accuracy and location-based services.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Google's Location service uses sources such as Wi-Fi, mobile networks and sensors to help estimate your device’s location. This service is active when your device’s Location setting is on.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />You can turn off Location by turning off the main Location setting on your device. You can also turn off the use of Wi-Fi, mobile networks and sensors for location in location settings.<ph name="END_PARAGRAPH3" /></translation> <translation id="7517569744831774757">Restore settings to their original defaults.</translation> <translation id="7517786267097410259">Create a password -</translation> <translation id="7518150891539970662">WebRTC logs (<ph name="WEBRTC_LOG_COUNT" />)</translation> @@ -4145,6 +4232,7 @@ <translation id="7543104066686362383">Enable debugging features on this <ph name="IDS_SHORT_PRODUCT_NAME" /> device</translation> <translation id="7544853251252956727">Shuffle</translation> <translation id="7545415673537747415">Control how Google uses your browsing history to personalise Search, ads and other Google services from <ph name="BEGIN_LINK" />Google Activity Controls<ph name="END_LINK" />.</translation> +<translation id="7545809182698428577">Turns on the features listed here. Uses your browser activity, content on some sites that you visit and other browser interactions for personalisation.</translation> <translation id="7547317915858803630">Warning: your <ph name="PRODUCT_NAME" /> settings are stored on a network drive. This may result in slowdowns, crashes or even loss of data.</translation> <translation id="7547483330017600937">Develop on your <ph name="DEVICE_TYPE" />. You can run your favourite native apps and command-line tools seamlessly and securely. @@ -4180,6 +4268,7 @@ <translation id="7589461650300748890">Whoa, there. Be careful.</translation> <translation id="7589661784326793847">Wait just a sec</translation> <translation id="7591957897535945411">This Page Has Been Translated.</translation> +<translation id="7595453277607160340">To use Android apps and keep your <ph name="DEVICE_TYPE" /> working properly, sign in again and update.</translation> <translation id="7595547011743502844"><ph name="ERROR" /> (error code <ph name="ERROR_CODE" />).</translation> <translation id="7598466960084663009">Restart computer</translation> <translation id="7600965453749440009">Never translate <ph name="LANGUAGE" /></translation> @@ -4201,6 +4290,7 @@ <translation id="7629827748548208700">Tab: <ph name="TAB_NAME" /></translation> <translation id="7631887513477658702">&Always Open Files of This Type</translation> <translation id="7632948528260659758">The following kiosk apps have been failed for updating:</translation> +<translation id="763632859238619983">Do not allow any site to install payment handlers</translation> <translation id="7639178625568735185">Got it!</translation> <translation id="764017888128728"><ph name="PASSWORD_MANAGER_BRAND" /> automatically signs you in to eligible sites with passwords that you saved.</translation> <translation id="7645176681409127223"><ph name="USER_NAME" /> (owner)</translation> @@ -4243,6 +4333,7 @@ <translation id="7707922173985738739">Use mobile data</translation> <translation id="7709152031285164251">Failed - <ph name="INTERRUPT_REASON" /></translation> <translation id="7710568461918838723">&Cast...</translation> +<translation id="7711920809702896782">Image info</translation> <translation id="7714307061282548371">Cookies from <ph name="DOMAIN" /> allowed</translation> <translation id="7714464543167945231">Certificate</translation> <translation id="7716781361494605745">Netscape Certification Authority Policy URL</translation> @@ -4342,6 +4433,7 @@ <translation id="7851457902707056880">Sign-in has been restricted to the owner account only. Please reboot and sign in with the owner account. The machine will auto reboot in 30 seconds.</translation> <translation id="7851716364080026749">Always block camera and microphone access</translation> <translation id="7853747251428735">More Too&ls</translation> +<translation id="7856006446339184955">Send system data. This device currently automatically sends diagnostic and device and app usage data to Google. This <ph name="BEGIN_LINK1" />setting<ph name="END_LINK1" /> is enforced by the owner. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK2" />Learn More<ph name="END_LINK2" /></translation> <translation id="7857117644404132472">Add exception</translation> <translation id="7857949311770343000">Is this the new tab page that you were expecting?</translation> <translation id="786073089922909430">Service: <ph name="ARC_PROCESS_NAME" /></translation> @@ -4360,6 +4452,7 @@ <translation id="7886917304091689118">Running in Chrome</translation> <translation id="7887334752153342268">Duplicate</translation> <translation id="7887864092952184874">Bluetooth mouse paired</translation> +<translation id="7889565820482017512">Display Size</translation> <translation id="7889966925761734854">Seek</translation> <translation id="7892100671754994880">Next user</translation> <translation id="7893008570150657497">Access photos, music and other media from your computer</translation> @@ -4463,6 +4556,7 @@ <translation id="8026334261755873520">Clear browsing data</translation> <translation id="8028060951694135607">Microsoft Key Recovery</translation> <translation id="8028134359912645720">Hold Control, Alt, Shift or Search to see keyboard shortcuts for those modifiers.</translation> +<translation id="8028803902702117856">Downloading <ph name="SIZE" />, <ph name="FILE_NAME" /></translation> <translation id="8028993641010258682">Size</translation> <translation id="8030656706657716245">Add Printer</translation> <translation id="8032244173881942855">Unable to cast tab.</translation> @@ -4662,6 +4756,7 @@ <translation id="8366396658833131068">Your network connectivity is restored. Please select a different network or press 'Continue' button below to launch your kiosk app.</translation> <translation id="8366947248864804596">When your phone is unlocked and nearby, just select to unlock. Otherwise, enter your password or PIN.</translation> <translation id="8368859634510605990">&Open all bookmarks</translation> +<translation id="8369547389711988632">Stopped loading</translation> <translation id="8371695176452482769">Speak now</translation> <translation id="8372369524088641025">Bad WEP key</translation> <translation id="8373553483208508744">Mute tabs</translation> @@ -4703,6 +4798,7 @@ <translation id="8439506636278576865">Offer to translate pages in this language</translation> <translation id="8446884382197647889">Learn More</translation> <translation id="8447409163267621480">Include either Ctrl or Alt</translation> +<translation id="8448729345478502352">Make items on your screen smaller or larger</translation> <translation id="8449008133205184768">Paste and Match Style</translation> <translation id="8449036207308062757">Manage storage</translation> <translation id="8451512073679317615">assistant</translation> @@ -4717,6 +4813,7 @@ <translation id="84613761564611563">Network configure UI requested, please wait...</translation> <translation id="8461914792118322307">Proxy</translation> <translation id="8463215747450521436">This supervised user may have been deleted or disabled by the manager. Please contact the manager if you would like to continue signing in as this user.</translation> +<translation id="846374874681391779">Downloads bar</translation> <translation id="8463955938112983119"><ph name="PLUGIN_NAME" /> disabled.</translation> <translation id="8464132254133862871">This user account is not eligible for the service.</translation> <translation id="8465252176946159372">Not valid</translation> @@ -4732,6 +4829,7 @@ <translation id="8477384620836102176">&General</translation> <translation id="8480082892550707549">Even if you have downloaded files from this site before, the site may be temporarily unsafe (hacked). Try downloading this file later.</translation> <translation id="8480869669560681089">Unknown device from <ph name="VENDOR_NAME" /></translation> +<translation id="8481187309597259238">Confirm USB Permission</translation> <translation id="8483248364096924578">IP address</translation> <translation id="8487678622945914333">Zoom In</translation> <translation id="8487693399751278191">Import bookmarks now...</translation> @@ -4757,6 +4855,7 @@ <translation id="8534656636775144800">Oops! Something went wrong when trying to join the domain. Please try again.</translation> <translation id="8535005006684281994">Netscape Certificate Renewal URL</translation> <translation id="8539727552378197395">No (HttpOnly)</translation> +<translation id="8541166929715485291">Send system data. Automatically send diagnostic and device and app usage data to Google. This setting is enforced by the owner. The owner may choose to send diagnostic and usage data for this device to Google. You may view this in <ph name="BEGIN_LINK1" />settings<ph name="END_LINK1" />. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK2" />Learn More<ph name="END_LINK2" /></translation> <translation id="8545107379349809705">Hide info ...</translation> <translation id="8545575359873600875">Sorry, your password could not be verified. The manager of this supervised user may have changed the password recently. If so, the new password will be applied the next time you sign in. Try using your old password.</translation> <translation id="8546186510985480118">Device is low on space</translation> @@ -4852,6 +4951,7 @@ <translation id="8677212948402625567">Collapse all...</translation> <translation id="8678648549315280022">Manage download settings...</translation> <translation id="8678933587484842200">How would you like this application to launch?</translation> +<translation id="8679788109894721265">This page uses more than <ph name="MEGABYTES" />MB</translation> <translation id="8680251145628383637">Sign in to get your bookmarks, history, passwords and other settings on all your devices. You'll also automatically be signed in to your Google services.</translation> <translation id="8680536109547170164"><ph name="QUERY" />, answer, <ph name="ANSWER" /></translation> <translation id="8686213429977032554">This Drive file isn't shared yet</translation> @@ -4865,6 +4965,7 @@ <translation id="8698464937041809063">Google drawing</translation> <translation id="869884720829132584">Applications menu</translation> <translation id="869891660844655955">Expiry date</translation> +<translation id="870073306461175568">Network File Shares</translation> <translation id="8700934097952626751">Click to start voice search</translation> <translation id="8704521619148782536">This is taking much longer than usual. You can keep waiting or cancel and try again later.</translation> <translation id="8705331520020532516">Serial Number</translation> @@ -4879,6 +4980,7 @@ <translation id="8714154114375107944">End of support</translation> <translation id="871476437400413057">Google saved passwords</translation> <translation id="8714838604780058252">Background graphics</translation> +<translation id="8715480913140015283">Background tab is using your camera</translation> <translation id="8719653885894320876"><ph name="PLUGIN_NAME" /> download failed</translation> <translation id="8723829621484579639">Incognito subframes for: <ph name="PARENT_SITE" /></translation> <translation id="8724859055372736596">&Show in Folder</translation> @@ -5012,6 +5114,7 @@ <translation id="8940081510938872932">Your computer is doing too many things right now. Try again later.</translation> <translation id="8941173171815156065">Revoke the permission '<ph name="PERMISSION" />'</translation> <translation id="8941882480823041320">Previous word</translation> +<translation id="8943076760234179177">File Share URL</translation> <translation id="894360074127026135">Netscape International Step-Up</translation> <translation id="8944099748578356325">Use the battery more quickly (currently <ph name="BATTERY_PERCENTAGE" />%)</translation> <translation id="8944964446326379280"><ph name="APP_NAME" /> is sharing a window with <ph name="TAB_NAME" />.</translation> @@ -5113,6 +5216,7 @@ <translation id="9094033019050270033">Update password</translation> <translation id="9094982973264386462">Remove</translation> <translation id="9095253524804455615">Remove</translation> +<translation id="9099674669267916096">Page count</translation> <translation id="9100765901046053179">Advanced settings</translation> <translation id="9101691533782776290">Launch app</translation> <translation id="9102610709270966160">Enable Extension</translation> @@ -5143,6 +5247,7 @@ <translation id="9137013805542155359">Show original</translation> <translation id="9137916601698928395">Open link as <ph name="USER" /></translation> <translation id="9138978632494473300">Add shortcuts to the following places:</translation> +<translation id="9140067245205650184">You are using an unsupported feature flag: <ph name="BAD_FLAG" />. Stability and security will suffer.</translation> <translation id="9147392381910171771">&Options</translation> <translation id="9148058034647219655">Exit</translation> <translation id="9148116311817999634">Set a screen lock for safety</translation> @@ -5158,7 +5263,9 @@ <translation id="9157697743260533322">Failed to set up automatic updates for all users (preflight launch error: <ph name="ERROR_NUMBER" />)</translation> <translation id="9158715103698450907">Oops! A network communication problem occurred during authentication. Please check your network connection and try again.</translation> <translation id="9161070040817969420">Subframes for: <ph name="PARENT_SITE" /></translation> +<translation id="916501514001398070">Send system data. This device automatically sends diagnostic and device and app usage data currently to Google. This setting is enforced by the owner. If you turned on additional Web & App Activity, this information will be stored with your account so that you can manage it in My Activity. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="9169496697824289689">View keyboard shortcuts</translation> +<translation id="9169931577761441333">Add <ph name="APP_NAME" /> to Home screen</translation> <translation id="9170397650136757332">Now move your finger slightly to capture all the different parts of your fingerprint</translation> <translation id="9170848237812810038">&Undo</translation> <translation id="9170884462774788842">Another programme on your computer added a theme that may change the way Chrome works.</translation> @@ -5180,6 +5287,7 @@ <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" added</translation> <translation id="9215934040295798075">Set wallpaper</translation> +<translation id="9218027443531385788">To download and use Android apps, you will need to install this required update first. While your <ph name="DEVICE_TYPE" /> is updating, you can’t use it. After installation completes, your <ph name="DEVICE_TYPE" /> will restart.</translation> <translation id="9218430445555521422">Set as default</translation> <translation id="9219103736887031265">Images</translation> <translation id="9220525904950070496">Remove account</translation> @@ -5200,6 +5308,7 @@ <translation id="939736085109172342">New folder</translation> <translation id="942532530371314860"><ph name="APP_NAME" /> is sharing a Chrome tab and audio.</translation> <translation id="942954117721265519">No images in this directory.</translation> +<translation id="943972244133411984">Modified by</translation> <translation id="945522503751344254">Send feedback</translation> <translation id="952992212772159698">Not activated</translation> <translation id="957960681186851048">This site attempted to download multiple files automatically</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index 313296c..ec6e5b8 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -3991,7 +3991,7 @@ <translation id="7296774163727375165">Condiciones de <ph name="DOMAIN" /></translation> <translation id="7297443947353982503">Nombre de usuario o contraseña incorrectos o error de autenticación EAP</translation> <translation id="729761647156315797">Seleccionar tu idioma y teclado</translation> -<translation id="7299337219131431707">Habilitar navegación para invitados</translation> +<translation id="7299337219131431707">Habilitar navegación como invitado</translation> <translation id="7303900363563182677">No se permite que este sitio vea el texto ni las imágenes que se copiaron en el portapapeles</translation> <translation id="730515362922783851">Intercambiar datos con cualquier dispositivo de la red local o Internet</translation> <translation id="7308002049209013926">Usa Launcher para acceder a actividades y apps nuevas rápidamente. Presiona Alt + mayúscula + L para acceder.</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index 54997bd3..25fad849 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -2070,7 +2070,7 @@ <translation id="4194570336751258953">Habilitar la función Tocar para hacer clic</translation> <translation id="4195643157523330669">Abrir en una pestaña nueva</translation> <translation id="4195814663415092787">Abrir todo como estaba antes de cerrar</translation> -<translation id="4197674956721858839">Selección de archivo comprimido</translation> +<translation id="4197674956721858839">Comprimir archivos seleccionados</translation> <translation id="4198146608511578238">Solo tienes que mantener pulsado el icono del menú de aplicaciones para hablar con el Asistente de Google.</translation> <translation id="4200689466366162458">Palabras personalizadas</translation> <translation id="4200983522494130825">Nueva pes&taña</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index 3287898..070c40ad 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -2843,7 +2843,7 @@ <translation id="5454166040603940656">dengan <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Tidak valid</translation> <translation id="5457459357461771897">Membaca dan menghapus foto, musik, serta media lain dari komputer Anda</translation> -<translation id="5457599981699367932">Jelajahi sebagai Tamu</translation> +<translation id="5457599981699367932">Login sebagai Tamu</translation> <translation id="5458998536542739734">Catatan layar kunci</translation> <translation id="5463275305984126951">Pengindeksan <ph name="LOCATION" /></translation> <translation id="5463856536939868464">Menu yang berisi bookmark tersembunyi</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index 887060e8..8c686d6 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -2195,7 +2195,7 @@ <translation id="444134486829715816">Espandi...</translation> <translation id="4441548209689510310">Mostra opzioni per il controllo ortografico</translation> <translation id="4442424173763614572">Ricerca DNS non riuscita</translation> -<translation id="4442498890824221158">Configurazione multidispositivo</translation> +<translation id="4442498890824221158">Configurazione MultiDevice</translation> <translation id="444267095790823769">Eccezioni di contenuti protetti</translation> <translation id="4443536555189480885">&Guida</translation> <translation id="4444304522807523469">Accesso a scanner di documenti aggiunti tramite USB o sulla rete locale</translation>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index ee415fd..f832006 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -710,6 +710,12 @@ <message name="IDS_SETTINGS_PASSWORDS_EXPORTING_FAILURE_TIP_ANOTHER_FOLDER" desc="Message that is shown when exporting passwords has failed. This is part of a list of things the user can try to resolve the problem. This advice implies that Chrome couldn't write into the specified folder."> Export your passwords to another folder </message> + <message name="IDS_SETTINGS_PASSWORD_ROW_MORE_ACTIONS" desc="The ARIA (accessibility) message for the More Actions button, which sits in every row of the password list. It opens a menu with a list of actions, which apply to the username-password pair on this row."> + More actions, password for <ph name="USERNAME">$1<ex>example@gmail.com</ex></ph> on <ph name="DOMAIN">$2<ex>www.google.com</ex></ph> + </message> + <message name="IDS_SETTINGS_PASSWORD_ROW_FEDERATED_MORE_ACTIONS" desc="The ARIA (accessibility) message for the More Actions button, which sits in every row of the password list. For this row does not include a password, only information of the account. It opens a menu with a list of actions, which apply to the account presented on this row."> + More actions, saved account for <ph name="USERNAME">$1<ex>example@gmail.com</ex></ph> on <ph name="DOMAIN">$2<ex>www.google.com</ex></ph> + </message> <!-- Default Browser Page --> @@ -2560,9 +2566,18 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_SENSORS" desc="Label for the sensors permission in Site Settings. Sensors are motion and light sensors, specifically accelerometers, gyroscope, magnetometers, and ambient-light sensors"> Motion or light sensors </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES" desc="Label for the USB devices in site settings."> + <message name="IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES" desc="Label for USB devices in site settings."> USB devices </message> + <message name="IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK" desc="The ask label for USB devices in site settings."> + Ask when a site wants to access USB devices + </message> + <message name="IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED" desc="The ask label for USB devices in site settings (with the 'recommended' suffix)."> + Ask when a site wants to access USB devices (recommended) + </message> + <message name="IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_BLOCK" desc="The block label for USB devices in site settings."> + Do not allow any sites to access USB devices + </message> <message name="IDS_SETTINGS_SITE_SETTINGS_REMOVE_ZOOM_LEVEL" desc="Title tooltip and accessibility text for the button to remove zoom levels in site settings"> Remove zoom level </message> @@ -3169,6 +3184,9 @@ <message name="IDS_SETTINGS_PEOPLE_SYNC_NOT_WORKING" desc="The label informing the user that sync is currently not working."> Sync isn't working </message> + <message name="IDS_SETTINGS_PEOPLE_SYNC_PAUSED" desc="The label informing the user that sync is currently paused."> + Sync is paused + </message> <message name="IDS_SETTINGS_SYNC_DISCONNECT_MANAGED_PROFILE_EXPLANATION" desc="The text to display in the 'Sign out of Chrome' dialog to stop syncing for managed profiles."> Because this account is managed by <ph name="DOMAIN">$1<ex>example.com</ex></ph>, your bookmarks, history, passwords, and other settings will be cleared from this device. However, your data will remain stored in your Google Account and can be managed on <ph name="BEGIN_LINK"><a href="$2" target="_blank"><ex><a href="$2" target="_blank"></ex></ph>Google Dashboard<ph name="END_LINK"></a><ex></a></ex></ph>. </message> @@ -3217,6 +3235,12 @@ <message name="IDS_SETTINGS_SYNC" desc="Name of the sync service."> Sync </message> + <message name="IDS_SETTINGS_SYNC_DESCRIPTION" desc="Text explaining what the sync system does."> + Passwords, bookmarks, history, and more are synced to your account + </message> + <message name="IDS_SETTINGS_SYNC_SECTION_ACCESSIBILITY_LABEL" desc="Label for the button that toggles showing the sync settings. Only visible by screen reader software."> + Show sync settings + </message> <message name="IDS_SETTINGS_SYNC_SYNC_AND_PERSONALIZATION" desc="The label of button that takes the user to manage their sync and personalization settings."> Sync and personalization </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES.png.sha1 new file mode 100644 index 0000000..08c7292 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES.png.sha1
@@ -0,0 +1 @@ +68d98edb1bc643b1f47b1f7a2a837b8300b6d111 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK.png.sha1 new file mode 100644 index 0000000..08c7292 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK.png.sha1
@@ -0,0 +1 @@ +68d98edb1bc643b1f47b1f7a2a837b8300b6d111 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED.png.sha1 new file mode 100644 index 0000000..eafcb15 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED.png.sha1
@@ -0,0 +1 @@ +b2cd1afb8e2c56fc0aebef7b3a30589d1049388c \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_BLOCK.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_BLOCK.png.sha1 new file mode 100644 index 0000000..25458a7 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_BLOCK.png.sha1
@@ -0,0 +1 @@ +e0f9d36f6850e446d429f123fb2919bdd9903ce5 \ No newline at end of file
diff --git a/chrome/app/theme/chrome_unscaled_resources.grd b/chrome/app/theme/chrome_unscaled_resources.grd index 9e9c69c5..383d4821 100644 --- a/chrome/app/theme/chrome_unscaled_resources.grd +++ b/chrome/app/theme/chrome_unscaled_resources.grd
@@ -111,9 +111,6 @@ <include name="IDR_APPS_FOLDER_OVERLAY_128" file="mac/apps_folder_overlay_128.png" type="BINDATA" /> <include name="IDR_APPS_FOLDER_OVERLAY_512" file="mac/apps_folder_overlay_512.png" type="BINDATA" /> </if> - <if expr="chromeos"> - <include name="IDR_KEYBOARD_SHORTCUT_VIEWER_LOGO_192" file="cros/keyboard_shortcut_viewer_logo_192.png" type="BINDATA" /> - </if> </includes> </release> </grit>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 7661789..dd33773 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -870,9 +870,6 @@ "ntp_tiles/chrome_popular_sites_factory.h", "offline_items_collection/offline_content_aggregator_factory.cc", "offline_items_collection/offline_content_aggregator_factory.h", - "overlay/overlay_surface_embedder.cc", - "overlay/overlay_surface_embedder.h", - "overlay/overlay_window.h", "page_load_metrics/browser_page_track_decider.cc", "page_load_metrics/browser_page_track_decider.h", "page_load_metrics/metrics_navigation_throttle.cc", @@ -1004,8 +1001,6 @@ "permissions/permission_uma_util.h", "permissions/permission_util.cc", "permissions/permission_util.h", - "picture_in_picture/picture_in_picture_window_controller.cc", - "picture_in_picture/picture_in_picture_window_controller.h", "platform_util.h", "platform_util_chromeos.cc", "platform_util_internal.h", @@ -1516,8 +1511,6 @@ "usb/usb_chooser_controller.h", "usb/usb_tab_helper.cc", "usb/usb_tab_helper.h", - "usb/usb_util.cc", - "usb/usb_util.h", "usb/web_usb_chooser_service.cc", "usb/web_usb_chooser_service.h", "usb/web_usb_histograms.cc", @@ -2555,8 +2548,6 @@ "metrics/tab_stats_tracker.h", "metrics/tab_usage_recorder.cc", "metrics/tab_usage_recorder.h", - "net/firefox_proxy_settings.cc", - "net/firefox_proxy_settings.h", "notifications/message_center_notification_manager.cc", "notifications/message_center_notification_manager.h", "notifications/notification_system_observer.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 475def0c..5b0633b 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -45,7 +45,6 @@ #include "components/autofill/core/common/autofill_util.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/browsing_data/core/features.h" -#include "components/cast_channel/cast_channel_util.h" #include "components/cloud_devices/common/cloud_devices_switches.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" @@ -134,6 +133,7 @@ #if defined(OS_ANDROID) #include "chrome/browser/android/chrome_feature_list.h" #else // OS_ANDROID +#include "chrome/browser/media/router/media_router_feature.h" #include "ui/message_center/public/cpp/features.h" #endif // OS_ANDROID @@ -2137,7 +2137,7 @@ {"media-router-cast-allow-all-ips", flag_descriptions::kMediaRouterCastAllowAllIPsName, flag_descriptions::kMediaRouterCastAllowAllIPsDescription, kOsDesktop, - FEATURE_VALUE_TYPE(cast_channel::kCastAllowAllIPsFeature)}, + FEATURE_VALUE_TYPE(media_router::kCastAllowAllIPsFeature)}, #endif // !OS_ANDROID // Since Drive Search is not available when app list is disabled, flag guard // enable-drive-search-in-chrome-launcher flag.
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc index e77b29b..9f55258 100644 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc +++ b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc
@@ -7,12 +7,12 @@ #include "base/android/callback_android.h" #include "base/android/jni_string.h" #include "base/callback.h" -#include "chrome/browser/ntp_snippets/content_suggestions_service_factory.h" #include "chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/content_suggestions_service.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" #include "components/ntp_snippets/contextual/contextual_suggestions_metrics_reporter.h" #include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/web_contents.h" @@ -30,43 +30,28 @@ namespace contextual_suggestions { -namespace { - -// Min size for site attribution. -static const int kPublisherFaviconMinimumSizePx = 16; -// Desired size for site attribution. -static const int kPublisherFaviconDesiredSizePx = 32; - -ntp_snippets::ContentSuggestion::ID ToContentSuggestionID( - JNIEnv* env, - const JavaParamRef<jstring>& j_suggestion_id) { - ntp_snippets::Category category(ntp_snippets::Category::FromKnownCategory( - ntp_snippets::KnownCategories::CONTEXTUAL)); - std::string suggestion_id(ConvertJavaStringToUTF8(env, j_suggestion_id)); - return ntp_snippets::ContentSuggestion::ID(category, suggestion_id); -} - -} // namespace - static jlong JNI_ContextualSuggestionsBridge_Init( JNIEnv* env, const JavaParamRef<jobject>& obj, const JavaParamRef<jobject>& j_profile) { + Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); + ntp_snippets::ContextualContentSuggestionsService* + contextual_suggestions_service = + ContextualContentSuggestionsServiceFactory::GetForProfile(profile); + + std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy = + std::make_unique<ContextualContentSuggestionsServiceProxy>( + contextual_suggestions_service); + ContextualSuggestionsBridge* contextual_suggestions_bridge = - new ContextualSuggestionsBridge(env, j_profile); + new ContextualSuggestionsBridge(env, std::move(service_proxy)); return reinterpret_cast<intptr_t>(contextual_suggestions_bridge); } ContextualSuggestionsBridge::ContextualSuggestionsBridge( JNIEnv* env, - const JavaParamRef<jobject>& j_profile) - : weak_ptr_factory_(this) { - Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); - content_suggestions_service_ = - ContentSuggestionsServiceFactory::GetForProfile(profile); - contextual_content_suggestions_service_ = - ContextualContentSuggestionsServiceFactory::GetForProfile(profile); -} + std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy) + : service_proxy_(std::move(service_proxy)), weak_ptr_factory_(this) {} ContextualSuggestionsBridge::~ContextualSuggestionsBridge() {} @@ -80,11 +65,8 @@ const JavaParamRef<jobject>& obj, const JavaParamRef<jstring>& j_url, const JavaParamRef<jobject>& j_callback) { - if (!contextual_content_suggestions_service_) - return; - GURL url(ConvertJavaStringToUTF8(env, j_url)); - contextual_content_suggestions_service_->FetchContextualSuggestionClusters( + service_proxy_->FetchContextualSuggestions( url, base::BindOnce(&ContextualSuggestionsBridge::OnSuggestionsAvailable, weak_ptr_factory_.GetWeakPtr(), ScopedJavaGlobalRef<jobject>(j_callback))); @@ -95,11 +77,9 @@ const JavaParamRef<jobject>& obj, const JavaParamRef<jstring>& j_suggestion_id, const JavaParamRef<jobject>& j_callback) { - if (!contextual_content_suggestions_service_) - return; - - contextual_content_suggestions_service_->FetchContextualSuggestionImage( - ToContentSuggestionID(env, j_suggestion_id), + std::string suggestion_id(ConvertJavaStringToUTF8(env, j_suggestion_id)); + service_proxy_->FetchContextualSuggestionImage( + suggestion_id, base::BindOnce(&ContextualSuggestionsBridge::OnImageFetched, weak_ptr_factory_.GetWeakPtr(), ScopedJavaGlobalRef<jobject>(j_callback))); @@ -110,12 +90,9 @@ const JavaParamRef<jobject>& obj, const JavaParamRef<jstring>& j_suggestion_id, const JavaParamRef<jobject>& j_callback) { - if (contextual_content_suggestions_service_ == nullptr) - return; - - content_suggestions_service_->FetchSuggestionFavicon( - ToContentSuggestionID(env, j_suggestion_id), - kPublisherFaviconMinimumSizePx, kPublisherFaviconDesiredSizePx, + std::string suggestion_id(ConvertJavaStringToUTF8(env, j_suggestion_id)); + service_proxy_->FetchContextualSuggestionFavicon( + suggestion_id, base::BindOnce(&ContextualSuggestionsBridge::OnImageFetched, weak_ptr_factory_.GetWeakPtr(), ScopedJavaGlobalRef<jobject>(j_callback))); @@ -123,6 +100,7 @@ void ContextualSuggestionsBridge::ClearState(JNIEnv* env, const JavaParamRef<jobject>& obj) { + service_proxy_->ClearState(); } void ContextualSuggestionsBridge::ReportEvent( @@ -130,9 +108,6 @@ const JavaParamRef<jobject>& obj, const JavaParamRef<jobject>& j_web_contents, jint j_event_id) { - if (!contextual_content_suggestions_service_) - return; - content::WebContents* web_contents = content::WebContents::FromJavaWebContents(j_web_contents); @@ -142,7 +117,8 @@ contextual_suggestions::ContextualSuggestionsEvent event = static_cast<contextual_suggestions::ContextualSuggestionsEvent>( j_event_id); - contextual_content_suggestions_service_->ReportEvent(ukm_source_id, event); + + service_proxy_->ReportEvent(ukm_source_id, event); } void ContextualSuggestionsBridge::OnSuggestionsAvailable(
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h index edcd9e6..d6bcdcf8 100644 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h +++ b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h
@@ -5,26 +5,26 @@ #ifndef CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_BRIDGE_H_ #define CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_BRIDGE_H_ +#include <memory> + #include "base/android/scoped_java_ref.h" #include "base/memory/weak_ptr.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" namespace gfx { class Image; } // namespace gfx -namespace ntp_snippets { -class ContentSuggestionsService; -} // namespace ntp_snippets - namespace contextual_suggestions { +class ContextualContentSuggestionsServiceProxy; + // Class implementing native side of ContextualSuggestionsBrigde.java. class ContextualSuggestionsBridge { public: ContextualSuggestionsBridge( JNIEnv* env, - const base::android::JavaParamRef<jobject>& j_profile); + std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy); // Deletes the bridge. void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); @@ -73,11 +73,9 @@ void OnImageFetched(base::android::ScopedJavaGlobalRef<jobject> j_callback, const gfx::Image& image); - // Content suggestions service is necessary for the favicon fetching. - ntp_snippets::ContentSuggestionsService* content_suggestions_service_; - // Contextual content suggestions service used for fetching suggestions. - ntp_snippets::ContextualContentSuggestionsService* - contextual_content_suggestions_service_; + // Proxy to contextual content suggestions service used for fetching + // suggestions and images. + std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy_; base::WeakPtrFactory<ContextualSuggestionsBridge> weak_ptr_factory_;
diff --git a/chrome/browser/android/ntp/ntp_snippets_bridge.cc b/chrome/browser/android/ntp/ntp_snippets_bridge.cc index 79fb6e2..66d50bc 100644 --- a/chrome/browser/android/ntp/ntp_snippets_bridge.cc +++ b/chrome/browser/android/ntp/ntp_snippets_bridge.cc
@@ -321,7 +321,7 @@ const JavaParamRef<jstring>& id_within_category, const JavaParamRef<jobject>& j_callback) { ScopedJavaGlobalRef<jobject> callback(j_callback); - contextual_content_suggestions_service_->FetchContextualSuggestionImage( + contextual_content_suggestions_service_->FetchContextualSuggestionImageLegacy( ContentSuggestion::ID(Category::FromIDValue(j_category_id), ConvertJavaStringToUTF8(env, id_within_category)), base::Bind(&NTPSnippetsBridge::OnImageFetched,
diff --git a/chrome/browser/android/vr/mailbox_to_surface_bridge.cc b/chrome/browser/android/vr/mailbox_to_surface_bridge.cc index 0d05a51af..afbffd8 100644 --- a/chrome/browser/android/vr/mailbox_to_surface_bridge.cc +++ b/chrome/browser/android/vr/mailbox_to_surface_bridge.cc
@@ -304,6 +304,12 @@ gl_->GenSyncTokenCHROMIUM(out_sync_token->GetData()); } +void MailboxToSurfaceBridge::WaitSyncToken(const gpu::SyncToken& sync_token) { + TRACE_EVENT0("gpu", __FUNCTION__); + DCHECK(IsConnected()); + gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); +} + void MailboxToSurfaceBridge::WaitForClientGpuFence(gfx::GpuFence* gpu_fence) { TRACE_EVENT0("gpu", __FUNCTION__); DCHECK(IsConnected());
diff --git a/chrome/browser/android/vr/mailbox_to_surface_bridge.h b/chrome/browser/android/vr/mailbox_to_surface_bridge.h index 4b4a943..e109473d 100644 --- a/chrome/browser/android/vr/mailbox_to_surface_bridge.h +++ b/chrome/browser/android/vr/mailbox_to_surface_bridge.h
@@ -61,6 +61,8 @@ void GenSyncToken(gpu::SyncToken* out_sync_token); + void WaitSyncToken(const gpu::SyncToken& sync_token); + // Copies a GpuFence from the local context to the GPU process, // and issues a server wait for it. void WaitForClientGpuFence(gfx::GpuFence*);
diff --git a/chrome/browser/android/vr/vr_gl_thread.cc b/chrome/browser/android/vr/vr_gl_thread.cc index 7d96a58..db5159e 100644 --- a/chrome/browser/android/vr/vr_gl_thread.cc +++ b/chrome/browser/android/vr/vr_gl_thread.cc
@@ -49,10 +49,9 @@ return vr_shell_gl_->GetWeakPtr(); } -void VrGLThread::SetInputConnection( - base::WeakPtr<VrInputConnection> weak_connection) { +void VrGLThread::SetInputConnection(VrInputConnection* input_connection) { DCHECK(OnGlThread()); - weak_input_connection_ = weak_connection; + input_connection_ = input_connection; } void VrGLThread::Init() { @@ -157,20 +156,20 @@ void VrGLThread::OnWebInputEdited(const TextEdits& edits) { DCHECK(OnGlThread()); - DCHECK(weak_input_connection_); - weak_input_connection_->OnKeyboardEdit(edits); + DCHECK(input_connection_); + input_connection_->OnKeyboardEdit(edits); } void VrGLThread::SubmitWebInput() { DCHECK(OnGlThread()); - DCHECK(weak_input_connection_); - weak_input_connection_->SubmitInput(); + DCHECK(input_connection_); + input_connection_->SubmitInput(); } void VrGLThread::RequestWebInputText(TextStateUpdateCallback callback) { DCHECK(OnGlThread()); - DCHECK(weak_input_connection_); - weak_input_connection_->RequestTextState(std::move(callback)); + DCHECK(input_connection_); + input_connection_->RequestTextState(std::move(callback)); } void VrGLThread::ForwardDialogEvent(
diff --git a/chrome/browser/android/vr/vr_gl_thread.h b/chrome/browser/android/vr/vr_gl_thread.h index f5d9c8b..6182046 100644 --- a/chrome/browser/android/vr/vr_gl_thread.h +++ b/chrome/browser/android/vr/vr_gl_thread.h
@@ -50,7 +50,7 @@ ~VrGLThread() override; base::WeakPtr<VrShellGl> GetVrShellGl(); - void SetInputConnection(base::WeakPtr<VrInputConnection> weak_connection); + void SetInputConnection(VrInputConnection* input_connection); // GlBrowserInterface implementation (GL calling to VrShell). void ContentSurfaceCreated(jobject surface, @@ -140,6 +140,10 @@ base::WeakPtr<VrShell> weak_vr_shell_; base::WeakPtr<BrowserUiInterface> weak_browser_ui_; base::WeakPtr<VrInputConnection> weak_input_connection_; + // Both VrInputConnection and VrGlThread are owned by VrShell. In VrShell, we + // made sure that this input_connection_ is up to date and destroyed after + // VrGlThread. So it is safe to use raw pointer here. + VrInputConnection* input_connection_; // This state is used for initializing vr_shell_gl_. scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chrome/browser/android/vr/vr_input_connection.cc b/chrome/browser/android/vr/vr_input_connection.cc index 2aa981e..b83ddc0 100644 --- a/chrome/browser/android/vr/vr_input_connection.cc +++ b/chrome/browser/android/vr/vr_input_connection.cc
@@ -19,8 +19,7 @@ namespace vr { -VrInputConnection::VrInputConnection(content::WebContents* web_contents) - : weak_ptr_factory_(this) { +VrInputConnection::VrInputConnection(content::WebContents* web_contents) { DCHECK(web_contents); JNIEnv* env = AttachCurrentThread(); j_object_.Reset(Java_VrInputConnection_create( @@ -29,10 +28,6 @@ VrInputConnection::~VrInputConnection() {} -base::WeakPtr<VrInputConnection> VrInputConnection::GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); -} - void VrInputConnection::OnKeyboardEdit(const TextEdits& edits) { JNIEnv* env = base::android::AttachCurrentThread(); auto java_edit_array = Java_TextEditAction_createArray(env, edits.size());
diff --git a/chrome/browser/android/vr/vr_input_connection.h b/chrome/browser/android/vr/vr_input_connection.h index df5d31d..2572c78 100644 --- a/chrome/browser/android/vr/vr_input_connection.h +++ b/chrome/browser/android/vr/vr_input_connection.h
@@ -11,7 +11,6 @@ #include "base/android/jni_weak_ref.h" #include "base/callback.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "chrome/browser/vr/content_input_delegate.h" #include "chrome/browser/vr/text_edit_action.h" @@ -26,8 +25,6 @@ explicit VrInputConnection(content::WebContents* web_contents); ~VrInputConnection(); - base::WeakPtr<VrInputConnection> GetWeakPtr(); - void OnKeyboardEdit(const TextEdits& edits); void SubmitInput(); void RequestTextState(TextStateUpdateCallback callback); @@ -41,8 +38,6 @@ base::android::ScopedJavaGlobalRef<jobject> j_object_; std::queue<vr::TextStateUpdateCallback> text_state_update_callbacks_; - base::WeakPtrFactory<VrInputConnection> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(VrInputConnection); };
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index adbaaf413..9a17d5c 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -225,12 +225,14 @@ if (web_contents_) { vr_input_connection_.reset(new VrInputConnection(web_contents_)); - PostToGlThread(FROM_HERE, - base::BindOnce(&VrGLThread::SetInputConnection, - base::Unretained(gl_thread_.get()), - vr_input_connection_->GetWeakPtr())); + PostToGlThread(FROM_HERE, base::BindOnce(&VrGLThread::SetInputConnection, + base::Unretained(gl_thread_.get()), + vr_input_connection_.get())); } else { vr_input_connection_ = nullptr; + PostToGlThread(FROM_HERE, + base::BindOnce(&VrGLThread::SetInputConnection, + base::Unretained(gl_thread_.get()), nullptr)); } vr_web_contents_observer_ = std::make_unique<VrWebContentsObserver>(
diff --git a/chrome/browser/android/vr/vr_shell.h b/chrome/browser/android/vr/vr_shell.h index 0160747..3cbb8d1 100644 --- a/chrome/browser/android/vr/vr_shell.h +++ b/chrome/browser/android/vr/vr_shell.h
@@ -293,6 +293,9 @@ base::android::ScopedJavaGlobalRef<jobject> j_motion_event_synthesizer_; std::unique_ptr<VrWebContentsObserver> vr_web_contents_observer_; + // Note this must be destroyed after VrGLThread is destroyed in the + // destruction of VrShell. VrGLThread keeps a raw pointer of VrInputConnection + // and uses the pointer on GL thread. std::unique_ptr<VrInputConnection> vr_input_connection_; VrShellDelegate* delegate_provider_ = nullptr;
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc index 559cd89..ff27353 100644 --- a/chrome/browser/android/vr/vr_shell_gl.cc +++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -339,7 +339,18 @@ } bool VrShellGl::WebVrCanProcessFrame() { - return mailbox_bridge_ready_ && !webvr_frame_processing_; + if (!mailbox_bridge_ready_) { + // Can't copy onto the transfer surface without mailbox_bridge_. + DVLOG(2) << __FUNCTION__ << ": waiting for mailbox bridge"; + return false; + } + + if (webvr_frame_processing_) { + DVLOG(2) << __FUNCTION__ << ": waiting for previous processing frame"; + return false; + } + + return true; } void VrShellGl::WebVrTryDeferredProcessing() { @@ -392,25 +403,51 @@ } } -void VrShellGl::SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox, - base::TimeDelta time_waited) { - TRACE_EVENT0("gpu", "VrShellGl::SubmitWebVRFrame"); - +bool VrShellGl::IsSubmitFrameExpected(int16_t frame_index) { // submit_client_ could be null when we exit presentation, if there were // pending SubmitFrame messages queued. VRDisplayClient::OnExitPresent // will clean up state in blink, so it doesn't wait for - // OnSubmitFrameTransferred or OnSubmitFrameRendered. - if (!submit_client_.get()) - return; + // OnSubmitFrameTransferred or OnSubmitFrameRendered. Similarly, + // the animating frame state is cleared when exiting presentation, + // and we should ignore a leftover queued SubmitFrame. + if (!submit_client_.get() || !webvr_frame_animating_) + return false; if (frame_index < 0 || !webvr_frame_oustanding_[frame_index % kPoseRingBufferSize]) { mojo::ReportBadMessage("SubmitFrame called with an invalid frame_index"); binding_.Close(); - return; + return false; } + // Frame looks valid. + return true; +} + +void VrShellGl::SubmitFrameMissing(int16_t frame_index, + const gpu::SyncToken& sync_token) { + TRACE_EVENT1("gpu", "VrShellGl::SubmitWebVRFrame", "frame", frame_index); + + if (!IsSubmitFrameExpected(frame_index)) + return; + + // Renderer didn't submit a frame. Wait for the sync token to ensure + // that any mailbox_bridge_ operations for the next frame happen after + // whatever drawing the Renderer may have done before exiting. + if (mailbox_bridge_ready_) + mailbox_bridge_->WaitSyncToken(sync_token); + + DVLOG(2) << __FUNCTION__ << ": recycle unused animating frame"; + webvr_frame_animating_ = false; +} + +void VrShellGl::SubmitFrame(int16_t frame_index, + const gpu::MailboxHolder& mailbox, + base::TimeDelta time_waited) { + TRACE_EVENT1("gpu", "VrShellGl::SubmitWebVRFrame", "frame", frame_index); + + if (!IsSubmitFrameExpected(frame_index)) + return; // The JavaScript wait time is supplied externally and not trustworthy. Clamp // to a reasonable range to avoid math errors. @@ -425,6 +462,18 @@ webvr_time_js_submit_[frame_index % kPoseRingBufferSize] = base::TimeTicks::Now(); + // Always tell the UI that we have a new WebVR frame, so that it can + // transition the UI state to "presenting" and cancel any pending timeouts. + // That's a prerequisite for ShouldDrawWebVr to become true, which is in turn + // required to complete a processing frame. + OnNewWebVRFrame(); + + if (!ShouldDrawWebVr()) { + DVLOG(1) << "Discarding received frame, UI is active"; + WebVrCancelAnimatingFrame(); + return; + } + if (WebVrCanProcessFrame()) { ProcessWebVrFrame(frame_index, mailbox); } else { @@ -440,12 +489,21 @@ const gpu::MailboxHolder& mailbox) { TRACE_EVENT0("gpu", __FUNCTION__); // Transition frame from "animating" to "processing" state. + DCHECK(webvr_frame_animating_); + DCHECK(!webvr_frame_processing_); + webvr_frame_animating_ = false; webvr_frame_processing_ = true; - OnNewWebVRFrame(); - // Swapping twice on a Surface without calling updateTexImage in - // between can lose frames, so don't draw+swap if we already have - // a pending frame we haven't consumed yet. + // LIFECYCLE: pending_frames_ should be empty when there's no processing + // frame. It gets one element here, and then is emptied again before leaving + // processing state. Swapping twice on a Surface without calling + // updateTexImage in between can lose frames, so don't draw+swap if we + // already have a pending frame we haven't consumed yet. + DCHECK(pending_frames_.empty()); + + // LIFECYCLE: We shouldn't have gotten here unless mailbox_bridge_ is ready. + DCHECK(mailbox_bridge_ready_); + bool swapped = false; if (pending_frames_.empty()) { swapped = mailbox_bridge_->CopyMailboxToSurfaceAndSwap(mailbox); @@ -455,6 +513,12 @@ pending_frames_.emplace(frame_index); } } + // Swapping should never fail, we waited for mailbox_bridge_ready_. + DCHECK(swapped); + + // LIFECYCLE: we should always have a pending frame now. + DCHECK_EQ(pending_frames_.size(), 1U); + // Always notify the client that we're done with the mailbox even // if we haven't drawn it, so that it's eligible for destruction. submit_client_->OnSubmitFrameTransferred(true); @@ -462,7 +526,7 @@ // We dropped without drawing, report this as completed rendering // now to unblock the client. We're not going to receive it in // OnWebVRFrameAvailable where we'd normally report that. - submit_client_->OnSubmitFrameRendered(); + WebVrSendRenderNotification(false); } // Unblock the next animating frame in case it was waiting for this @@ -582,12 +646,31 @@ // an incoming SubmitFrame call. DCHECK(!pending_frames_.empty()) << ": Frame arrived before SubmitFrame"; + // LIFECYCLE: we should have exactly one pending frame. This is true + // even after exiting a session with a not-yet-surfaced frame. + DCHECK_EQ(pending_frames_.size(), 1U); + webvr_surface_texture_->UpdateTexImage(); int frame_index = pending_frames_.front(); TRACE_EVENT1("gpu", "VrShellGl::OnWebVRFrameAvailable", "frame", frame_index); pending_frames_.pop(); - DrawFrame(frame_index, base::TimeTicks::Now()); + // LIFECYCLE: we should be in processing state. + DCHECK(webvr_frame_processing_); + + if (ShouldDrawWebVr()) { + DrawFrame(frame_index, base::TimeTicks::Now()); + } else { + // Silently consume a frame if we don't want to draw it. This can happen + // due to an active exclusive UI such as a permission prompt, or after + // exiting a presentation session when a pending frame arrives late. + DVLOG(1) << __FUNCTION__ << ": discarding frame, " + << (web_vr_mode_ ? "UI is active" : "not presenting"); + WebVrCancelProcessingFrameAfterTransfer(); + // We're no longer in processing state, unblock WebVrCanProcessFrame which + // may be waiting for this. + WebVrTryDeferredProcessing(); + } } void VrShellGl::OnNewWebVRFrame() { @@ -1011,6 +1094,29 @@ return; } + if (web_vr_mode_ && !ShouldDrawWebVr()) { + // We're in a WebVR session, but don't want to draw WebVR frames, i.e. + // because UI has taken over for a permissions prompt. Do state cleanup if + // needed. + if (webvr_frame_animating_ && webvr_deferred_start_processing_) { + // We have an animating frame that's waiting to start processing. Cancel + // that. + DVLOG(1) << __FUNCTION__ << ": cancel waiting WebVR frame, UI is active"; + WebVrCancelAnimatingFrame(); + webvr_deferred_start_processing_.Reset(); + } + } + + // From this point on, the current frame is either a pure UI frame + // (frame_index==-1), or a WebVR frame (frame_index >= 0). If it's a WebVR + // frame, it must be the current processing frame, and ShouldDrawWebVr() must + // be true (not in UI-only mode). Careful, we may still have a processing + // frame in UI mode that couldn't be cancelled yet. Also, WebVR frames + // can still have overlay UI drawn on top of them. + bool is_webvr_frame = frame_index >= 0; + DCHECK_EQ(is_webvr_frame, ShouldDrawWebVr()); + DCHECK(!is_webvr_frame || webvr_frame_processing_); + CHECK(!acquired_frame_); // Reset the viewport list to just the pair of viewports for the @@ -1024,7 +1130,7 @@ // If needed, resize the primary buffer for use with WebVR. Resizing // needs to happen before acquiring a frame. - if (ShouldDrawWebVr()) { + if (is_webvr_frame) { if (!ResizeForWebVR(frame_index)) { // We don't have a valid size yet, can't draw. return; @@ -1048,7 +1154,7 @@ // submitting. Technically we don't need a pose if not reprojecting, // but keeping it uninitialized seems likely to cause problems down // the road. Copying it is cheaper than fetching a new one. - if (ShouldDrawWebVr()) { + if (is_webvr_frame) { static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize), "kPoseRingBufferSize must be a power of 2"); // Copy into render info for overlay UI. WebVR doesn't use this. @@ -1068,7 +1174,7 @@ // WebVR handles controller input in OnVsync. base::TimeDelta controller_time = base::TimeDelta(); - if (!ShouldDrawWebVr()) { + if (!is_webvr_frame) { TRACE_EVENT0("gpu", "Controller"); base::TimeTicks controller_start = base::TimeTicks::Now(); UpdateController(render_info_primary_, current_time); @@ -1091,7 +1197,7 @@ render_info_primary_.head_pose, kRedrawSceneAngleDeltaDegrees); - bool dirty = ShouldDrawWebVr() || head_moved || redraw_needed; + bool dirty = is_webvr_frame || head_moved || redraw_needed; base::TimeDelta scene_time = base::TimeTicks::Now() - scene_start; // Don't double-count the controller time that was part of the scene time. @@ -1116,6 +1222,9 @@ base::TimeTicks current_time) { TRACE_EVENT1("gpu", "VrShellGl::DrawIntoAcquiredFrame", "frame", frame_index); + bool is_webvr_frame = frame_index >= 0; + DCHECK(!is_webvr_frame || webvr_frame_processing_); + last_used_head_pose_ = render_info_primary_.head_pose; acquired_frame_.BindBuffer(kFramePrimaryBuffer); @@ -1128,7 +1237,7 @@ // it's not supported on older devices such as Nexus 5X. glClear(GL_COLOR_BUFFER_BIT); - if (ShouldDrawWebVr()) + if (is_webvr_frame) DrawWebVr(); UpdateEyeInfos(render_info_primary_.head_pose, kViewportListPrimaryOffset, @@ -1141,8 +1250,9 @@ // At this point, we draw non-WebVR content that could, potentially, fill the // viewport. NB: this is not just 2d browsing stuff, we may have a splash // screen showing in WebVR mode that must also fill the screen. That said, - // while the splash screen is up ShouldDrawWebVr() will return false. - if (!ShouldDrawWebVr()) { + // while the splash screen is up ShouldDrawWebVr() will return false, + // and we only draw UI frames, not WebVR frames. + if (!is_webvr_frame) { ui_->ui_renderer()->Draw(render_info_primary_); } @@ -1150,13 +1260,13 @@ acquired_frame_.Unbind(); std::vector<const UiElement*> overlay_elements; - if (ShouldDrawWebVr()) { + if (is_webvr_frame) { overlay_elements = ui_->scene()->GetVisibleWebVrOverlayElementsToDraw(); } TRACE_COUNTER1("gpu", "VR overlay element count", overlay_elements.size()); - if (!overlay_elements.empty() && ShouldDrawWebVr()) { + if (!overlay_elements.empty() && is_webvr_frame) { // WebVR content may use an arbitray size buffer. We need to draw browser UI // on a different buffer to make sure that our UI has enough resolution. acquired_frame_.BindBuffer(kFrameWebVrBrowserUiBuffer); @@ -1212,7 +1322,7 @@ // GVR submit needs the exact head pose that was used for rendering. gfx::Transform submit_head_pose; - if (ShouldDrawWebVr()) { + if (is_webvr_frame) { // Don't use render_info_primary_.head_pose here, that may have been // overwritten by OnVSync's controller handling. We need the pose that was // sent to JS. @@ -1221,7 +1331,7 @@ submit_head_pose = render_info_primary_.head_pose; } std::unique_ptr<gl::GLFenceEGL> fence = nullptr; - if (ShouldDrawWebVr() && surfaceless_rendering_) { + if (is_webvr_frame && surfaceless_rendering_) { webvr_time_copied_[frame_index % kPoseRingBufferSize] = base::TimeTicks::Now(); if (webvr_use_gpu_fence_) { @@ -1329,6 +1439,29 @@ } } +void VrShellGl::WebVrSendRenderNotification(bool was_rendered) { + if (!submit_client_) + return; + + if (webvr_use_gpu_fence_) { + // Renderer is waiting for a frame-separating GpuFence. + + if (was_rendered) { + // Save a fence for local completion checking. + webvr_prev_frame_completion_fence_ = gl::GLFenceEGL::Create(); + } + + // Create a local GpuFence and pass it to the Renderer via IPC. + std::unique_ptr<gl::GLFence> gl_fence = gl::GLFence::CreateForGpuFence(); + std::unique_ptr<gfx::GpuFence> gpu_fence = gl_fence->GetGpuFence(); + submit_client_->OnSubmitFrameGpuFence( + gfx::CloneHandleForIPC(gpu_fence->GetGpuFenceHandle())); + } else { + // Renderer is waiting for the previous frame to render, unblock it now. + submit_client_->OnSubmitFrameRendered(); + } +} + void VrShellGl::DrawFrameSubmitNow(int16_t frame_index, const gfx::Transform& head_pose) { TRACE_EVENT1("gpu", "VrShellGl::DrawFrameSubmitNow", "frame", frame_index); @@ -1351,27 +1484,18 @@ surface_->SwapBuffers(base::DoNothing()); } - // Report rendering completion to WebVR so that it's permitted to submit - // a fresh frame. We could do this earlier, as soon as the frame got pulled - // off the transfer surface, but that appears to result in overstuffed - // buffers. - if (submit_client_) { - if (webvr_use_gpu_fence_) { - // Save a fence for local completion checking. - webvr_prev_frame_completion_fence_ = gl::GLFenceEGL::Create(); + // At this point, ShouldDrawWebVr and webvr_frame_processing_ may have become + // false for a WebVR frame. Ignore the ShouldDrawWebVr status to ensure we + // send render notifications while paused for exclusive UI mode. Skip the + // steps if we lost the processing state, that means presentation has ended. + bool is_webvr_frame = frame_index >= 0; + if (is_webvr_frame && webvr_frame_processing_) { + // Report rendering completion to the Renderer so that it's permitted to + // submit a fresh frame. We could do this earlier, as soon as the frame + // got pulled off the transfer surface, but that results in overstuffed + // buffers. + WebVrSendRenderNotification(true); - // Make a GpuFence and pass it to the Renderer for sequencing frames. - std::unique_ptr<gl::GLFence> gl_fence = gl::GLFence::CreateForGpuFence(); - std::unique_ptr<gfx::GpuFence> gpu_fence = gl_fence->GetGpuFence(); - submit_client_->OnSubmitFrameGpuFence( - gfx::CloneHandleForIPC(gpu_fence->GetGpuFenceHandle())); - } else { - // Renderer is waiting for the previous frame to render, unblock it now. - submit_client_->OnSubmitFrameRendered(); - } - } - - if (ShouldDrawWebVr()) { base::TimeTicks pose_time = webvr_time_pose_[frame_index % kPoseRingBufferSize]; base::TimeTicks js_submit_time = @@ -1384,12 +1508,8 @@ webvr_render_time_.AddSample(now - js_submit_time); } - // Only mark processing as complete if this was a WebVR frame. - // We shouldn't be getting UI frames while ShouldDrawWebVr() is true, - // but the logic is a bit complicated. - if (frame_index >= 0) { - webvr_frame_processing_ = false; - } + // Mark this WebVR frame's processing as complete. + webvr_frame_processing_ = false; } // After saving the timestamp, fps will be available via GetFPS(). @@ -1402,10 +1522,16 @@ "controller", ui_controller_update_time_.GetAverage().InMicroseconds()); - if (ShouldDrawWebVr()) { + if (is_webvr_frame) { // We finished processing a frame, this may make pending WebVR // work eligible to proceed. WebVrTryDeferredProcessing(); + } + + if (ShouldDrawWebVr()) { + // See if we can animate a new WebVR frame. Intentionally using + // ShouldDrawWebVr here since we also want to run this check after + // UI frames, i.e. transitioning from transient UI to WebVR. WebVrTryStartAnimatingFrame(false); } } @@ -1471,13 +1597,29 @@ browser_->ToggleCardboardGamepad(enabled); if (!web_vr_mode_) { + // Closing presentation bindings ensures we won't get any mojo calls such + // as SubmitFrame from this session anymore. This makes it legal to cancel + // an outstanding animating frame (if any). ClosePresentationBindings(); // Ensure that re-entering VR later gets a fresh start by clearing out the - // current session's animating and processing frame state. + // current session's animating frame state. webvr_frame_oustanding_.assign(kPoseRingBufferSize, false); webvr_deferred_start_processing_.Reset(); - webvr_frame_processing_ = false; + webvr_frame_animating_ = false; last_ui_allows_sending_webvr_vsync_ = false; + // Do not clear pending_frames_ here, need to track Surface state across + // sessions. + if (pending_frames_.empty()) { + // Safe to cancel a processing frame (if any) since it's fully + // transferred. + webvr_frame_processing_ = false; + } else { + // There's a leftover pending frame. Need to wait for that to arrive on + // the Surface, and that will clear webvr_frame_processing_ once it's + // done. Until then, webvr_frame_processing_ will stay true to block a + // new session from starting processing. + DCHECK(webvr_frame_processing_); + } } } @@ -1534,15 +1676,12 @@ return false; } - // If the previous frame deferred starting processing, that frame is still - // considered the current animating frame, so we must wait for that to - // transition to processing before sending the next VSync. Don't check - // WebVrCanProcessFrame() here - we intentionally want to allow the first - // VSync to go out before mailbox_bridge_ready_ becomes true. The first - // SubmitFrame will be deferred if needed. - if (webvr_deferred_start_processing_) { + // If we already have a JS frame that's animating, don't send another one. + // This check depends on the Renderer calling either SubmitFrame or + // SubmitFrameMissing for each animated frame. + if (webvr_frame_animating_) { DVLOG(2) << __FUNCTION__ - << ": waiting for previous frame to start processing"; + << ": waiting for current animating frame to start processing"; return false; } @@ -1571,6 +1710,24 @@ } } +void VrShellGl::WebVrCancelAnimatingFrame() { + webvr_frame_animating_ = false; + if (submit_client_) { + // We haven't written to the Surface yet. Mark as transferred and rendered. + submit_client_->OnSubmitFrameTransferred(true); + WebVrSendRenderNotification(false); + } +} + +void VrShellGl::WebVrCancelProcessingFrameAfterTransfer() { + webvr_frame_processing_ = false; + if (submit_client_) { + // We've already sent the transferred notification. + // Just report rendering complete. + WebVrSendRenderNotification(false); + } +} + void VrShellGl::OnVSync(base::TimeTicks frame_time) { TRACE_EVENT0("gpu", "VrShellGl::OnVSync"); // Create a synthetic VSync trace event for the reported last-VSync time. Use @@ -1619,6 +1776,7 @@ ClosePresentationBindings(); return; } + get_vsync_callback_ = std::move(callback); WebVrTryStartAnimatingFrame(false); } @@ -1797,6 +1955,9 @@ // frame. webvr_time_js_submit_[frame_index % kPoseRingBufferSize] = base::TimeTicks(); + DCHECK(!webvr_frame_animating_); + webvr_frame_animating_ = true; + base::ResetAndReturn(&get_vsync_callback_) .Run(std::move(pose), pending_time_ - base::TimeTicks(), frame_index, device::mojom::VRPresentationProvider::VSyncStatus::SUCCESS);
diff --git a/chrome/browser/android/vr/vr_shell_gl.h b/chrome/browser/android/vr/vr_shell_gl.h index bfd05950..754ee41 100644 --- a/chrome/browser/android/vr/vr_shell_gl.h +++ b/chrome/browser/android/vr/vr_shell_gl.h
@@ -66,6 +66,49 @@ gfx::Size source_size; }; +// WebVR/WebXR frames go through a three-stage pipeline: Animating, Processing, +// and Rendering. There's also an Idle state used as the starting state before +// Animating and ending state after Rendering. +// +// The stages can overlap, but we enforce that there isn't more than one +// frame in a given non-Idle state at any one time. +// +// <- GetVSync +// Idle +// SendVSync +// Animating +// <- UpdateLayerBounds (optional) +// <- GetVSync +// <- SubmitFrame +// ProcessWebVrFrame +// Processing +// <- OnWebVrFrameAvailable +// DrawFrame +// DrawFrameSubmitWhenReady +// <= poll prev_frame_completion_fence_ +// DrawFrameSubmitNow +// Rendering +// <= prev_frame_completion_fence_ signals +// DrawFrameSubmitNow (of next frame) +// Idle +// +// Note that the frame is considered to still be in "Animating" state until +// ProcessWebVrFrame is called. If the current processing frame isn't done yet +// at the time the incoming SubmitFrame arrives, we defer ProcessWebVrFrame +// until that finishes. +// +// The renderer may call SubmitFrameMissing instead of SubmitFrame. In that +// case, the frame transitions from Animating back to Idle. +// +// <- GetVSync +// Idle +// SendVSync +// Animating +// <- UpdateLayerBounds (optional) +// <- GetVSync +// <- SubmitFrameMissing +// Idle + // This class manages all GLThread owned objects and GL rendering for VrShell. // It is not threadsafe and must only be used on the GL thread. class VrShellGl : public device::mojom::VRPresentationProvider { @@ -175,8 +218,11 @@ void OnVSync(base::TimeTicks frame_time); + bool IsSubmitFrameExpected(int16_t frame_index); + // VRPresentationProvider void GetVSync(GetVSyncCallback callback) override; + void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, base::TimeDelta time_waited) override; @@ -216,6 +262,15 @@ void ProcessWebVrFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox); + // Used for discarding unwanted WebVR frames while UI is showing. We can't + // safely cancel frames from processing start until they show up in + // OnWebVRFrameAvailable, so only support cancelling them before or after + // that lifecycle segment. + void WebVrCancelAnimatingFrame(); + void WebVrCancelProcessingFrameAfterTransfer(); + + void WebVrSendRenderNotification(bool was_rendered); + void ClosePresentationBindings(); device::mojom::XRInputSourceStatePtr GetGazeInputSourceState(); @@ -363,13 +418,17 @@ void(int16_t, const gfx::Transform&, std::unique_ptr<gl::GLFenceEGL>)> webvr_delayed_gvr_submit_; - // We only want one frame at a time in the lifecycle from - // mojo SubmitFrame until we submit to GVR. This flag is true - // for that timespan. + // We only want one "animating" frame at a time in the lifecycle from + // SendVSync to ProcessWebVrFrame. + bool webvr_frame_animating_ = false; + + // We only want one "processing" frame at a time in the lifecycle from + // ProcessWebVrFrame until we submit to GVR. This flag is true for that + // timespan. bool webvr_frame_processing_ = false; // If we receive a new SubmitFrame when we're not ready, defer start of - // processing for later. + // processing for later. Canceled if UI takes over while processing. base::OnceClosure webvr_deferred_start_processing_; std::vector<gvr::BufferSpec> specs_;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c02dcda..c7bbff2 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -205,6 +205,7 @@ #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/overlay_window.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -4155,6 +4156,22 @@ return true; } +std::unique_ptr<content::OverlayWindow> +ChromeContentBrowserClient::CreateWindowForPictureInPicture() { +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) || \ + defined(OS_CHROMEOS) + // Note: content::OverlayWindow::Create() is defined by platform-specific + // implementation in chrome/browser/ui/views. This layering hack, which goes + // through //content and ContentBrowserClient, allows us to work around the + // dependency constraints that disallow directly calling + // chrome/browser/ui/views code either from here or from other code in + // chrome/browser. + return content::OverlayWindow::Create(); +#else + return nullptr; +#endif +} + // Static; handles rewriting Web UI URLs. bool ChromeContentBrowserClient::HandleWebUI( GURL* url,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 4bd802a..ed1843a 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -427,6 +427,8 @@ bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) override; + std::unique_ptr<content::OverlayWindow> CreateWindowForPictureInPicture() + override; protected: static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context);
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 8429322..75e37b0 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -155,44 +155,6 @@ : notification_type(notification_type), enabled(enabled) {} /////////////////////////////////////////////////////////////////////////////// -// AccessibilityManager::PrefHandler - -AccessibilityManager::PrefHandler::PrefHandler(const char* pref_path) - : pref_path_(pref_path) {} - -AccessibilityManager::PrefHandler::~PrefHandler() {} - -void AccessibilityManager::PrefHandler::HandleProfileChanged( - Profile* previous_profile, - Profile* current_profile) { - // Returns if the current profile is null. - if (!current_profile) - return; - - // If the user set a pref value on the login screen and is now starting a - // session with a new profile, copy the pref value to the profile. - if ((previous_profile && ProfileHelper::IsSigninProfile(previous_profile) && - current_profile->IsNewProfile() && - !ProfileHelper::IsSigninProfile(current_profile)) || - // Special case for Guest mode: - // Guest mode launches a guest-mode browser process before session starts, - // so the previous profile is null. - (!previous_profile && current_profile->IsGuestSession())) { - // Returns if the pref has not been set by the user. - const PrefService::Preference* pref = - ProfileHelper::GetSigninProfile()->GetPrefs()->FindPreference( - pref_path_); - if (!pref || !pref->IsUserControlled()) - return; - - // Copy the pref value from the signin screen. - const base::Value* value_on_login = pref->GetValue(); - PrefService* user_prefs = current_profile->GetPrefs(); - user_prefs->Set(pref_path_, *value_on_login); - } -} - -/////////////////////////////////////////////////////////////////////////////// // // AccessibilityManager @@ -221,27 +183,6 @@ AccessibilityManager::AccessibilityManager() : profile_(NULL), - large_cursor_pref_handler_(ash::prefs::kAccessibilityLargeCursorEnabled), - sticky_keys_pref_handler_(ash::prefs::kAccessibilityStickyKeysEnabled), - spoken_feedback_pref_handler_( - ash::prefs::kAccessibilitySpokenFeedbackEnabled), - high_contrast_pref_handler_( - ash::prefs::kAccessibilityHighContrastEnabled), - autoclick_pref_handler_(ash::prefs::kAccessibilityAutoclickEnabled), - autoclick_delay_pref_handler_(ash::prefs::kAccessibilityAutoclickDelayMs), - virtual_keyboard_pref_handler_( - ash::prefs::kAccessibilityVirtualKeyboardEnabled), - mono_audio_pref_handler_(ash::prefs::kAccessibilityMonoAudioEnabled), - caret_highlight_pref_handler_( - ash::prefs::kAccessibilityCaretHighlightEnabled), - cursor_highlight_pref_handler_( - ash::prefs::kAccessibilityCursorHighlightEnabled), - focus_highlight_pref_handler_( - ash::prefs::kAccessibilityFocusHighlightEnabled), - select_to_speak_pref_handler_( - ash::prefs::kAccessibilitySelectToSpeakEnabled), - switch_access_pref_handler_( - ash::prefs::kAccessibilitySwitchAccessEnabled), spoken_feedback_enabled_(false), select_to_speak_enabled_(false), switch_access_enabled_(false), @@ -360,8 +301,10 @@ prefs->GetBoolean(ash::prefs::kAccessibilityMonoAudioEnabled) || prefs->GetBoolean(ash::prefs::kAccessibilityCaretHighlightEnabled) || prefs->GetBoolean(ash::prefs::kAccessibilityCursorHighlightEnabled) || - prefs->GetBoolean(ash::prefs::kAccessibilityFocusHighlightEnabled)) + prefs->GetBoolean(ash::prefs::kAccessibilityFocusHighlightEnabled) || + prefs->GetBoolean(ash::prefs::kDockedMagnifierEnabled)) { return true; + } } return false; } @@ -995,20 +938,6 @@ extension_registry_observer_.Add(registry); } - large_cursor_pref_handler_.HandleProfileChanged(profile_, profile); - spoken_feedback_pref_handler_.HandleProfileChanged(profile_, profile); - high_contrast_pref_handler_.HandleProfileChanged(profile_, profile); - sticky_keys_pref_handler_.HandleProfileChanged(profile_, profile); - autoclick_pref_handler_.HandleProfileChanged(profile_, profile); - autoclick_delay_pref_handler_.HandleProfileChanged(profile_, profile); - virtual_keyboard_pref_handler_.HandleProfileChanged(profile_, profile); - mono_audio_pref_handler_.HandleProfileChanged(profile_, profile); - caret_highlight_pref_handler_.HandleProfileChanged(profile_, profile); - cursor_highlight_pref_handler_.HandleProfileChanged(profile_, profile); - focus_highlight_pref_handler_.HandleProfileChanged(profile_, profile); - select_to_speak_pref_handler_.HandleProfileChanged(profile_, profile); - switch_access_pref_handler_.HandleProfileChanged(profile_, profile); - bool had_profile = (profile_ != NULL); profile_ = profile;
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 9667641..fa39790 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -110,25 +110,6 @@ // Show the accessibility help as a tab in the browser. static void ShowAccessibilityHelp(Browser* browser); - // On a user's first login into a device, any a11y features enabled/disabled - // by the user on the login screen are enabled/disabled in the user's profile. - // This class watches for profile changes and copies settings into the user's - // profile when it detects a login with a newly created profile. - class PrefHandler { - public: - explicit PrefHandler(const char* pref_path); - virtual ~PrefHandler(); - - // Should be called from AccessibilityManager::SetProfile(). - void HandleProfileChanged(Profile* previous_profile, - Profile* current_profile); - - private: - const char* pref_path_; - - DISALLOW_COPY_AND_ASSIGN(PrefHandler); - }; - // Returns true when the accessibility menu should be shown. bool ShouldShowAccessibilityMenu(); @@ -394,20 +375,6 @@ std::unique_ptr<user_manager::ScopedUserSessionStateObserver> session_state_observer_; - PrefHandler large_cursor_pref_handler_; - PrefHandler sticky_keys_pref_handler_; - PrefHandler spoken_feedback_pref_handler_; - PrefHandler high_contrast_pref_handler_; - PrefHandler autoclick_pref_handler_; - PrefHandler autoclick_delay_pref_handler_; - PrefHandler virtual_keyboard_pref_handler_; - PrefHandler mono_audio_pref_handler_; - PrefHandler caret_highlight_pref_handler_; - PrefHandler cursor_highlight_pref_handler_; - PrefHandler focus_highlight_pref_handler_; - PrefHandler select_to_speak_pref_handler_; - PrefHandler switch_access_pref_handler_; - bool spoken_feedback_enabled_; bool select_to_speak_enabled_; bool switch_access_enabled_;
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc index 0702393..be7d077f 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
@@ -201,36 +201,6 @@ enabled); } -bool GetLargeCursorEnabledFromPref() { - return GetActiveUserPrefs()->GetBoolean( - ash::prefs::kAccessibilityLargeCursorEnabled); -} - -bool GetHighContrastEnabledFromPref() { - return GetActiveUserPrefs()->GetBoolean( - ash::prefs::kAccessibilityHighContrastEnabled); -} - -bool GetSpokenFeedbackEnabledFromPref() { - return GetActiveUserPrefs()->GetBoolean( - ash::prefs::kAccessibilitySpokenFeedbackEnabled); -} - -bool GetAutoclickEnabledFromPref() { - return GetActiveUserPrefs()->GetBoolean( - ash::prefs::kAccessibilityAutoclickEnabled); -} - -int GetAutoclickDelayFromPref() { - return GetActiveUserPrefs()->GetInteger( - ash::prefs::kAccessibilityAutoclickDelayMs); -} - -bool GetMonoAudioEnabledFromPref() { - return GetActiveUserPrefs()->GetBoolean( - ash::prefs::kAccessibilityMonoAudioEnabled); -} - bool IsBrailleImeActive() { InputMethodManager* imm = InputMethodManager::Get(); std::unique_ptr<InputMethodDescriptors> descriptors = @@ -605,29 +575,6 @@ EXPECT_TRUE(IsMonoAudioEnabled()); } -IN_PROC_BROWSER_TEST_F(AccessibilityManagerLoginTest, ResumeSavedPref) { - WaitForSigninScreen(); - // Sets the prefs on signin screen. - SetLargeCursorEnabledPref(true); - SetSpokenFeedbackEnabledPref(true); - SetHighContrastEnabledPref(true); - SetAutoclickEnabledPref(true); - SetAutoclickDelayPref(kTestAutoclickDelayMs); - SetVirtualKeyboardEnabledPref(true); - SetMonoAudioEnabledPref(true); - - CreateSession(test_account_id_); - StartUserSession(test_account_id_); - - EXPECT_EQ(GetActiveUserProfile(), AccessibilityManager::Get()->profile()); - EXPECT_TRUE(GetLargeCursorEnabledFromPref()); - EXPECT_TRUE(GetSpokenFeedbackEnabledFromPref()); - EXPECT_TRUE(GetHighContrastEnabledFromPref()); - EXPECT_TRUE(GetAutoclickEnabledFromPref()); - EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelayFromPref()); - EXPECT_TRUE(GetMonoAudioEnabledFromPref()); -} - class AccessibilityManagerUserTypeTest : public AccessibilityManagerTest, public WithParamInterface<AccountId> { protected: @@ -720,68 +667,4 @@ EXPECT_TRUE(IsBrailleImeActive()); } -class AccessibilityManagerUserTypeLoginTest - : public AccessibilityManagerLoginTest, - public WithParamInterface<AccountId> { - protected: - AccessibilityManagerUserTypeLoginTest() = default; - virtual ~AccessibilityManagerUserTypeLoginTest() = default; - - private: - DISALLOW_COPY_AND_ASSIGN(AccessibilityManagerUserTypeLoginTest); -}; - -// TODO(yoshiki): Enable a test for retail mode (i.e. RetailAccountId). -INSTANTIATE_TEST_CASE_P( - UserTypeInstantiation, - AccessibilityManagerUserTypeLoginTest, - ::testing::Values(AccountId::FromUserEmailGaiaId(kTestUserName, - kTestUserGaiaId), - user_manager::GuestAccountId(), - AccountId::FromUserEmail(kTestSupervisedUserName))); - -IN_PROC_BROWSER_TEST_P(AccessibilityManagerUserTypeLoginTest, - EnableOnLoginScreenAndLogin) { - WaitForSigninScreen(); - SetLargeCursorEnabled(true); - EXPECT_TRUE(IsLargeCursorEnabled()); - SetSpokenFeedbackEnabled(true); - EXPECT_TRUE(IsSpokenFeedbackEnabled()); - SetHighContrastEnabled(true); - EXPECT_TRUE(IsHighContrastEnabled()); - SetAutoclickEnabled(true); - EXPECT_TRUE(IsAutoclickEnabled()); - SetAutoclickDelay(kTestAutoclickDelayMs); - EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay()); - SetMonoAudioEnabled(true); - EXPECT_TRUE(IsMonoAudioEnabled()); - - CreateSession(GetParam()); - - EXPECT_TRUE(IsLargeCursorEnabled()); - EXPECT_TRUE(IsSpokenFeedbackEnabled()); - EXPECT_TRUE(IsHighContrastEnabled()); - EXPECT_TRUE(IsAutoclickEnabled()); - EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay()); - EXPECT_TRUE(IsMonoAudioEnabled()); - - StartUserSession(GetParam()); - - // Confirms that the features keep enabled after session starts. - EXPECT_TRUE(IsLargeCursorEnabled()); - EXPECT_TRUE(IsSpokenFeedbackEnabled()); - EXPECT_TRUE(IsHighContrastEnabled()); - EXPECT_TRUE(IsAutoclickEnabled()); - EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay()); - EXPECT_TRUE(IsMonoAudioEnabled()); - - // Confirms that the prefs have been copied to the user's profile. - EXPECT_TRUE(GetLargeCursorEnabledFromPref()); - EXPECT_TRUE(GetSpokenFeedbackEnabledFromPref()); - EXPECT_TRUE(GetHighContrastEnabledFromPref()); - EXPECT_TRUE(GetAutoclickEnabledFromPref()); - EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelayFromPref()); - EXPECT_TRUE(GetMonoAudioEnabledFromPref()); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.cc b/chrome/browser/chromeos/accessibility/chromevox_panel.cc index 7fb4423..fef32986a 100644 --- a/chrome/browser/chromeos/accessibility/chromevox_panel.cc +++ b/chrome/browser/chromeos/accessibility/chromevox_panel.cc
@@ -7,21 +7,18 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/interfaces/accessibility_controller.mojom.h" #include "ash/public/interfaces/constants.mojom.h" -#include "ash/shell.h" // mash-ok #include "base/macros.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" +#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/common/extensions/extension_constants.h" #include "content/public/browser/web_contents.h" #include "content/public/common/service_manager_connection.h" #include "extensions/browser/view_type_utils.h" -#include "mojo/public/cpp/bindings/type_converter.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/views/controls/webview/webview.h" @@ -106,20 +103,9 @@ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); // Placing the panel in the accessibility panel container allows ash to manage // both the window bounds and display work area. - const int container_id = ash::kShellWindowId_AccessibilityPanelContainer; - const display::Display primary_display = - display::Screen::GetScreen()->GetPrimaryDisplay(); - if (chromeos::GetAshConfig() == ash::Config::MASH) { - using ui::mojom::WindowManager; - params.mus_properties[WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(container_id); - params.mus_properties[WindowManager::kDisplayId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(primary_display.id()); - } else { - params.parent = ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), - container_id); - } - params.bounds = primary_display.bounds(); + ash_util::SetupWidgetInitParamsForContainer( + ¶ms, ash::kShellWindowId_AccessibilityPanelContainer); + params.bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); params.delegate = this; params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; params.name = "ChromeVoxPanel";
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.cc b/chrome/browser/chromeos/accessibility/magnification_manager.cc index ef6b5c1..cd57ca4 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager.cc +++ b/chrome/browser/chromeos/accessibility/magnification_manager.cc
@@ -16,7 +16,6 @@ #include "base/macros.h" #include "base/memory/singleton.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -43,10 +42,6 @@ public: MagnificationManagerImpl() : profile_(NULL), - magnifier_enabled_pref_handler_( - ash::prefs::kAccessibilityScreenMagnifierEnabled), - magnifier_scale_pref_handler_( - ash::prefs::kAccessibilityScreenMagnifierScale), enabled_(false), keep_focus_centered_(false), scale_(0.0), @@ -125,9 +120,6 @@ base::Unretained(this))); } - magnifier_enabled_pref_handler_.HandleProfileChanged(profile_, profile); - magnifier_scale_pref_handler_.HandleProfileChanged(profile_, profile); - profile_ = profile; UpdateMagnifierFromPrefs(); } @@ -252,9 +244,6 @@ Profile* profile_; - AccessibilityManager::PrefHandler magnifier_enabled_pref_handler_; - AccessibilityManager::PrefHandler magnifier_scale_pref_handler_; - bool enabled_; bool keep_focus_centered_; double scale_;
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc index 29fe479..e481399 100644 --- a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
@@ -318,49 +318,6 @@ EXPECT_FALSE(GetScreenMagnifierEnabledFromPref()); } -IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserOff) { - // Confirms that magnifier is disabled on the login screen. - EXPECT_FALSE(IsMagnifierEnabled()); - - // Disables magnifier on login screen explicitly. - SetMagnifierEnabled(false); - - // Logs in (but the session is not started yet). - session_manager::SessionManager::Get()->CreateSession(test_account_id_, - kTestUserName, false); - - // Confirms that magnifier is keeping disabled. - EXPECT_FALSE(IsMagnifierEnabled()); - - StartUserSession(test_account_id_); - - // Confirms that magnifier is keeping disabled. - EXPECT_FALSE(IsMagnifierEnabled()); - EXPECT_FALSE(GetScreenMagnifierEnabledFromPref()); -} - -IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserFull) { - // Enables magnifier on login screen. - SetMagnifierEnabled(true); - SetFullScreenMagnifierScale(2.5); - EXPECT_TRUE(IsMagnifierEnabled()); - EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); - - // Logs in (but the session is not started yet). - session_manager::SessionManager::Get()->CreateSession(test_account_id_, - kTestUserName, false); - - // Confirms that magnifier is keeping enabled. - EXPECT_TRUE(IsMagnifierEnabled()); - - StartUserSession(test_account_id_); - - // Confirms that magnifier keeps enabled. - EXPECT_TRUE(IsMagnifierEnabled()); - EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); - EXPECT_TRUE(GetScreenMagnifierEnabledFromPref()); -} - IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserUnset) { // Confirms that magnifier is disabled on the login screen. EXPECT_FALSE(IsMagnifierEnabled());
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc index f62d473d0..1c349a3 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -692,6 +692,7 @@ const BluetoothDevice* device, const LocalGattAttribute* attribute, int offset, + mojom::BluetoothGattDBAttributeType attribute_type, const ValueCallback& success_callback, const ErrorCallback& error_callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -707,6 +708,7 @@ bluetooth_instance->RequestGattRead( mojom::BluetoothAddress::From(device->GetAddress()), gatt_handle_[attribute->GetIdentifier()], offset, false /* is_long */, + attribute_type, base::BindOnce(&OnGattServerRead, success_callback, error_callback)); } @@ -716,6 +718,7 @@ const LocalGattAttribute* attribute, const std::vector<uint8_t>& value, int offset, + mojom::BluetoothGattDBAttributeType attribute_type, const base::Closure& success_callback, const ErrorCallback& error_callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -730,7 +733,7 @@ bluetooth_instance->RequestGattWrite( mojom::BluetoothAddress::From(device->GetAddress()), - gatt_handle_[attribute->GetIdentifier()], offset, value, + gatt_handle_[attribute->GetIdentifier()], offset, value, attribute_type, base::BindOnce(&OnGattServerWrite, success_callback, error_callback)); } @@ -740,8 +743,10 @@ int offset, const ValueCallback& callback, const ErrorCallback& error_callback) { - OnGattAttributeReadRequest(device, characteristic, offset, callback, - error_callback); + OnGattAttributeReadRequest( + device, characteristic, offset, + mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, callback, + error_callback); } void ArcBluetoothBridge::OnCharacteristicWriteRequest( @@ -751,8 +756,10 @@ int offset, const base::Closure& callback, const ErrorCallback& error_callback) { - OnGattAttributeWriteRequest(device, characteristic, value, offset, callback, - error_callback); + OnGattAttributeWriteRequest( + device, characteristic, value, offset, + mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, callback, + error_callback); } void ArcBluetoothBridge::OnDescriptorReadRequest( @@ -761,8 +768,10 @@ int offset, const ValueCallback& callback, const ErrorCallback& error_callback) { - OnGattAttributeReadRequest(device, descriptor, offset, callback, - error_callback); + OnGattAttributeReadRequest( + device, descriptor, offset, + mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, callback, + error_callback); } void ArcBluetoothBridge::OnDescriptorWriteRequest( @@ -772,8 +781,10 @@ int offset, const base::Closure& callback, const ErrorCallback& error_callback) { - OnGattAttributeWriteRequest(device, descriptor, value, offset, callback, - error_callback); + OnGattAttributeWriteRequest( + device, descriptor, value, offset, + mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, callback, + error_callback); } void ArcBluetoothBridge::OnNotificationsStart(
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h index d5ce371..7a96ef03 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h
@@ -433,20 +433,24 @@ // Common code for OnCharacteristicReadRequest and OnDescriptorReadRequest template <class LocalGattAttribute> - void OnGattAttributeReadRequest(const device::BluetoothDevice* device, - const LocalGattAttribute* attribute, - int offset, - const ValueCallback& success_callback, - const ErrorCallback& error_callback); + void OnGattAttributeReadRequest( + const device::BluetoothDevice* device, + const LocalGattAttribute* attribute, + int offset, + mojom::BluetoothGattDBAttributeType attribute_type, + const ValueCallback& success_callback, + const ErrorCallback& error_callback); // Common code for OnCharacteristicWriteRequest and OnDescriptorWriteRequest template <class LocalGattAttribute> - void OnGattAttributeWriteRequest(const device::BluetoothDevice* device, - const LocalGattAttribute* attribute, - const std::vector<uint8_t>& value, - int offset, - const base::Closure& success_callback, - const ErrorCallback& error_callback); + void OnGattAttributeWriteRequest( + const device::BluetoothDevice* device, + const LocalGattAttribute* attribute, + const std::vector<uint8_t>& value, + int offset, + mojom::BluetoothGattDBAttributeType attribute_type, + const base::Closure& success_callback, + const ErrorCallback& error_callback); void OnSetDiscoverable(bool discoverable, bool success, uint32_t timeout); void SetDiscoverable(bool discoverable, uint32_t timeout);
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc index 421e3314f..e4fb55b 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
@@ -150,10 +150,6 @@ // Android boot after AppInstance is ready and send it to Android. // TODO(crbug.com/762553): Sync settings at proper time. void SyncAppTimeSettings(); - // Determine whether a particular setting needs to be synced to Android. - // Keep these lines ordered lexicographically. - bool ShouldSyncBackupEnabled() const; - bool ShouldSyncLocationServiceEnabled() const; // Send particular settings to Android. // Keep these lines ordered lexicographically. void SyncAccessibilityLargeMouseCursorEnabled() const; @@ -270,12 +266,6 @@ SyncSwitchAccessEnabled(); } else if (pref_name == ash::prefs::kAccessibilityVirtualKeyboardEnabled) { SyncAccessibilityVirtualKeyboardEnabled(); - } else if (pref_name == prefs::kArcBackupRestoreEnabled) { - if (ShouldSyncBackupEnabled()) - SyncBackupEnabled(); - } else if (pref_name == prefs::kArcLocationServiceEnabled) { - if (ShouldSyncLocationServiceEnabled()) - SyncLocationServiceEnabled(); } else if (pref_name == ::prefs::kApplicationLocale || pref_name == ::prefs::kLanguagePreferredLanguages) { SyncLocale(); @@ -329,8 +319,6 @@ AddPrefToObserve(ash::prefs::kAccessibilitySpokenFeedbackEnabled); AddPrefToObserve(ash::prefs::kAccessibilitySwitchAccessEnabled); AddPrefToObserve(ash::prefs::kAccessibilityVirtualKeyboardEnabled); - AddPrefToObserve(prefs::kArcBackupRestoreEnabled); - AddPrefToObserve(prefs::kArcLocationServiceEnabled); AddPrefToObserve(prefs::kSmsConnectEnabled); AddPrefToObserve(::prefs::kResolveTimezoneByGeolocationMethod); AddPrefToObserve(::prefs::kUse24HourClock); @@ -341,6 +329,10 @@ AddPrefToObserve(onc::prefs::kDeviceOpenNetworkConfiguration); AddPrefToObserve(onc::prefs::kOpenNetworkConfiguration); + // Note that some preferences, such as kArcBackupRestoreEnabled and + // kArcLocationServiceEnabled, are not dynamically updated after initial + // ARC setup and therefore are not observed here. + reporting_consent_subscription_ = CrosSettings::Get()->AddSettingsObserver( chromeos::kStatsReportingPref, base::Bind(&ArcSettingsServiceImpl::SyncReportingConsent, @@ -391,11 +383,6 @@ SyncTimeZone(); SyncTimeZoneByGeolocation(); SyncUse24HourClock(); - - if (ShouldSyncBackupEnabled()) - SyncBackupEnabled(); - if (ShouldSyncLocationServiceEnabled()) - SyncLocationServiceEnabled(); } void ArcSettingsServiceImpl::SyncAppTimeSettings() { @@ -410,22 +397,6 @@ AddPrefToObserve(::prefs::kLanguagePreferredLanguages); } -bool ArcSettingsServiceImpl::ShouldSyncBackupEnabled() const { - // Always sync the managed setting. Also sync when the pref is unset, which - // normally happens once after the pref changes from the managed state to - // unmanaged. - return GetPrefs()->IsManagedPreference(prefs::kArcBackupRestoreEnabled) || - !GetPrefs()->HasPrefPath(prefs::kArcBackupRestoreEnabled); -} - -bool ArcSettingsServiceImpl::ShouldSyncLocationServiceEnabled() const { - // Always sync the managed setting. Also sync when the pref is unset, which - // normally happens once after the pref changes from the managed state to - // unmanaged. - return GetPrefs()->IsManagedPreference(prefs::kArcLocationServiceEnabled) || - !GetPrefs()->HasPrefPath(prefs::kArcLocationServiceEnabled); -} - void ArcSettingsServiceImpl::SyncAccessibilityLargeMouseCursorEnabled() const { SendBoolPrefSettingsBroadcast( ash::prefs::kAccessibilityLargeCursorEnabled, @@ -450,16 +421,6 @@ backup_settings->SetBackupEnabled(value->GetBool(), !pref->IsUserModifiable()); } - - if (GetPrefs()->IsManagedPreference(prefs::kArcBackupRestoreEnabled)) { - // Unset the user pref so that if the pref becomes unmanaged at some point, - // this change will be synced. - GetPrefs()->ClearPref(prefs::kArcBackupRestoreEnabled); - } else if (!GetPrefs()->HasPrefPath(prefs::kArcBackupRestoreEnabled)) { - // Set the pref value in order to prevent the subsequent syncing. The - // "false" value is a safe default from the legal/privacy perspective. - GetPrefs()->SetBoolean(prefs::kArcBackupRestoreEnabled, false); - } } void ArcSettingsServiceImpl::SyncFocusHighlightEnabled() const { @@ -518,15 +479,6 @@ SendBoolPrefSettingsBroadcast( prefs::kArcLocationServiceEnabled, "org.chromium.arc.intent_helper.SET_LOCATION_SERVICE_ENABLED"); - if (GetPrefs()->IsManagedPreference(prefs::kArcLocationServiceEnabled)) { - // Unset the user pref so that if the pref becomes unmanaged at some point, - // this change will be synced. - GetPrefs()->ClearPref(prefs::kArcLocationServiceEnabled); - } else if (!GetPrefs()->HasPrefPath(prefs::kArcLocationServiceEnabled)) { - // Set the pref value in order to prevent the subsequent syncing. The - // "false" value is a safe default from the legal/privacy perspective. - GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, false); - } } void ArcSettingsServiceImpl::SyncProxySettings() const {
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc index f5d10915..cfef948 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -179,33 +179,22 @@ constexpr char kONCPacUrl[] = "http://domain.com/x"; -constexpr char kLocationServiceBroadcastAction[] = - "org.chromium.arc.intent_helper.SET_LOCATION_SERVICE_ENABLED"; constexpr char kSetProxyBroadcastAction[] = "org.chromium.arc.intent_helper.SET_PROXY"; -// Returns the number of |broadcasts| having the |action| action, and checks -// that all their extras match with |extras|. -int CountBroadcasts( - const std::vector<FakeIntentHelperInstance::Broadcast>& broadcasts, - const std::string& action, - const base::DictionaryValue* extras) { - int count = 0; - for (const FakeIntentHelperInstance::Broadcast& broadcast : broadcasts) { - if (broadcast.action == action) { - EXPECT_TRUE(base::JSONReader::Read(broadcast.extras)->Equals(extras)); - count++; - } - } - return count; -} - // Returns the number of |broadcasts| having the proxy action, and checks that // all their extras match with |extras|. int CountProxyBroadcasts( const std::vector<FakeIntentHelperInstance::Broadcast>& broadcasts, - const base::DictionaryValue* proxy_settings) { - return CountBroadcasts(broadcasts, kSetProxyBroadcastAction, proxy_settings); + const base::DictionaryValue* extras) { + int count = 0; + for (const FakeIntentHelperInstance::Broadcast& broadcast : broadcasts) { + if (broadcast.action == kSetProxyBroadcastAction) { + EXPECT_TRUE(base::JSONReader::Read(broadcast.extras)->Equals(extras)); + count++; + } + } + return count; } void RunUntilIdle() { @@ -362,13 +351,13 @@ nullptr); UpdatePolicy(policy); - // The pref is disabled and managed, and the corresponding sync method - // reflects the pref. + // The pref is disabled and managed, but the corresponding sync method does + // not reflect the pref as it is not dynamically applied. EXPECT_FALSE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); - EXPECT_TRUE(fake_backup_settings_instance_->set_backup_enabled_called()); + EXPECT_FALSE(fake_backup_settings_instance_->set_backup_enabled_called()); EXPECT_FALSE(fake_backup_settings_instance_->enabled()); - EXPECT_TRUE(fake_backup_settings_instance_->managed()); + EXPECT_FALSE(fake_backup_settings_instance_->managed()); fake_backup_settings_instance_->ClearCallHistory(); @@ -379,13 +368,13 @@ nullptr); UpdatePolicy(policy); - // The pref is enabled and managed, and the corresponding sync method - // reflects the pref. + // The pref is enabled and managed, but the corresponding sync method does + // not reflect the pref as it is not dynamically applied. EXPECT_TRUE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); - EXPECT_TRUE(fake_backup_settings_instance_->set_backup_enabled_called()); - EXPECT_TRUE(fake_backup_settings_instance_->enabled()); - EXPECT_TRUE(fake_backup_settings_instance_->managed()); + EXPECT_FALSE(fake_backup_settings_instance_->set_backup_enabled_called()); + EXPECT_FALSE(fake_backup_settings_instance_->enabled()); + EXPECT_FALSE(fake_backup_settings_instance_->managed()); fake_backup_settings_instance_->ClearCallHistory(); @@ -393,11 +382,11 @@ policy.Erase(policy::key::kArcBackupRestoreEnabled); UpdatePolicy(policy); - // The pref is disabled and unmanaged, and the corresponding sync method - // reflects the pref. - EXPECT_FALSE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); + // The pref is unmanaged, but the corresponding sync method does not reflect + // the pref as it is not dynamically applied. + EXPECT_TRUE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); EXPECT_FALSE(prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); - EXPECT_TRUE(fake_backup_settings_instance_->set_backup_enabled_called()); + EXPECT_FALSE(fake_backup_settings_instance_->set_backup_enabled_called()); EXPECT_FALSE(fake_backup_settings_instance_->enabled()); EXPECT_FALSE(fake_backup_settings_instance_->managed()); } @@ -419,17 +408,11 @@ nullptr); UpdatePolicy(policy); - // The pref is disabled and managed, and the corresponding broadcast is sent - // at least once. + // The pref is disabled and managed, but no broadcast is sent as the setting + // is not dynamically applied. EXPECT_FALSE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)); - base::DictionaryValue expected_broadcast_extras; - expected_broadcast_extras.SetBoolean("enabled", false); - expected_broadcast_extras.SetBoolean("managed", true); - EXPECT_GE(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), - kLocationServiceBroadcastAction, - &expected_broadcast_extras), - 1); + EXPECT_EQ(0UL, fake_intent_helper_instance_->broadcasts().size()); fake_intent_helper_instance_->clear_broadcasts(); @@ -440,15 +423,11 @@ nullptr); UpdatePolicy(policy); - // The pref is enabled and managed, and the corresponding broadcast is sent at - // least once. + // The pref is enabled and managed, but no broadcast is sent as the setting + // is not dynamically applied. EXPECT_TRUE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)); - expected_broadcast_extras.SetBoolean("enabled", true); - EXPECT_GE(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), - kLocationServiceBroadcastAction, - &expected_broadcast_extras), - 1); + EXPECT_EQ(0UL, fake_intent_helper_instance_->broadcasts().size()); fake_intent_helper_instance_->clear_broadcasts(); @@ -456,16 +435,10 @@ policy.Erase(policy::key::kArcLocationServiceEnabled); UpdatePolicy(policy); - // The pref is disabled and unmanaged, and the corresponding broadcast is - // sent. - EXPECT_FALSE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); + // The pref is unmanaged, but no broadcast is sent as the setting is not + // dynamically applied. EXPECT_FALSE(prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)); - expected_broadcast_extras.SetBoolean("enabled", false); - expected_broadcast_extras.SetBoolean("managed", false); - EXPECT_EQ(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), - kLocationServiceBroadcastAction, - &expected_broadcast_extras), - 1); + EXPECT_EQ(0UL, fake_intent_helper_instance_->broadcasts().size()); } IN_PROC_BROWSER_TEST_F(ArcSettingsServiceTest, ProxyModePolicyTest) {
diff --git a/chrome/browser/chromeos/display/display_prefs.cc b/chrome/browser/chromeos/display/display_prefs.cc index 8af9595..3014ec2 100644 --- a/chrome/browser/chromeos/display/display_prefs.cc +++ b/chrome/browser/chromeos/display/display_prefs.cc
@@ -23,7 +23,6 @@ #include "ui/display/manager/display_layout_store.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/display_manager_utilities.h" -#include "ui/display/manager/display_pref_util.h" #include "ui/display/manager/json_converter.h" #include "ui/display/types/display_constants.h" #include "ui/gfx/geometry/insets.h" @@ -34,14 +33,14 @@ namespace { -const char kInsetsTopKey[] = "insets_top"; -const char kInsetsLeftKey[] = "insets_left"; -const char kInsetsBottomKey[] = "insets_bottom"; -const char kInsetsRightKey[] = "insets_right"; +constexpr char kInsetsTopKey[] = "insets_top"; +constexpr char kInsetsLeftKey[] = "insets_left"; +constexpr char kInsetsBottomKey[] = "insets_bottom"; +constexpr char kInsetsRightKey[] = "insets_right"; -const char kTouchCalibrationWidth[] = "touch_calibration_width"; -const char kTouchCalibrationHeight[] = "touch_calibration_height"; -const char kTouchCalibrationPointPairs[] = "touch_calibration_point_pairs"; +constexpr char kTouchCalibrationWidth[] = "touch_calibration_width"; +constexpr char kTouchCalibrationHeight[] = "touch_calibration_height"; +constexpr char kTouchCalibrationPointPairs[] = "touch_calibration_point_pairs"; constexpr char kTouchAssociationTimestamp[] = "touch_association_timestamp"; constexpr char kTouchAssociationCalibrationData[] = @@ -52,6 +51,12 @@ constexpr char kDisplayZoom[] = "display_zoom"; +constexpr char kDisplayPowerAllOn[] = "all_on"; +constexpr char kDisplayPowerInternalOffExternalOn[] = + "internal_off_external_on"; +constexpr char kDisplayPowerInternalOnExternalOff[] = + "internal_on_external_off"; + // This kind of boilerplates should be done by base::JSONValueConverter but it // doesn't support classes like gfx::Insets for now. // TODO(mukai): fix base::JSONValueConverter and use it here. @@ -512,35 +517,40 @@ } } -typedef std::map<chromeos::DisplayPowerState, std::string> - DisplayPowerStateToStringMap; - -const DisplayPowerStateToStringMap* GetDisplayPowerStateToStringMap() { - // Don't save or retore ALL_OFF state. http://crbug.com/318456. - static const DisplayPowerStateToStringMap* map = display::CreateToStringMap( - chromeos::DISPLAY_POWER_ALL_ON, "all_on", - chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, - "internal_off_external_on", - chromeos::DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF, - "internal_on_external_off"); - return map; -} - -bool GetDisplayPowerStateFromString(const base::StringPiece& state, - chromeos::DisplayPowerState* field) { - if (display::ReverseFind(GetDisplayPowerStateToStringMap(), state, field)) - return true; - LOG(ERROR) << "Invalid display power state value:" << state; - return false; +bool GetDisplayPowerStateFromString(const std::string& state_string, + chromeos::DisplayPowerState* power_state) { + if (state_string == kDisplayPowerAllOn) { + *power_state = chromeos::DISPLAY_POWER_ALL_ON; + } else if (state_string == kDisplayPowerInternalOffExternalOn) { + *power_state = chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON; + } else if (state_string == kDisplayPowerInternalOnExternalOff) { + *power_state = chromeos::DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF; + } else { + // Don't restore ALL_OFF state. http://crbug.com/318456. + return false; + } + return true; } void StoreDisplayPowerState(PrefService* local_state, DisplayPowerState power_state) { - const DisplayPowerStateToStringMap* map = GetDisplayPowerStateToStringMap(); - DisplayPowerStateToStringMap::const_iterator iter = map->find(power_state); - if (iter != map->end()) { - local_state->SetString(prefs::kDisplayPowerState, iter->second); + const char* state_string = nullptr; + switch (power_state) { + case chromeos::DISPLAY_POWER_ALL_ON: + state_string = kDisplayPowerAllOn; + break; + case chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON: + state_string = kDisplayPowerInternalOffExternalOn; + break; + case chromeos::DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF: + state_string = kDisplayPowerInternalOnExternalOff; + break; + case chromeos::DISPLAY_POWER_ALL_OFF: + // Don't store ALL_OFF state. http://crbug.com/318456. + break; } + if (state_string) + local_state->SetString(prefs::kDisplayPowerState, state_string); } void StoreCurrentDisplayPowerState(PrefService* local_state) { @@ -672,9 +682,7 @@ // Per-display preference. registry->RegisterDictionaryPref(prefs::kSecondaryDisplays); registry->RegisterDictionaryPref(prefs::kDisplayProperties); - DisplayPowerStateToStringMap::const_iterator iter = - GetDisplayPowerStateToStringMap()->find(chromeos::DISPLAY_POWER_ALL_ON); - registry->RegisterStringPref(prefs::kDisplayPowerState, iter->second); + registry->RegisterStringPref(prefs::kDisplayPowerState, kDisplayPowerAllOn); registry->RegisterDictionaryPref(prefs::kDisplayRotationLock); registry->RegisterDictionaryPref(prefs::kDisplayTouchAssociations); registry->RegisterListPref(prefs::kExternalDisplayMirrorInfo);
diff --git a/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc b/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc index e206dc5..ede6d12b 100644 --- a/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc +++ b/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc
@@ -78,7 +78,8 @@ info.activity = activity; info.sticky = false; info.notifications_enabled = false; - info.orientation_lock = arc::mojom::OrientationLock::NONE; + info.orientation_lock_deprecated = + arc::mojom::OrientationLockDeprecated::NONE; return info; }
diff --git a/chrome/browser/chromeos/lock_screen_apps/toast_dialog_view.cc b/chrome/browser/chromeos/lock_screen_apps/toast_dialog_view.cc index bf49ccfd..5939c71 100644 --- a/chrome/browser/chromeos/lock_screen_apps/toast_dialog_view.cc +++ b/chrome/browser/chromeos/lock_screen_apps/toast_dialog_view.cc
@@ -7,14 +7,10 @@ #include <memory> #include <utility> -#include "ash/public/cpp/config.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/shell.h" #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/grit/generated_resources.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/geometry/rect.h" @@ -80,15 +76,8 @@ views::Widget::InitParams params = GetDialogWidgetInitParams(this, nullptr, nullptr, gfx::Rect()); - const int container_id = ash::kShellWindowId_SettingBubbleContainer; - if (ash_util::IsRunningInMash()) { - using ui::mojom::WindowManager; - params.mus_properties[WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(container_id); - } else { - params.parent = ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), - container_id); - } + ash_util::SetupWidgetInitParamsForContainer( + ¶ms, ash::kShellWindowId_SettingBubbleContainer); views::Widget* widget = new views::Widget; // owned by native widget widget->Init(params);
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 45b00b9a..a0266d0 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -125,7 +125,6 @@ #include "content/public/browser/storage_partition.h" #include "content/public/common/content_switches.h" #include "extensions/common/features/feature_session_type.h" -#include "net/cert/sth_distributor.h" #include "rlz/buildflags/buildflags.h" #include "third_party/cros_system_api/switches/chrome_switches.h" #include "ui/base/ime/chromeos/input_method_descriptor.h"
diff --git a/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.cc b/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.cc index cee6427..1bb2e01 100644 --- a/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.cc +++ b/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/chromeos/login/ui/gaia_dialog_delegate.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/shell.h" #include "chrome/browser/chromeos/login/ui/login_display_host_views.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" @@ -13,8 +12,6 @@ #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "content/public/browser/web_contents.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/base/accelerators/accelerator.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -52,16 +49,8 @@ views::Widget::InitParams params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); params.delegate = dialog_view_; - if (!ash_util::IsRunningInMash()) { - params.parent = - ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), - ash::kShellWindowId_LockSystemModalContainer); - } else { - using ui::mojom::WindowManager; - params.mus_properties[WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int32_t>(ash::kShellWindowId_LockSystemModalContainer)); - } + ash_util::SetupWidgetInitParamsForContainer( + ¶ms, ash::kShellWindowId_LockSystemModalContainer); dialog_widget_ = new views::Widget; dialog_widget_->Init(params);
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 0e0a4f92..1a4ee880 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -239,10 +239,6 @@ registry->RegisterBooleanPref( ash::prefs::kShouldAlwaysShowAccessibilityMenu, false, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); - registry->RegisterBooleanPref( - ash::prefs::kTapDraggingEnabled, false, - user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF | - PrefRegistry::PUBLIC); registry->RegisterIntegerPref( prefs::kMouseSensitivity,
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc index 33ec3cdf..9f340d8 100644 --- a/chrome/browser/chromeos/tether/tether_service_unittest.cc +++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -199,7 +199,7 @@ : public cryptauth::RemoteDeviceProviderImpl::Factory { public: FakeRemoteDeviceProviderFactory() = default; - virtual ~FakeRemoteDeviceProviderFactory() = default; + ~FakeRemoteDeviceProviderFactory() override = default; // cryptauth::RemoteDeviceProviderImpl::Factory: std::unique_ptr<cryptauth::RemoteDeviceProvider> BuildInstance(
diff --git a/chrome/browser/chromeos/upgrade_detector_chromeos.cc b/chrome/browser/chromeos/upgrade_detector_chromeos.cc index 2a3511f3a..7fffeef 100644 --- a/chrome/browser/chromeos/upgrade_detector_chromeos.cc +++ b/chrome/browser/chromeos/upgrade_detector_chromeos.cc
@@ -161,26 +161,35 @@ } void UpgradeDetectorChromeos::NotifyOnUpgrade() { + const base::TimeDelta elevated_threshold = + high_threshold_ * kElevatedScaleFactor; base::TimeDelta delta = tick_clock()->NowTicks() - upgrade_detected_time(); + // The delay from now until the next highest notification stage is reached, or + // zero if the highest notification stage has been reached. + base::TimeDelta next_delay; // These if statements must be sorted (highest interval first). - if (delta >= high_threshold_) + if (delta >= high_threshold_) { set_upgrade_notification_stage(UPGRADE_ANNOYANCE_HIGH); - else if (delta >= high_threshold_ * kElevatedScaleFactor) + } else if (delta >= elevated_threshold) { set_upgrade_notification_stage(UPGRADE_ANNOYANCE_ELEVATED); - else + next_delay = high_threshold_ - delta; + } else { set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW); + next_delay = elevated_threshold - delta; + } - // Stop the timer if the highest threshold has been reached. Otherwise, make - // sure it is running. It is possible that a change in the notification period - // (via administrative policy) has moved the detector from high annoyance back - // down to a lower level, in which case the timer must be restarted. - if (upgrade_notification_stage() == UPGRADE_ANNOYANCE_HIGH) { - upgrade_notification_timer_.Stop(); - } else if (!upgrade_notification_timer_.IsRunning()) { + if (!next_delay.is_zero()) { + // Schedule the next wakeup in 20 minutes or when the next change to the + // notification stage should take place. upgrade_notification_timer_.Start( - FROM_HERE, kNotifyCycleDelta, this, + FROM_HERE, std::min(next_delay, kNotifyCycleDelta), this, &UpgradeDetectorChromeos::NotifyOnUpgrade); + } else if (upgrade_notification_timer_.IsRunning()) { + // Explicitly stop the timer in case this call is due to a + // RelaunchNotificationPeriod change that brought the instance up to the + // "high" annoyance level. + upgrade_notification_timer_.Stop(); } NotifyUpgrade(); @@ -196,10 +205,6 @@ // ChromeOS shows upgrade arrow once the upgrade becomes available. NotifyOnUpgrade(); - - // Setup timer to to move along the upgrade advisory system. - upgrade_notification_timer_.Start(FROM_HERE, kNotifyCycleDelta, this, - &UpgradeDetectorChromeos::NotifyOnUpgrade); } // static
diff --git a/chrome/browser/chromeos/upgrade_detector_chromeos.h b/chrome/browser/chromeos/upgrade_detector_chromeos.h index de44d08..8e4e68d 100644 --- a/chrome/browser/chromeos/upgrade_detector_chromeos.h +++ b/chrome/browser/chromeos/upgrade_detector_chromeos.h
@@ -66,9 +66,9 @@ // The delta from upgrade detection until high annoyance level is reached. base::TimeDelta high_threshold_; - // After we detect an upgrade we start a recurring timer to see if enough time - // has passed and we should start notifying the user. - base::RepeatingTimer upgrade_notification_timer_; + // A timer used to move through the various upgrade notification stages and + // call UpgradeDetector::NotifyUpgrade. + base::OneShotTimer upgrade_notification_timer_; bool initialized_; base::WeakPtrFactory<UpgradeDetectorChromeos> weak_factory_;
diff --git a/chrome/browser/client_hints/client_hints.cc b/chrome/browser/client_hints/client_hints.cc index 77e0fb9..4fec5e2 100644 --- a/chrome/browser/client_hints/client_hints.cc +++ b/chrome/browser/client_hints/client_hints.cc
@@ -10,6 +10,8 @@ #include "base/strings/string_number_conversions.h" #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h" +#include "chrome/browser/net/nqe/ui_network_quality_estimator_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/client_hints/client_hints.h" #include "components/content_settings/core/browser/cookie_settings.h" @@ -20,6 +22,7 @@ #include "content/public/common/origin_util.h" #include "net/base/url_util.h" #include "net/http/http_request_headers.h" +#include "net/nqe/effective_connection_type.h" #include "net/url_request/url_request.h" #include "third_party/WebKit/public/common/client_hints/client_hints.h" #include "third_party/WebKit/public/common/device_memory/approximated_device_memory.h" @@ -170,12 +173,53 @@ } } + UINetworkQualityEstimatorService* estimator = + UINetworkQualityEstimatorServiceFactory::GetForProfile( + Profile::FromBrowserContext(context)); + + // TODO(crbug.com/826950): Add host specific noise and bucketization to RTT + // and downlink values. + if (web_client_hints.IsEnabled(blink::mojom::WebClientHintsType::kRtt)) { + if (estimator->GetHttpRTT()) { + additional_headers->SetHeader( + blink::kClientHintsHeaderMapping[static_cast<int>( + blink::mojom::WebClientHintsType::kRtt)], + base::NumberToString(estimator->GetHttpRTT()->InMilliseconds())); + } + } + + if (web_client_hints.IsEnabled(blink::mojom::WebClientHintsType::kDownlink)) { + if (estimator->GetDownstreamThroughputKbps()) { + additional_headers->SetHeader( + blink::kClientHintsHeaderMapping[static_cast<int>( + blink::mojom::WebClientHintsType::kDownlink)], + base::NumberToString( + ((double)estimator->GetDownstreamThroughputKbps().value()) / + 1024)); + } + } + + if (web_client_hints.IsEnabled(blink::mojom::WebClientHintsType::kEct)) { + DCHECK_EQ(blink::kWebEffectiveConnectionTypeMappingCount, + net::EFFECTIVE_CONNECTION_TYPE_4G + 1u); + DCHECK_EQ(blink::kWebEffectiveConnectionTypeMappingCount, + net::EFFECTIVE_CONNECTION_TYPE_LAST); + + int effective_connection_type = + static_cast<int>(estimator->GetEffectiveConnectionType()); + + additional_headers->SetHeader( + blink::kClientHintsHeaderMapping[static_cast<int>( + blink::mojom::WebClientHintsType::kEct)], + blink::kWebEffectiveConnectionTypeMapping[effective_connection_type]); + } + // Static assert that triggers if a new client hint header is added. If a // new client hint header is added, the following assertion should be updated. // If possible, logic should be added above so that the request headers for // the newly added client hint can be added to the request. static_assert( - blink::mojom::WebClientHintsType::kViewportWidth == + blink::mojom::WebClientHintsType::kEct == blink::mojom::WebClientHintsType::kMaxValue, "Consider adding client hint request headers from the browser process");
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index f0e9a46..99a881e 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -28,9 +28,11 @@ #include "content/public/test/url_loader_interceptor.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_request_headers.h" +#include "net/nqe/effective_connection_type.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "services/network/public/cpp/network_switches.h" #include "third_party/WebKit/public/common/client_hints/client_hints.h" namespace { @@ -159,6 +161,8 @@ void SetUpCommandLine(base::CommandLine* cmd) override { cmd->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures); + cmd->AppendSwitchASCII(network::switches::kForceEffectiveConnectionType, + net::kEffectiveConnectionType2G); } void SetClientHintExpectationsOnMainFrame(bool expect_client_hints) { @@ -275,6 +279,7 @@ EXPECT_EQ(980, value); #endif main_frame_viewport_width_observed_ = value; + VerifyNetworkQualityClientHints(request); } } @@ -312,6 +317,7 @@ EXPECT_EQ(main_frame_viewport_width_observed_, value); } #endif + VerifyNetworkQualityClientHints(request); } } @@ -336,6 +342,22 @@ } } + void VerifyNetworkQualityClientHints( + const net::test_server::HttpRequest& request) const { + // Effective connection type is forced to 2G using command line in these + // tests. + double value = 0.0; + EXPECT_TRUE( + base::StringToDouble(request.headers.find("rtt")->second, &value)); + EXPECT_LE(0, value); + + EXPECT_TRUE( + base::StringToDouble(request.headers.find("downlink")->second, &value)); + EXPECT_LE(0, value); + + EXPECT_FALSE(request.headers.find("ect")->second.empty()); + } + net::EmbeddedTestServer http_server_; net::EmbeddedTestServer https_server_; GURL accept_ch_with_lifetime_http_local_url_; @@ -376,8 +398,8 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // client_hints_url() sets three client hints. - histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 3, 1); + // client_hints_url() sets six client hints. + histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 6, 1); // accept_ch_with_lifetime_url() sets client hints persist duration to 3600 // seconds. histogram_tester.ExpectUniqueSample("ClientHints.PersistDuration", @@ -429,9 +451,9 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // Three client hints are attached to the image request, and three to the main + // Six client hints are attached to the image request, and six to the main // frame request. - EXPECT_EQ(6u, count_client_hints_headers_seen()); + EXPECT_EQ(12u, count_client_hints_headers_seen()); // Navigating to without_accept_ch_without_lifetime_img_foo_com() should not // attach client hints to the image subresouce contained in that page since @@ -446,7 +468,7 @@ #if defined(OS_ANDROID) EXPECT_EQ(6u, count_client_hints_headers_seen()); #else - EXPECT_EQ(9u, count_client_hints_headers_seen()); + EXPECT_EQ(18u, count_client_hints_headers_seen()); #endif // Requests to third party servers should not have client hints attached. EXPECT_EQ(1u, third_party_request_count_seen()); @@ -504,8 +526,7 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // client_hints_url() sets three client hints. - histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 3, 1); + histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 6, 1); // accept_ch_with_lifetime_http_local_url() sets client hints persist duration // to 3600 seconds. histogram_tester.ExpectUniqueSample("ClientHints.PersistDuration", @@ -524,9 +545,9 @@ ui_test_utils::NavigateToURL(browser(), without_accept_ch_without_lifetime_local_url()); - // Three client hints are attached to the image request, and three to the main + // Six client hints are attached to the image request, and six to the main // frame request. - EXPECT_EQ(6u, count_client_hints_headers_seen()); + EXPECT_EQ(12u, count_client_hints_headers_seen()); } // Loads a webpage that does not request persisting of client hints. @@ -564,8 +585,7 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // client_hints_url() sets three client hints. - histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 3, 1); + histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 6, 1); // accept_ch_with_lifetime_url() sets client hints persist duration to 3600 // seconds. histogram_tester.ExpectUniqueSample("ClientHints.PersistDuration", @@ -583,9 +603,9 @@ ui_test_utils::NavigateToURL(browser(), without_accept_ch_without_lifetime_url()); - // Three client hints are attached to the image request, and three to the main + // Six client hints are attached to the image request, and six to the main // frame request. - EXPECT_EQ(6u, count_client_hints_headers_seen()); + EXPECT_EQ(12u, count_client_hints_headers_seen()); } // Ensure that when cookies are blocked, client hint preferences are not @@ -643,8 +663,7 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // client_hints_url() sets three client hints. - histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 3, 1); + histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 6, 1); // accept_ch_with_lifetime_url() tries to set client hints persist duration to // 3600 seconds. histogram_tester.ExpectUniqueSample("ClientHints.PersistDuration", @@ -679,9 +698,9 @@ ui_test_utils::NavigateToURL(browser(), without_accept_ch_without_lifetime_url()); - // Three client hints are attached to the image request, and three to the main + // Six client hints are attached to the image request, and six to the main // frame request. - EXPECT_EQ(6u, count_client_hints_headers_seen()); + EXPECT_EQ(12u, count_client_hints_headers_seen()); // Clear settings. HostContentSettingsMapFactory::GetForProfile(browser()->profile()) @@ -746,8 +765,7 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // client_hints_url() sets three client hints. - histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 3, 1); + histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 6, 1); // accept_ch_with_lifetime_url() tries to set client hints persist duration to // 3600 seconds. histogram_tester.ExpectUniqueSample("ClientHints.PersistDuration", @@ -781,9 +799,9 @@ ui_test_utils::NavigateToURL(browser(), without_accept_ch_without_lifetime_url()); - // Three client hints are attached to the image request, and three to the main + // Six client hints are attached to the image request, and six to the main // frame request. - EXPECT_EQ(6u, count_client_hints_headers_seen()); + EXPECT_EQ(12u, count_client_hints_headers_seen()); // Clear settings. HostContentSettingsMapFactory::GetForProfile(browser()->profile()) @@ -826,8 +844,7 @@ ui_test_utils::NavigateToURL(browser(), accept_ch_without_lifetime_img_localhost()); - // Client hints are attached to only the first party image subresource. - EXPECT_EQ(3u, count_client_hints_headers_seen()); + EXPECT_EQ(6u, count_client_hints_headers_seen()); EXPECT_EQ(2u, third_party_request_count_seen()); EXPECT_EQ(0u, third_party_client_hints_count_seen()); VerifyContentSettingsNotNotified(); @@ -845,7 +862,7 @@ CONTENT_SETTING_BLOCK); ui_test_utils::NavigateToURL(browser(), accept_ch_without_lifetime_img_localhost()); - EXPECT_EQ(3u, count_client_hints_headers_seen()); + EXPECT_EQ(6u, count_client_hints_headers_seen()); EXPECT_EQ(3u, third_party_request_count_seen()); EXPECT_EQ(0u, third_party_client_hints_count_seen()); @@ -891,8 +908,7 @@ SetClientHintExpectationsOnSubresources(true); ui_test_utils::NavigateToURL(browser(), accept_ch_without_lifetime_img_localhost()); - // Client hints are attached to only the first party image subresource. - EXPECT_EQ(3u, count_client_hints_headers_seen()); + EXPECT_EQ(6u, count_client_hints_headers_seen()); EXPECT_EQ(2u, third_party_request_count_seen()); EXPECT_EQ(0u, third_party_client_hints_count_seen()); @@ -906,7 +922,7 @@ ui_test_utils::NavigateToURL(browser(), accept_ch_without_lifetime_img_localhost()); - EXPECT_EQ(3u, count_client_hints_headers_seen()); + EXPECT_EQ(6u, count_client_hints_headers_seen()); EXPECT_EQ(3u, third_party_request_count_seen()); EXPECT_EQ(0u, third_party_client_hints_count_seen()); @@ -930,8 +946,8 @@ content::FetchHistogramsFromChildProcesses(); SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); - // accept_ch_with_lifetime_url() sets three client hints. - histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 3, 1); + // accept_ch_with_lifetime_url() sets six client hints. + histogram_tester.ExpectUniqueSample("ClientHints.UpdateSize", 6, 1); // At least one renderer must have been created. All the renderers created // must have read 0 client hints.
diff --git a/chrome/browser/component_updater/sth_set_component_installer.cc b/chrome/browser/component_updater/sth_set_component_installer.cc index 1bc9312..c370903 100644 --- a/chrome/browser/component_updater/sth_set_component_installer.cc +++ b/chrome/browser/component_updater/sth_set_component_installer.cc
@@ -19,13 +19,13 @@ #include "base/values.h" #include "base/version.h" #include "chrome/browser/net/sth_distributor_provider.h" +#include "components/certificate_transparency/sth_distributor.h" +#include "components/certificate_transparency/sth_observer.h" #include "components/component_updater/component_updater_paths.h" #include "content/public/browser/browser_thread.h" #include "crypto/sha2.h" #include "net/cert/ct_log_response_parser.h" #include "net/cert/signed_tree_head.h" -#include "net/cert/sth_distributor.h" -#include "net/cert/sth_observer.h" using component_updater::ComponentUpdateService; @@ -52,7 +52,7 @@ const char kSTHSetFetcherManifestName[] = "Signed Tree Heads"; STHSetComponentInstallerPolicy::STHSetComponentInstallerPolicy( - net::ct::STHObserver* sth_observer) + certificate_transparency::STHObserver* sth_observer) : sth_observer_(sth_observer), weak_ptr_factory_(this) {} STHSetComponentInstallerPolicy::~STHSetComponentInstallerPolicy() {} @@ -185,7 +185,7 @@ content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO) ->PostTask( FROM_HERE, - base::BindOnce(&net::ct::STHObserver::NewSTHObserved, + base::BindOnce(&certificate_transparency::STHObserver::NewSTHObserved, base::Unretained(sth_observer_), signed_tree_head)); } @@ -200,7 +200,7 @@ const base::FilePath& user_data_dir) { DVLOG(1) << "Registering STH Set fetcher component."; - net::ct::STHDistributor* distributor = + certificate_transparency::STHDistributor* distributor = chrome_browser_net::GetGlobalSTHDistributor(); // The global STHDistributor should have been created by this point. DCHECK(distributor);
diff --git a/chrome/browser/component_updater/sth_set_component_installer.h b/chrome/browser/component_updater/sth_set_component_installer.h index a2d181f..93f4776 100644 --- a/chrome/browser/component_updater/sth_set_component_installer.h +++ b/chrome/browser/component_updater/sth_set_component_installer.h
@@ -20,11 +20,9 @@ class Value; } // namespace base -namespace net { -namespace ct { +namespace certificate_transparency { class STHObserver; -} // namespace ct -} // namespace net +} // namespace certificate_transparency namespace component_updater { @@ -36,12 +34,14 @@ // To identify the log each STH belongs to, the name of the file is // hex-encoded Log ID of the log that produced this STH. // -// Notifications of each of the new STHs are sent to the net::ct::STHObserver, -// so that it can take appropriate steps, including possible persistence. +// Notifications of each of the new STHs are sent to the +// certificate_transparency::STHObserver, so that it can take appropriate +// steps, including possible persistence. class STHSetComponentInstallerPolicy : public ComponentInstallerPolicy { public: // The |sth_distributor| will be notified each time a new STH is observed. - explicit STHSetComponentInstallerPolicy(net::ct::STHObserver* sth_observer); + explicit STHSetComponentInstallerPolicy( + certificate_transparency::STHObserver* sth_observer); ~STHSetComponentInstallerPolicy() override; private: @@ -79,7 +79,7 @@ // The observer is not owned by this class, so the code creating an instance // of this class is expected to ensure the STHObserver lives as long as // this class does. Typically the observer provided will be a global. - net::ct::STHObserver* sth_observer_; + certificate_transparency::STHObserver* sth_observer_; base::WeakPtrFactory<STHSetComponentInstallerPolicy> weak_ptr_factory_;
diff --git a/chrome/browser/component_updater/sth_set_component_installer_unittest.cc b/chrome/browser/component_updater/sth_set_component_installer_unittest.cc index 0172fb1..ee83dbd3 100644 --- a/chrome/browser/component_updater/sth_set_component_installer_unittest.cc +++ b/chrome/browser/component_updater/sth_set_component_installer_unittest.cc
@@ -17,9 +17,9 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "base/version.h" +#include "components/certificate_transparency/sth_observer.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/cert/signed_tree_head.h" -#include "net/cert/sth_observer.h" #include "net/test/ct_test_util.h" #include "services/data_decoder/public/cpp/testing_json_parser.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,7 +27,7 @@ namespace component_updater { -class StoringSTHObserver : public net::ct::STHObserver { +class StoringSTHObserver : public certificate_transparency::STHObserver { public: void NewSTHObserved(const net::ct::SignedTreeHead& sth) override { sths[sth.log_id] = sth;
diff --git a/chrome/browser/content_settings/web_site_settings_uma_util.cc b/chrome/browser/content_settings/web_site_settings_uma_util.cc index d47e6f1..6de8108 100644 --- a/chrome/browser/content_settings/web_site_settings_uma_util.cc +++ b/chrome/browser/content_settings/web_site_settings_uma_util.cc
@@ -21,6 +21,9 @@ } else if (setting == ContentSetting::CONTENT_SETTING_BLOCK) { UMA_HISTOGRAM_EXACT_LINEAR("WebsiteSettings.Menu.PermissionChanged.Blocked", histogram_value, num_values); + } else if (setting == ContentSetting::CONTENT_SETTING_ASK) { + UMA_HISTOGRAM_EXACT_LINEAR("WebsiteSettings.Menu.PermissionChanged.Ask", + histogram_value, num_values); } else if (setting == ContentSetting::CONTENT_SETTING_DEFAULT) { UMA_HISTOGRAM_EXACT_LINEAR("WebsiteSettings.Menu.PermissionChanged.Reset", histogram_value, num_values);
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc index 65273566..3245c5f 100644 --- a/chrome/browser/extensions/active_tab_unittest.cc +++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -12,6 +12,10 @@ #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/active_tab_permission_granter.h" +#include "chrome/browser/extensions/chrome_test_extension_loader.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_service_test_base.h" +#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_tab_helper.h" @@ -24,15 +28,20 @@ #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" #include "content/public/common/frame_navigate_params.h" +#include "content/public/test/browser_side_navigation_test_utils.h" #include "content/public/test/navigation_simulator.h" #include "content/public/test/test_browser_thread.h" +#include "content/public/test/web_contents_tester.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/test_extension_registry_observer.h" +#include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_channel.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/value_builder.h" +#include "extensions/test/test_extension_dir.h" #if defined(OS_CHROMEOS) #include "base/run_loop.h" @@ -152,8 +161,8 @@ nullptr) && permissions_data->CanRunContentScriptOnPage( extension.get(), url, tab_id, nullptr); - bool capture = HasTabsPermission(extension, tab_id) && - permissions_data->CanCaptureVisiblePage(tab_id, NULL); + bool capture = permissions_data->CanCaptureVisiblePage(url, extension.get(), + tab_id, NULL); switch (feature) { case PERMITTED_SCRIPT_ONLY: return script && !capture; @@ -236,7 +245,7 @@ // Other subdomains shouldn't be given access. GURL mail_google("http://mail.google.com"); - EXPECT_TRUE(IsAllowed(extension, mail_google, PERMITTED_CAPTURE_ONLY)); + EXPECT_TRUE(IsBlocked(extension, mail_google)); EXPECT_TRUE(IsBlocked(another_extension, mail_google)); EXPECT_TRUE(IsBlocked(extension_without_active_tab, mail_google)); @@ -296,8 +305,8 @@ active_tab_permission_granter()->GrantIfRequested( extension_without_active_tab.get()); - EXPECT_TRUE(IsAllowed(extension, google, PERMITTED_CAPTURE_ONLY)); - EXPECT_TRUE(IsAllowed(another_extension, google, PERMITTED_CAPTURE_ONLY)); + EXPECT_TRUE(IsBlocked(extension, google)); + EXPECT_TRUE(IsBlocked(another_extension, google)); EXPECT_TRUE(IsBlocked(extension_without_active_tab, google)); EXPECT_TRUE(IsAllowed(extension, chromium)); @@ -316,8 +325,8 @@ EXPECT_TRUE(IsAllowed(another_extension, google)); EXPECT_TRUE(IsBlocked(extension_without_active_tab, google)); - EXPECT_TRUE(IsAllowed(extension, chromium, PERMITTED_CAPTURE_ONLY)); - EXPECT_TRUE(IsAllowed(another_extension, chromium, PERMITTED_CAPTURE_ONLY)); + EXPECT_TRUE(IsBlocked(extension, chromium)); + EXPECT_TRUE(IsBlocked(another_extension, chromium)); EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium)); } @@ -531,5 +540,92 @@ } #endif // defined(OS_CHROMEOS) +// An active tab test that includes an ExtensionService. +class ActiveTabWithServiceTest : public ExtensionServiceTestBase { + public: + ActiveTabWithServiceTest() {} + + void SetUp() override; + void TearDown() override; + + private: + DISALLOW_COPY_AND_ASSIGN(ActiveTabWithServiceTest); +}; + +void ActiveTabWithServiceTest::SetUp() { + ExtensionServiceTestBase::SetUp(); + content::BrowserSideNavigationSetUp(); +} + +void ActiveTabWithServiceTest::TearDown() { + content::BrowserSideNavigationTearDown(); + ExtensionServiceTestBase::TearDown(); +} + +// Tests that an extension can only capture file:// URLs with the active tab +// permission when it has file access granted. +// Regression test for https://crbug.com/810220. +TEST_F(ActiveTabWithServiceTest, FileURLs) { + InitializeEmptyExtensionService(); + + TestExtensionDir test_dir; + test_dir.WriteManifest(R"( + { + "name": "Active Tab Capture With File Urls", + "description": "Testing activeTab on file urls", + "version": "0.1", + "manifest_version": 2, + "permissions": ["activeTab"] + })"); + + ChromeTestExtensionLoader loader(profile()); + loader.set_allow_file_access(false); + scoped_refptr<const Extension> extension = + loader.LoadExtension(test_dir.UnpackedPath()); + ASSERT_TRUE(extension); + const std::string id = extension->id(); + ASSERT_TRUE(registry()->enabled_extensions().Contains(id)); + + EXPECT_FALSE(util::AllowFileAccess(id, profile())); + + std::unique_ptr<content::WebContents> web_contents( + content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); + ASSERT_TRUE(web_contents); + + const GURL file_url("file:///foo"); + ASSERT_TRUE(content::WebContentsTester::For(web_contents.get())); + content::WebContentsTester::For(web_contents.get()) + ->NavigateAndCommit(file_url); + EXPECT_EQ(file_url, web_contents->GetLastCommittedURL()); + + TabHelper::CreateForWebContents(web_contents.get()); + ActiveTabPermissionGranter* permission_granter = + TabHelper::FromWebContents(web_contents.get()) + ->active_tab_permission_granter(); + ASSERT_TRUE(permission_granter); + const int tab_id = SessionTabHelper::IdForTab(web_contents.get()).id(); + EXPECT_NE(extension_misc::kUnknownTabId, tab_id); + + EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage( + web_contents->GetLastCommittedURL(), extension.get(), tab_id, nullptr)); + + permission_granter->GrantIfRequested(extension.get()); + EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage( + web_contents->GetLastCommittedURL(), extension.get(), tab_id, nullptr)); + + permission_granter->RevokeForTesting(); + TestExtensionRegistryObserver observer(registry(), id); + // This will reload the extension, so we need to reset the extension pointer. + util::SetAllowFileAccess(id, profile(), true); + extension = observer.WaitForExtensionLoaded(); + ASSERT_TRUE(extension); + + EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage( + web_contents->GetLastCommittedURL(), extension.get(), tab_id, nullptr)); + permission_granter->GrantIfRequested(extension.get()); + EXPECT_TRUE(extension->permissions_data()->CanCaptureVisiblePage( + web_contents->GetLastCommittedURL(), extension.get(), tab_id, nullptr)); +} + } // namespace } // namespace extensions
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc index abea2a947..1b40c82 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
@@ -5,6 +5,7 @@ #include <stdint.h> #include <memory> +#include <tuple> #include <utility> #include "chrome/browser/extensions/extension_apitest.h" @@ -224,19 +225,19 @@ ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - ::std::tr1::get<k>(args).Run(); + std::get<k>(args).Run(); } ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - ::std::tr1::get<k>(args).Run(p0); + std::get<k>(args).Run(p0); } ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg, HAS_2_TEMPLATE_PARAMS(int, k, typename, T), AND_1_VALUE_PARAMS(p0)) { - ::std::tr1::get<k>(args).Run(std::unique_ptr<T>(p0)); + std::get<k>(args).Run(std::unique_ptr<T>(p0)); } BluetoothGattConnection* CreateGattConnection(
diff --git a/chrome/browser/extensions/api/commands/command_service.cc b/chrome/browser/extensions/api/commands/command_service.cc index 362c8e4b..3177718 100644 --- a/chrome/browser/extensions/api/commands/command_service.cc +++ b/chrome/browser/extensions/api/commands/command_service.cc
@@ -52,10 +52,6 @@ // actually assigned. const char kSuggestedKeyWasAssigned[] = "was_assigned"; -// A preference that indicates that the initial keybindings for the given -// extension have been set. -const char kInitialBindingsHaveBeenAssigned[] = "initial_keybindings_set"; - std::string GetPlatformKeybindingKeyForAccelerator( const ui::Accelerator& accelerator, const std::string& extension_id) { std::string key = Command::CommandPlatform() + ":" + @@ -84,23 +80,6 @@ return result; } -void SetInitialBindingsHaveBeenAssigned( - ExtensionPrefs* prefs, const std::string& extension_id) { - prefs->UpdateExtensionPref(extension_id, kInitialBindingsHaveBeenAssigned, - std::make_unique<base::Value>(true)); -} - -bool InitialBindingsHaveBeenAssigned( - const ExtensionPrefs* prefs, const std::string& extension_id) { - bool assigned = false; - if (!prefs || !prefs->ReadPrefAsBoolean(extension_id, - kInitialBindingsHaveBeenAssigned, - &assigned)) - return false; - - return assigned; -} - // Merge |suggested_key_prefs| into the saved preferences for the extension. We // merge rather than overwrite to preserve existing was_assigned preferences. void MergeSuggestedKeyPrefs( @@ -533,11 +512,6 @@ if (!commands) return; - ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_); - // TODO(wittman): remove use of this pref after M37 hits stable. - if (!InitialBindingsHaveBeenAssigned(extension_prefs, extension->id())) - SetInitialBindingsHaveBeenAssigned(extension_prefs, extension->id()); - for (CommandMap::const_iterator iter = commands->begin(); iter != commands->end(); ++iter) { const Command command = iter->second;
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc index 3c5d791..fa676fa 100644 --- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc +++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -852,7 +852,6 @@ cryptauth::CryptAuthDeviceIdProviderImpl::GetInstance()->GetDeviceId(), account_id.GetUserEmail()); - user.ble_discovery_enabled = true; users.push_back(std::move(user)); } return RespondNow(
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc index 8dd064b8..6376582 100644 --- a/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -2004,7 +2004,9 @@ EXPECT_FALSE(func->scope_ui_shown()); } -IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionPublicSessionTest, Whitelisted) { +// TODO(crbug.com/830052): This test is flaky. +IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionPublicSessionTest, + DISABLED_Whitelisted) { // GetAuthToken() should return a token for whitelisted extensions. user_manager::ScopedUserManager user_manager_enabler( base::WrapUnique(user_manager_));
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 47d3336..62667505 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1739,6 +1739,7 @@ } if (!extension()->permissions_data()->CanCaptureVisiblePage( + contents->GetLastCommittedURL(), extension(), SessionTabHelper::IdForTab(contents).id(), error)) { return nullptr; } @@ -1762,9 +1763,8 @@ std::string error; WebContents* contents = GetWebContentsForID(context_id, &error); - // TODO(wjmaclean): If |error| was populated, shouldn't we send error - // response? Currently doing that will fail - // ExtensionApiCaptureTest.CaptureNullWindow test. + if (!contents) + return RespondNow(Error(error)); const CaptureResult capture_result = CaptureAsync( contents, image_details.get(),
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h index 2fcc4ba..ce4a83e 100644 --- a/chrome/browser/extensions/extension_install_prompt.h +++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -260,15 +260,6 @@ // Callback to show the default extension install dialog. // The implementations of this function are platform-specific. static ShowDialogCallback GetDefaultShowDialogCallback(); -#if defined(OS_MACOSX) - // Temporary shim for Polychrome. See bottom of first comment in - // https://crbug.com/804950 for details - static ShowDialogCallback GetDefaultShowDialogCallbackCocoa(); -#endif - - // Callback to show the Views extension install dialog. Don't use this; it is - // a temporary hack for MacViews. - static ShowDialogCallback GetViewsShowDialogCallback(); // Returns the appropriate prompt type for the given |extension|. // TODO(devlin): This method is yucky - callers probably only care about one
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc index 210841f8..b42e180 100644 --- a/chrome/browser/extensions/extension_special_storage_policy.cc +++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -6,6 +6,7 @@ #include <stddef.h> #include <stdint.h> +#include <utility> #include "base/bind.h" #include "base/command_line.h" @@ -112,11 +113,18 @@ return cookie_settings_->IsCookieSessionOnly(origin); } -bool ExtensionSpecialStoragePolicy::ShouldDeleteCookieOnExit( - const GURL& origin) { +storage::SpecialStoragePolicy::DeleteCookiePredicate +ExtensionSpecialStoragePolicy::CreateDeleteCookieOnExitPredicate() { if (cookie_settings_.get() == NULL) - return false; - return cookie_settings_->ShouldDeleteCookieOnExit(origin); + return DeleteCookiePredicate(); + // Fetch the list of cookies related content_settings and bind it + // to CookieSettings::ShouldDeleteCookieOnExit to avoid fetching it on + // every call. + ContentSettingsForOneType entries; + cookie_settings_->GetCookieSettings(&entries); + return base::BindRepeating( + &content_settings::CookieSettings::ShouldDeleteCookieOnExit, + cookie_settings_, std::move(entries)); } bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h index b39a09e..6f4502e 100644 --- a/chrome/browser/extensions/extension_special_storage_policy.h +++ b/chrome/browser/extensions/extension_special_storage_policy.h
@@ -39,10 +39,10 @@ bool IsStorageProtected(const GURL& origin) override; bool IsStorageUnlimited(const GURL& origin) override; bool IsStorageSessionOnly(const GURL& origin) override; - bool ShouldDeleteCookieOnExit(const GURL& origin) override; bool HasIsolatedStorage(const GURL& origin) override; bool HasSessionOnlyOrigins() override; bool IsStorageDurable(const GURL& origin) override; + DeleteCookiePredicate CreateDeleteCookieOnExitPredicate() override; // Methods used by the ExtensionService to populate this class. void GrantRightsForExtension(const extensions::Extension* extension,
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.cc b/chrome/browser/extensions/mock_extension_special_storage_policy.cc index 7ff427f..db84c943 100644 --- a/chrome/browser/extensions/mock_extension_special_storage_policy.cc +++ b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
@@ -20,13 +20,13 @@ return false; } -bool MockExtensionSpecialStoragePolicy::ShouldDeleteCookieOnExit( - const GURL& origin) { +bool MockExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() { return false; } -bool MockExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() { - return false; +storage::SpecialStoragePolicy::DeleteCookiePredicate +MockExtensionSpecialStoragePolicy::CreateDeleteCookieOnExitPredicate() { + return DeleteCookiePredicate(); } MockExtensionSpecialStoragePolicy::~MockExtensionSpecialStoragePolicy() {}
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.h b/chrome/browser/extensions/mock_extension_special_storage_policy.h index ecbe07a..5f0f436 100644 --- a/chrome/browser/extensions/mock_extension_special_storage_policy.h +++ b/chrome/browser/extensions/mock_extension_special_storage_policy.h
@@ -23,8 +23,8 @@ bool IsStorageProtected(const GURL& origin) override; bool IsStorageUnlimited(const GURL& origin) override; bool IsStorageSessionOnly(const GURL& origin) override; - bool ShouldDeleteCookieOnExit(const GURL& origin) override; bool HasSessionOnlyOrigins() override; + DeleteCookiePredicate CreateDeleteCookieOnExitPredicate() override; void AddProtected(const GURL& origin) { protected_.insert(origin);
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc index 04049de..487083db 100644 --- a/chrome/browser/importer/external_process_importer_client.cc +++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -50,27 +50,28 @@ // Dictionary of all localized strings that could be needed by the importer // in the external process. - auto localized_strings = std::make_unique<base::DictionaryValue>(); - localized_strings->SetString(base::IntToString(IDS_BOOKMARK_GROUP), - l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP)); - localized_strings->SetString( + base::Value localized_strings(base::Value::Type::DICTIONARY); + localized_strings.SetKey( + base::IntToString(IDS_BOOKMARK_GROUP), + base::Value(l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP))); + localized_strings.SetKey( base::IntToString(IDS_BOOKMARK_GROUP_FROM_FIREFOX), - l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX)); - localized_strings->SetString( + base::Value(l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX))); + localized_strings.SetKey( base::IntToString(IDS_BOOKMARK_GROUP_FROM_SAFARI), - l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_SAFARI)); - localized_strings->SetString( + base::Value(l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_SAFARI))); + localized_strings.SetKey( base::IntToString(IDS_IMPORT_FROM_FIREFOX), - l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX)); - localized_strings->SetString( + base::Value(l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX))); + localized_strings.SetKey( base::IntToString(IDS_IMPORT_FROM_ICEWEASEL), - l10n_util::GetStringUTF8(IDS_IMPORT_FROM_ICEWEASEL)); - localized_strings->SetString( + base::Value(l10n_util::GetStringUTF8(IDS_IMPORT_FROM_ICEWEASEL))); + localized_strings.SetKey( base::IntToString(IDS_IMPORT_FROM_SAFARI), - l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI)); - localized_strings->SetString( + base::Value(l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI))); + localized_strings.SetKey( base::IntToString(IDS_BOOKMARK_BAR_FOLDER_NAME), - l10n_util::GetStringUTF8(IDS_BOOKMARK_BAR_FOLDER_NAME)); + base::Value(l10n_util::GetStringUTF8(IDS_BOOKMARK_BAR_FOLDER_NAME))); // If the utility process hasn't started yet the message will queue until it // does.
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 2f0de62..c809003 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -43,6 +43,8 @@ #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "components/certificate_transparency/sth_distributor.h" +#include "components/certificate_transparency/sth_observer.h" #include "components/certificate_transparency/tree_state_tracker.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h" #include "components/data_usage/core/data_use_aggregator.h" @@ -73,8 +75,6 @@ #include "net/cert/ct_verifier.h" #include "net/cert/multi_log_ct_verifier.h" #include "net/cert/multi_threaded_cert_verifier.h" -#include "net/cert/sth_distributor.h" -#include "net/cert/sth_observer.h" #include "net/dns/host_cache.h" #include "net/dns/host_resolver.h" #include "net/dns/mapped_host_resolver.h" @@ -428,7 +428,7 @@ pac_https_url_stripping_enabled_.MoveToThread(io_thread_proxy); chrome_browser_net::SetGlobalSTHDistributor( - std::make_unique<net::ct::STHDistributor>()); + std::make_unique<certificate_transparency::STHDistributor>()); BrowserThread::SetIOThreadDelegate(this); @@ -739,11 +739,13 @@ } } -void IOThread::RegisterSTHObserver(net::ct::STHObserver* observer) { +void IOThread::RegisterSTHObserver( + certificate_transparency::STHObserver* observer) { chrome_browser_net::GetGlobalSTHDistributor()->RegisterObserver(observer); } -void IOThread::UnregisterSTHObserver(net::ct::STHObserver* observer) { +void IOThread::UnregisterSTHObserver( + certificate_transparency::STHObserver* observer) { chrome_browser_net::GetGlobalSTHDistributor()->UnregisterObserver(observer); }
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index b3a7aac..93dd862 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h
@@ -46,6 +46,7 @@ namespace certificate_transparency { class TreeStateTracker; +class STHObserver; } namespace chrome_browser_net { @@ -75,11 +76,6 @@ class SSLConfigService; class URLRequestContext; class URLRequestContextGetter; - -namespace ct { -class STHObserver; -} - } // namespace net namespace net_log { @@ -198,10 +194,10 @@ metrics::UpdateUsagePrefCallbackType GetMetricsDataUseForwarder(); // Registers the |observer| for new STH notifications. - void RegisterSTHObserver(net::ct::STHObserver* observer); + void RegisterSTHObserver(certificate_transparency::STHObserver* observer); // Un-registers the |observer|. - void UnregisterSTHObserver(net::ct::STHObserver* observer); + void UnregisterSTHObserver(certificate_transparency::STHObserver* observer); // Returns true if the indicated proxy resolution features are // enabled. These features are controlled through
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 56e9be8..a667d8d 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <memory> +#include <tuple> #include <utility> #include "base/command_line.h" @@ -406,17 +407,13 @@ // Note: Only parameterized (*_P) tests can be used. Non-parameterized (*_F) // tests will crash at GetParam(). To add non-parameterized tests, use // EncryptedMediaTestBase or one of its subclasses (e.g. WVEncryptedMediaTest). -class EncryptedMediaTest : public EncryptedMediaTestBase, - public testing::WithParamInterface< - std::tr1::tuple<const char*, SrcType>> { +class EncryptedMediaTest + : public EncryptedMediaTestBase, + public testing::WithParamInterface<std::tuple<const char*, SrcType>> { public: - std::string CurrentKeySystem() { - return std::tr1::get<0>(GetParam()); - } + std::string CurrentKeySystem() { return std::get<0>(GetParam()); } - SrcType CurrentSourceType() { - return std::tr1::get<1>(GetParam()); - } + SrcType CurrentSourceType() { return std::get<1>(GetParam()); } void TestSimplePlayback(const std::string& encrypted_media, const std::string& media_type) {
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc index fada978..a6f692c 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
@@ -9,10 +9,13 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/media/router/discovery/discovery_network_monitor.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/media_router/media_sink.h" #include "components/cast_channel/cast_socket_service.h" +#include "components/prefs/pref_service.h" #include "net/base/host_port_pair.h" #include "net/base/ip_address.h" @@ -141,13 +144,28 @@ cast_channel::CastSocketService::GetInstance(); scoped_refptr<base::SequencedTaskRunner> task_runner = cast_socket_service->task_runner(); + + local_state_change_registrar_.Init(g_browser_process->local_state()); + local_state_change_registrar_.Add( + prefs::kMediaRouterCastAllowAllIPs, + base::BindRepeating(&CastMediaSinkService::SetCastAllowAllIPs, + base::Unretained(this))); return std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter>( - new CastMediaSinkServiceImpl(sinks_discovered_cb, observer, - cast_socket_service, - DiscoveryNetworkMonitor::GetInstance()), + new CastMediaSinkServiceImpl( + sinks_discovered_cb, observer, cast_socket_service, + DiscoveryNetworkMonitor::GetInstance(), + GetCastAllowAllIPsPref(g_browser_process->local_state())), base::OnTaskRunnerDeleter(task_runner)); } +void CastMediaSinkService::SetCastAllowAllIPs() { + impl_->task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&CastMediaSinkServiceImpl::SetCastAllowAllIPs, + base::Unretained(impl_.get()), + GetCastAllowAllIPsPref(g_browser_process->local_state()))); +} + void CastMediaSinkService::StartMdnsDiscovery() { // |dns_sd_registry_| is already set to a mock version in unit tests only. // |impl_| must be initialized first because AddObserver might end up calling
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h index 886f6fcf..7455b47 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "base/feature_list.h" #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -18,6 +19,7 @@ #include "chrome/browser/media/router/discovery/mdns/dns_sd_registry.h" #include "chrome/common/media_router/discovery/media_sink_internal.h" #include "chrome/common/media_router/discovery/media_sink_service_util.h" +#include "components/prefs/pref_change_registrar.h" namespace media_router { @@ -85,6 +87,9 @@ void OnDnsSdEvent(const std::string& service_type, const DnsSdRegistry::DnsSdServiceList& services) override; + // Sets the current value of |CastAllowAllIPs()| on |impl_|. + void SetCastAllowAllIPs(); + // Raw pointer to DnsSdRegistry instance, which is a global leaky singleton // and lives as long as the browser process. DnsSdRegistry* dns_sd_registry_ = nullptr; @@ -92,6 +97,9 @@ // Created on the UI thread, used and destroyed on its SequencedTaskRunner. std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter> impl_; + // Listens for local state pref changes for kMediaRouterCastAllowAllIPs. + PrefChangeRegistrar local_state_change_registrar_; + // List of cast sinks found in current round of mDNS discovery. std::vector<MediaSinkInternal> cast_sinks_;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index 48f85bc..19001cc7 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -12,7 +12,6 @@ #include "chrome/common/media_router/discovery/media_sink_internal.h" #include "chrome/common/media_router/media_sink.h" #include "components/cast_channel/cast_channel_enum.h" -#include "components/cast_channel/cast_channel_util.h" #include "components/cast_channel/cast_socket_service.h" #include "components/cast_channel/logger.h" #include "components/net_log/chrome_net_log.h" @@ -180,11 +179,13 @@ const OnSinksDiscoveredCallback& callback, Observer* observer, cast_channel::CastSocketService* cast_socket_service, - DiscoveryNetworkMonitor* network_monitor) + DiscoveryNetworkMonitor* network_monitor, + bool allow_all_ips) : MediaSinkServiceBase(callback), observer_(observer), cast_socket_service_(cast_socket_service), network_monitor_(network_monitor), + allow_all_ips_(allow_all_ips), task_runner_(cast_socket_service_->task_runner()), clock_(base::DefaultClock::GetInstance()), weak_ptr_factory_(this) { @@ -446,8 +447,10 @@ SinkSource sink_source) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!cast_channel::IsValidCastIPAddress(ip_endpoint.address())) + if (!allow_all_ips_ && !ip_endpoint.address().IsReserved()) { + DVLOG(2) << "Invalid Cast IP address: " << ip_endpoint.address().ToString(); return; + } // Erase the entry from |dial_sink_failure_count_| since the device is now // known to be a Cast device. @@ -667,6 +670,11 @@ base::Unretained(this)); } +void CastMediaSinkServiceImpl::SetCastAllowAllIPs(bool allow_all_ips) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + allow_all_ips_ = allow_all_ips; +} + CastMediaSinkServiceImpl::RetryParams::RetryParams() : initial_delay_in_milliseconds(kDefaultInitialDelayInMilliSeconds), max_retry_attempts(kDefaultMaxRetryAttempts),
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h index 253db30..2078fc50 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -23,7 +23,7 @@ namespace cast_channel { class CastSocketService; -} // namespace cast_channel +} namespace media_router { @@ -71,10 +71,13 @@ // discovered devices. // |network_monitor|: DiscoveryNetworkMonitor to use to listen for network // changes. + // |allow_all_ips|: If |true|, |this| will try to open channel to + // sinks on all IPs, and not just private IPs. CastMediaSinkServiceImpl(const OnSinksDiscoveredCallback& callback, Observer* observer, cast_channel::CastSocketService* cast_socket_service, - DiscoveryNetworkMonitor* network_monitor); + DiscoveryNetworkMonitor* network_monitor, + bool allow_all_ips); ~CastMediaSinkServiceImpl() override; // Returns the SequencedTaskRunner that should be used to invoke methods on @@ -85,7 +88,8 @@ void SetClockForTest(base::Clock* clock); - // Marked virtual for tests. + // Marked virtual for tests. Registers observers to listen for Cast devices + // and network changes. virtual void Start(); // MediaSinkServiceBase implementation @@ -113,6 +117,9 @@ // (DialMediaSinkServiceImpl), and that they run on the same sequence. OnDialSinkAddedCallback GetDialSinkAddedCallback(); + // Called by CastMediaSinkService to set |allow_all_ips_|. + void SetCastAllowAllIPs(bool allow_all_ips); + private: friend class CastMediaSinkServiceImplTest; FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, @@ -345,6 +352,10 @@ net::BackoffEntry::Policy backoff_policy_; + // If |true|, |this| will try to open channel to sinks on all IPs, and not + // just private IPs. + bool allow_all_ips_ = false; + // Map of consecutive failure count keyed by IP endpoint. Keeps track of // failure counts for each IP endpoint. Used to dynamically adjust timeout // values. If a Cast channel opens successfully, it is removed from the map.
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 62bd0fc..094a345 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -73,7 +73,8 @@ media_sink_service_impl_(mock_sink_discovered_cb_.Get(), &observer_, mock_cast_socket_service_.get(), - discovery_network_monitor_.get()) { + discovery_network_monitor_.get(), + /* allow_all_ips */ false) { mock_cast_socket_service_->SetTaskRunnerForTest(mock_time_task_runner_); }
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc index 2fc2646..41e4375 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
@@ -15,6 +15,7 @@ #include "components/cast_channel/cast_socket_service.h" #include "components/cast_channel/cast_test_util.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "net/base/ip_address.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -64,7 +65,8 @@ : CastMediaSinkServiceImpl(callback, observer, cast_socket_service, - network_monitor), + network_monitor, + /* allow_all_ips */ false), sinks_discovered_cb_(callback) {} ~MockCastMediaSinkServiceImpl() override {}
diff --git a/chrome/browser/media/router/discovery/mdns/dns_sd_registry.cc b/chrome/browser/media/router/discovery/mdns/dns_sd_registry.cc index 4fc7e7f..54a394c 100644 --- a/chrome/browser/media/router/discovery/mdns/dns_sd_registry.cc +++ b/chrome/browser/media/router/discovery/mdns/dns_sd_registry.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/local_discovery/service_discovery_shared_client.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_device_lister.h" #include "chrome/common/buildflags.h" -#include "components/cast_channel/cast_channel_util.h" using local_discovery::ServiceDiscoveryClient; using local_discovery::ServiceDiscoverySharedClient; @@ -197,8 +196,11 @@ if (!IsRegistered(service_type)) return; + // TODO(imcheng): This should be validated upstream in + // dns_sd_device_lister.cc, i.e., |service.ip_address| should be a + // valid net::IPAddress. net::IPAddress ip_address; - if (!cast_channel::IsValidCastIPAddressString(service.ip_address)) { + if (!ip_address.AssignFromIPLiteral(service.ip_address)) { VLOG(1) << "Invalid IP address: " << service.ip_address; return; }
diff --git a/chrome/browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc b/chrome/browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc index 12a65718..3c473ac9c 100644 --- a/chrome/browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc
@@ -158,9 +158,6 @@ const std::string service_type = "_testing._tcp.local"; const std::string ip_address1 = "invalid"; - // |ip_address2| is not a private IP address and is therefore invalid. - const std::string ip_address2 = "111.111.111.111"; - DnsSdService service; service.service_name = "_myDevice." + service_type; @@ -173,8 +170,6 @@ EXPECT_CALL(observer_, OnDnsSdEvent(_, _)).Times(0); service.ip_address = ip_address1; registry_->GetDelegate()->ServiceChanged(service_type, true, service); - service.ip_address = ip_address2; - registry_->GetDelegate()->ServiceChanged(service_type, false, service); } // Tests registering a listener and receiving an added and removed event.
diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browser/media/router/media_router_feature.cc index 0e8fe7dc..9898488 100644 --- a/chrome/browser/media/router/media_router_feature.cc +++ b/chrome/browser/media/router/media_router_feature.cc
@@ -17,6 +17,10 @@ #include "components/user_prefs/user_prefs.h" #endif // defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS) +#if !defined(OS_ANDROID) +#include "components/prefs/pref_registry_simple.h" +#endif + namespace media_router { #if !defined(OS_ANDROID) @@ -41,7 +45,7 @@ const PrefService::Preference* GetMediaRouterPref( content::BrowserContext* context) { return user_prefs::UserPrefs::Get(context)->FindPreference( - prefs::kEnableMediaRouter); + ::prefs::kEnableMediaRouter); } } // namespace #endif // defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS) @@ -65,6 +69,28 @@ } #if !defined(OS_ANDROID) +void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kMediaRouterCastAllowAllIPs, false, + PrefRegistry::PUBLIC); +} + +const base::Feature kCastAllowAllIPsFeature{"CastAllowAllIPs", + base::FEATURE_DISABLED_BY_DEFAULT}; + +bool GetCastAllowAllIPsPref(PrefService* pref_service) { + auto* pref = pref_service->FindPreference(prefs::kMediaRouterCastAllowAllIPs); + + // Only use the pref value if it is set from a mandatory policy. + bool allow_all_ips = false; + if (pref->IsManaged() && !pref->IsDefaultValue()) { + CHECK(pref->GetValue()->GetAsBoolean(&allow_all_ips)); + } else { + allow_all_ips = base::FeatureList::IsEnabled(kCastAllowAllIPsFeature); + } + + return allow_all_ips; +} + // Returns true if browser side DIAL sink query is enabled. bool DialSinkQueryEnabled() { return base::FeatureList::IsEnabled(kEnableDialSinkQuery); @@ -93,6 +119,6 @@ return true; #endif } -#endif +#endif // !defined(OS_ANDROID) } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_feature.h b/chrome/browser/media/router/media_router_feature.h index 8b315386..a4d1d20 100644 --- a/chrome/browser/media/router/media_router_feature.h +++ b/chrome/browser/media/router/media_router_feature.h
@@ -7,6 +7,9 @@ #include "base/feature_list.h" +class PrefRegistrySimple; +class PrefService; + namespace content { class BrowserContext; } @@ -18,6 +21,24 @@ #if !defined(OS_ANDROID) +namespace prefs { +// Pref name for the enterprise policy for allowing Cast devices on all IPs. +constexpr char kMediaRouterCastAllowAllIPs[] = + "media_router.cast_allow_all_ips"; +} // namespace prefs + +// Registers |kMediaRouterCastAllowAllIPs| with local state pref |registry|. +void RegisterLocalStatePrefs(PrefRegistrySimple* registry); + +// If enabled, allows Media Router to connect to Cast devices on all IP +// addresses, not just RFC1918/RFC4913 private addresses. Workaround for +// https://crbug.com/813974. +extern const base::Feature kCastAllowAllIPsFeature; + +// Returns |true| if CastMediaSinkService can connect to Cast devices on +// all IPs, as determined by local state |pref_service| / feature flag. +bool GetCastAllowAllIPsPref(PrefService* pref_service); + extern const base::Feature kEnableDialSinkQuery; extern const base::Feature kEnableCastDiscovery; extern const base::Feature kCastMediaRouteProvider; @@ -41,7 +62,7 @@ // TODO(crbug.com/802332): Remove this when mac_views_browser=1 by default. bool PresentationReceiverWindowEnabled(); -#endif +#endif // !defined(OS_ANDROID) } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_feature_unittest.cc b/chrome/browser/media/router/media_router_feature_unittest.cc new file mode 100644 index 0000000..16ed5b7 --- /dev/null +++ b/chrome/browser/media/router/media_router_feature_unittest.cc
@@ -0,0 +1,33 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/media_router_feature.h" + +#include "base/test/scoped_feature_list.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media_router { + +TEST(MediaRouterFeatureTest, GetCastAllowAllIPsPref) { + auto pref_service = std::make_unique<TestingPrefServiceSimple>(); + pref_service->registry()->RegisterBooleanPref( + prefs::kMediaRouterCastAllowAllIPs, false); + EXPECT_FALSE(GetCastAllowAllIPsPref(pref_service.get())); + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(kCastAllowAllIPsFeature); + EXPECT_TRUE(GetCastAllowAllIPsPref(pref_service.get())); + + pref_service->SetManagedPref(prefs::kMediaRouterCastAllowAllIPs, + std::make_unique<base::Value>(true)); + EXPECT_TRUE(GetCastAllowAllIPsPref(pref_service.get())); + + pref_service->SetManagedPref(prefs::kMediaRouterCastAllowAllIPs, + std::make_unique<base::Value>(false)); + EXPECT_FALSE(GetCastAllowAllIPsPref(pref_service.get())); +} + +} // namespace media_router
diff --git a/chrome/browser/net/firefox_proxy_settings.cc b/chrome/browser/net/firefox_proxy_settings.cc deleted file mode 100644 index df2f9f4..0000000 --- a/chrome/browser/net/firefox_proxy_settings.cc +++ /dev/null
@@ -1,307 +0,0 @@ -// Copyright 2013 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/net/firefox_proxy_settings.h" - -#include <stddef.h> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_tokenizer.h" -#include "base/strings/string_util.h" -#include "base/values.h" -#include "chrome/common/importer/firefox_importer_utils.h" -#include "net/proxy_resolution/proxy_config.h" - -namespace { - -const char* const kNetworkProxyTypeKey = "network.proxy.type"; -const char* const kHTTPProxyKey = "network.proxy.http"; -const char* const kHTTPProxyPortKey = "network.proxy.http_port"; -const char* const kSSLProxyKey = "network.proxy.ssl"; -const char* const kSSLProxyPortKey = "network.proxy.ssl_port"; -const char* const kFTPProxyKey = "network.proxy.ftp"; -const char* const kFTPProxyPortKey = "network.proxy.ftp_port"; -const char* const kGopherProxyKey = "network.proxy.gopher"; -const char* const kGopherProxyPortKey = "network.proxy.gopher_port"; -const char* const kSOCKSHostKey = "network.proxy.socks"; -const char* const kSOCKSHostPortKey = "network.proxy.socks_port"; -const char* const kSOCKSVersionKey = "network.proxy.socks_version"; -const char* const kAutoconfigURL = "network.proxy.autoconfig_url"; -const char* const kNoProxyListKey = "network.proxy.no_proxies_on"; -const char* const kPrefFileName = "prefs.js"; - -FirefoxProxySettings::ProxyConfig IntToProxyConfig(int type) { - switch (type) { - case 1: - return FirefoxProxySettings::MANUAL; - case 2: - return FirefoxProxySettings::AUTO_FROM_URL; - case 4: - return FirefoxProxySettings::AUTO_DETECT; - case 5: - return FirefoxProxySettings::SYSTEM; - default: - LOG(ERROR) << "Unknown Firefox proxy config type: " << type; - return FirefoxProxySettings::NO_PROXY; - } -} - -FirefoxProxySettings::SOCKSVersion IntToSOCKSVersion(int type) { - switch (type) { - case 4: - return FirefoxProxySettings::V4; - case 5: - return FirefoxProxySettings::V5; - default: - LOG(ERROR) << "Unknown Firefox proxy config type: " << type; - return FirefoxProxySettings::UNKNONW; - } -} - -// Parses the prefs found in the file |pref_file| and puts the key/value pairs -// in |prefs|. Keys are strings, and values can be strings, booleans or -// integers. Returns true if it succeeded, false otherwise (in which case -// |prefs| is not filled). -// Note: for strings, only valid UTF-8 string values are supported. If a -// key/pair is not valid UTF-8, it is ignored and will not appear in |prefs|. -bool ParsePrefFile(const base::FilePath& pref_file, - base::DictionaryValue* prefs) { - // The string that is before a pref key. - const std::string kUserPrefString = "user_pref(\""; - std::string contents; - if (!base::ReadFileToString(pref_file, &contents)) - return false; - - for (const std::string& line : - base::SplitString(contents, "\n", base::KEEP_WHITESPACE, - base::SPLIT_WANT_NONEMPTY)) { - size_t start_key = line.find(kUserPrefString); - if (start_key == std::string::npos) - continue; // Could be a comment or a blank line. - start_key += kUserPrefString.length(); - size_t stop_key = line.find('"', start_key); - if (stop_key == std::string::npos) { - LOG(ERROR) << "Invalid key found in Firefox pref file '" << - pref_file.value() << "' line is '" << line << "'."; - continue; - } - std::string key = line.substr(start_key, stop_key - start_key); - size_t start_value = line.find(',', stop_key + 1); - if (start_value == std::string::npos) { - LOG(ERROR) << "Invalid value found in Firefox pref file '" << - pref_file.value() << "' line is '" << line << "'."; - continue; - } - size_t stop_value = line.find(");", start_value + 1); - if (stop_value == std::string::npos) { - LOG(ERROR) << "Invalid value found in Firefox pref file '" << - pref_file.value() << "' line is '" << line << "'."; - continue; - } - std::string value = line.substr(start_value + 1, - stop_value - start_value - 1); - base::TrimWhitespaceASCII(value, base::TRIM_ALL, &value); - // Value could be a boolean. - bool is_value_true = base::LowerCaseEqualsASCII(value, "true"); - if (is_value_true || base::LowerCaseEqualsASCII(value, "false")) { - prefs->SetBoolean(key, is_value_true); - continue; - } - - // Value could be a string. - if (value.size() >= 2U && value[0] == '"' && value.back() == '"') { - value = value.substr(1, value.size() - 2); - // ValueString only accept valid UTF-8. Simply ignore that entry if it is - // not UTF-8. - if (base::IsStringUTF8(value)) - prefs->SetString(key, value); - else - VLOG(1) << "Non UTF8 value for key " << key << ", ignored."; - continue; - } - - // Or value could be an integer. - int int_value = 0; - if (base::StringToInt(value, &int_value)) { - prefs->SetInteger(key, int_value); - continue; - } - - LOG(ERROR) << "Invalid value found in Firefox pref file '" - << pref_file.value() << "' value is '" << value << "'."; - } - return true; -} - -} // namespace - -FirefoxProxySettings::FirefoxProxySettings() { - Reset(); -} - -FirefoxProxySettings::~FirefoxProxySettings() { -} - -void FirefoxProxySettings::Reset() { - config_type_ = NO_PROXY; - http_proxy_.clear(); - http_proxy_port_ = 0; - ssl_proxy_.clear(); - ssl_proxy_port_ = 0; - ftp_proxy_.clear(); - ftp_proxy_port_ = 0; - gopher_proxy_.clear(); - gopher_proxy_port_ = 0; - socks_host_.clear(); - socks_port_ = 0; - socks_version_ = UNKNONW; - proxy_bypass_list_.clear(); - autoconfig_url_.clear(); -} - -// static -bool FirefoxProxySettings::GetSettings(FirefoxProxySettings* settings) { - DCHECK(settings); - settings->Reset(); - - base::FilePath profile_path = GetFirefoxProfilePath(); - if (profile_path.empty()) - return false; - base::FilePath pref_file = profile_path.AppendASCII(kPrefFileName); - return GetSettingsFromFile(pref_file, settings); -} - -bool FirefoxProxySettings::ToProxyConfig(net::ProxyConfig* config) { - switch (config_type()) { - case NO_PROXY: - *config = net::ProxyConfig::CreateDirect(); - return true; - case AUTO_DETECT: - *config = net::ProxyConfig::CreateAutoDetect(); - return true; - case AUTO_FROM_URL: - *config = net::ProxyConfig::CreateFromCustomPacURL( - GURL(autoconfig_url())); - return true; - case SYSTEM: - // Can't convert this directly to a ProxyConfig. - return false; - case MANUAL: - // Handled outside of the switch (since it is a lot of code.) - break; - default: - NOTREACHED(); - return false; - } - - // The rest of this funciton is for handling the MANUAL case. - DCHECK_EQ(MANUAL, config_type()); - - *config = net::ProxyConfig(); - config->proxy_rules().type = - net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME; - - if (!http_proxy().empty()) { - config->proxy_rules().proxies_for_http.SetSingleProxyServer( - net::ProxyServer( - net::ProxyServer::SCHEME_HTTP, - net::HostPortPair(http_proxy(), http_proxy_port()))); - } - - if (!ftp_proxy().empty()) { - config->proxy_rules().proxies_for_ftp.SetSingleProxyServer( - net::ProxyServer( - net::ProxyServer::SCHEME_HTTP, - net::HostPortPair(ftp_proxy(), ftp_proxy_port()))); - } - - if (!ssl_proxy().empty()) { - config->proxy_rules().proxies_for_https.SetSingleProxyServer( - net::ProxyServer( - net::ProxyServer::SCHEME_HTTP, - net::HostPortPair(ssl_proxy(), ssl_proxy_port()))); - } - - if (!socks_host().empty()) { - net::ProxyServer::Scheme proxy_scheme = V5 == socks_version() ? - net::ProxyServer::SCHEME_SOCKS5 : net::ProxyServer::SCHEME_SOCKS4; - - config->proxy_rules().fallback_proxies.SetSingleProxyServer( - net::ProxyServer( - proxy_scheme, - net::HostPortPair(socks_host(), socks_port()))); - } - - config->proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching( - base::JoinString(proxy_bypass_list_, ";")); - - return true; -} - -// static -bool FirefoxProxySettings::GetSettingsFromFile(const base::FilePath& pref_file, - FirefoxProxySettings* settings) { - base::DictionaryValue dictionary; - if (!ParsePrefFile(pref_file, &dictionary)) - return false; - - int proxy_type = 0; - if (!dictionary.GetInteger(kNetworkProxyTypeKey, &proxy_type)) - return true; // No type means no proxy. - - settings->config_type_ = IntToProxyConfig(proxy_type); - if (settings->config_type_ == AUTO_FROM_URL) { - if (!dictionary.GetStringASCII(kAutoconfigURL, - &(settings->autoconfig_url_))) { - LOG(ERROR) << "Failed to retrieve Firefox proxy autoconfig URL"; - } - return true; - } - - if (settings->config_type_ == MANUAL) { - if (!dictionary.GetStringASCII(kHTTPProxyKey, &(settings->http_proxy_))) - LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP host"; - if (!dictionary.GetInteger(kHTTPProxyPortKey, - &(settings->http_proxy_port_))) { - LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP port"; - } - if (!dictionary.GetStringASCII(kSSLProxyKey, &(settings->ssl_proxy_))) - LOG(ERROR) << "Failed to retrieve Firefox proxy SSL host"; - if (!dictionary.GetInteger(kSSLProxyPortKey, &(settings->ssl_proxy_port_))) - LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port"; - if (!dictionary.GetStringASCII(kFTPProxyKey, &(settings->ftp_proxy_))) - LOG(ERROR) << "Failed to retrieve Firefox proxy FTP host"; - if (!dictionary.GetInteger(kFTPProxyPortKey, &(settings->ftp_proxy_port_))) - LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port"; - if (!dictionary.GetStringASCII(kGopherProxyKey, &(settings->gopher_proxy_))) - LOG(ERROR) << "Failed to retrieve Firefox proxy gopher host"; - if (!dictionary.GetInteger(kGopherProxyPortKey, - &(settings->gopher_proxy_port_))) { - LOG(ERROR) << "Failed to retrieve Firefox proxy gopher port"; - } - if (!dictionary.GetStringASCII(kSOCKSHostKey, &(settings->socks_host_))) - LOG(ERROR) << "Failed to retrieve Firefox SOCKS host"; - if (!dictionary.GetInteger(kSOCKSHostPortKey, &(settings->socks_port_))) - LOG(ERROR) << "Failed to retrieve Firefox SOCKS port"; - int socks_version; - if (dictionary.GetInteger(kSOCKSVersionKey, &socks_version)) - settings->socks_version_ = IntToSOCKSVersion(socks_version); - - std::string proxy_bypass; - if (dictionary.GetStringASCII(kNoProxyListKey, &proxy_bypass) && - !proxy_bypass.empty()) { - base::StringTokenizer string_tok(proxy_bypass, ","); - while (string_tok.GetNext()) { - std::string token = string_tok.token(); - base::TrimWhitespaceASCII(token, base::TRIM_ALL, &token); - if (!token.empty()) - settings->proxy_bypass_list_.push_back(token); - } - } - } - return true; -}
diff --git a/chrome/browser/net/firefox_proxy_settings.h b/chrome/browser/net/firefox_proxy_settings.h deleted file mode 100644 index 03ecfc7..0000000 --- a/chrome/browser/net/firefox_proxy_settings.h +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2013 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_NET_FIREFOX_PROXY_SETTINGS_H_ -#define CHROME_BROWSER_NET_FIREFOX_PROXY_SETTINGS_H_ - -#include <string> -#include <vector> - -#include "base/macros.h" - -namespace base { -class FilePath; -} - -namespace net { -class ProxyConfig; -} - -class FirefoxProxySettings { - public: - enum ProxyConfig { - NO_PROXY = 0, // No proxy are used. - AUTO_DETECT, // Automatically detected. - SYSTEM, // Using system proxy settings. - AUTO_FROM_URL, // Automatically configured from a URL. - MANUAL // User specified settings. - }; - - enum SOCKSVersion { - UNKNONW = 0, - V4, - V5 - }; - - FirefoxProxySettings(); - ~FirefoxProxySettings(); - - // Sets |settings| to the proxy settings for the current installed version of - // Firefox and returns true if successful. - // Returns false if Firefox is not installed or if the settings could not be - // retrieved. - static bool GetSettings(FirefoxProxySettings* settings); - - // Resets all the states of this FirefoxProxySettings to no proxy. - void Reset(); - - ProxyConfig config_type() const { return config_type_; } - - std::string http_proxy() const { return http_proxy_; } - int http_proxy_port() const { return http_proxy_port_; } - - std::string ssl_proxy() const { return ssl_proxy_; } - int ssl_proxy_port() const { return ssl_proxy_port_; } - - std::string ftp_proxy() const { return ftp_proxy_; } - int ftp_proxy_port() const { return ftp_proxy_port_; } - - std::string gopher_proxy() const { return gopher_proxy_; } - int gopher_proxy_port() const { return gopher_proxy_port_; } - - std::string socks_host() const { return socks_host_; } - int socks_port() const { return socks_port_; } - SOCKSVersion socks_version() const { return socks_version_; } - - std::vector<std::string> proxy_bypass_list() const { - return proxy_bypass_list_; - } - - const std::string& autoconfig_url() const { return autoconfig_url_; } - - // Converts a FirefoxProxySettings object to a net::ProxyConfig. - // On success returns true and fills |config| with the result. - bool ToProxyConfig(net::ProxyConfig* config); - - protected: - // Gets the settings from the passed prefs.js file and returns true if - // successful. - // Protected for tests. - static bool GetSettingsFromFile(const base::FilePath& pref_file, - FirefoxProxySettings* settings); - - private: - ProxyConfig config_type_; - - std::string http_proxy_; - int http_proxy_port_; - - std::string ssl_proxy_; - int ssl_proxy_port_; - - std::string ftp_proxy_; - int ftp_proxy_port_; - - std::string gopher_proxy_; - int gopher_proxy_port_; - - std::string socks_host_; - int socks_port_; - SOCKSVersion socks_version_; - - std::vector<std::string> proxy_bypass_list_; - - std::string autoconfig_url_; - - DISALLOW_COPY_AND_ASSIGN(FirefoxProxySettings); -}; - -#endif // CHROME_BROWSER_NET_FIREFOX_PROXY_SETTINGS_H_
diff --git a/chrome/browser/net/firefox_proxy_settings_unittest.cc b/chrome/browser/net/firefox_proxy_settings_unittest.cc deleted file mode 100644 index f3d27d9d..0000000 --- a/chrome/browser/net/firefox_proxy_settings_unittest.cc +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2013 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/net/firefox_proxy_settings.h" - -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "chrome/common/chrome_paths.h" -#include "net/proxy_resolution/proxy_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -class FirefoxProxySettingsTest : public testing::Test { -}; - -class TestFirefoxProxySettings : public FirefoxProxySettings { - public: - TestFirefoxProxySettings() {} - - static bool TestGetSettingsFromFile(const base::FilePath& pref_file, - FirefoxProxySettings* settings) { - return GetSettingsFromFile(pref_file, settings); - } -}; - -TEST_F(FirefoxProxySettingsTest, TestParse) { - FirefoxProxySettings settings; - - base::FilePath js_pref_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &js_pref_path)); - js_pref_path = js_pref_path.AppendASCII("firefox3_pref.js"); - - EXPECT_TRUE(TestFirefoxProxySettings::TestGetSettingsFromFile(js_pref_path, - &settings)); - EXPECT_EQ(FirefoxProxySettings::MANUAL, settings.config_type()); - EXPECT_EQ("http_proxy", settings.http_proxy()); - EXPECT_EQ(1111, settings.http_proxy_port()); - EXPECT_EQ("ssl_proxy", settings.ssl_proxy()); - EXPECT_EQ(2222, settings.ssl_proxy_port()); - EXPECT_EQ("ftp_proxy", settings.ftp_proxy()); - EXPECT_EQ(3333, settings.ftp_proxy_port()); - EXPECT_EQ("gopher_proxy", settings.gopher_proxy()); - EXPECT_EQ(4444, settings.gopher_proxy_port()); - EXPECT_EQ("socks_host", settings.socks_host()); - EXPECT_EQ(5555, settings.socks_port()); - EXPECT_EQ(FirefoxProxySettings::V4, settings.socks_version()); - ASSERT_EQ(3U, settings.proxy_bypass_list().size()); - EXPECT_EQ("localhost", settings.proxy_bypass_list()[0]); - EXPECT_EQ("127.0.0.1", settings.proxy_bypass_list()[1]); - EXPECT_EQ("noproxy.com", settings.proxy_bypass_list()[2]); - EXPECT_EQ("", settings.autoconfig_url()); - - // Test that ToProxyConfig() properly translates into a net::ProxyConfig. - net::ProxyConfig config; - EXPECT_TRUE(settings.ToProxyConfig(&config)); - - { - net::ProxyConfig expected_config; - expected_config.proxy_rules().ParseFromString("http=http_proxy:1111; " - "https=ssl_proxy:2222; " - "ftp=ftp_proxy:3333; " - "socks=socks_host:5555"); - expected_config.proxy_rules().bypass_rules.ParseFromString( - "*localhost, 127.0.0.1, *noproxy.com"); - } -} - -TEST_F(FirefoxProxySettingsTest, TestParseAutoConfigUrl) { - FirefoxProxySettings settings; - - base::FilePath js_pref_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &js_pref_path)); - js_pref_path = js_pref_path.AppendASCII("firefox3_pref_pac_url.js"); - - EXPECT_TRUE(TestFirefoxProxySettings::TestGetSettingsFromFile(js_pref_path, - &settings)); - EXPECT_EQ(FirefoxProxySettings::AUTO_FROM_URL, settings.config_type()); - - // Everything should be empty except for the autoconfig URL. - EXPECT_EQ("http://custom-pac-url/", settings.autoconfig_url()); - EXPECT_EQ("", settings.http_proxy()); - EXPECT_EQ(0, settings.http_proxy_port()); - EXPECT_EQ("", settings.ssl_proxy()); - EXPECT_EQ(0, settings.ssl_proxy_port()); - EXPECT_EQ("", settings.ftp_proxy()); - EXPECT_EQ(0, settings.ftp_proxy_port()); - EXPECT_EQ("", settings.gopher_proxy()); - EXPECT_EQ(0, settings.gopher_proxy_port()); - EXPECT_EQ("", settings.socks_host()); - EXPECT_EQ(0, settings.socks_port()); - EXPECT_EQ(0, settings.socks_port()); - EXPECT_EQ(0U, settings.proxy_bypass_list().size()); - - // Test that ToProxyConfig() properly translates into a net::ProxyConfig. - net::ProxyConfig config; - EXPECT_TRUE(settings.ToProxyConfig(&config)); - - EXPECT_TRUE(config.Equals(net::ProxyConfig::CreateFromCustomPacURL( - GURL("http://custom-pac-url/")))); -}
diff --git a/chrome/browser/net/sth_distributor_provider.cc b/chrome/browser/net/sth_distributor_provider.cc index ae09fbe..a0ecb31b 100644 --- a/chrome/browser/net/sth_distributor_provider.cc +++ b/chrome/browser/net/sth_distributor_provider.cc
@@ -5,21 +5,21 @@ #include "chrome/browser/net/sth_distributor_provider.h" #include "base/lazy_instance.h" -#include "net/cert/sth_distributor.h" +#include "components/certificate_transparency/sth_distributor.h" namespace chrome_browser_net { namespace { -base::LazyInstance<std::unique_ptr<net::ct::STHDistributor>>::DestructorAtExit - global_sth_distributor = LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<std::unique_ptr<certificate_transparency::STHDistributor>>:: + DestructorAtExit global_sth_distributor = LAZY_INSTANCE_INITIALIZER; } // namespace void SetGlobalSTHDistributor( - std::unique_ptr<net::ct::STHDistributor> distributor) { + std::unique_ptr<certificate_transparency::STHDistributor> distributor) { global_sth_distributor.Get().swap(distributor); } -net::ct::STHDistributor* GetGlobalSTHDistributor() { +certificate_transparency::STHDistributor* GetGlobalSTHDistributor() { CHECK(global_sth_distributor.Get()); return global_sth_distributor.Get().get(); }
diff --git a/chrome/browser/net/sth_distributor_provider.h b/chrome/browser/net/sth_distributor_provider.h index b8e36676..c79f1ba 100644 --- a/chrome/browser/net/sth_distributor_provider.h +++ b/chrome/browser/net/sth_distributor_provider.h
@@ -7,19 +7,15 @@ #include <memory> -namespace net { - -namespace ct { +namespace certificate_transparency { class STHDistributor; -} // namespace ct - -} // namespace net +} // namespace certificate_transparency namespace chrome_browser_net { void SetGlobalSTHDistributor( - std::unique_ptr<net::ct::STHDistributor> distributor); -net::ct::STHDistributor* GetGlobalSTHDistributor(); + std::unique_ptr<certificate_transparency::STHDistributor> distributor); +certificate_transparency::STHDistributor* GetGlobalSTHDistributor(); } // namespace chrome_browser_net
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc index da25185..db6926c 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc
@@ -670,8 +670,8 @@ net::CertVerifier::RequestParams params( leaf_cert_1_, "127.0.0.1", - net::CertVerifier::VERIFY_EV_CERT | - net::CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY, + net::CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS | + net::CertVerifier::VERIFY_REV_CHECKING_ENABLED, std::string() /* ocsp_response */, {} /* additional_trust_anchors */); net::CertVerifyResult result; net::TestCompletionCallback callback; @@ -714,12 +714,12 @@ EXPECT_EQ(chrome_browser_ssl::CertLoggerRequest::STATUS_CT_COMPLIANCE_FAILED, trial_info.cert_status()[0]); - ASSERT_EQ(2, trial_info.verify_flags_size()); - EXPECT_EQ(chrome_browser_ssl::TrialVerificationInfo::VERIFY_EV_CERT, - trial_info.verify_flags()[0]); - EXPECT_EQ(chrome_browser_ssl::TrialVerificationInfo:: - VERIFY_REV_CHECKING_ENABLED_EV_ONLY, - trial_info.verify_flags()[1]); + EXPECT_THAT( + trial_info.verify_flags(), + testing::UnorderedElementsAre(chrome_browser_ssl::TrialVerificationInfo:: + VERIFY_REV_CHECKING_ENABLED, + chrome_browser_ssl::TrialVerificationInfo:: + VERIFY_ENABLE_SHA1_LOCAL_ANCHORS)); EXPECT_THAT(report.unverified_cert_chain(), CertChainMatches(leaf_cert_1_)); EXPECT_THAT(report.cert_chain(), CertChainMatches(cert_chain_1_));
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller.cc deleted file mode 100644 index 1dcc49f..0000000 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller.cc +++ /dev/null
@@ -1,62 +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 "chrome/browser/picture_in_picture/picture_in_picture_window_controller.h" - -#include "chrome/browser/overlay/overlay_surface_embedder.h" -#include "chrome/browser/overlay/overlay_window.h" -#include "components/viz/common/surfaces/surface_id.h" -#include "content/public/browser/web_contents.h" - -DEFINE_WEB_CONTENTS_USER_DATA_KEY(PictureInPictureWindowController); - -// static -PictureInPictureWindowController* -PictureInPictureWindowController::GetOrCreateForWebContents( - content::WebContents* web_contents) { - DCHECK(web_contents); - - // This is a no-op if the controller already exists. - CreateForWebContents(web_contents); - return FromWebContents(web_contents); -} - -PictureInPictureWindowController::~PictureInPictureWindowController() { - if (window_) - window_->Close(); -} - -PictureInPictureWindowController::PictureInPictureWindowController( - content::WebContents* initiator) - : initiator_(initiator) { - DCHECK(initiator_); - window_ = OverlayWindow::Create(); -} - -void PictureInPictureWindowController::Show() { - DCHECK(window_); - DCHECK(surface_id_.is_valid()); - window_->Show(); -} - -void PictureInPictureWindowController::Close() { - if (window_) - window_->Close(); - - surface_id_ = viz::SurfaceId(); -} - -void PictureInPictureWindowController::EmbedSurface(viz::SurfaceId surface_id) { - DCHECK(window_); - DCHECK(surface_id.is_valid()); - surface_id_ = surface_id; - - if (!embedder_) - embedder_.reset(new OverlaySurfaceEmbedder(window_.get())); - embedder_->SetPrimarySurfaceId(surface_id_); -} - -OverlayWindow* PictureInPictureWindowController::GetWindowForTesting() { - return window_.get(); -}
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller.h b/chrome/browser/picture_in_picture/picture_in_picture_window_controller.h deleted file mode 100644 index 79c83b0..0000000 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller.h +++ /dev/null
@@ -1,60 +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_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_ -#define CHROME_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_ - -#include "base/memory/weak_ptr.h" -#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace content { -class WebContents; -} - -namespace viz { -class SurfaceId; -} // namespace viz - -class OverlayWindow; -class OverlaySurfaceEmbedder; - -// Class for Picture in Picture window controllers. This is currently tied to a -// WebContents |initiator| and created when a Picture in Picture window is to -// be shown. This allows creation of a single window for a initiator -// WebContents. -// TODO(apacible): Determine expected window behaviour and update controller -// to reflect decisions. -class PictureInPictureWindowController - : public content::WebContentsUserData<PictureInPictureWindowController> { - public: - ~PictureInPictureWindowController() override; - // Gets a reference to the controller associated with |initiator| and creates - // one if it does not exist. The returned pointer is guaranteed to be - // non-null. - static PictureInPictureWindowController* GetOrCreateForWebContents( - content::WebContents* initiator); - - void Show(); - void Close(); - void EmbedSurface(viz::SurfaceId); - OverlayWindow* GetWindowForTesting(); - - private: - friend class content::WebContentsUserData<PictureInPictureWindowController>; - - // Use PictureInPictureWindowController::GetOrCreateForWebContents() to - // create an instance. - explicit PictureInPictureWindowController(content::WebContents* initiator); - - content::WebContents* const initiator_; - std::unique_ptr<OverlayWindow> window_; - std::unique_ptr<OverlaySurfaceEmbedder> embedder_; - - viz::SurfaceId surface_id_; - - DISALLOW_COPY_AND_ASSIGN(PictureInPictureWindowController); -}; - -#endif // CHROME_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index 2f4db379..9300d9e2 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/picture_in_picture/picture_in_picture_window_controller.h" +#include "content/public/browser/picture_in_picture_window_controller.h" #include "build/build_config.h" -#include "chrome/browser/overlay/overlay_window.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" +#include "components/viz/common/surfaces/surface_id.h" +#include "content/public/browser/overlay_window.h" #include "content/public/browser/web_contents.h" class PictureInPictureWindowControllerBrowserTest @@ -18,16 +19,16 @@ void SetUpWindowController(content::WebContents* web_contents) { pip_window_controller_ = - PictureInPictureWindowController::GetOrCreateForWebContents( + content::PictureInPictureWindowController::GetOrCreateForWebContents( web_contents); } - PictureInPictureWindowController* window_controller() { + content::PictureInPictureWindowController* window_controller() { return pip_window_controller_; } private: - PictureInPictureWindowController* pip_window_controller_ = nullptr; + content::PictureInPictureWindowController* pip_window_controller_ = nullptr; DISALLOW_COPY_AND_ASSIGN(PictureInPictureWindowControllerBrowserTest); };
diff --git a/chrome/browser/policy/browser_dm_token_storage_win.cc b/chrome/browser/policy/browser_dm_token_storage_win.cc index 0c6843f..4edc280 100644 --- a/chrome/browser/policy/browser_dm_token_storage_win.cc +++ b/chrome/browser/policy/browser_dm_token_storage_win.cc
@@ -189,7 +189,6 @@ } // namespace BrowserDMTokenStorage* BrowserDMTokenStorage::Get() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); static base::NoDestructor<BrowserDMTokenStorageWin> storage; return storage.get(); }
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc index 683e9ad3..9cdf7149 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.cc +++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -10,26 +10,33 @@ #include "base/callback.h" #include "base/command_line.h" -#include "base/files/file_path.h" #include "base/path_service.h" -#include "base/strings/sys_string_conversions.h" #include "base/task_scheduler/post_task.h" -#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/policy/browser_dm_token_storage.h" +#include "chrome/browser/policy/cloud/machine_level_user_cloud_policy_helper.h" #include "chrome/browser/policy/configuration_policy_handler_list_factory.h" #include "chrome/browser/policy/device_management_service_configuration.h" #include "chrome/common/chrome_paths.h" #include "components/policy/core/common/async_policy_provider.h" +#include "components/policy/core/common/cloud/cloud_external_data_manager.h" +#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h" #include "components/policy/core/common/cloud/device_management_service.h" +#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h" +#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h" +#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/policy/core/common/configuration_policy_provider.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_service.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" +#include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "net/url_request/url_request_context_getter.h" #if defined(OS_WIN) +#include "base/win/registry.h" #include "components/policy/core/common/policy_loader_win.h" #elif defined(OS_MACOSX) #include <CoreFoundation/CoreFoundation.h> @@ -59,8 +66,37 @@ } #endif // defined(OS_MACOSX) +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +std::unique_ptr<MachineLevelUserCloudPolicyManager> +CreateMachineLevelUserCloudPolicyManager() { + base::FilePath user_data_dir; + if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) + return nullptr; + + DVLOG(1) << "Creating machine level cloud policy manager"; + + base::FilePath policy_dir = + user_data_dir.Append(ChromeBrowserPolicyConnector::kPolicyDir); + std::string dm_token = BrowserDMTokenStorage::Get()->RetrieveDMToken(); + std::string client_id = BrowserDMTokenStorage::Get()->RetrieveClientId(); + std::unique_ptr<MachineLevelUserCloudPolicyStore> policy_store = + MachineLevelUserCloudPolicyStore::Create( + dm_token, client_id, policy_dir, + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); + return std::make_unique<MachineLevelUserCloudPolicyManager>( + std::move(policy_store), nullptr, policy_dir, + base::ThreadTaskRunnerHandle::Get(), + content::BrowserThread::GetTaskRunnerForThread( + content::BrowserThread::IO)); +} +#endif + } // namespace +const base::FilePath::CharType ChromeBrowserPolicyConnector::kPolicyDir[] = + FILE_PATH_LITERAL("Policy"); + ChromeBrowserPolicyConnector::ChromeBrowserPolicyConnector() : BrowserPolicyConnector(base::Bind(&BuildHandlerList)) { } @@ -83,6 +119,22 @@ kServiceInitializationStartupDelay); InitInternal(local_state, std::move(device_management_service)); + +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + if (machine_level_user_cloud_policy_manager_) + InitializeMachineLevelUserCloudPolicies(local_state, request_context); +#endif +} + +void ChromeBrowserPolicyConnector::Shutdown() { +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // Reset the registrar and fetcher before calling base class so that + // shutdown occurs in correct sequence. + machine_level_user_cloud_policy_registrar_.reset(); + machine_level_user_cloud_policy_fetcher_.reset(); +#endif + + BrowserPolicyConnector::Shutdown(); } ConfigurationPolicyProvider* @@ -102,6 +154,21 @@ // PlatformProvider should be before all other providers (highest priority). providers.insert(providers.begin(), std::move(platform_provider)); } + +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + std::string enrollment_token = + BrowserDMTokenStorage::Get()->RetrieveEnrollmentToken(); + std::string dm_token = BrowserDMTokenStorage::Get()->RetrieveDMToken(); + if (!enrollment_token.empty() || !dm_token.empty()) { + std::unique_ptr<MachineLevelUserCloudPolicyManager> cloud_policy_manager = + CreateMachineLevelUserCloudPolicyManager(); + if (cloud_policy_manager) { + machine_level_user_cloud_policy_manager_ = cloud_policy_manager.get(); + providers.push_back(std::move(cloud_policy_manager)); + } + } +#endif + return providers; } @@ -141,4 +208,82 @@ #endif } +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + +void ChromeBrowserPolicyConnector::InitializeMachineLevelUserCloudPolicies( + PrefService* local_state, + scoped_refptr<net::URLRequestContextGetter> request_context) { + // If there exists an enrollment token, then there are two states: + // 1/ There also exists a DM token. This machine is already registeted, so + // the next step is to fetch policies. + // 2/ There is no DM token. In this case the machine is not already + // registered and needs to request a DM token. + std::string enrollment_token; + std::string client_id; + + if (!GetEnrollmentTokenAndClientId(&enrollment_token, &client_id)) + return; + + DCHECK(!enrollment_token.empty()); + DCHECK(!client_id.empty()); + DVLOG(1) << "Enrollment token = " << enrollment_token; + DVLOG(1) << "Client ID = " << client_id; + + machine_level_user_cloud_policy_registrar_ = + std::make_unique<MachineLevelUserCloudPolicyRegistrar>( + device_management_service(), request_context); + machine_level_user_cloud_policy_fetcher_ = + std::make_unique<MachineLevelUserCloudPolicyFetcher>( + machine_level_user_cloud_policy_manager_, local_state, + device_management_service(), request_context); + + std::string dm_token = BrowserDMTokenStorage::Get()->RetrieveDMToken(); + DVLOG(1) << "DM token = " << (dm_token.empty() ? "none" : "from persistence"); + + if (dm_token.empty()) { + // Not registered already, so do it now. + machine_level_user_cloud_policy_registrar_ + ->RegisterForPolicyWithEnrollmentToken( + enrollment_token, client_id, + base::Bind(&ChromeBrowserPolicyConnector:: + RegisterForPolicyWithEnrollmentTokenCallback, + base::Unretained(this))); + } +} + +bool ChromeBrowserPolicyConnector::GetEnrollmentTokenAndClientId( + std::string* enrollment_token, + std::string* client_id) { + *client_id = BrowserDMTokenStorage::Get()->RetrieveClientId(); + if (client_id->empty()) + return false; + + *enrollment_token = BrowserDMTokenStorage::Get()->RetrieveEnrollmentToken(); + return !enrollment_token->empty(); +} + +void ChromeBrowserPolicyConnector::RegisterForPolicyWithEnrollmentTokenCallback( + const std::string& dm_token, + const std::string& client_id) { + if (dm_token.empty()) { + DVLOG(1) << "No DM token returned from browser registration"; + return; + } + + DVLOG(1) << "DM token = retrieved from server"; + + // TODO(alito): Log failures to store the DM token. Should we try again later? + BrowserDMTokenStorage::Get()->StoreDMToken( + dm_token, base::BindOnce([](bool success) { + DVLOG(1) << (success ? "Successfully stored the DM token" + : "Failed to store the DM token"); + })); + + // Start fetching policies. + machine_level_user_cloud_policy_fetcher_->SetupRegistrationAndFetchPolicy( + dm_token, client_id); +} + +#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + } // namespace policy
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.h b/chrome/browser/policy/chrome_browser_policy_connector.h index 5b21e20..4704b01 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.h +++ b/chrome/browser/policy/chrome_browser_policy_connector.h
@@ -10,8 +10,10 @@ #include <memory> #include <vector> +#include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "build/build_config.h" #include "components/policy/core/browser/browser_policy_connector.h" class PrefService; @@ -23,6 +25,9 @@ namespace policy { class ConfigurationPolicyProvider; +class MachineLevelUserCloudPolicyManager; +class MachineLevelUserCloudPolicyFetcher; +class MachineLevelUserCloudPolicyRegistrar; // Extends BrowserPolicyConnector with the setup shared among the desktop // implementations and Android. @@ -32,6 +37,10 @@ // displaying Chrome's GUI does not get delayed.) static const int64_t kServiceInitializationStartupDelay = 5000; + // Directory name under the user-data-dir where machine level user cloud + // policy data is stored. + static const base::FilePath::CharType kPolicyDir[]; + // Builds an uninitialized ChromeBrowserPolicyConnector, suitable for testing. // Init() should be called to create and start the policy machinery. ChromeBrowserPolicyConnector(); @@ -46,6 +55,8 @@ PrefService* local_state, scoped_refptr<net::URLRequestContextGetter> request_context) override; + void Shutdown() override; + ConfigurationPolicyProvider* GetPlatformProvider(); protected: @@ -56,6 +67,26 @@ private: std::unique_ptr<ConfigurationPolicyProvider> CreatePlatformProvider(); +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + void InitializeMachineLevelUserCloudPolicies( + PrefService* local_state, + scoped_refptr<net::URLRequestContextGetter> request_context); + bool GetEnrollmentTokenAndClientId(std::string* enrollment_token, + std::string* client_id); + void RegisterForPolicyWithEnrollmentTokenCallback( + const std::string& dm_token, + const std::string& client_id); + + // Owned by base class. + MachineLevelUserCloudPolicyManager* machine_level_user_cloud_policy_manager_ = + nullptr; + + std::unique_ptr<MachineLevelUserCloudPolicyRegistrar> + machine_level_user_cloud_policy_registrar_; + std::unique_ptr<MachineLevelUserCloudPolicyFetcher> + machine_level_user_cloud_policy_fetcher_; +#endif + // Owned by base class. ConfigurationPolicyProvider* platform_provider_ = nullptr;
diff --git a/chrome/browser/policy/cloud/DEPS b/chrome/browser/policy/cloud/DEPS index 7f429a0..dcc7475 100644 --- a/chrome/browser/policy/cloud/DEPS +++ b/chrome/browser/policy/cloud/DEPS
@@ -18,6 +18,7 @@ r"cloud_policy_manager_browsertest|" r"component_cloud_policy_browsertest|" r"device_management_service_browsertest|" + r"machine_level_user_cloud_policy_browsertest|" r"test_request_interceptor|" r"policy_header_service_factory|" r"policy_header_service_unittest|"
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc new file mode 100644 index 0000000..cfbfab8 --- /dev/null +++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
@@ -0,0 +1,257 @@ +// Copyright (c) 2018 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 <stdint.h> + +#include <memory> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/message_loop/message_loop.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/stl_util.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/policy/chrome_browser_policy_connector.h" +#include "chrome/browser/policy/test/local_policy_test_server.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/policy/core/common/cloud/device_management_service.h" +#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h" +#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h" +#include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h" +#include "components/policy/core/common/cloud/mock_device_management_service.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/upload_bytes_element_reader.h" +#include "net/base/upload_data_stream.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context_getter.h" +#include "net/url_request/url_request_test_job.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using content::BrowserThread; +using testing::DoAll; +using testing::Invoke; +using testing::InvokeWithoutArgs; +using testing::_; + +namespace em = enterprise_management; + +namespace { +const char kEnrollmentToken[] = "enrollment_token"; +const char kMachineName[] = "foo"; +const char kClientID[] = "fake-client-id"; +const char kDMToken[] = "fake-dm-token"; +} // namespace + +namespace policy { + +MATCHER_P(MatchProto, expected, "matches protobuf") { + return arg.SerializePartialAsString() == expected.SerializePartialAsString(); +} + +class MachineLevelUserCloudPolicyServiceIntegrationTest + : public InProcessBrowserTest, + public testing::WithParamInterface<std::string ( + MachineLevelUserCloudPolicyServiceIntegrationTest::*)(void)> { + public: + MOCK_METHOD3(OnJobDone, + void(DeviceManagementStatus, + int, + const em::DeviceManagementResponse&)); + + std::string InitTestServer() { + StartTestServer(); + return test_server_->GetServiceURL().spec(); + } + + protected: + void PerformRegistration(const std::string& enrollment_token, + const std::string& machine_name, + bool expect_success) { + base::RunLoop run_loop; + if (expect_success) { + EXPECT_CALL(*this, OnJobDone(testing::Eq(DM_STATUS_SUCCESS), _, _)) + .WillOnce(DoAll( + Invoke(this, &MachineLevelUserCloudPolicyServiceIntegrationTest:: + RecordToken), + InvokeWithoutArgs(&run_loop, &base::RunLoop::QuitWhenIdle))); + } else { + EXPECT_CALL(*this, OnJobDone(testing::Ne(DM_STATUS_SUCCESS), _, _)) + .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::QuitWhenIdle)); + } + std::unique_ptr<DeviceManagementRequestJob> job( + service_->CreateJob(DeviceManagementRequestJob::TYPE_TOKEN_ENROLLMENT, + g_browser_process->system_request_context())); + job->GetRequest()->mutable_register_browser_request(); + if (!machine_name.empty()) { + job->GetRequest()->mutable_register_browser_request()->set_machine_name( + machine_name); + } + if (!enrollment_token.empty()) + job->SetEnrollmentToken(enrollment_token); + job->SetClientID(kClientID); + job->Start(base::Bind( + &MachineLevelUserCloudPolicyServiceIntegrationTest::OnJobDone, + base::Unretained(this))); + run_loop.Run(); + } + + void UploadChromeDesktopReport( + const em::ChromeDesktopReportRequest* chrome_desktop_report) { + base::RunLoop run_loop; + em::DeviceManagementResponse chrome_desktop_report_response; + chrome_desktop_report_response.mutable_chrome_desktop_report_response(); + EXPECT_CALL(*this, OnJobDone(testing::Eq(DM_STATUS_SUCCESS), _, + MatchProto(chrome_desktop_report_response))) + .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::QuitWhenIdle)); + + std::unique_ptr<DeviceManagementRequestJob> job(service_->CreateJob( + DeviceManagementRequestJob::TYPE_CHROME_DESKTOP_REPORT, + g_browser_process->system_request_context())); + + em::DeviceManagementRequest* request = job->GetRequest(); + if (chrome_desktop_report) { + *request->mutable_chrome_desktop_report_request() = + *chrome_desktop_report; + } + + job->SetDMToken(kDMToken); + job->SetClientID(kClientID); + job->Start(base::Bind( + &MachineLevelUserCloudPolicyServiceIntegrationTest::OnJobDone, + base::Unretained(this))); + run_loop.Run(); + } + + void SetUpOnMainThread() override { + std::string service_url((this->*(GetParam()))()); + service_.reset(new DeviceManagementService( + std::unique_ptr<DeviceManagementService::Configuration>( + new MockDeviceManagementServiceConfiguration(service_url)))); + service_->ScheduleInitialization(0); + } + + void TearDownOnMainThread() override { + service_.reset(); + test_server_.reset(); + } + + void StartTestServer() { + test_server_.reset(new LocalPolicyTestServer( + "machine_level_user_cloud_policy_service_browsertest")); + ASSERT_TRUE(test_server_->Start()); + } + + void RecordToken(DeviceManagementStatus status, + int net_error, + const em::DeviceManagementResponse& response) { + token_ = response.register_response().device_management_token(); + } + + std::string token_; + std::unique_ptr<DeviceManagementService> service_; + std::unique_ptr<LocalPolicyTestServer> test_server_; +}; + +IN_PROC_BROWSER_TEST_P(MachineLevelUserCloudPolicyServiceIntegrationTest, + Registration) { + ASSERT_TRUE(token_.empty()); + PerformRegistration(kEnrollmentToken, kMachineName, /*expect_success=*/true); + EXPECT_FALSE(token_.empty()); +} + +IN_PROC_BROWSER_TEST_P(MachineLevelUserCloudPolicyServiceIntegrationTest, + RegistrationNoEnrollmentToken) { + ASSERT_TRUE(token_.empty()); + PerformRegistration(std::string(), kMachineName, /*expect_success=*/false); + EXPECT_TRUE(token_.empty()); +} + +IN_PROC_BROWSER_TEST_P(MachineLevelUserCloudPolicyServiceIntegrationTest, + RegistrationNoMachineName) { + ASSERT_TRUE(token_.empty()); + PerformRegistration(kEnrollmentToken, std::string(), + /*expect_success=*/false); + EXPECT_TRUE(token_.empty()); +} + +IN_PROC_BROWSER_TEST_P(MachineLevelUserCloudPolicyServiceIntegrationTest, + ChromeDesktopReport) { + em::ChromeDesktopReportRequest chrome_desktop_report; + UploadChromeDesktopReport(&chrome_desktop_report); +} + +INSTANTIATE_TEST_CASE_P( + MachineLevelUserCloudPolicyServiceIntegrationTestInstance, + MachineLevelUserCloudPolicyServiceIntegrationTest, + testing::Values( + &MachineLevelUserCloudPolicyServiceIntegrationTest::InitTestServer)); + +class CloudPolicyStoreObserverStub : public CloudPolicyStore::Observer { + public: + CloudPolicyStoreObserverStub() {} + + bool was_called() const { return on_loaded_ || on_error_; } + + private: + // CloudPolicyStore::Observer + void OnStoreLoaded(CloudPolicyStore* store) override { on_loaded_ = true; } + void OnStoreError(CloudPolicyStore* store) override { on_error_ = true; } + + bool on_loaded_ = false; + bool on_error_ = false; + + DISALLOW_COPY_AND_ASSIGN(CloudPolicyStoreObserverStub); +}; + +class MachineLevelUserCloudPolicyManagerTest : public InProcessBrowserTest { + protected: + bool CreateAndInitManager(const std::string& dm_token) { + base::ScopedAllowBlockingForTesting scope_for_testing; + std::string client_id("client_id"); + base::FilePath user_data_dir; + CombinedSchemaRegistry schema_registry; + CloudPolicyStoreObserverStub observer; + + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + + std::unique_ptr<MachineLevelUserCloudPolicyStore> policy_store = + MachineLevelUserCloudPolicyStore::Create( + dm_token, client_id, user_data_dir, + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); + policy_store->AddObserver(&observer); + + base::FilePath policy_dir = + user_data_dir.Append(ChromeBrowserPolicyConnector::kPolicyDir); + + std::unique_ptr<MachineLevelUserCloudPolicyManager> manager = + std::make_unique<MachineLevelUserCloudPolicyManager>( + std::move(policy_store), nullptr, policy_dir, + base::ThreadTaskRunnerHandle::Get(), + content::BrowserThread::GetTaskRunnerForThread( + content::BrowserThread::IO)); + manager->Init(&schema_registry); + + manager->store()->RemoveObserver(&observer); + manager->Shutdown(); + return observer.was_called(); + } +}; + +IN_PROC_BROWSER_TEST_F(MachineLevelUserCloudPolicyManagerTest, NoDmToken) { + EXPECT_FALSE(CreateAndInitManager(std::string())); +} + +IN_PROC_BROWSER_TEST_F(MachineLevelUserCloudPolicyManagerTest, WithDmToken) { + EXPECT_TRUE(CreateAndInitManager("dummy_dm_token")); +} + +} // namespace policy
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_helper.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_helper.cc index 5a488505..d01566a 100644 --- a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_helper.cc +++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_helper.cc
@@ -81,6 +81,7 @@ scoped_refptr<net::URLRequestContextGetter> system_request_context) : policy_manager_(policy_manager), local_state_(local_state), + device_management_service_(device_management_service), system_request_context_(system_request_context) { std::unique_ptr<CloudPolicyClient> client = std::make_unique<CloudPolicyClient>(
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index c91d384..b04b499 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -85,6 +85,7 @@ #if !defined(OS_ANDROID) #include "chrome/browser/download/default_download_dir_policy_handler.h" #include "chrome/browser/download/download_dir_policy_handler.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/policy/local_sync_policy_handler.h" #endif @@ -482,6 +483,9 @@ { key::kShowCastIconInToolbar, prefs::kShowCastIconInToolbar, base::Value::Type::BOOLEAN }, + { key::kMediaRouterCastAllowAllIPs, + media_router::prefs::kMediaRouterCastAllowAllIPs, + base::Value::Type::BOOLEAN }, #endif // !defined(OS_ANDROID) #if BUILDFLAG(ENABLE_WEBRTC) { key::kWebRtcUdpPortRange, @@ -761,8 +765,8 @@ prefs::kAbusiveExperienceInterventionEnforce, base::Value::Type::BOOLEAN }, - { key::kTabUnderProtectionEnabled, - prefs::kTabUnderProtection, + { key::kTabUnderAllowed, + prefs::kTabUnderAllowed, base::Value::Type::BOOLEAN }, #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) @@ -1002,8 +1006,22 @@ handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>( key::kCertificateTransparencyEnforcementDisabledForUrls, certificate_transparency::prefs::kCTExcludedHosts, chrome_schema, - SCHEMA_STRICT, SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED, + SCHEMA_STRICT, + SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED, SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); + handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>( + key::kCertificateTransparencyEnforcementDisabledForCas, + certificate_transparency::prefs::kCTExcludedSPKIs, chrome_schema, + SCHEMA_STRICT, + SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED, + SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); + handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>( + key::kCertificateTransparencyEnforcementDisabledForLegacyCas, + certificate_transparency::prefs::kCTExcludedLegacySPKIs, chrome_schema, + SCHEMA_STRICT, + SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED, + SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); + handlers->AddHandler(std::make_unique<SecureOriginPolicyHandler>()); #if defined(OS_ANDROID)
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 1fdb31a..5e894ba 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -191,8 +191,10 @@ #include "extensions/common/switches.h" #include "extensions/common/value_builder.h" #include "media/media_buildflags.h" +#include "net/base/hash_value.h" #include "net/base/net_errors.h" #include "net/base/url_util.h" +#include "net/cert/x509_util.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_stream_factory.h" #include "net/http/transport_security_state.h" @@ -258,6 +260,10 @@ #include "base/win/win_util.h" #endif +#if !defined(OS_ANDROID) +#include "chrome/browser/media/router/media_router_feature.h" +#endif + using content::BrowserThread; using net::URLRequestMockHTTPJob; using testing::Mock; @@ -3836,7 +3842,57 @@ UpdateProviderPolicy(policies); FlushBlacklistPolicy(); - SetShouldRequireCTForTesting(nullptr); + ui_test_utils::NavigateToURL(browser(), + https_server_ok.GetURL("/simple.html")); + + // There should be no interstitial after the page loads. + interstitial = content::InterstitialPage::GetInterstitialPage( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_FALSE(interstitial); + + EXPECT_EQ(base::UTF8ToUTF16("OK"), + browser()->tab_strip_model()->GetActiveWebContents()->GetTitle()); +} + +IN_PROC_BROWSER_TEST_F(PolicyTest, + CertificateTransparencyEnforcementDisabledForCas) { + net::EmbeddedTestServer https_server_ok(net::EmbeddedTestServer::TYPE_HTTPS); + https_server_ok.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + https_server_ok.ServeFilesFromSourceDirectory("chrome/test/data"); + ASSERT_TRUE(https_server_ok.Start()); + + // Require CT for all hosts (in the absence of policy). + bool required = true; + SetShouldRequireCTForTesting(&required); + + ui_test_utils::NavigateToURL(browser(), https_server_ok.GetURL("/")); + + // The page should initially be blocked. + const content::InterstitialPage* interstitial = + content::InterstitialPage::GetInterstitialPage( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_TRUE(interstitial); + ASSERT_TRUE(content::WaitForRenderFrameReady(interstitial->GetMainFrame())); + + EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText( + interstitial->GetMainFrame(), "proceed-link")); + EXPECT_NE(base::UTF8ToUTF16("OK"), + browser()->tab_strip_model()->GetActiveWebContents()->GetTitle()); + + // Now exempt the leaf SPKI from being blocked by setting policy. + net::HashValue leaf_hash; + ASSERT_TRUE(net::x509_util::CalculateSha256SpkiHash( + https_server_ok.GetCertificate()->cert_buffer(), &leaf_hash)); + std::unique_ptr<base::ListValue> disabled_spkis = + std::make_unique<base::ListValue>(); + disabled_spkis->AppendString(leaf_hash.ToString()); + + PolicyMap policies; + policies.Set(key::kCertificateTransparencyEnforcementDisabledForCas, + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + std::move(disabled_spkis), nullptr); + UpdateProviderPolicy(policies); + FlushBlacklistPolicy(); ui_test_utils::NavigateToURL(browser(), https_server_ok.GetURL("/simple.html")); @@ -4570,6 +4626,7 @@ EXPECT_FALSE(media_router::MediaRouterEnabled(browser()->profile())); } +#if !defined(OS_ANDROID) template <bool enable> class MediaRouterActionPolicyTest : public PolicyTest { public: @@ -4611,6 +4668,37 @@ EXPECT_FALSE(HasMediaRouterActionAtInit()); } +class MediaRouterCastAllowAllIPsPolicyTest + : public PolicyTest, + public testing::WithParamInterface<bool> { + public: + void SetUpInProcessBrowserTestFixture() override { + PolicyTest::SetUpInProcessBrowserTestFixture(); + PolicyMap policies; + policies.Set(key::kMediaRouterCastAllowAllIPs, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>(is_enabled()), nullptr); + provider_.UpdateChromePolicy(policies); + } + + bool is_enabled() const { return GetParam(); } +}; + +IN_PROC_BROWSER_TEST_P(MediaRouterCastAllowAllIPsPolicyTest, RunTest) { + PrefService* const pref = g_browser_process->local_state(); + ASSERT_TRUE(pref); + EXPECT_EQ(is_enabled(), + pref->GetBoolean(media_router::prefs::kMediaRouterCastAllowAllIPs)); + EXPECT_TRUE(pref->IsManagedPreference( + media_router::prefs::kMediaRouterCastAllowAllIPs)); + EXPECT_EQ(is_enabled(), media_router::GetCastAllowAllIPsPref(pref)); +} + +INSTANTIATE_TEST_CASE_P(MediaRouterCastAllowAllIPsPolicyTestInstance, + MediaRouterCastAllowAllIPsPolicyTest, + testing::Values(true, false)); +#endif // !defined(OS_ANDROID) + #if BUILDFLAG(ENABLE_WEBRTC) // Sets the proper policy before the browser is started. template <bool enable>
diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc index de4286d..edfe805 100644 --- a/chrome/browser/policy/profile_policy_connector.cc +++ b/chrome/browser/policy/profile_policy_connector.cc
@@ -76,6 +76,19 @@ policy_providers_.push_back( connector->GetDeviceActiveDirectoryPolicyManager()); } +#else + for (auto* provider : connector->GetPolicyProviders()) { + // Skip the platform provider since it was already handled above. The + // platform provider should be first in the list so that it always takes + // precedence. + if (provider == connector->GetPlatformProvider()) { + continue; + } else { + // TODO(zmin): In the future, we may want to have special handling for + // the other providers too. + policy_providers_.push_back(provider); + } + } #endif if (configuration_policy_provider)
diff --git a/chrome/browser/policy/test/policy_testserver.py b/chrome/browser/policy/test/policy_testserver.py index 49100a2..6d2a5df 100644 --- a/chrome/browser/policy/test/policy_testserver.py +++ b/chrome/browser/policy/test/policy_testserver.py
@@ -330,6 +330,12 @@ response = self.ProcessCheckAndroidManagementRequest( rmsg.check_android_management_request, str(self.GetUniqueParam('oauth_token'))) + elif request_type == 'register_browser': + response = self.ProcessRegisterBrowserRequest( + rmsg.register_browser_request) + elif request_type == 'chrome_desktop_report': + response = self.ProcessChromeDesktopReportUploadRequest( + rmsg.chrome_desktop_report_request) elif request_type == 'app_install_report': response = self.ProcessAppInstallReportRequest( rmsg.app_install_report_request) @@ -740,6 +746,47 @@ return (200, response) + def ProcessRegisterBrowserRequest(self, msg): + """Handles a browser registration request. + + Returns: + A tuple of HTTP status code and response data to send to the client. + """ + enrollment_token = None + match = re.match('GoogleEnrollmentToken token=(\\w+)', + self.headers.getheader('Authorization', '')) + if match: + enrollment_token = match.group(1) + if not enrollment_token: + return (401, 'Missing enrollment token.') + + device_id = self.GetUniqueParam('deviceid') + if not device_id: + return (400, 'Parameter deviceid is missing.') + + if not msg.machine_name: + return (400, 'Invalid machine name: ') + + response = dm.DeviceManagementResponse() + response.register_response.device_management_token = ( + 'fake_device_management_token') + return (200, response) + + def ProcessChromeDesktopReportUploadRequest(self, chrome_desktop_report): + """Handles a chrome desktop report upload request. + + Returns: + A tuple of HTTP status code and response data to send to the client. + """ + # Empty responses indicate a successful upload. + chrome_desktop_report_response = dm.ChromeDesktopReportResponse() + + response = dm.DeviceManagementResponse() + response.chrome_desktop_report_response.CopyFrom( + chrome_desktop_report_response) + + return (200, response) + def SetProtoRepeatedField(self, group_message, field, field_value): assert type(field_value) == list entries = group_message.__getattribute__(field.name)
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 87607cca..acc2e45c 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -187,6 +187,7 @@ #include "components/ntp_tiles/popular_sites_impl.h" #else #include "chrome/browser/gcm/gcm_product_util.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/metrics/tab_stats_tracker.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" @@ -402,6 +403,7 @@ registry->RegisterListPref(kStabilityCrashedActivityCounts); registry->RegisterListPref(kStabilityLaunchedActivityCounts); #else + media_router::RegisterLocalStatePrefs(registry); // The native GCM is used on Android instead. gcm::GCMChannelStatusSyncer::RegisterPrefs(registry); gcm::RegisterPrefs(registry);
diff --git a/chrome/browser/profiling_host/chrome_browser_main_extra_parts_profiling.cc b/chrome/browser/profiling_host/chrome_browser_main_extra_parts_profiling.cc index 4cebdd0..6e5b891 100644 --- a/chrome/browser/profiling_host/chrome_browser_main_extra_parts_profiling.cc +++ b/chrome/browser/profiling_host/chrome_browser_main_extra_parts_profiling.cc
@@ -27,7 +27,6 @@ if (mode != heap_profiling::Mode::kNone) { heap_profiling::ProfilingProcessHost::Start( connection, mode, heap_profiling::GetStackModeForStartup(), - heap_profiling::GetShouldSampleForStartup(), heap_profiling::GetSamplingRateForStartup()); } #endif
diff --git a/chrome/browser/profiling_host/profiling_process_host.cc b/chrome/browser/profiling_host/profiling_process_host.cc index bd42936..83891c4 100644 --- a/chrome/browser/profiling_host/profiling_process_host.cc +++ b/chrome/browser/profiling_host/profiling_process_host.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/tracing/crash_service_uploader.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_switches.h" +#include "components/services/heap_profiling/public/cpp/controller.h" #include "components/services/heap_profiling/public/cpp/sender_pipe.h" #include "components/services/heap_profiling/public/cpp/settings.h" #include "components/services/heap_profiling/public/cpp/switches.h" @@ -235,24 +236,7 @@ mojom::ProcessType process_type) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - SenderPipe::PipePair pipes; - - // Passes the client_for_profiling directly to the profiling process. - // The client process can not start sending data until the pipe is ready, - // so talking to the client is done in the AddSender completion callback. - // - // This code doesn't actually hang onto the client_for_browser interface - // poiner beyond sending this message to start since there are no other - // messages we need to send. - mojom::ProfilingParamsPtr params = mojom::ProfilingParams::New(); - params->sampling_rate = should_sample_ ? sampling_rate_ : 1; - params->sender_pipe = - mojo::WrapPlatformFile(pipes.PassSender().release().handle); - params->stack_mode = stack_mode_; - profiling_service_->AddProfilingClient( - pid, std::move(client), - mojo::WrapPlatformFile(pipes.PassReceiver().release().handle), - process_type, std::move(params)); + controller_->StartProfilingClient(std::move(client), pid, process_type); } // static @@ -260,24 +244,38 @@ content::ServiceManagerConnection* connection, Mode mode, mojom::StackMode stack_mode, - bool should_sample, uint32_t sampling_rate) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); CHECK(!has_started_); has_started_ = true; ProfilingProcessHost* host = GetInstance(); - host->stack_mode_ = stack_mode; - host->should_sample_ = should_sample; - host->sampling_rate_ = sampling_rate; + + host->connector_ = connection->GetConnector()->Clone(); + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO) + ->PostTask( + FROM_HERE, + base::BindOnce(&ProfilingProcessHost::StartServiceOnIOThread, + base::Unretained(host), stack_mode, sampling_rate, + connection->GetConnector()->Clone())); + host->SetMode(mode); host->Register(); - host->MakeConnector(connection); - host->LaunchAsService(); host->ConfigureBackgroundProfilingTriggers(); host->metrics_timer_.Start( FROM_HERE, base::TimeDelta::FromHours(24), base::Bind(&ProfilingProcessHost::ReportMetrics, base::Unretained(host))); + // Start profiling the browser process if desired. + if (host->ShouldProfileNonRendererProcessType( + content::ProcessType::PROCESS_TYPE_BROWSER)) { + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO) + ->PostTask( + FROM_HERE, + base::BindOnce( + &ProfilingProcessHost::StartProfilingBrowserProcessOnIOThread, + base::Unretained(host))); + } + return host; } @@ -300,13 +298,6 @@ SaveTraceFinishedCallback done, bool stop_immediately_after_heap_dump_for_tests) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - if (!profiling_service_.is_bound()) { - DLOG(ERROR) - << "Requesting heap dump when profiling process hasn't started."; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(done), false)); - return; - } auto finish_trace_callback = base::BindOnce( [](base::FilePath dest, SaveTraceFinishedCallback done, bool success, @@ -357,7 +348,7 @@ } }, base::Unretained(this), std::move(trigger_name), - should_sample_ ? sampling_rate_ : 1); + controller_->sampling_rate()); RequestTraceWithHeapDump(std::move(finish_report_callback), true /* anonymize */); } @@ -430,7 +421,7 @@ void ProfilingProcessHost::GetProfiledPidsOnIOThread( GetProfiledPidsCallback callback) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - if (!profiling_service_.is_bound()) { + if (!controller_) { content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) ->PostTask(FROM_HERE, base::BindOnce(std::move(callback), std::vector<base::ProcessId>())); @@ -445,7 +436,7 @@ ->PostTask(FROM_HERE, base::BindOnce(std::move(callback), result)); }, std::move(callback)); - profiling_service_->GetProfiledPids(std::move(post_result_to_ui_thread)); + controller_->GetProfiledPids(std::move(post_result_to_ui_thread)); } void ProfilingProcessHost::StartManualProfiling(base::ProcessId pid) { @@ -454,8 +445,7 @@ if (!has_started_) { ProfilingProcessHost::Start( content::ServiceManagerConnection::GetForProcess(), Mode::kManual, - GetStackModeForStartup(), GetShouldSampleForStartup(), - GetSamplingRateForStartup()); + GetStackModeForStartup(), GetSamplingRateForStartup()); } else { SetMode(Mode::kManual); } @@ -498,7 +488,7 @@ return; } - profiling_service_->SetKeepSmallAllocations(keep_small_allocations); + controller_->SetKeepSmallAllocations(keep_small_allocations); } void ProfilingProcessHost::StartProfilingPidOnIOThread(base::ProcessId pid) { @@ -530,45 +520,22 @@ << pid; } -void ProfilingProcessHost::MakeConnector( - content::ServiceManagerConnection* connection) { - connector_ = connection->GetConnector()->Clone(); +void ProfilingProcessHost::StartServiceOnIOThread( + mojom::StackMode stack_mode, + uint32_t sampling_rate, + std::unique_ptr<service_manager::Connector> connector) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + controller_.reset( + new Controller(std::move(connector), stack_mode, sampling_rate)); } -void ProfilingProcessHost::LaunchAsService() { - // May get called on different threads, we need to be on the IO thread to - // work. - if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) { - content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO) - ->PostTask(FROM_HERE, - base::BindOnce(&ProfilingProcessHost::LaunchAsService, - base::Unretained(this))); - return; - } - - // Bind to the memlog service. This will start it if it hasn't started - // already. - connector_->BindInterface(mojom::kServiceName, &profiling_service_); - - // Set some state for heap dumps. - SetKeepSmallAllocations(ShouldKeepSmallAllocations()); - - // Grab a HeapProfiler InterfacePtr and pass that to memory instrumentation. - memory_instrumentation::mojom::HeapProfilerPtr heap_profiler; - connector_->BindInterface(mojom::kServiceName, &heap_profiler); - - memory_instrumentation::mojom::CoordinatorPtr coordinator; - connector_->BindInterface(resource_coordinator::mojom::kServiceName, - &coordinator); - coordinator->RegisterHeapProfiler(std::move(heap_profiler)); - - // Start profiling the browser if the mode allows. - if (ShouldProfileNonRendererProcessType( - content::ProcessType::PROCESS_TYPE_BROWSER)) { - ProfilingClientBinder client(connector_.get()); - AddClientToProfilingService(client.take(), base::Process::Current().Pid(), - mojom::ProcessType::BROWSER); - } +void ProfilingProcessHost::StartProfilingBrowserProcessOnIOThread() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + ProfilingClientBinder client(connector_.get()); + controller_->StartProfilingClient(client.take(), + base::Process::Current().Pid(), + mojom::ProcessType::BROWSER); } void ProfilingProcessHost::SaveTraceToFileOnBlockingThread(
diff --git a/chrome/browser/profiling_host/profiling_process_host.h b/chrome/browser/profiling_host/profiling_process_host.h index 51431b8..d655a59 100644 --- a/chrome/browser/profiling_host/profiling_process_host.h +++ b/chrome/browser/profiling_host/profiling_process_host.h
@@ -34,6 +34,7 @@ namespace heap_profiling { +class Controller; enum class Mode; // Represents the browser side of the profiling process (//chrome/profiling). @@ -71,7 +72,6 @@ content::ServiceManagerConnection* connection, Mode mode, mojom::StackMode stack_mode, - bool should_sample, uint32_t sampling_rate); // Returns true if Start() has been called. @@ -147,9 +147,6 @@ // Set/Get the profiling mode. Exposed for unittests. void SetMode(Mode mode); - // Make and store a connector from |connection|. - void MakeConnector(content::ServiceManagerConnection* connection); - // BrowserChildProcessObserver // Observe connection of non-renderer child processes. void BrowserChildProcessLaunchedAndConnected( @@ -162,7 +159,12 @@ const content::NotificationDetails& details) override; // Starts the profiling process. - void LaunchAsService(); + void StartServiceOnIOThread( + mojom::StackMode stack_mode, + uint32_t sampling_rate, + std::unique_ptr<service_manager::Connector> connector); + + void StartProfilingBrowserProcessOnIOThread(); // Called on the UI thread after the heap dump has been added to the trace. void DumpProcessFinishedUIThread(); @@ -198,8 +200,12 @@ bool SetTakingTraceForUpload(bool new_state); content::NotificationRegistrar registrar_; + + // Bound to the IO thread. std::unique_ptr<service_manager::Connector> connector_; - mojom::ProfilingServicePtr profiling_service_; + + // Bound to the IO thread. + std::unique_ptr<Controller> controller_; // Whether or not the host is registered to the |registrar_|. bool is_registered_;
diff --git a/chrome/browser/profiling_host/profiling_test_driver.cc b/chrome/browser/profiling_host/profiling_test_driver.cc index 64262fd..a0aa518a 100644 --- a/chrome/browser/profiling_host/profiling_test_driver.cc +++ b/chrome/browser/profiling_host/profiling_test_driver.cc
@@ -661,9 +661,11 @@ } } + uint32_t sampling_rate = options_.should_sample + ? (options_.sample_everything ? 2 : kSampleRate) + : 1; ProfilingProcessHost::Start(connection, options_.mode, options_.stack_mode, - options_.should_sample, - options_.sample_everything ? 2 : kSampleRate); + sampling_rate); ProfilingProcessHost::GetInstance()->SetKeepSmallAllocations(true); if (run_loop) @@ -774,7 +776,7 @@ bool result = false; bool should_validate_dumps = true; -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) && !defined(OFFICIAL_BUILD) // TODO(ajwong): This step fails on Nexus 5X devices running kit-kat. It works // on Nexus 5X devices running oreo. The problem is that all allocations have // the same [an effectively empty] backtrace and get glommed together. More
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 7ba83d0..e882ab9 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -39,7 +39,6 @@ #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" -#include "chrome/browser/picture_in_picture/picture_in_picture_window_controller.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" @@ -106,6 +105,7 @@ #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/picture_in_picture_window_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc index fc032dc..ae5aaf9 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -171,7 +171,7 @@ if (GetWebContents()->GetPageImportanceSignals().had_form_interaction) return false; - // Do discard media tabs as it's too distruptive to the user experience. + // Do not discard media tabs as it's too distruptive to the user experience. if (IsMediaTab()) return false;
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index 685ddba2..a160091 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -115,6 +115,14 @@ return std::move(data); } +int GetNumLoadedLifecycleUnits(LifecycleUnitSet lifecycle_unit_set) { + int num_loaded_lifecycle_units = 0; + for (auto* lifecycle_unit : lifecycle_unit_set) + if (lifecycle_unit->GetState() == LifecycleUnit::State::LOADED) + num_loaded_lifecycle_units++; + return num_loaded_lifecycle_units; +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -905,15 +913,35 @@ return force_load_timer_ && force_load_timer_->IsRunning(); } +void TabManager::OnLifecycleUnitStateChanged(LifecycleUnit* lifecycle_unit) { + if (lifecycle_unit->GetState() == LifecycleUnit::State::LOADED) + num_loaded_lifecycle_units_++; + else + num_loaded_lifecycle_units_--; + + DCHECK_EQ(num_loaded_lifecycle_units_, + GetNumLoadedLifecycleUnits(lifecycle_units_)); +} + void TabManager::OnLifecycleUnitDestroyed(LifecycleUnit* lifecycle_unit) { + if (lifecycle_unit->GetState() == LifecycleUnit::State::LOADED) + num_loaded_lifecycle_units_--; lifecycle_units_.erase(lifecycle_unit); + + DCHECK_EQ(num_loaded_lifecycle_units_, + GetNumLoadedLifecycleUnits(lifecycle_units_)); } void TabManager::OnLifecycleUnitCreated(LifecycleUnit* lifecycle_unit) { lifecycle_units_.insert(lifecycle_unit); + if (lifecycle_unit->GetState() == LifecycleUnit::State::LOADED) + num_loaded_lifecycle_units_++; // Add an observer to be notified of destruction. lifecycle_unit->AddObserver(this); + + DCHECK_EQ(num_loaded_lifecycle_units_, + GetNumLoadedLifecycleUnits(lifecycle_units_)); } } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h index fa423ab..25dea18 100644 --- a/chrome/browser/resource_coordinator/tab_manager.h +++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -259,6 +259,8 @@ FRIEND_TEST_ALL_PREFIXES(TabManagerTest, IsTabRestoredInForeground); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, EnablePageAlmostIdleSignal); FRIEND_TEST_ALL_PREFIXES(TabManagerTest, FreezeTab); + FRIEND_TEST_ALL_PREFIXES(TabManagerTest, + TrackingNumberOfLoadedLifecycleUnits); // The time of the first purging after a renderer is backgrounded. // The initial value was chosen because most of users activate backgrounded @@ -409,6 +411,7 @@ // LifecycleUnitObserver: void OnLifecycleUnitDestroyed(LifecycleUnit* lifecycle_unit) override; + void OnLifecycleUnitStateChanged(LifecycleUnit* lifecycle_unit) override; // LifecycleUnitSourceObserver: void OnLifecycleUnitCreated(LifecycleUnit* lifecycle_unit) override; @@ -416,6 +419,10 @@ // LifecycleUnits managed by this. LifecycleUnitSet lifecycle_units_; + // Number of LifecycleUnits in |lifecycle_units_| that are State::LOADED. Used + // to determine threshold for proactive tab discarding experiments. + int num_loaded_lifecycle_units_ = 0; + // Timer to periodically update the stats of the renderers. base::RepeatingTimer update_timer_;
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc index a6da556..31320d3 100644 --- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -860,13 +860,13 @@ "if (window.location.pathname != '/iframe_cross_site.html')" " throw 'Incorrect frame';" "mainFrameFreezeCount = 0;" - "window.onfreeze = function(){ mainFrameFreezeCount++; };")); + "window.document.onfreeze = function(){ mainFrameFreezeCount++; };")); EXPECT_TRUE(content::ExecuteScript( child_frame, "if (window.location.pathname != '/title1.html') throw 'Incorrect frame';" "childFrameFreezeCount = 0;" - "window.onfreeze = function(){ childFrameFreezeCount++; };")); + "window.document.onfreeze = function(){ childFrameFreezeCount++; };")); // freeze_count_result should be 0 for both frames, if it is undefined then we // are in the wrong frame/tab.
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc index e4c17164..a74f5d61 100644 --- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -140,7 +140,10 @@ class TabManagerTest : public ChromeRenderViewHostTestHarness { public: TabManagerTest() - : scoped_set_tick_clock_for_testing_(task_runner_->GetMockTickClock()) { + : scoped_context_( + std::make_unique<base::TestMockTimeTaskRunner::ScopedContext>( + task_runner_)), + scoped_set_tick_clock_for_testing_(task_runner_->GetMockTickClock()) { base::MessageLoop::current()->SetTaskRunner(task_runner_); } @@ -174,7 +177,8 @@ contents2_.reset(); contents3_.reset(); - base::MessageLoop::current()->SetTaskRunner(original_task_runner_); + task_runner_->RunUntilIdle(); + scoped_context_.reset(); ChromeRenderViewHostTestHarness::TearDown(); } @@ -243,10 +247,6 @@ } } - private: - scoped_refptr<base::SingleThreadTaskRunner> original_task_runner_ = - base::ThreadTaskRunnerHandle::Get(); - protected: std::unique_ptr<NavigationHandle> CreateTabAndNavigation(const char* url) { content::WebContents* web_contents = CreateTestWebContents(); @@ -258,6 +258,7 @@ TabManager* tab_manager_ = nullptr; scoped_refptr<base::TestMockTimeTaskRunner> task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + std::unique_ptr<base::TestMockTimeTaskRunner::ScopedContext> scoped_context_; ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_; std::unique_ptr<BackgroundTabNavigationThrottle> throttle1_; std::unique_ptr<BackgroundTabNavigationThrottle> throttle2_; @@ -1034,4 +1035,51 @@ EXPECT_FALSE(tab_manager_->IsNavigationDelayedForTest(nav_handle3_.get())); } +TEST_F(TabManagerTest, TrackingNumberOfLoadedLifecycleUnits) { + auto window = std::make_unique<TestBrowserWindow>(); + Browser::CreateParams params(profile(), true); + params.type = Browser::TYPE_TABBED; + params.window = window.get(); + auto browser = std::make_unique<Browser>(params); + TabStripModel* tab_strip = browser->tab_strip_model(); + + // TabManager should start out with 0 loaded LifecycleUnits. + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, 0); + + // Number of loaded LifecycleUnits should go up by 1 for each new WebContents. + for (int i = 1; i <= 5; i++) { + tab_strip->AppendWebContents(CreateWebContents(), false); + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, i); + } + + // Closing loaded tabs should reduce |num_loaded_lifecycle_units_| back to the + // original amount. + tab_strip->CloseAllTabs(); + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, 0); + + // Number of loaded LifecycleUnits should go up by 1 for each new WebContents. + for (int i = 1; i <= 5; i++) { + tab_strip->AppendWebContents(CreateWebContents(), false); + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, i); + } + + task_runner_->FastForwardBy(TabManager::kDiscardProtectionTime); + + // Number of loaded LifecycleUnits should go down by 1 for each discarded + // WebContents. + for (int i = 0; i < 5; i++) { + TabLifecycleUnitExternal::FromWebContents(tab_strip->GetWebContentsAt(i)) + ->DiscardTab(); + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, 4 - i); + } + + // All tabs were discarded, so there should be no loaded LifecycleUnits. + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, 0); + + tab_strip->CloseAllTabs(); + + // Closing discarded tabs shouldn't affect |num_loaded_lifecycle_units_|. + EXPECT_EQ(tab_manager_->num_loaded_lifecycle_units_, 0); +} + } // namespace resource_coordinator
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb index 55f54fa7..9c119f1 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb
@@ -370,6 +370,7 @@ <translation id="4176463684765177261">Disabled</translation> <translation id="4188530942454211480">Previous Sentence</translation> <translation id="4191918948604314587">A button</translation> +<translation id="419265409837491189">Go to the previous column</translation> <translation id="4202186506458631436">Move right</translation> <translation id="4206289001967551965">Inside table</translation> <translation id="4209770650650780359">Press up or down arrow for auto completions.</translation> @@ -420,6 +421,7 @@ <translation id="4660783501463101648">Classic removed. The keyboard toggle to switch back into ChromeVox Classic has been removed.</translation> <translation id="4661075872484491155">tree</translation> <translation id="4668929960204016307">,</translation> +<translation id="4677535310137735442">Go to the next column</translation> <translation id="4688873778442829762">grd</translation> <translation id="4693675773662933727">Previous landmark</translation> <translation id="4696413482802371445">No next level 5 heading.</translation> @@ -435,6 +437,7 @@ <translation id="4826415162591436065">Navigate forward</translation> <translation id="4826604887384865800">Next jump</translation> <translation id="4827410568042294688">unselected</translation> +<translation id="4839925464551908214">Go to the previous row</translation> <translation id="4842108708071771135">No next block quote.</translation> <translation id="4844625982113518938">Press any key to learn its name. Ctrl+W will close learn mode.</translation> <translation id="4846428657345567687">Welcome to ChromeVox!</translation> @@ -789,6 +792,7 @@ <translation id="8186185314313222077">toggle full screen</translation> <translation id="8199231515320852133">Announce the headers of the current cell</translation> <translation id="820417203470636242">Empty cell.</translation> +<translation id="820469951249669083">Go to the next row</translation> <translation id="8215202828671303819">Multi select</translation> <translation id="826991282343985864">r$1c$2</translation> <translation id="8276439074553447000">Jump to previous focusable item</translation>
diff --git a/chrome/browser/resources/chromeos/emulator/audio_settings.html b/chrome/browser/resources/chromeos/emulator/audio_settings.html index 688da48..966f6bd0 100644 --- a/chrome/browser/resources/chromeos/emulator/audio_settings.html +++ b/chrome/browser/resources/chromeos/emulator/audio_settings.html
@@ -18,7 +18,7 @@ See https://github.com/Polymer/polymer/pull/3668. --> <style include="device-emulator-shared-styles cr-shared-style iron-flex iron-flex-alignment iron-positioning"> </style> - <dialog is="cr-dialog" id="editDialog"> + <cr-dialog id="editDialog"> <div slot="title">[[currentEditableObject.deviceName]]</div> <div slot="body"> <form> @@ -59,7 +59,7 @@ Done </paper-button> </div> - </dialog> + </cr-dialog> <div class="layout vertical"> <div class="element-label">
diff --git a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html index 5389e24..e804c7b 100644 --- a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html +++ b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html
@@ -18,7 +18,7 @@ See https://github.com/Polymer/polymer/pull/3668. --> <style include="device-emulator-shared-styles cr-shared-style iron-flex iron-flex-alignment iron-positioning"> </style> - <dialog is="cr-dialog" id="editDialog"> + <cr-dialog id="editDialog"> <div slot="title">[[currentEditableObject.alias]]</div> <div slot="body"> <form> @@ -99,7 +99,7 @@ Close </paper-button> </div> - </dialog> + </cr-dialog> <div class="layout vertical"> <div class="element-label">
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.html b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.html index af490f28..068a4b3 100644 --- a/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.html +++ b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.html
@@ -27,13 +27,15 @@ <dom-module id="internet-config-dialog"> <template> <style include="network-shared iron-flex"> - dialog { - border-radius: 0; - height: 100%; - width: 100%; + cr-dialog { + --cr-dialog-native: { + border-radius: 0; + height: 100%; + width: 100%; + } } - dialog [slot=body] { + cr-dialog [slot=body] { /* This should match or exceed SystemWebDialogDelegate::kDialogHeight to ensure the content is stretched to fit. */ height: 480px; @@ -45,7 +47,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" no-cancel> + <cr-dialog id="dialog" no-cancel> <div slot="title">[[getDialogTitle_(networkProperties_)]]</div> <div slot="body"> <network-config id="networkConfig" class="flex" @@ -72,7 +74,7 @@ $i18n{networkButtonConnect} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="internet_config_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/offline_ad_login.html b/chrome/browser/resources/chromeos/login/offline_ad_login.html index 9127f20a..936d518b 100644 --- a/chrome/browser/resources/chromeos/login/offline_ad_login.html +++ b/chrome/browser/resources/chromeos/login/offline_ad_login.html
@@ -71,7 +71,7 @@ </div> </gaia-card> - <dialog is="cr-dialog" id="moreOptionsDlg" on-close="onMoreOptionsClosed_"> + <cr-dialog id="moreOptionsDlg" on-close="onMoreOptionsClosed_"> <div slot="title"> $i18n{adJoinMoreOptions} </div> @@ -108,6 +108,6 @@ $i18n{adJoinConfirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.css b/chrome/browser/resources/chromeos/login/offline_gaia.css index 1033709..7e65290 100644 --- a/chrome/browser/resources/chromeos/login/offline_gaia.css +++ b/chrome/browser/resources/chromeos/login/offline_gaia.css
@@ -11,9 +11,11 @@ } #forgotPasswordDlg { - color: var(--primary-text-color); - font-size: 15px; - width: 384px; + --cr-dialog-native: { + color: var(--primary-text-color); + font-size: 15px; + width: 384px; + } } /*
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.html b/chrome/browser/resources/chromeos/login/offline_gaia.html index 351cd9a..8a3cade 100644 --- a/chrome/browser/resources/chromeos/login/offline_gaia.html +++ b/chrome/browser/resources/chromeos/login/offline_gaia.html
@@ -160,7 +160,7 @@ </neon-animated-pages> </template> - <dialog is="cr-dialog" id="forgotPasswordDlg" + <cr-dialog id="forgotPasswordDlg" on-close="onDialogOverlayClosed_"> <div slot="body" i18n-content="offlineLoginForgotPasswordDlg"></div> @@ -169,6 +169,6 @@ i18n-content="offlineLoginCloseBtn" class="action-button"> </paper-button> </div> - </dialog> + </cr-dialog> </template> </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.css b/chrome/browser/resources/chromeos/login/saml_confirm_password.css index d30b2ff6..7de5aba 100644 --- a/chrome/browser/resources/chromeos/login/saml_confirm_password.css +++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.css
@@ -17,7 +17,9 @@ } #cancelConfirmDlg { - color: var(--primary-text-color); - font-size: 15px; - width: 384px; + --cr-dialog-native: { + color: var(--primary-text-color); + font-size: 15px; + width: 384px; + }; }
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.html b/chrome/browser/resources/chromeos/login/saml_confirm_password.html index 480cfa5..f4e948a 100644 --- a/chrome/browser/resources/chromeos/login/saml_confirm_password.html +++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.html
@@ -79,7 +79,7 @@ disabled="[[disabled]]"> </navigation-bar> - <dialog is="cr-dialog" id="cancelConfirmDlg" + <cr-dialog id="cancelConfirmDlg" on-close="onDialogOverlayClosed_"> <div slot="body" i18n-content="accountSetupCancelDialogTitle"></div> @@ -91,7 +91,7 @@ i18n-content="accountSetupCancelDialogYes" on-tap="onCancelYes_"> </paper-button> </div> - </dialog> + </cr-dialog> </template> </dom-module>
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.html b/chrome/browser/resources/md_bookmarks/command_manager.html index c5e38f8..12447ac7 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.html +++ b/chrome/browser/resources/md_bookmarks/command_manager.html
@@ -57,7 +57,7 @@ </cr-lazy-render> <cr-lazy-render id="openDialog"> <template> - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">$i18n{openDialogTitle}</div> <div slot="body"></div> <div slot="button-container"> @@ -68,7 +68,7 @@ $i18n{openDialogConfirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> </cr-lazy-render> </template>
diff --git a/chrome/browser/resources/md_bookmarks/edit_dialog.html b/chrome/browser/resources/md_bookmarks/edit_dialog.html index 2be1feb..1fc0ecd 100644 --- a/chrome/browser/resources/md_bookmarks/edit_dialog.html +++ b/chrome/browser/resources/md_bookmarks/edit_dialog.html
@@ -11,7 +11,7 @@ <dom-module id="bookmarks-edit-dialog"> <template> <style include="cr-shared-style paper-button-style"></style> - <dialog is="cr-dialog" id="dialog"> + <cr-dialog id="dialog"> <div slot="title"> [[getDialogTitle_(isFolder_, isEdit_)]] </div> @@ -39,7 +39,7 @@ $i18n{saveEdit} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="chrome://bookmarks/edit_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_extensions/compiled_resources2.gyp b/chrome/browser/resources/md_extensions/compiled_resources2.gyp index 39b6a26..dec283f 100644 --- a/chrome/browser/resources/md_extensions/compiled_resources2.gyp +++ b/chrome/browser/resources/md_extensions/compiled_resources2.gyp
@@ -147,6 +147,7 @@ { 'target_name': 'load_error', 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(EXTERNS_GYP):developer_private', @@ -187,6 +188,7 @@ { 'target_name': 'options_dialog', 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(EXTERNS_GYP):developer_private', @@ -204,6 +206,16 @@ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'pack_dialog_alert', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(EXTERNS_GYP):developer_private', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'service', 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
diff --git a/chrome/browser/resources/md_extensions/install_warnings_dialog.html b/chrome/browser/resources/md_extensions/install_warnings_dialog.html index 286b25e5..b65e209 100644 --- a/chrome/browser/resources/md_extensions/install_warnings_dialog.html +++ b/chrome/browser/resources/md_extensions/install_warnings_dialog.html
@@ -20,7 +20,7 @@ padding-top: 10px; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{installWarnings}</div> <div slot="body"> <ul> @@ -34,7 +34,7 @@ $i18n{ok} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="install_warnings_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_extensions/kiosk_dialog.html b/chrome/browser/resources/md_extensions/kiosk_dialog.html index e85ab696..5fe53138 100644 --- a/chrome/browser/resources/md_extensions/kiosk_dialog.html +++ b/chrome/browser/resources/md_extensions/kiosk_dialog.html
@@ -75,7 +75,7 @@ visibility: visible; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}" + <cr-dialog id="dialog" close-text="$i18n{close}" ignore-enter-key> <div slot="title">$i18n{manageKioskApp}</div> <div slot="body"> @@ -131,8 +131,8 @@ $i18n{done} </paper-button> </div> - </dialog> - <dialog is="cr-dialog" id="confirm-dialog" close-text="$i18n{close}" + </cr-dialog> + <cr-dialog id="confirm-dialog" close-text="$i18n{close}" ignore-enter-key on-close="stopPropagation_"> <div slot="title">$i18n{kioskDisableBailoutWarningTitle}</div> <div slot="body">$i18n{kioskDisableBailoutWarningBody}</div> @@ -146,7 +146,7 @@ $i18n{confirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="kiosk_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_extensions/load_error.html b/chrome/browser/resources/md_extensions/load_error.html index 10080e15..32693f9 100644 --- a/chrome/browser/resources/md_extensions/load_error.html +++ b/chrome/browser/resources/md_extensions/load_error.html
@@ -21,7 +21,7 @@ width: 104px; /* Magic number from the specs. */ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{loadErrorHeading}</div> <div slot="body"> <div id="info"> @@ -48,7 +48,7 @@ $i18n{loadErrorRetry} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="load_error.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_extensions/load_error.js b/chrome/browser/resources/md_extensions/load_error.js index 8c22a6b..be8d902 100644 --- a/chrome/browser/resources/md_extensions/load_error.js +++ b/chrome/browser/resources/md_extensions/load_error.js
@@ -33,11 +33,11 @@ ], show: function() { - this.$$('dialog').showModal(); + /** @type {!CrDialogElement} */ (this.$.dialog).showModal(); }, close: function() { - this.$$('dialog').close(); + /** @type {!CrDialogElement} */ (this.$.dialog).close(); }, /** @private */
diff --git a/chrome/browser/resources/md_extensions/options_dialog.html b/chrome/browser/resources/md_extensions/options_dialog.html index 524b35a..76b427a 100644 --- a/chrome/browser/resources/md_extensions/options_dialog.html +++ b/chrome/browser/resources/md_extensions/options_dialog.html
@@ -26,7 +26,7 @@ overflow: hidden; } - dialog { + cr-dialog { --scroll-border: 0; --cr-dialog-body: { height: 100%; @@ -47,7 +47,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}" + <cr-dialog id="dialog" close-text="$i18n{close}" on-close="onClose_"> <div slot="title"> <div id="icon-and-name-wrapper"> @@ -61,7 +61,7 @@ </div> <div slot="body" id="body"> </div> - </dialog> + </cr-dialog> </template> <script src="options_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_extensions/options_dialog.js b/chrome/browser/resources/md_extensions/options_dialog.js index e5dbb639..9c2cc23 100644 --- a/chrome/browser/resources/md_extensions/options_dialog.js +++ b/chrome/browser/resources/md_extensions/options_dialog.js
@@ -24,6 +24,12 @@ }); } + // The minimum width in pixels for the options dialog. + const MIN_WIDTH = 400; + + // The maximum height in pixels for the options dialog. + const MAX_HEIGHT = 640; + const OptionsDialog = Polymer({ is: 'extensions-options-dialog', @@ -41,21 +47,27 @@ boundResizeListener_: null, get open() { - return this.$$('dialog').open; + return /** @type {!CrDialogElement} */ (this.$.dialog).open; }, /** * Resizes the dialog to the given width/height, taking into account the * window width/height. - * @param {number} width - * @param {number} height + * @param {number} width The desired height of the dialog contents. + * @param {number} height The desired width of the dialog contents. * @private */ updateDialogSize_: function(width, height) { - const effectiveHeight = Math.min(window.innerHeight, height); - const effectiveWidth = Math.min(window.innerWidth, width); - this.$.dialog.style.height = effectiveHeight + 'px'; - this.$.dialog.style.width = effectiveWidth + 'px'; + const HEADER_HEIGHT = 64; + const maxHeight = Math.min(0.9 * window.innerHeight, MAX_HEIGHT); + const effectiveHeight = Math.min(maxHeight, HEADER_HEIGHT + height); + const effectiveWidth = Math.max(MIN_WIDTH, width); + + // Get a reference to the inner native <dialog>. + const nativeDialog = + /** @type {!CrDialogElement} */ (this.$.dialog).getNative(); + nativeDialog.style.height = `${effectiveHeight}px`; + nativeDialog.style.width = `${effectiveWidth}px`; }, /** @param {chrome.developerPrivate.ExtensionInfo} data */ @@ -71,7 +83,7 @@ const onSizeChanged = e => { preferredSize = e; this.updateDialogSize_(preferredSize.width, preferredSize.height); - this.$$('dialog').showModal(); + this.$.dialog.showModal(); this.extensionOptions_.onpreferredsizechanged = null; }; @@ -91,7 +103,7 @@ }, close: function() { - this.$$('dialog').close(); + /** @type {!CrDialogElement} */ (this.$.dialog).close(); this.extensionOptions_.onpreferredsizechanged = null; }, @@ -117,5 +129,9 @@ }, }); - return {OptionsDialog: OptionsDialog}; + return { + OptionsDialog: OptionsDialog, + OptionsDialogMinWidth: MIN_WIDTH, + OptionsDialogMaxHeight: MAX_HEIGHT, + }; });
diff --git a/chrome/browser/resources/md_extensions/pack_dialog.html b/chrome/browser/resources/md_extensions/pack_dialog.html index e984b8565..ce51758 100644 --- a/chrome/browser/resources/md_extensions/pack_dialog.html +++ b/chrome/browser/resources/md_extensions/pack_dialog.html
@@ -28,7 +28,7 @@ color: var(--google-blue-500); } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{packDialogTitle}</div> <div slot="body"> <div>$i18n{packDialogContent}</div> @@ -58,7 +58,7 @@ $i18n{packDialogConfirm} </paper-button> </div> - </dialog> + </cr-dialog> <template is="dom-if" if="[[lastResponse_]]" restamp> <extensions-pack-dialog-alert model="[[lastResponse_]]" on-close="onAlertClose_">
diff --git a/chrome/browser/resources/md_extensions/pack_dialog_alert.html b/chrome/browser/resources/md_extensions/pack_dialog_alert.html index ebf69a9..79fa1a74 100644 --- a/chrome/browser/resources/md_extensions/pack_dialog_alert.html +++ b/chrome/browser/resources/md_extensions/pack_dialog_alert.html
@@ -16,7 +16,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div class="title" slot="title">[[title_]]</div> <!-- No whitespace or new-lines allowed within the div.body tag. --> <div class="body" slot="body">[[model.message]]</div> @@ -30,7 +30,7 @@ [[confirmLabel_]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="pack_dialog_alert.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_extensions/pack_dialog_alert.js b/chrome/browser/resources/md_extensions/pack_dialog_alert.js index 7c3e475..9b33668 100644 --- a/chrome/browser/resources/md_extensions/pack_dialog_alert.js +++ b/chrome/browser/resources/md_extensions/pack_dialog_alert.js
@@ -17,12 +17,12 @@ /** @private */ message_: String, - /** @private */ + /** @private {?string} */ cancelLabel_: String, /** * This needs to be initialized to trigger data-binding. - * @private + * @private {?string} */ confirmLabel_: { type: String, @@ -32,7 +32,9 @@ /** @return {string} */ get returnValue() { - return this.$.dialog.returnValue; + return /** @type {!CrDialogElement} */ (this.$.dialog) + .getNative() + .returnValue; }, /** @override */
diff --git a/chrome/browser/resources/md_history/history_list.html b/chrome/browser/resources/md_history/history_list.html index 5a86619..dae8f5e 100644 --- a/chrome/browser/resources/md_history/history_list.html +++ b/chrome/browser/resources/md_history/history_list.html
@@ -60,7 +60,7 @@ <cr-lazy-render id="dialog"> <template> - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">$i18n{removeSelected}</div> <div slot="body">$i18n{deleteWarning}</div> <div slot="button-container"> @@ -71,7 +71,7 @@ $i18n{deleteConfirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> </cr-lazy-render>
diff --git a/chrome/browser/resources/md_user_manager/error_dialog.html b/chrome/browser/resources/md_user_manager/error_dialog.html index a55ec1bf..9cae3a5 100644 --- a/chrome/browser/resources/md_user_manager/error_dialog.html +++ b/chrome/browser/resources/md_user_manager/error_dialog.html
@@ -16,11 +16,11 @@ word-wrap: break-word; } </style> - <dialog is="cr-dialog" id="dialog"> + <cr-dialog id="dialog"> <div slot="body"> <div id="message">[[message_]]</div> </div> - </dialog> + </cr-dialog> </template> <script src="error_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_user_manager/import_supervised_user.html b/chrome/browser/resources/md_user_manager/import_supervised_user.html index b308c93..73b108c 100644 --- a/chrome/browser/resources/md_user_manager/import_supervised_user.html +++ b/chrome/browser/resources/md_user_manager/import_supervised_user.html
@@ -62,7 +62,7 @@ flex-shrink: 0; } </style> - <dialog is="cr-dialog" id="dialog"> + <cr-dialog id="dialog"> <div slot="title">$i18n{supervisedUserImportTitle}</div> <div slot="body"> <div id="message">$i18n{supervisedUserImportText}</div> @@ -88,7 +88,7 @@ $i18n{supervisedUserImportOk} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="import_supervised_user.js"></script> </dom-module>
diff --git a/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html b/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html index 6844a00..b5032db 100644 --- a/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html +++ b/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html
@@ -6,7 +6,7 @@ <dom-module id="viewer-error-screen"> <template> <style include="cr-shared-style"></style> - <dialog is="cr-dialog" id="dialog" no-cancel> + <cr-dialog id="dialog" no-cancel> <div slot="title"> [[strings.errorDialogTitle]] </div> @@ -18,7 +18,7 @@ [[strings.pageReload]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="viewer-error-screen.js"></script> </dom-module>
diff --git a/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html b/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html index 485a061..8259dac 100644 --- a/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html +++ b/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html
@@ -15,7 +15,7 @@ }; } </style> - <dialog is="cr-dialog" id="dialog" no-cancel> + <cr-dialog id="dialog" no-cancel> <div slot="title">[[strings.passwordDialogTitle]]</div> <div slot="body"> <div id="message">[[strings.passwordPrompt]]</div> @@ -32,7 +32,7 @@ [[strings.passwordSubmit]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="viewer-password-screen.js"></script> </dom-module>
diff --git a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html index 91e920b53..bc4b5856 100644 --- a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html +++ b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html
@@ -14,7 +14,7 @@ <style include="print-preview-shared search-dialog button cr-hidden-style"> </style> <template> - <dialog is="cr-dialog" id="dialog" on-close="onCloseOrCancel_"> + <cr-dialog id="dialog" on-close="onCloseOrCancel_"> <div slot="title"> <div>[[i18n('advancedSettingsDialogTitle', destination.displayName)]] </div> @@ -41,7 +41,7 @@ $i18n{advancedSettingsDialogConfirm} </button> </div> - </dialog> + </cr-dialog> </template> <script src="advanced_settings_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/print_preview/new/destination_dialog.html b/chrome/browser/resources/print_preview/new/destination_dialog.html index 380dc64..e740071 100644 --- a/chrome/browser/resources/print_preview/new/destination_dialog.html +++ b/chrome/browser/resources/print_preview/new/destination_dialog.html
@@ -20,7 +20,11 @@ <template> <style include="print-preview-shared button action-link select cr-hidden-style search-dialog throbber"> :host #dialog { - width: 640px; + --cr-dialog-native: { + box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), + 0 2px 6px rgba(0, 0, 0, 0.15); + width: 640px; + } } :host .user-info { @@ -95,7 +99,7 @@ -webkit-margin-start: 10px; } </style> - <dialog is="cr-dialog" id="dialog" on-close="onCloseOrCancel_"> + <cr-dialog id="dialog" on-close="onCloseOrCancel_"> <div slot="title"> <div>$i18n{destinationSearchTitle}</div> <div class="user-info" hidden$="[[!userInfo.loggedIn]]"> @@ -160,7 +164,7 @@ </div> </div> </div> - </dialog> + </cr-dialog> </template> <script src="destination_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/print_preview/new/search_dialog_css.html b/chrome/browser/resources/print_preview/new/search_dialog_css.html index 6ec2597..90db69a 100644 --- a/chrome/browser/resources/print_preview/new/search_dialog_css.html +++ b/chrome/browser/resources/print_preview/new/search_dialog_css.html
@@ -8,31 +8,32 @@ <dom-module id="search-dialog"> <template> <style include="print-preview-shared button"> - #dialog::backdrop { - background-color: rgba(255, 255, 255, 0.75); - } - #dialog { + /* TODO(dpapad): Figure out how to specify + background-color: rgba(255, 255, 255, 0.75) for the inner dialog's + backdrop. See context at crbug.com/827397 */ --cr-dialog-close-image: { background-image: url(chrome://theme/IDR_CLOSE_DIALOG); - } + }; --cr-dialog-close-image-active: { background-image: url(chrome://theme/IDR_CLOSE_DIALOG_P); - } + }; --cr-dialog-close-image-hover: { background-image: url(chrome://theme/IDR_CLOSE_DIALOG_H); - } + }; + --cr-dialog-native: { + box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), + 0 2px 6px rgba(0, 0, 0, 0.15); + }; --cr-icon-ripple-size: 0; --cr-icon-size: 14px; --cr-dialog-body: { box-sizing: border-box; padding-top: 0; - } + }; --cr-dialog-wrapper: { max-height: calc(100vh - 40px); - } - box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), - 0 2px 6px rgba(0, 0, 0, 0.15); + }; } #searchBox {
diff --git a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html index 70cbc55e..32ef3ea 100644 --- a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html +++ b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
@@ -15,7 +15,7 @@ display: none; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{aboutChangeChannel}</div> <div slot="body"> <!-- TODO(dbeam): this can be policy-controlled. Show this in the UI. @@ -66,7 +66,7 @@ $i18n{aboutChangeChannelAndPowerwash} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="channel_switcher_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/about_page/update_warning_dialog.html b/chrome/browser/resources/settings/about_page/update_warning_dialog.html index e6dd4ab..73621cfe 100644 --- a/chrome/browser/resources/settings/about_page/update_warning_dialog.html +++ b/chrome/browser/resources/settings/about_page/update_warning_dialog.html
@@ -9,7 +9,7 @@ <dom-module id="settings-update-warning-dialog"> <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{aboutUpdateWarningTitle}</div> <div slot="body"> <div id="update-warning-message"></div> @@ -22,7 +22,7 @@ $i18n{aboutUpdateWarningContinue} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="update_warning_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html b/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html index 8f2d54ad..8041f79 100644 --- a/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html +++ b/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> @@ -30,7 +31,7 @@ </template> <!-- Confirm disable android apps dialog --> - <dialog is="cr-dialog" id="confirmDisableDialog" close-text="$i18n{close}" + <cr-dialog id="confirmDisableDialog" close-text="$i18n{close}" on-cancel="onConfirmDisableDialogCancel_" on-close="onConfirmDisableDialogClose_"> <div slot="title">$i18n{androidAppsDisableDialogTitle}</div> @@ -45,7 +46,7 @@ $i18n{androidAppsDisableDialogRemove} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="android_apps_subpage.js"></script>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js index 0278e40..9e1869e 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -170,15 +170,34 @@ * sections. * @param {string} query The text to search for. * @return {!Promise<!settings.SearchResult>} A signal indicating that - * searching finished. + * searching finished. */ searchContents: function(query) { - const nodes = [assert(this.$$('#basicPage'))]; - if (this.pageVisibility.advancedSettings !== false) - nodes.push(this.$$('#advancedPageTemplate').get()); + const whenSearchDone = [ + settings.getSearchManager().search(query, assert(this.$$('#basicPage'))), + ]; - return Promise.all(nodes).then( - nodes => settings.getSearchManager().search(query, nodes)); + if (this.pageVisibility.advancedSettings !== false) { + whenSearchDone.push( + this.$$('#advancedPageTemplate').get().then(function(advancedPage) { + return settings.getSearchManager().search(query, advancedPage); + })); + } + + return Promise.all(whenSearchDone).then(function(requests) { + // Combine the SearchRequests results to a single SearchResult object. + return { + canceled: requests.some(function(r) { + return r.canceled; + }), + didFindMatches: requests.some(function(r) { + return r.didFindMatches(); + }), + // All requests correspond to the same user query, so only need to check + // one of them. + wasClearSearch: requests[0].isSame(''), + }; + }); }, // <if expr="chromeos">
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html index dbbc94a3..40e0062a 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html
@@ -114,7 +114,7 @@ } </style> - <dialog is="cr-dialog" id="clearBrowsingDataDialog" + <cr-dialog id="clearBrowsingDataDialog" on-close="onClearBrowsingDataDialogClose_" close-text="$i18n{close}" ignore-popstate has-tabs> <div slot="title"> @@ -259,10 +259,10 @@ $i18n{clearData} </paper-button> </div> - </dialog> + </cr-dialog> <template is="dom-if" if="[[showImportantSitesDialog_]]"> - <dialog is="cr-dialog" id="importantSitesDialog" close-text="$i18n{close}" + <cr-dialog id="importantSitesDialog" close-text="$i18n{close}" show-scroll-borders ignore-popstate> <div slot="title"> $i18n{clearBrowsingData} @@ -296,7 +296,7 @@ $i18n{importantSitesConfirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> <template is="dom-if" if="[[showHistoryDeletionDialog_]]" restamp>
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html b/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html index 52429899..5ca1761 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html
@@ -7,7 +7,7 @@ <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{historyDeletionDialogTitle}</div> <div slot="body">$i18nRaw{historyDeletionDialogBody}</div> <div slot="button-container"> @@ -15,7 +15,7 @@ $i18n{historyDeletionDialogOK} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="history_deletion_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/device_page/display_overscan_dialog.html b/chrome/browser/resources/settings/device_page/display_overscan_dialog.html index 5c90de1c..c5b2d74 100644 --- a/chrome/browser/resources/settings/device_page/display_overscan_dialog.html +++ b/chrome/browser/resources/settings/device_page/display_overscan_dialog.html
@@ -43,7 +43,7 @@ padding: 4px 8px 0; } </style> - <dialog is="cr-dialog" id="dialog" on-close="close" + <cr-dialog id="dialog" on-close="close" close-text="$i18n{close}"> <div slot="title">$i18n{displayOverscanPageTitle}</div> <div slot="body"> @@ -81,7 +81,7 @@ $i18n{ok} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="display_overscan_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/device_page/drive_cache_dialog.html b/chrome/browser/resources/settings/device_page/drive_cache_dialog.html index d111fcf..c493176b 100644 --- a/chrome/browser/resources/settings/device_page/drive_cache_dialog.html +++ b/chrome/browser/resources/settings/device_page/drive_cache_dialog.html
@@ -8,7 +8,7 @@ <dom-module id="settings-drive-cache-dialog"> <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title"> $i18n{storageClearDriveCacheDialogTitle} </div> @@ -25,7 +25,7 @@ $i18n{storageDeleteAllButtonTitle} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="drive_cache_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_page.html b/chrome/browser/resources/settings/downloads_page/downloads_page.html index 6e293c5..089b55a 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_page.html +++ b/chrome/browser/resources/settings/downloads_page/downloads_page.html
@@ -24,7 +24,7 @@ <div class="settings-box first two-line"> <div class="start"> <div>$i18n{downloadLocation}</div> - <div class="secondary"> + <div class="secondary" no-search> <if expr="not chromeos"> [[prefs.download.default_directory.value]] </if>
diff --git a/chrome/browser/resources/settings/internet_page/internet_config.html b/chrome/browser/resources/settings/internet_page/internet_config.html index fce0c7e..8e2b173 100644 --- a/chrome/browser/resources/settings/internet_page/internet_config.html +++ b/chrome/browser/resources/settings/internet_page/internet_config.html
@@ -11,8 +11,10 @@ <dom-module id="internet-config"> <template> <style include="internet-shared iron-flex"> - dialog { - width: 460px; + cr-dialog { + --cr-dialog-native: { + width: 460px; + }; } .error { @@ -21,7 +23,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[getDialogTitle_(networkProperties_)]]</div> <div slot="body"> <network-config id="networkConfig" class="flex" @@ -57,7 +59,7 @@ </template> </div> - </dialog> + </cr-dialog> </template> <script src="internet_config.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy_section.html b/chrome/browser/resources/settings/internet_page/network_proxy_section.html index 7aa2e64..146da4c1 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy_section.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy_section.html
@@ -77,7 +77,7 @@ </div> <!-- Confirm Allow shared proxies dialog --> - <dialog is="cr-dialog" id="confirmAllowSharedDialog" + <cr-dialog id="confirmAllowSharedDialog" close-text="$i18n{close}" on-cancel="onAllowSharedDialogCancel_" on-close="onAllowSharedDialogClose_"> <div slot="title"> @@ -98,7 +98,7 @@ $i18n{confirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="network_proxy_section.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html b/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html index c54c5c1..2a305ca 100644 --- a/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html +++ b/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html
@@ -66,7 +66,7 @@ font-weight: 500; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{tetherConnectionDialogTitle}</div> <div slot="body"> <span id="availability-title"> @@ -116,7 +116,7 @@ $i18n{tetherConnectionConnectButton} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="tether_connection_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/languages_page/add_languages_dialog.html b/chrome/browser/resources/settings/languages_page/add_languages_dialog.html index a3f6edd..e143de5 100644 --- a/chrome/browser/resources/settings/languages_page/add_languages_dialog.html +++ b/chrome/browser/resources/settings/languages_page/add_languages_dialog.html
@@ -39,7 +39,7 @@ } } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{addLanguagesDialogTitle}</div> <div slot="body" scrollable> <settings-subpage-search label="[[searchLabel]]" @@ -67,7 +67,7 @@ $i18n{add} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="add_languages_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html index 313bdf7a..fb74c039 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html +++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html
@@ -9,7 +9,7 @@ <dom-module id="settings-startup-url-dialog"> <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[dialogTitle_]]</div> <div slot="body"> <paper-input always-float-label id="url" label="$i18n{onStartupSiteUrl}" @@ -26,7 +26,7 @@ <paper-button id="actionButton" class="action-button" on-click="onActionButtonTap_">[[actionButtonText_]]</paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="startup_url_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html index 8d6515df..539781b 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html
@@ -92,7 +92,7 @@ transform: translate3d(0, 0, 0); } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[title_]]</div> <div slot="body"> <template is="dom-repeat" items="[[addressWrapper_]]"> @@ -152,7 +152,7 @@ $i18n{save} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="address_edit_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp b/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp index 92e674c..8f16bb2 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/passwords_and_forms_page/compiled_resources2.gyp
@@ -52,6 +52,7 @@ 'target_name': 'password_list_item', 'dependencies': [ '../compiled_resources2.gyp:focus_row_behavior', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', 'show_password_behavior', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.html index 6465c600..9a522be 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.html
@@ -49,7 +49,7 @@ padding-top: 8px; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[title_]]</div> <div slot="body"> <paper-input id="nameInput" label="$i18n{creditCardName}" @@ -93,7 +93,7 @@ <paper-button id="saveButton" class="action-button" on-click="onSaveButtonTap_" disabled>$i18n{save}</paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="credit_card_edit_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html index 89ad315..05d713e 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
@@ -40,7 +40,7 @@ background-size: 24px; /* Other buttons are sized by --cr-icon-size. */ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{passwordDetailsTitle}</div> <div slot="body"> <paper-input id="websiteInput" label="$i18n{editPasswordWebsiteLabel}" @@ -75,7 +75,7 @@ $i18n{done} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="password_edit_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.html b/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.html index 126b704..e83c9d5 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.html
@@ -74,7 +74,8 @@ <button id="passwordMenu" on-click="onPasswordMenuTap_" title="$i18n{moreActions}" focus-row-control - focus-type="passwordMenu"> + focus-type="passwordMenu" + aria-label$="[[getMoreActionsLabel_(item)]]"> </button> </paper-icon-button-light> </div>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.js b/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.js index 8b2b619f..9a317f0 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.js +++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.js
@@ -29,4 +29,22 @@ this.fire( 'password-menu-tap', {target: this.$.passwordMenu, listItem: this}); }, + + /** + * Get the aria label for the More Actions button on this row. + * @param {{ + * entry: !chrome.passwordsPrivate.PasswordUiEntry, + * password: string + * }} item This row's item. + * @private + */ + getMoreActionsLabel_: function(item) { + // Avoid using I18nBehavior.i18n, because it will filter sequences, which + // are otherwise not illegal for usernames. Polymer still protects against + // XSS injection. + return loadTimeData.getStringF( + (item.entry.federationText) ? 'passwordRowFederatedMoreActionsButton' : + 'passwordRowMoreActionsButton', + item.entry.loginPair.username, item.entry.loginPair.urls.shown); + }, });
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html index 2cfe136..33e3643 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html
@@ -16,7 +16,7 @@ -webkit-margin-start: 8px; } </style> - <dialog is="cr-dialog" id="dialog_start" close-text="$i18n{close}"> + <cr-dialog id="dialog_start" close-text="$i18n{close}"> <div slot="title">$i18n{exportPasswordsTitle}</div> <div slot="body"> <div class="layout horizontal center"> @@ -33,9 +33,9 @@ $i18n{exportPasswords} </paper-button> </div> - </dialog> + </cr-dialog> - <dialog is="cr-dialog" id="dialog_progress" no-cancel="true"> + <cr-dialog id="dialog_progress" no-cancel="true"> <div slot="title">$i18n{exportingPasswordsTitle}</div> <div slot="body"> <paper-progress indeterminate class="blue"></paper-progress> @@ -47,9 +47,9 @@ $i18n{cancel} </paper-button> </div> - </dialog> + </cr-dialog> - <dialog is="cr-dialog" id="dialog_error" close-text="$i18n{close}"> + <cr-dialog id="dialog_error" close-text="$i18n{close}"> <div slot="title">[[exportErrorMessage]]</div> <div slot="body"> $i18n{exportPasswordsFailTips} @@ -68,7 +68,7 @@ $i18n{exportPasswordsTryAgain} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="passwords_export_dialog.js"></script>
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html index 147f3ecf..eaee130 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html
@@ -84,7 +84,9 @@ <span>$i18nRaw{managePasswordsLabel}</span> </div> <div class="settings-box first"> - <h2 class="start">$i18n{savedPasswordsHeading}</h2> + <h2 id="savedPasswordsHeading" class="start"> + $i18n{savedPasswordsHeading} + </h2> <template is="dom-if" if="[[showImportOrExportPasswords_( showExportPasswords_, showImportPasswords_)]]"> @@ -92,7 +94,8 @@ class="icon-more-vert"> <button id="exportImportMenuButton" on-click="onImportExportMenuTap_" - title="$i18n{moreActions}" focus-type="exportImportMenuButton"> + title="$i18n{moreActions}" focus-type="exportImportMenuButton" + aria-describedby="savedPasswordsHeading"> </button> </paper-icon-button-light> </template>
diff --git a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp index 3c72741d..f64ad71 100644 --- a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp
@@ -203,6 +203,7 @@ '../compiled_resources2.gyp:route', '../settings_page/compiled_resources2.gyp:settings_animated_pages', '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted', + '<(DEPTH)/ui/webui/resources/cr_elements/cr_expand_button/compiled_resources2.gyp:cr_expand_button', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior',
diff --git a/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html b/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html index dd65510..df78b847 100644 --- a/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html +++ b/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html
@@ -12,7 +12,7 @@ <dom-module id="easy-unlock-turn-off-dialog"> <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[getTitleText_(status_)]]</div> <div slot="body"> [[getDescriptionText_(status_)]] @@ -31,7 +31,7 @@ [[getTurnOffButtonText_(status_)]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="easy_unlock_turn_off_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/people_page/import_data_dialog.html b/chrome/browser/resources/settings/people_page/import_data_dialog.html index cb07d33..395da90 100644 --- a/chrome/browser/resources/settings/people_page/import_data_dialog.html +++ b/chrome/browser/resources/settings/people_page/import_data_dialog.html
@@ -35,7 +35,7 @@ width: 100%; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}" + <cr-dialog id="dialog" close-text="$i18n{close}" ignore-popstate> <div slot="title">$i18n{importTitle}</div> <div slot="body"> @@ -121,7 +121,7 @@ importStatusEnum_.SUCCEEDED, importStatus_)]]" on-click="closeDialog_">$i18n{done}</paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="import_data_dialog.js"></script> :</dom-module>
diff --git a/chrome/browser/resources/settings/people_page/password_prompt_dialog.html b/chrome/browser/resources/settings/people_page/password_prompt_dialog.html index 3a5e4b6..0aafe38 100644 --- a/chrome/browser/resources/settings/people_page/password_prompt_dialog.html +++ b/chrome/browser/resources/settings/people_page/password_prompt_dialog.html
@@ -18,7 +18,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{passwordPromptTitle}</div> <div slot="body"> @@ -42,7 +42,7 @@ $i18n{confirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="password_prompt_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html index ee0dead..2adc21a 100644 --- a/chrome/browser/resources/settings/people_page/people_page.html +++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -67,11 +67,16 @@ --iron-icon-fill-color: var(--settings-error-color); } + #sync-status[actionable].auth-error + iron-icon[icon='settings:sync-disabled'] { + --iron-icon-fill-color: var(--google-blue-500); + } + #sync-status:not([actionable]) .subpage-arrow { display: none; } - .settings-box[actionable] .sync-error { + .settings-box[actionable].sync-error #syncSecondary { color: var(--settings-error-color); } @@ -212,17 +217,17 @@ <template is="dom-if" if="[[isAdvancedSyncSettingsVisible_( syncStatus, unifiedConsentEnabled_)]]"> - <div class="settings-box two-line" on-click="onSyncTap_" - id="sync-status" actionable$="[[isSyncStatusActionable_( - syncStatus)]]"> + <div class$="settings-box two-line + [[getSyncStatusClass_(syncStatus)]]" + on-click="onSyncTap_" id="sync-status" + actionable$="[[isSyncStatusActionable_(syncStatus)]]"> <div class="icon-container"> <iron-icon id="sync-icon" icon$="[[getSyncIcon_(syncStatus)]]"> </iron-icon> </div> <div class="middle"> $i18n{sync} - <div class$="secondary [[getSyncStatusTextClass_(syncStatus)]]" - id="syncSecondary"> + <div class="secondary" id="syncSecondary"> [[syncStatus.statusText]] </div> </div> @@ -355,7 +360,7 @@ </settings-animated-pages> <template is="dom-if" if="[[showDisconnectDialog_]]" restamp> - <dialog is="cr-dialog" id="disconnectDialog" + <cr-dialog id="disconnectDialog" ignore-popstate ignore-enter-key on-close="onDisconnectClosed_" close-text="$i18n{close}"> <div slot="title">$i18n{syncDisconnectTitle}</div> @@ -398,7 +403,7 @@ </div> </template> </if> - </dialog> + </cr-dialog> </template> <template is="dom-if" if="[[showImportDataDialog_]]" restamp>
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index 3fa0504..1d82cce 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -487,7 +487,8 @@ syncIcon = 'settings:sync-problem'; // Override the icon to the disabled icon if sync is managed. - if (syncStatus.managed) + if (syncStatus.managed || + syncStatus.statusAction == settings.StatusAction.REAUTHENTICATE) syncIcon = 'settings:sync-disabled'; return syncIcon; @@ -496,10 +497,18 @@ /** * @private * @param {?settings.SyncStatus} syncStatus - * @return {string} The class name for the sync status text. + * @return {string} The class name for the sync status row. */ - getSyncStatusTextClass_: function(syncStatus) { - return (!!syncStatus && syncStatus.hasError) ? 'sync-error' : ''; + getSyncStatusClass_: function(syncStatus) { + if (syncStatus && syncStatus.hasError) { + // Most of the time re-authenticate states are caused by intentional user + // action, so they will be displayed differently as other errors. + return syncStatus.statusAction == settings.StatusAction.REAUTHENTICATE ? + 'auth-error' : + 'sync-error'; + } + + return ''; }, /**
diff --git a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html index 7e005111..60c3e30 100644 --- a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html +++ b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> @@ -20,8 +21,10 @@ } #dialog { - min-width: 500px; - width: 500px; + --cr-dialog-native: { + min-width: 500px; + width: 500px; + }; } #image { @@ -52,7 +55,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" on-close="close" + <cr-dialog id="dialog" on-close="close" close-text="$i18n{close}"> <div slot="title">$i18n{configureFingerprintTitle}</div> <div slot="body"> @@ -82,7 +85,7 @@ [[getCloseButtonText_(step_)]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="setup_fingerprint_dialog.js"></script>
diff --git a/chrome/browser/resources/settings/people_page/setup_pin_dialog.html b/chrome/browser/resources/settings/people_page/setup_pin_dialog.html index 7cffa7ec..61c3c8e7 100644 --- a/chrome/browser/resources/settings/people_page/setup_pin_dialog.html +++ b/chrome/browser/resources/settings/people_page/setup_pin_dialog.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> @@ -50,7 +51,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" on-close="close" + <cr-dialog id="dialog" on-close="close" close-text="$i18n{close}"> <div slot="title">[[getTitleMessage_(isConfirmStep_)]]</div> <div slot="body"> @@ -78,7 +79,7 @@ <span>[[getContinueMessage_(isConfirmStep_)]]</span> </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="setup_pin_dialog.js"></script>
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html index 78658e4..3bf5636 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -58,7 +58,7 @@ #sync-icon-container { align-items: center; - background: var(--google-blue-500); + background: var(--google-green-700); border: var(--sync-icon-border-size) solid white; border-radius: 50%; display: flex; @@ -75,12 +75,12 @@ right: initial; } - #sync-icon-container[signed-in] { - background: green; + #sync-icon-container.sync-problem { + background: var(--settings-error-color); } - #sync-icon-container[signed-in][has-error] { - background: var(--settings-error-color); + #sync-icon-container.sync-disabled { + background: var(--google-blue-500); } #sync-icon-container iron-icon { @@ -147,9 +147,11 @@ <div id="avatar-container"> <img class="account-icon" alt="" src="[[getAccountImageSrc_(shownAccount_.avatarImage)]]"> - <div id="sync-icon-container" signed-in$="[[syncStatus.signedIn]]" - has-error$="[[syncStatus.hasError]]"> - <iron-icon icon="[[getSyncIcon_(syncStatus.hasError)]]"></iron-icon> + <div id="sync-icon-container" hidden="[[!syncStatus.signedIn]]" + class$="[[getSyncIcon_( + syncStatus.hasError, syncStatus.statusAction)]]"> + <iron-icon icon$="settings:[[getSyncIcon_( + syncStatus.hasError, syncStatus.statusAction)]]"></iron-icon> </div> </div> <div class="middle two-line no-min-width"> @@ -157,7 +159,7 @@ <span> [[getNameDisplay_('$i18nPolymer{syncedToName}', shownAccount_.fullName, '$i18nPolymer{syncNotWorking}', - syncStatus)]] + '$i18nPolymer{syncPaused}', syncStatus)]] </span> <div class="secondary">[[shownAccount_.email]]</div> </div>
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.js b/chrome/browser/resources/settings/people_page/sync_account_control.js index fd6e8b7d..b898765 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.js +++ b/chrome/browser/resources/settings/people_page/sync_account_control.js
@@ -111,12 +111,20 @@ /** * @param {string} label * @param {string} name + * @param {string} syncErrorLabel + * @param {string} authErrorLabel * @return {string} * @private */ - getNameDisplay_: function(label, name, errorLabel) { - if (this.syncStatus.hasError === true) - return errorLabel; + getNameDisplay_: function(label, name, syncErrorLabel, authErrorLabel) { + if (this.syncStatus.hasError) { + // Most of the time re-authenticate states are caused by intentional user + // action, so they will be displayed differently as other errors. + return this.syncStatus.statusAction == + settings.StatusAction.REAUTHENTICATE ? + authErrorLabel : + syncErrorLabel; + } return this.syncStatus.signedIn ? loadTimeData.substituteString(label, name) : @@ -134,11 +142,19 @@ }, /** + * Returned value must match one of iron-icon's settings:(*) icon name. * @return {string} * @private */ getSyncIcon_: function() { - return this.syncStatus.hasError ? 'settings:sync-problem' : 'settings:sync'; + if (this.syncStatus.hasError) { + return this.syncStatus.statusAction == + settings.StatusAction.REAUTHENTICATE ? + 'sync-disabled' : + 'sync-problem'; + } + + return 'sync'; }, /**
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index 34b019e..ee01bc3b 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -3,7 +3,9 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> @@ -65,6 +67,10 @@ border-top: var(--settings-separator-line); } + #other-sync-items > .list-item { + border-top: var(--settings-separator-line); + } + <if expr="not chromeos"> #toast { color: white; @@ -99,280 +105,309 @@ </settings-sync-account-control> </template> </if> - <div id="[[pages_.SPINNER]]" class="settings-box first" - hidden$="[[!isStatus_(pages_.SPINNER, pageStatus_)]]"> - $i18n{syncLoading} + <div class="settings-box first two-line" id="sync-section-toggle" + actionable$="[[!syncSectionDisabled_]]" + on-click="toggleExpandButton_" + hidden="[[!unifiedConsentEnabled]]"> + <div class="start"> + <div>$i18n{sync}</div> + <div class="secondary">$i18n{syncDescription}</div> + </div> + <cr-expand-button expanded="{{syncSectionOpened_}}" + disabled$="[[syncSectionDisabled_]]" alt="$i18n{syncExpandA11yLabel}"> + </cr-expand-button> </div> - <div id="[[pages_.TIMEOUT]]" class="settings-box first" - hidden$="[[!isStatus_(pages_.TIMEOUT, pageStatus_)]]"> - $i18n{syncTimeout} - </div> - <div id="[[pages_.CONFIGURE]]" - hidden$="[[!isStatus_(pages_.CONFIGURE, pageStatus_)]]"> - <template is="dom-if" if="[[syncPrefs.passphraseRequired]]"> - <div id="existingPassphrase" class="list-frame"> - <div class="list-item"> - <span> - [[enterPassphrasePrompt_(syncPrefs.passphraseTypeIsCustom)]] - <a href="$i18nRaw{syncErrorHelpUrl}" target="_blank"> + + <iron-collapse id="sync-section" opened="[[syncSectionOpened_]]" + hidden="[[syncSectionDisabled_]]"> + <div id="[[pages_.SPINNER]]" class="settings-box first" + hidden$="[[!isStatus_(pages_.SPINNER, pageStatus_)]]"> + $i18n{syncLoading} + </div> + <div id="[[pages_.TIMEOUT]]" class="settings-box first" + hidden$="[[!isStatus_(pages_.TIMEOUT, pageStatus_)]]"> + $i18n{syncTimeout} + </div> + <div id="[[pages_.CONFIGURE]]" + hidden$="[[!isStatus_(pages_.CONFIGURE, pageStatus_)]]"> + <template is="dom-if" if="[[syncPrefs.passphraseRequired]]"> + <div id="existingPassphrase" class="list-frame"> + <div class="list-item"> + <span> + [[enterPassphrasePrompt_(syncPrefs.passphraseTypeIsCustom)]] + <a href="$i18nRaw{syncErrorHelpUrl}" target="_blank"> + $i18n{learnMore} + </a> + </span> + </div> + <div id="existingPassphraseContainer" class="list-item"> + <paper-input id="existingPassphraseInput" type="password" + value="{{existingPassphrase_}}" + placeholder="$i18n{passphrasePlaceholder}" + error-message="$i18n{incorrectPassphraseError}" + on-keypress="onSubmitExistingPassphraseTap_"> + </paper-input> + <paper-button id="submitExistingPassphrase" + on-click="onSubmitExistingPassphraseTap_" + class="action-button" disabled="[[!existingPassphrase_]]"> + $i18n{submitPassphraseButton} + </paper-button> + </div> + <div id="passphraseRecoverHint" class="list-item"> + <span>$i18nRaw{passphraseRecover}</span> + </div> + </div> + </template> + + <div class="settings-box first" hidden="[[unifiedConsentEnabled]]"> + <div id="syncEverythingCheckboxLabel" class="start"> + $i18n{syncEverythingCheckboxLabel} + </div> + <cr-toggle id="syncAllDataTypesControl" + checked="{{syncPrefs.syncAllDataTypes}}" + on-change="onSyncAllDataTypesChanged_" + aria-labelledby="syncEverythingCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-frame" id="sync-data-types"> + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.appsRegistered]]"> + <div id="appCheckboxLabel" class="flex"> + $i18n{appCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.appsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]" + aria-labelledby="appCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.autofillRegistered]]"> + <div id="autofillCheckboxLabel" class="flex"> + $i18n{autofillCheckboxLabel} + </div> + <!-- Autofill has a special on-change handler to deal with + Payments integration. --> + <cr-toggle checked="{{syncPrefs.autofillSynced}}" + on-change="onAutofillDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]" + aria-labelledby="autofillCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.bookmarksRegistered]]"> + <div id="bookmarksCheckboxLabel" class="flex"> + $i18n{bookmarksCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.bookmarksSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]" + aria-labelledby="bookmarksCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.extensionsRegistered]]"> + <div id="extensionsCheckboxLabel" class="flex"> + $i18n{extensionsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.extensionsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]" + aria-labelledby="extensionsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.typedUrlsRegistered]]"> + <div id="historyCheckboxLabel" class="flex"> + $i18n{historyCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.typedUrlsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]" + aria-labelledby="historyCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.passwordsRegistered]]"> + <div id="passwordsCheckboxLabel" class="flex"> + $i18n{passwordsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.passwordsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]" + aria-labelledby="passwordsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.preferencesRegistered]]"> + <div id="settingsCheckboxLabel" class="flex"> + $i18n{settingsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.preferencesSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, + syncPrefs.preferencesEnforced)]]" + aria-labelledby="settingsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.themesRegistered]]"> + <div id="themesAndWallpapersCheckboxLabel" class="flex"> + $i18n{themesAndWallpapersCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.themesSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]" + aria-labelledby="themesAndWallpapersCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.tabsRegistered]]"> + <div id="openTabsCheckboxLabel" class="flex"> + $i18n{openTabsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.tabsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]" + aria-labelledby="openTabsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="layout horizontal list-item" + hidden="[[!syncPrefs.autofillRegistered]]"> + <!-- The Payments integration checkbox is a special case in many + ways. It's visible only if autofill is registered. It's + disabled and unchecked if autofill is unchecked.--> + <div class="flex"> + $i18n{enablePaymentsIntegrationCheckboxLabel} + <a href="$i18nRaw{autofillHelpURL}" target="_blank"> $i18n{learnMore} </a> - </span> - </div> - <div id="existingPassphraseContainer" class="list-item"> - <paper-input id="existingPassphraseInput" type="password" - value="{{existingPassphrase_}}" - placeholder="$i18n{passphrasePlaceholder}" - error-message="$i18n{incorrectPassphraseError}" - on-keypress="onSubmitExistingPassphraseTap_"> - </paper-input> - <paper-button id="submitExistingPassphrase" - on-click="onSubmitExistingPassphraseTap_" class="action-button" - disabled="[[!existingPassphrase_]]"> - $i18n{submitPassphraseButton} - </paper-button> - </div> - <div id="passphraseRecoverHint" class="list-item"> - <span>$i18nRaw{passphraseRecover}</span> - </div> - </div> - </template> - - <div class="settings-box first"> - <div id="syncEverythingCheckboxLabel" class="start"> - $i18n{syncEverythingCheckboxLabel} - </div> - <cr-toggle id="syncAllDataTypesControl" - checked="{{syncPrefs.syncAllDataTypes}}" - on-change="onSyncAllDataTypesChanged_" - aria-labelledby="syncEverythingCheckboxLabel"> - </cr-toggle> - </div> - - <div class="list-frame" id="sync-data-types"> - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.appsRegistered]]"> - <div id="appCheckboxLabel" class="flex">$i18n{appCheckboxLabel}</div> - <cr-toggle checked="{{syncPrefs.appsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]" - aria-labelledby="appCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.autofillRegistered]]"> - <div id="autofillCheckboxLabel" class="flex"> - $i18n{autofillCheckboxLabel} - </div> - <!-- Autofill has a special on-change handler to deal with - Payments integration. --> - <cr-toggle checked="{{syncPrefs.autofillSynced}}" - on-change="onAutofillDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]" - aria-labelledby="autofillCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.bookmarksRegistered]]"> - <div id="bookmarksCheckboxLabel" class="flex"> - $i18n{bookmarksCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.bookmarksSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]" - aria-labelledby="bookmarksCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.extensionsRegistered]]"> - <div id="extensionsCheckboxLabel" class="flex"> - $i18n{extensionsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.extensionsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]" - aria-labelledby="extensionsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.typedUrlsRegistered]]"> - <div id="historyCheckboxLabel" class="flex"> - $i18n{historyCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.typedUrlsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]" - aria-labelledby="historyCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.passwordsRegistered]]"> - <div id="passwordsCheckboxLabel" class="flex"> - $i18n{passwordsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.passwordsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]" - aria-labelledby="passwordsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.preferencesRegistered]]"> - <div id="settingsCheckboxLabel" class="flex"> - $i18n{settingsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.preferencesSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.preferencesEnforced)]]" - aria-labelledby="settingsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.themesRegistered]]"> - <div id="themesAndWallpapersCheckboxLabel" class="flex"> - $i18n{themesAndWallpapersCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.themesSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]" - aria-labelledby="themesAndWallpapersCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.tabsRegistered]]"> - <div id="openTabsCheckboxLabel" class="flex"> - $i18n{openTabsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.tabsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]" - aria-labelledby="openTabsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.autofillRegistered]]"> - <!-- The Payments integration checkbox is a special case in many ways. - It's visible only if autofill is registered. It's disabled and - unchecked if autofill is unchecked.--> - <div class="flex"> - $i18n{enablePaymentsIntegrationCheckboxLabel} - <a href="$i18nRaw{autofillHelpURL}" target="_blank"> - $i18n{learnMore} - </a> - </div> - <cr-toggle - checked="{{syncPrefs.paymentsIntegrationEnabled}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldPaymentsCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.autofillSynced)]]" - aria-label="$i18n{enablePaymentsIntegrationCheckboxLabel}"> - </cr-toggle> - </div> - </div> - - <a class="settings-box two-line inherit-color no-outline" tabindex="-1" - target="_blank" href="$i18n{activityControlsUrl}" - on-click="onActivityControlsTap_"> - <div class="start"> - $i18n{personalizeGoogleServicesTitle} - <div class="secondary" id="activityControlsSecondary"> - $i18n{personalizeGoogleServicesText} - </div> - </div> - <paper-icon-button-light actionable class="icon-external"> - <button aria-label="$i18n{personalizeGoogleServicesTitle}" - aria-describedby="activityControlsSecondary"></button> - </paper-icon-button-light> - </a> - - <a class="settings-box inherit-color no-outline" tabindex="-1" - target="_blank" href="$i18n{syncDashboardUrl}"> - <div class="start"> - $i18n{manageSyncedDataTitle} - </div> - <paper-icon-button-light actionable class="icon-external"> - <button aria-label="$i18n{manageSyncedDataTitle}"></button> - </paper-icon-button-light> - </a> - - <div id="encryptionDescription" hidden="[[syncPrefs.passphraseRequired]]" - class="settings-box two-line single-column"> - <div>$i18n{encryptionOptionsTitle}</div> - <div class="secondary">$i18n{syncDataEncryptedText}</div> - </div> - - <div id="encryptionRadioGroupContainer" class="list-frame" - hidden="[[syncPrefs.passphraseRequired]]"> - <paper-radio-group disabled$="[[syncPrefs.encryptAllData]]" - selected="[[selectedEncryptionRadio_( - syncPrefs.passphraseTypeIsCustom)]]" - on-paper-radio-group-changed="onEncryptionRadioSelectionChanged_"> - <paper-radio-button name="encrypt-with-google" - class="list-item" disabled="[[syncPrefs.encryptAllData]]"> - $i18n{encryptWithGoogleCredentialsLabel} - </paper-radio-button> - <paper-radio-button name="encrypt-with-passphrase" - class="list-item" disabled="[[syncPrefs.encryptAllData]]"> - <template is="dom-if" if="[[syncPrefs.fullEncryptionBody]]"> - <span>[[syncPrefs.fullEncryptionBody]]</span> - </template> - <template is="dom-if" if="[[!syncPrefs.fullEncryptionBody]]"> - <span on-click="onLearnMoreTap_"> - $i18nRaw{encryptWithSyncPassphraseLabel} - </span> - </template> - </paper-radio-button> - </paper-radio-group> - <div id="reset-sync-message-box" class="list-item" - hidden="[[!syncPrefs.encryptAllData]]"> - <span>$i18nRaw{passphraseResetHint}</span> - </div> - </div> - - <template is="dom-if" if="[[creatingNewPassphrase_]]"> - <div class="list-frame"> - <div id="create-password-box" on-keypress="onSaveNewPassphraseTap_"> - <div class="list-item"> - <span>$i18nRaw{passphraseExplanationText}</span> </div> - <paper-input id="passphraseInput" type="password" - value="{{passphrase_}}" - placeholder="$i18n{passphrasePlaceholder}" - error-message="$i18n{emptyPassphraseError}"> - </paper-input> - <paper-input id="passphraseConfirmationInput" type="password" - value="{{confirmation_}}" - placeholder="$i18n{passphraseConfirmationPlaceholder}" - error-message="$i18n{mismatchedPassphraseError}"> - </paper-input> - <paper-button id="saveNewPassphrase" - on-click="onSaveNewPassphraseTap_" class="action-button" - disabled="[[!isSaveNewPassphraseEnabled_(passphrase_, - confirmation_)]]"> - $i18n{save} - </paper-button> + <cr-toggle + checked="{{syncPrefs.paymentsIntegrationEnabled}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldPaymentsCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.autofillSynced)]]" + aria-label="$i18n{enablePaymentsIntegrationCheckboxLabel}"> + </cr-toggle> </div> </div> - </template> - </div> + + <div id="other-sync-items" + class$="[[getListFrameClass_(unifiedConsentEnabled)]]"> + <a class$="two-line inherit-color no-outline + [[getListItemClass_(unifiedConsentEnabled)]]" tabindex="-1" + target="_blank" href="$i18n{activityControlsUrl}" + on-click="onActivityControlsTap_"> + <div class="start"> + $i18n{personalizeGoogleServicesTitle} + <div class="secondary" id="activityControlsSecondary"> + $i18n{personalizeGoogleServicesText} + </div> + </div> + <paper-icon-button-light actionable class="icon-external"> + <button aria-label="$i18n{personalizeGoogleServicesTitle}" + aria-describedby="activityControlsSecondary"></button> + </paper-icon-button-light> + </a> + + <a class$="inherit-color no-outline + [[getListItemClass_(unifiedConsentEnabled)]]" tabindex="-1" + target="_blank" href="$i18n{syncDashboardUrl}"> + <div class="start"> + $i18n{manageSyncedDataTitle} + </div> + <paper-icon-button-light actionable class="icon-external"> + <button aria-label="$i18n{manageSyncedDataTitle}"></button> + </paper-icon-button-light> + </a> + + <div id="encryptionDescription" + hidden="[[syncPrefs.passphraseRequired]]" + class$="two-line single-column + [[getListItemClass_(unifiedConsentEnabled)]]"> + <div>$i18n{encryptionOptionsTitle}</div> + <div class="secondary">$i18n{syncDataEncryptedText}</div> + </div> + + <div id="encryptionRadioGroupContainer" class="list-frame" + hidden="[[syncPrefs.passphraseRequired]]"> + <paper-radio-group disabled$="[[syncPrefs.encryptAllData]]" + selected="[[selectedEncryptionRadio_( + syncPrefs.passphraseTypeIsCustom)]]" + on-paper-radio-group-changed= + "onEncryptionRadioSelectionChanged_"> + <paper-radio-button name="encrypt-with-google" + class="list-item" disabled="[[syncPrefs.encryptAllData]]"> + $i18n{encryptWithGoogleCredentialsLabel} + </paper-radio-button> + <paper-radio-button name="encrypt-with-passphrase" + class="list-item" disabled="[[syncPrefs.encryptAllData]]"> + <template is="dom-if" if="[[syncPrefs.fullEncryptionBody]]"> + <span>[[syncPrefs.fullEncryptionBody]]</span> + </template> + <template is="dom-if" if="[[!syncPrefs.fullEncryptionBody]]"> + <span on-click="onLearnMoreTap_"> + $i18nRaw{encryptWithSyncPassphraseLabel} + </span> + </template> + </paper-radio-button> + </paper-radio-group> + <div id="reset-sync-message-box" class="list-item" + hidden="[[!syncPrefs.encryptAllData]]"> + <span>$i18nRaw{passphraseResetHint}</span> + </div> + </div> + + <template is="dom-if" if="[[creatingNewPassphrase_]]"> + <div class="list-frame"> + <div id="create-password-box" + on-keypress="onSaveNewPassphraseTap_"> + <div class="list-item"> + <span>$i18nRaw{passphraseExplanationText}</span> + </div> + <paper-input id="passphraseInput" type="password" + value="{{passphrase_}}" + placeholder="$i18n{passphrasePlaceholder}" + error-message="$i18n{emptyPassphraseError}"> + </paper-input> + <paper-input id="passphraseConfirmationInput" type="password" + value="{{confirmation_}}" + placeholder="$i18n{passphraseConfirmationPlaceholder}" + error-message="$i18n{mismatchedPassphraseError}"> + </paper-input> + <paper-button id="saveNewPassphrase" + on-click="onSaveNewPassphraseTap_" class="action-button" + disabled="[[!isSaveNewPassphraseEnabled_(passphrase_, + confirmation_)]]"> + $i18n{save} + </paper-button> + </div> + </div> + </template> + </div> + </div> + </iron-collapse> + <if expr="not chromeos"> <cr-toast id="toast" open="[[syncStatus.setupInProgress]]"> $i18n{syncWillStart}
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index ee32d2c..edc4382 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -54,7 +54,10 @@ }, /** @type {settings.SyncStatus} */ - syncStatus: Object, + syncStatus: { + type: Object, + observer: 'onSyncStatusChanged_', + }, /** * Whether the "create passphrase" inputs should be shown. These inputs @@ -94,6 +97,20 @@ value: '', }, + /** @private */ + syncSectionDisabled_: { + type: Boolean, + value: false, + computed: 'computeSyncSectionDisabled_(' + + 'unifiedConsentEnabled, syncStatus.signedIn)', + }, + + /** @private */ + syncSectionOpened_: { + type: Boolean, + value: true, + }, + // <if expr="not chromeos"> diceEnabled: Boolean, // </if> @@ -149,6 +166,14 @@ } }, + /** + * @return {boolean} + * @private + */ + computeSyncSectionDisabled_() { + return this.unifiedConsentEnabled && !this.syncStatus.signedIn; + }, + /** @protected */ currentRouteChanged: function() { if (settings.getCurrentRoute() == settings.routes.SYNC) @@ -430,6 +455,53 @@ settings.navigateTo(settings.routes.BASIC); }, + /** @private */ + onSyncStatusChanged_: function() { + this.syncSectionOpened_ = !!this.syncStatus.signedIn; + }, + + /** + * Toggles the expand button within the element being listened to. + * @param {!Event} e + * @private + */ + toggleExpandButton_: function(e) { + // The expand button handles toggling itself. + const expandButtonTag = 'CR-EXPAND-BUTTON'; + if (e.target.tagName == expandButtonTag) + return; + + if (!e.currentTarget.hasAttribute('actionable')) + return; + + /** @type {!CrExpandButtonElement} */ + const expandButton = e.currentTarget.querySelector(expandButtonTag); + assert(expandButton); + expandButton.expanded = !expandButton.expanded; + }, + + /** + * When unified-consent enabled, the non-toggle items on the bottom of sync + * section should be wrapped with 'list-frame' in order to be indented + * correctly. + * @return {string} + * @private + */ + getListFrameClass_: function() { + return this.unifiedConsentEnabled ? 'list-frame' : ''; + }, + + /** + * When unified-consent enabled, the non-toggle items on the bottom of sync + * section will be wrapped with 'list-frame', and should have the 'list-item' + * instead of 'settings-box' in order to be indented correctly. + * @return {string} + * @private + */ + getListItemClass_: function() { + return this.unifiedConsentEnabled ? 'list-item' : 'settings-box'; + }, + // <if expr="not chromeos"> /** * @return {boolean}
diff --git a/chrome/browser/resources/settings/people_page/users_add_user_dialog.html b/chrome/browser/resources/settings/people_page/users_add_user_dialog.html index fe8cd9c..97358beb 100644 --- a/chrome/browser/resources/settings/people_page/users_add_user_dialog.html +++ b/chrome/browser/resources/settings/people_page/users_add_user_dialog.html
@@ -17,7 +17,7 @@ }; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{addUsers}</div> <div slot="body"> <paper-input id="addUserInput" label="$i18n{addUsersEmail}" autofocus @@ -33,7 +33,7 @@ $i18n{add} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="users_add_user_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog_util.html b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog_util.html index 2c7ba3387..70ae6da0 100644 --- a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog_util.html +++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog_util.html
@@ -100,7 +100,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title"> <slot name="dialog-title"></slot> </div> @@ -110,7 +110,7 @@ <div slot="button-container"> <slot name="dialog-buttons"></slot> </div> - </dialog> + </cr-dialog> </template> <script src="cups_add_printer_dialog_util.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index ec6446f..c938b42ff 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -45,7 +45,7 @@ </template> <template id="doNotTrackDialogIf" is="dom-if" if="[[showDoNotTrackDialog_]]" notify-dom-change> - <dialog is="cr-dialog" id="confirmDoNotTrackDialog" + <cr-dialog id="confirmDoNotTrackDialog" close-text="$i18n{close}" on-cancel="onDoNotTrackDialogCancel_" on-close="onDoNotTrackDialogClosed_"> <div slot="title">$i18n{doNotTrackDialogTitle}</div> @@ -60,7 +60,7 @@ $i18n{confirm} </paper-button> </div> - </dialog> + </cr-dialog> </template> <settings-animated-pages id="pages" section="privacy" focus-config="[[focusConfig_]]"> @@ -481,6 +481,12 @@ </template> <template is="dom-if" route-path="/content/usbDevices" no-search> <settings-subpage page-title="$i18n{siteSettingsUsbDevices}"> + <category-default-setting + toggle-off-label="$i18n{siteSettingsUsbDevicesBlock}" + toggle-on-label= + "$i18n{siteSettingsUsbDevicesAskRecommended}" + category="{{ContentSettingsTypes.USB_DEVICES}}"> + </category-default-setting> <usb-devices></usb-devices> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/reset_page/powerwash_dialog.html b/chrome/browser/resources/settings/reset_page/powerwash_dialog.html index 98a82fd..90e2a12 100644 --- a/chrome/browser/resources/settings/reset_page/powerwash_dialog.html +++ b/chrome/browser/resources/settings/reset_page/powerwash_dialog.html
@@ -10,7 +10,7 @@ <template> <style include="settings-shared"> </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}" + <cr-dialog id="dialog" close-text="$i18n{close}" ignore-enter-key> <div slot="title">$i18n{powerwashDialogTitle}</div> <div slot="body"> @@ -27,7 +27,7 @@ <paper-button class="action-button" id="powerwash" on-click="onRestartTap_">$i18n{powerwashDialogButton}</paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="powerwash_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_banner.html b/chrome/browser/resources/settings/reset_page/reset_profile_banner.html index aed186e6..3eaaf42 100644 --- a/chrome/browser/resources/settings/reset_page/reset_profile_banner.html +++ b/chrome/browser/resources/settings/reset_page/reset_profile_banner.html
@@ -8,7 +8,7 @@ <dom-module id="settings-reset-profile-banner"> <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}" ignore-popstate> + <cr-dialog id="dialog" close-text="$i18n{close}" ignore-popstate> <div slot="title">$i18n{resetAutomatedDialogTitle}</div> <div slot="body"> <span id="description"> @@ -26,7 +26,7 @@ $i18n{resetProfileBannerButton} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="reset_profile_banner.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html index dcf2d3ab..d48cb08 100644 --- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html +++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
@@ -19,7 +19,7 @@ margin: 0 8px; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}" + <cr-dialog id="dialog" close-text="$i18n{close}" ignore-popstate ignore-enter-key> <div slot="title"> [[getPageTitle_(isTriggered_, triggeredResetToolName_)]] @@ -48,7 +48,7 @@ <paper-checkbox id="sendSettings" checked> $i18nRaw{resetPageFeedback}</paper-checkbox> </div> - </dialog> + </cr-dialog> </template> <script src="reset_profile_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html index a8e0591..ce40163 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html
@@ -22,7 +22,7 @@ }; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[dialogTitle_]]</div> <div slot="body" spellcheck="false"> <paper-input always-float-label id="searchEngine" @@ -51,7 +51,7 @@ [[actionButtonText_]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="search_engine_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/search_settings.js b/chrome/browser/resources/settings/search_settings.js index 6fd23591..71971fa 100644 --- a/chrome/browser/resources/settings/search_settings.js +++ b/chrome/browser/resources/settings/search_settings.js
@@ -11,7 +11,6 @@ * @typedef {{ * canceled: Boolean, * didFindMatches: Boolean, - * rawQuery: string, * wasClearSearch: Boolean, * }} */ @@ -50,14 +49,12 @@ * children's Shadow DOM) and replaces the highlights (yellow rectangle and * search bubbles) with the original text node. * TODO(dpapad): Consider making this a private method of TopLevelSearchTask. - * @param {!Array<!Node>} nodes + * @param {!Node} node * @private */ - function findAndRemoveHighlights_(nodes) { - nodes.forEach(node => { - cr.search_highlight_utils.findAndRemoveHighlights(node); - cr.search_highlight_utils.findAndRemoveBubbles(node); - }); + function findAndRemoveHighlights_(node) { + cr.search_highlight_utils.findAndRemoveHighlights(node); + cr.search_highlight_utils.findAndRemoveBubbles(node); } /** @@ -67,36 +64,33 @@ * occurred under their subtree. * * @param {!settings.SearchRequest} request - * @param {!Array<!Node>} roots The roots of the sub-trees to be searched. - * @param {!function(!Node): void} addTextObserver + * @param {!Node} root The root of the sub-tree to be searched * @private */ - function findAndHighlightMatches_(request, roots, addTextObserver) { + function findAndHighlightMatches_(request, root) { let foundMatches = false; function doSearch(node) { if (node.nodeName == 'TEMPLATE' && node.hasAttribute('route-path') && !node.if && !node.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE)) { - request.queue_.addRenderTask( - new RenderTask(request, node, addTextObserver)); - return false; + request.queue_.addRenderTask(new RenderTask(request, node)); + return; } if (IGNORED_ELEMENTS.has(node.nodeName)) - return false; + return; if (node instanceof HTMLElement) { const element = /** @type {HTMLElement} */ (node); if (element.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE) || element.hasAttribute('hidden') || element.style.display == 'none') { - return false; + return; } } if (node.nodeType == Node.TEXT_NODE) { - addTextObserver(node); const textContent = node.nodeValue.trim(); if (textContent.length == 0) - return false; + return; if (request.regExp.test(textContent)) { foundMatches = true; @@ -112,23 +106,24 @@ } } // Returning early since TEXT_NODE nodes never have children. - return false; + return; } - return true; - } - - const nodes = Array.from(roots); - while (nodes.length > 0) { - const node = nodes.pop(); - const continueSearchChildren = doSearch(node); - if (continueSearchChildren) { - nodes.push(...node.childNodes); - if (node.shadowRoot) - nodes.push(node.shadowRoot); + let child = node.firstChild; + while (child !== null) { + // Getting a reference to the |nextSibling| before calling doSearch() + // because |child| could be removed from the DOM within doSearch(). + const nextSibling = child.nextSibling; + doSearch(child); + child = nextSibling; } + + const shadowRoot = node.shadowRoot; + if (shadowRoot) + doSearch(shadowRoot); } + doSearch(root); return foundMatches; } @@ -169,18 +164,14 @@ class Task { /** * @param {!settings.SearchRequest} request - * @param {!Array<!Node>} nodes - * @param {!function(!Node): void} addTextObserver + * @param {!Node} node */ - constructor(request, nodes, addTextObserver) { + constructor(request, node) { /** @protected {!settings.SearchRequest} */ this.request = request; - /** @protected {!Array<!Node>} */ - this.nodes = nodes; - - /** @protected {!function(!Node): void} */ - this.addTextObserver = addTextObserver; + /** @protected {!Node} */ + this.node = node; } /** @@ -199,32 +190,29 @@ * * @param {!settings.SearchRequest} request * @param {!Node} node - * @param {!function(!Node): void} addTextObserver */ - constructor(request, node, addTextObserver) { - super(request, [node], addTextObserver); + constructor(request, node) { + super(request, node); } /** @override */ exec() { - const node = this.nodes[0]; - const routePath = node.getAttribute('route-path'); + const routePath = this.node.getAttribute('route-path'); const subpageTemplate = - node['_content'].querySelector('settings-subpage'); + this.node['_content'].querySelector('settings-subpage'); subpageTemplate.setAttribute('route-path', routePath); - assert(!node.if); - node.if = true; + assert(!this.node.if); + this.node.if = true; return new Promise((resolve, reject) => { - const parent = node.parentNode; + const parent = this.node.parentNode; parent.async(() => { const renderedNode = parent.querySelector('[route-path="' + routePath + '"]'); // Register a SearchAndHighlightTask for the part of the DOM that was // just rendered. this.request.queue_.addSearchAndHighlightTask( - new SearchAndHighlightTask( - this.request, assert(renderedNode), this.addTextObserver)); + new SearchAndHighlightTask(this.request, assert(renderedNode))); resolve(); }); }); @@ -235,16 +223,14 @@ /** * @param {!settings.SearchRequest} request * @param {!Node} node - * @param {!function(!Node): void} addTextObserver */ - constructor(request, node, addTextObserver) { - super(request, [node], addTextObserver); + constructor(request, node) { + super(request, node); } /** @override */ exec() { - const foundMatches = findAndHighlightMatches_( - this.request, this.nodes, this.addTextObserver); + const foundMatches = findAndHighlightMatches_(this.request, this.node); this.request.updateMatches(foundMatches); return Promise.resolve(); } @@ -253,21 +239,20 @@ class TopLevelSearchTask extends Task { /** * @param {!settings.SearchRequest} request - * @param {!Array<!Node>} pages + * @param {!Node} page */ - constructor(request, pages, addTextObserver) { - super(request, pages, addTextObserver); + constructor(request, page) { + super(request, page); } /** @override */ exec() { - findAndRemoveHighlights_(this.nodes); + findAndRemoveHighlights_(this.node); const shouldSearch = this.request.regExp !== null; this.setSectionsVisibility_(!shouldSearch); if (shouldSearch) { - const foundMatches = findAndHighlightMatches_( - this.request, this.nodes, this.addTextObserver); + const foundMatches = findAndHighlightMatches_(this.request, this.node); this.request.updateMatches(foundMatches); } @@ -279,11 +264,10 @@ * @private */ setSectionsVisibility_(visible) { - this.nodes.forEach(node => { - const sections = node.querySelectorAll('settings-section'); - for (let i = 0; i < sections.length; i++) - sections[i].hiddenBySearch = !visible; - }); + const sections = this.node.querySelectorAll('settings-section'); + + for (let i = 0; i < sections.length; i++) + sections[i].hiddenBySearch = !visible; } } @@ -383,15 +367,14 @@ class SearchRequest { /** * @param {string} rawQuery - * @param {!Array<!HTMLElement>} roots - * @param {!function(!Node): void} addTextObserver + * @param {!HTMLElement} root */ - constructor(rawQuery, roots, addTextObserver) { + constructor(rawQuery, root) { /** @private {string} */ this.rawQuery_ = rawQuery; - /** @private {!Array<!HTMLElement>} */ - this.roots_ = roots; + /** @private {!HTMLElement} */ + this.root_ = root; /** @type {?RegExp} */ this.regExp = this.generateRegExp_(); @@ -413,9 +396,6 @@ this.queue_.onEmpty(() => { this.resolver.resolve(this); }); - - /** @private {!function(!Node): void} */ - this.addTextObserver_ = addTextObserver; } /** @@ -423,7 +403,7 @@ */ start() { this.queue_.addTopLevelSearchTask( - new TopLevelSearchTask(this, this.roots_, this.addTextObserver_)); + new TopLevelSearchTask(this, this.root_)); } /** @@ -459,14 +439,9 @@ this.foundMatches_ = this.foundMatches_ || found; } - /** @return {!settings.SearchResult} */ - result() { - return /** @type {!settings.SearchResult} */ ({ - canceled: this.canceled, - didFindMatches: this.foundMatches_, - rawQuery: this.rawQuery_, - wasClearSearch: this.isSame(''), - }); + /** @return {boolean} Whether any matches were found. */ + didFindMatches() { + return this.foundMatches_; } } @@ -474,25 +449,14 @@ const SANITIZE_REGEX = /[-[\]{}()*+?.,\\^$|#\s]/g; /** @interface */ - class SearchManagerObserver { - onSearchStart() {} - - /** @param {!settings.SearchResult} searchResult */ - onSearchComplete(searchResult) {} - } - - /** @interface */ class SearchManager { /** * @param {string} text The text to search for. - * @param {!Array<!Node>} pages - * @return {!Promise<!settings.SearchResult>} A signal indicating that + * @param {!Node} page + * @return {!Promise<!settings.SearchRequest>} A signal indicating that * searching finished. */ - search(text, pages) {} - - /** @param {!settings.SearchManagerObserver} observer */ - registerObserver(observer) {} + search(text, page) {} } /** @implements {SearchManager} */ @@ -503,39 +467,10 @@ /** @private {?string} */ this.lastSearchedText_ = null; - - /** @private {!Array<!settings.SearchManagerObserver>} */ - this.observers_ = []; - - /** @private {!Set<!MutationObserver>} */ - this.textObservers_ = new Set(); - } - - /** - * @param {!function(): void} redoSearch - * @return {!function(!Node): void} - * @private - */ - getAddTextObserverFunction_(redoSearch) { - this.textObservers_.forEach(observer => { - observer.disconnect(); - }); - this.textObservers_.clear(); - return node => { - const observer = new MutationObserver(mutations => { - const oldValue = mutations[0].oldValue.trim(); - const newValue = mutations[0].target.nodeValue.trim(); - if (oldValue != newValue) - redoSearch(); - }); - observer.observe( - node, {characterData: true, characterDataOldValue: true}); - this.textObservers_.add(observer); - }; } /** @override */ - search(text, pages) { + search(text, page) { // Cancel any pending requests if a request with different text is // submitted. if (text != this.lastSearchedText_) { @@ -547,30 +482,15 @@ } this.lastSearchedText_ = text; - - const addTextObserver = this.getAddTextObserverFunction_(() => { - this.search(text, pages); - }); - const request = new SearchRequest(text, pages, addTextObserver); + const request = new SearchRequest(text, page); this.activeRequests_.add(request); request.start(); - this.observers_.forEach(observer => { - observer.onSearchStart.call(observer); - }); return request.resolver.promise.then(() => { // Stop tracking requests that finished. this.activeRequests_.delete(request); - this.observers_.forEach(observer => { - observer.onSearchComplete.call(observer, request.result()); - }); - return request.result(); + return request; }); } - - /** @override */ - registerObserver(observer) { - this.observers_.push(observer); - } } cr.addSingletonGetter(SearchManagerImpl); @@ -590,7 +510,6 @@ return { getSearchManager: getSearchManager, setSearchManagerForTesting: setSearchManagerForTesting, - SearchManagerObserver: SearchManagerObserver, SearchRequest: SearchRequest, }; });
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index c12ebae2..20fd8440 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -87,7 +87,6 @@ attached: function() { this.listen(this, 'freeze-scroll', 'onFreezeScroll_'); this.listen(this, 'lazy-loaded', 'onLazyLoaded_'); - this.registerSearchManagerObserver_(); }, /** @private */ @@ -251,56 +250,42 @@ assertNotReached(); }, - /** @private */ - registerSearchManagerObserver_: function() { - const observer = /** @type {!settings.SearchManagerObserver} */ ({ - onSearchStart: () => { - // Trigger rendering of the basic and advanced pages and search once - // ready. - this.inSearchMode_ = true; - this.toolbarSpinnerActive = true; - }, - onSearchComplete: searchResult => { - if (searchResult.canceled) { - // Nothing to do here. A previous search request was canceled - // because a new search request was issued with a different query - // before the previous completed. - return; - } - - this.toolbarSpinnerActive = false; - this.inSearchMode_ = !searchResult.wasClearSearch; - this.showNoResultsFound_ = - this.inSearchMode_ && !searchResult.didFindMatches; - if (this.showNoResultsFound_ && - settings.getCurrentRoute().isSubpage()) { - settings.navigateTo(settings.routes.BASIC); - this.searchContents(searchResult.rawQuery); - return; - } - if (this.inSearchMode_) { - Polymer.IronA11yAnnouncer.requestAvailability(); - this.fire('iron-announce', { - text: this.showNoResultsFound_ ? - loadTimeData.getString('searchNoResults') : - loadTimeData.getStringF('searchResults', searchResult.rawQuery) - }); - } - }, - }); - settings.getSearchManager().registerObserver(observer); - }, - /** * @param {string} query - * @return {!Promise<!settings.SearchResult>} A promise indicating that - * searching finished. + * @return {!Promise} A promise indicating that searching finished. */ searchContents: function(query) { + // Trigger rendering of the basic and advanced pages and search once ready. + this.inSearchMode_ = true; + this.toolbarSpinnerActive = true; + return new Promise((resolve, reject) => { setTimeout(() => { - const basicPage = assert(this.getPage_(settings.routes.BASIC)); - basicPage.searchContents(query).then(resolve); + const whenSearchDone = + assert(this.getPage_(settings.routes.BASIC)).searchContents(query); + whenSearchDone.then(result => { + resolve(); + if (result.canceled) { + // Nothing to do here. A previous search request was canceled + // because a new search request was issued with a different query + // before the previous completed. + return; + } + + this.toolbarSpinnerActive = false; + this.inSearchMode_ = !result.wasClearSearch; + this.showNoResultsFound_ = + this.inSearchMode_ && !result.didFindMatches; + + if (this.inSearchMode_) { + Polymer.IronA11yAnnouncer.requestAvailability(); + this.fire('iron-announce', { + text: this.showNoResultsFound_ ? + loadTimeData.getString('searchNoResults') : + loadTimeData.getStringF('searchResults', query) + }); + } + }); }, 0); }); },
diff --git a/chrome/browser/resources/settings/site_settings/add_site_dialog.html b/chrome/browser/resources/settings/site_settings/add_site_dialog.html index 3aad9d1..9d78be71 100644 --- a/chrome/browser/resources/settings/site_settings/add_site_dialog.html +++ b/chrome/browser/resources/settings/site_settings/add_site_dialog.html
@@ -21,7 +21,7 @@ visibility: hidden; } </style> - <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> + <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{addSiteTitle}</div> <div slot="body"> <paper-input id="site" always-float-label label="$i18n{addSite}" @@ -43,7 +43,7 @@ $i18n{add} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="add_site_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.js b/chrome/browser/resources/settings/site_settings/all_sites.js index 1c18d198..8edec70 100644 --- a/chrome/browser/resources/settings/site_settings/all_sites.js +++ b/chrome/browser/resources/settings/site_settings/all_sites.js
@@ -51,7 +51,6 @@ continue; // </if> if (type == settings.ContentSettingsTypes.PROTOCOL_HANDLERS || - type == settings.ContentSettingsTypes.USB_DEVICES || type == settings.ContentSettingsTypes.ZOOM_LEVELS) { // Some categories store their data in a custom way. continue;
diff --git a/chrome/browser/resources/settings/site_settings/category_default_setting.js b/chrome/browser/resources/settings/site_settings/category_default_setting.js index e596b8f..150a607 100644 --- a/chrome/browser/resources/settings/site_settings/category_default_setting.js +++ b/chrome/browser/resources/settings/site_settings/category_default_setting.js
@@ -116,6 +116,7 @@ case settings.ContentSettingsTypes.NOTIFICATIONS: case settings.ContentSettingsTypes.UNSANDBOXED_PLUGINS: case settings.ContentSettingsTypes.MIDI_DEVICES: + case settings.ContentSettingsTypes.USB_DEVICES: // "Ask" vs "Blocked". this.browserProxy.setDefaultValueForContentType( this.category,
diff --git a/chrome/browser/resources/settings/site_settings/constants.js b/chrome/browser/resources/settings/site_settings/constants.js index 15e8539..bc8b5a8 100644 --- a/chrome/browser/resources/settings/site_settings/constants.js +++ b/chrome/browser/resources/settings/site_settings/constants.js
@@ -28,7 +28,7 @@ AUTOMATIC_DOWNLOADS: 'multiple-automatic-downloads', BACKGROUND_SYNC: 'background-sync', MIDI_DEVICES: 'midi-sysex', - USB_DEVICES: 'usb-chooser-data', + USB_DEVICES: 'usb-devices', ZOOM_LEVELS: 'zoom-levels', PROTECTED_CONTENT: 'protected-content', ADS: 'ads',
diff --git a/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html b/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html index eb103ec0..ced08d7 100644 --- a/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html +++ b/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html
@@ -9,7 +9,7 @@ <dom-module id="settings-edit-exception-dialog"> <template> <style include="settings-shared"></style> - <dialog is="cr-dialog" id="dialog"> + <cr-dialog id="dialog"> <div slot="title">$i18n{editSiteTitle}</div> <div slot="body"> <paper-input always-float-label label="$i18n{addSite}" @@ -26,7 +26,7 @@ $i18n{save} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="edit_exception_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/site_settings/site_data.html b/chrome/browser/resources/settings/site_settings/site_data.html index af0aad9..8779e1c 100644 --- a/chrome/browser/resources/settings/site_settings/site_data.html +++ b/chrome/browser/resources/settings/site_settings/site_data.html
@@ -76,7 +76,7 @@ </iron-list> <!-- Confirm Delete dialog --> - <dialog is="cr-dialog" id="confirmDeleteDialog" close-text="$i18n{close}" + <cr-dialog id="confirmDeleteDialog" close-text="$i18n{close}" on-close="onConfirmDeleteDialogClosed_"> <div slot="title"> $i18n{siteSettingsCookieRemoveDialogTitle} @@ -90,7 +90,7 @@ $i18n{siteSettingsCookiesClearAll} </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="site_data.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html index b177b18..c0e72f6 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.html +++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -36,7 +36,7 @@ } </style> <!-- Confirm Delete dialog --> - <dialog is="cr-dialog" id="confirmDeleteDialog" close-text="$i18n{close}"> + <cr-dialog id="confirmDeleteDialog" close-text="$i18n{close}"> <div slot="title"> $i18n{siteSettingsSiteResetDialogTitle} </div> @@ -51,7 +51,7 @@ $i18n{siteSettingsSiteResetAll} </paper-button> </div> - </dialog> + </cr-dialog> <template is="dom-if" if="[[enableSiteSettings_]]"> <div id="usage"> @@ -140,6 +140,10 @@ id="midiDevices" label="$i18n{siteSettingsMidiDevices}"> </site-details-permission> <site-details-permission + category="{{ContentSettingsTypes.USB_DEVICES}}" icon="settings:usb" + id="usbDevices" label="$i18n{siteSettingsUsbDevices}"> + </site-details-permission> + <site-details-permission category="{{ContentSettingsTypes.UNSANDBOXED_PLUGINS}}" icon="cr:extension" id="unsandboxedPlugins" label="$i18n{siteSettingsUnsandboxedPlugins}">
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.html b/chrome/browser/resources/settings/site_settings/site_details_permission.html index fc064fd..37dfe6d 100644 --- a/chrome/browser/resources/settings/site_settings/site_details_permission.html +++ b/chrome/browser/resources/settings/site_settings/site_details_permission.html
@@ -56,14 +56,16 @@ '$i18nPolymer{siteSettingsActionAllowDefault}', '$i18nPolymer{siteSettingsActionBlockDefault}')]] </option> - <option id="allow" value$="[[ContentSetting.ALLOW]]"> + <option id="allow" value$="[[ContentSetting.ALLOW]]" + hidden$="[[!showAllowedSetting_(category)]]"> $i18n{siteSettingsActionAllow} </option> <option id="block" value$="[[ContentSetting.BLOCK]]"> $i18n{siteSettingsActionBlock} </option> <option id="ask" value$="[[ContentSetting.ASK]]" - hidden$="[[!isNonDefaultAsk_(site.setting, site.source)]]"> + hidden$="[[!showAskSetting_(category, site.setting, + site.source)]]"> $i18n{siteSettingsActionAsk} </option> </select>
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chrome/browser/resources/settings/site_settings/site_details_permission.js index 4cfe5f1..ce339395 100644 --- a/chrome/browser/resources/settings/site_settings/site_details_permission.js +++ b/chrome/browser/resources/settings/site_settings/site_details_permission.js
@@ -172,6 +172,32 @@ }, /** + * Returns true if the 'allow' option should be shown. + * @param {!settings.ContentSettingsTypes} category The permission type. + * @return {boolean} + * @private + */ + showAllowedSetting_: function(category) { + return category != settings.ContentSettingsTypes.USB_DEVICES; + }, + + /** + * Returns true if the 'ask' option should be shown. + * @param {!settings.ContentSettingsTypes} category The permission type. + * @param {!settings.ContentSetting} setting The setting of the permission. + * @param {!settings.SiteSettingSource} source The source of the permission. + * @return {boolean} + * @private + */ + showAskSetting_: function(category, setting, source) { + // For chooser-based permissions 'ask' takes the place of 'allow'. + if (category == settings.ContentSettingsTypes.USB_DEVICES) + return true; + + return this.isNonDefaultAsk_(setting, source); + }, + + /** * Returns true if the permission is set to a non-default 'ask'. Currently, * this only gets called when |this.site| is updated. * @param {!settings.ContentSetting} setting The setting of the permission.
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html index 60ec3f3..190322c 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
@@ -365,14 +365,23 @@ <button aria-label="$i18n{siteSettingsZoomLevels}"></button> </paper-icon-button-light> </div> - <div id="usb-devices" class="settings-box" + <div id="usb-devices" class="settings-box two-line" category$="[[ContentSettingsTypes.USB_DEVICES]]" data-route="SITE_SETTINGS_USB_DEVICES" on-click="onTapNavigate_" actionable> <iron-icon icon="settings:usb"></iron-icon> - <div class="middle">$i18n{siteSettingsUsbDevices}</div> + <div class="middle"> + $i18n{siteSettingsUsbDevices} + <div class="secondary" id="usbDevicesSecondary"> + [[defaultSettingLabel_( + default_.usbDevices, + '$i18nPolymer{siteSettingsUsbDevicesAsk}', + '$i18nPolymer{siteSettingsUsbDevicesBlock}')]] + </div> + </div> <paper-icon-button-light class="subpage-arrow"> - <button aria-label="$i18n{siteSettingsUsbDevices}"></button> + <button aria-label="$i18n{siteSettingsUsbDevices}" + area-describedby="usbDevicesSecondary"></button> </paper-icon-button-light> </div> <div id="pdf-documents" class="settings-box"
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js index fb521d2..eb57c9f 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -149,9 +149,8 @@ const keys = Object.keys(settings.ContentSettingsTypes); for (let i = 0; i < keys.length; ++i) { const key = settings.ContentSettingsTypes[keys[i]]; - // Default labels are not applicable to USB and ZOOM. - if (key == settings.ContentSettingsTypes.USB_DEVICES || - key == settings.ContentSettingsTypes.ZOOM_LEVELS) + // Default labels are not applicable to ZOOM. + if (key == settings.ContentSettingsTypes.ZOOM_LEVELS) continue; // Protocol handlers are not available (and will DCHECK) in guest mode. if (this.isGuest_ &&
diff --git a/chrome/browser/resources/welcome/dice_welcome/welcome_app.html b/chrome/browser/resources/welcome/dice_welcome/welcome_app.html index 1ecd003b..59f3269 100644 --- a/chrome/browser/resources/welcome/dice_welcome/welcome_app.html +++ b/chrome/browser/resources/welcome/dice_welcome/welcome_app.html
@@ -85,7 +85,7 @@ .slider { align-items: center; - animation: slideUpContent 600ms 3s cubic-bezier(.4, .2, 0, 1) both; + animation: slideUpContent 600ms 2.5s cubic-bezier(.4, .2, 0, 1) both; display: flex; flex: 1; flex-direction: column; @@ -94,7 +94,7 @@ } .heading-container { - animation: fadeInAndSlideUp 1s 600ms cubic-bezier(.4, .2, 0, 1) both; + animation: fadeInAndSlideUp 1s 400ms cubic-bezier(.4, .2, 0, 1) both; color: var(--paper-grey-800); font-size: 2.5em; line-height: 1em; @@ -104,13 +104,13 @@ } .heading { - animation: fadeOutAndSlideUp 600ms 2.6s cubic-bezier(.4, .2, 0, 1) forwards; + animation: fadeOutAndSlideUp 600ms 2.1s cubic-bezier(.4, .2, 0, 1) forwards; /* Makes sure fading-in/out doesn't impact the logo position. */ position: absolute; } .second-heading { - animation: fadeInAndSlideUp 600ms 3s cubic-bezier(.4, .2, 0, 1) both; + animation: fadeInAndSlideUp 600ms 2.5s cubic-bezier(.4, .2, 0, 1) both; font-size: 0.6em; } @@ -132,7 +132,7 @@ } .signin { - animation: fadeInAndSlideUp 600ms 3s cubic-bezier(.4, .2, 0, 1) both; + animation: fadeInAndSlideUp 600ms 2.5s cubic-bezier(.4, .2, 0, 1) both; } .signin-description {
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index 07294d3b..5c3fbc1f 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -101,15 +101,15 @@ } ACTION_P(InvokeDoneCallback, verdict) { - std::unique_ptr<ClientPhishingRequest> request(::std::tr1::get<1>(args)); + std::unique_ptr<ClientPhishingRequest> request(std::get<1>(args)); request->CopyFrom(*verdict); - ::std::tr1::get<2>(args).Run(true, std::move(request)); + std::get<2>(args).Run(true, std::move(request)); } ACTION_P(InvokeMalwareCallback, verdict) { - std::unique_ptr<ClientMalwareRequest> request(::std::tr1::get<1>(args)); + std::unique_ptr<ClientMalwareRequest> request(std::get<1>(args)); request->CopyFrom(*verdict); - ::std::tr1::get<2>(args).Run(true, std::move(request)); + std::get<2>(args).Run(true, std::move(request)); } class MockClientSideDetectionService : public ClientSideDetectionService {
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc index afa279b..60c4ad2 100644 --- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include <tuple> #include <utility> #include <vector> @@ -117,12 +118,12 @@ class PreferenceValidationDelegateValues : public PreferenceValidationDelegateTest, public testing::WithParamInterface< - std::tr1::tuple<base::Value::Type, const char*> > { + std::tuple<base::Value::Type, const char*>> { protected: void SetUp() override { PreferenceValidationDelegateTest::SetUp(); - value_type_ = std::tr1::get<0>(GetParam()); - expected_value_ = std::tr1::get<1>(GetParam()); + value_type_ = std::get<0>(GetParam()); + expected_value_ = std::get<1>(GetParam()); } static std::unique_ptr<base::Value> MakeValue(base::Value::Type value_type) { @@ -179,31 +180,27 @@ // testing/gtest/include/gtest/internal/gtest-tuple.h:246:48: // error: array used as initializer testing::Values( - std::tr1::make_tuple(base::Value::Type::NONE, - const_cast<char*>("null")), - std::tr1::make_tuple(base::Value::Type::BOOLEAN, - const_cast<char*>("false")), - std::tr1::make_tuple(base::Value::Type::INTEGER, - const_cast<char*>("47")), - std::tr1::make_tuple(base::Value::Type::DOUBLE, - const_cast<char*>("0.47")), - std::tr1::make_tuple(base::Value::Type::STRING, - const_cast<char*>("i have a spleen")), - std::tr1::make_tuple(base::Value::Type::DICTIONARY, + std::make_tuple(base::Value::Type::NONE, const_cast<char*>("null")), + std::make_tuple(base::Value::Type::BOOLEAN, const_cast<char*>("false")), + std::make_tuple(base::Value::Type::INTEGER, const_cast<char*>("47")), + std::make_tuple(base::Value::Type::DOUBLE, const_cast<char*>("0.47")), + std::make_tuple(base::Value::Type::STRING, + const_cast<char*>("i have a spleen")), + std::make_tuple( + base::Value::Type::DICTIONARY, const_cast<char*>("{\"forty-seven\":47,\"twenty-two\":22}")), - std::tr1::make_tuple(base::Value::Type::LIST, - const_cast<char*>("[22,47]")))); + std::make_tuple(base::Value::Type::LIST, + const_cast<char*>("[22,47]")))); // Tests that no incidents are reported for relevant combinations of ValueState. class PreferenceValidationDelegateNoIncident : public PreferenceValidationDelegateTest, - public testing::WithParamInterface< - std::tr1::tuple<ValueState, ValueState>> { + public testing::WithParamInterface<std::tuple<ValueState, ValueState>> { protected: void SetUp() override { PreferenceValidationDelegateTest::SetUp(); - value_state_ = std::tr1::get<0>(GetParam()); - external_validation_value_state_ = std::tr1::get<1>(GetParam()); + value_state_ = std::get<0>(GetParam()); + external_validation_value_state_ = std::get<1>(GetParam()); } ValueState value_state_; @@ -239,13 +236,13 @@ class PreferenceValidationDelegateWithIncident : public PreferenceValidationDelegateTest, public testing::WithParamInterface< - std::tr1::tuple<ValueState, ValueState, bool>> { + std::tuple<ValueState, ValueState, bool>> { protected: void SetUp() override { PreferenceValidationDelegateTest::SetUp(); - value_state_ = std::tr1::get<0>(GetParam()); - external_validation_value_state_ = std::tr1::get<1>(GetParam()); - is_personal_ = std::tr1::get<2>(GetParam()); + value_state_ = std::get<0>(GetParam()); + external_validation_value_state_ = std::get<1>(GetParam()); + is_personal_ = std::get<2>(GetParam()); } ValueState value_state_;
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc index 539e9e4..14daf7c8 100644 --- a/chrome/browser/sessions/session_data_deleter.cc +++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -105,11 +105,15 @@ void SessionDataDeleter::DeleteSessionOnlyOriginCookies( const std::vector<net::CanonicalCookie>& cookies) { base::Time yesterday(base::Time::Now() - base::TimeDelta::FromDays(1)); + + auto delete_cookie_predicate = + storage_policy_->CreateDeleteCookieOnExitPredicate(); + DCHECK(delete_cookie_predicate); + for (const auto& cookie : cookies) { - GURL url = - net::cookie_util::CookieOriginToURL(cookie.Domain(), cookie.IsSecure()); - if (!storage_policy_->ShouldDeleteCookieOnExit(url)) + if (!delete_cookie_predicate.Run(cookie.Domain(), cookie.IsSecure())) { continue; + } // Delete a single cookie by setting its expiration time into the past. cookie_manager_->SetCanonicalCookie(
diff --git a/chrome/browser/ssl/cert_logger.proto b/chrome/browser/ssl/cert_logger.proto index a9373f6f..7f99dc6 100644 --- a/chrome/browser/ssl/cert_logger.proto +++ b/chrome/browser/ssl/cert_logger.proto
@@ -201,9 +201,9 @@ enum VerifyFlags { UNKNOWN_VERIFY_FLAG = 0; VERIFY_REV_CHECKING_ENABLED = 1; - VERIFY_EV_CERT = 2; - VERIFY_CERT_IO_ENABLED = 3; - VERIFY_REV_CHECKING_ENABLED_EV_ONLY = 4; + VERIFY_EV_CERT = 2 [deprecated = true]; + VERIFY_CERT_IO_ENABLED = 3 [deprecated = true]; + VERIFY_REV_CHECKING_ENABLED_EV_ONLY = 4 [deprecated = true]; VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS = 5; VERIFY_ENABLE_SHA1_LOCAL_ANCHORS = 6; VERIFY_DISABLE_SYMANTEC_ENFORCEMENT = 7;
diff --git a/chrome/browser/ssl/certificate_error_report.cc b/chrome/browser/ssl/certificate_error_report.cc index 7aefa74..2942cf64 100644 --- a/chrome/browser/ssl/certificate_error_report.cc +++ b/chrome/browser/ssl/certificate_error_report.cc
@@ -82,9 +82,6 @@ report_flags->Add(chrome_browser_ssl::TrialVerificationInfo::VERIFY_##flag); COPY_VERIFY_FLAGS(REV_CHECKING_ENABLED); - COPY_VERIFY_FLAGS(EV_CERT); - COPY_VERIFY_FLAGS(CERT_IO_ENABLED); - COPY_VERIFY_FLAGS(REV_CHECKING_ENABLED_EV_ONLY); COPY_VERIFY_FLAGS(REV_CHECKING_REQUIRED_LOCAL_ANCHORS); COPY_VERIFY_FLAGS(ENABLE_SHA1_LOCAL_ANCHORS); COPY_VERIFY_FLAGS(DISABLE_SYMANTEC_ENFORCEMENT);
diff --git a/chrome/browser/ssl/certificate_transparency_browsertest.cc b/chrome/browser/ssl/certificate_transparency_browsertest.cc index a53dd0c8..190b3ea 100644 --- a/chrome/browser/ssl/certificate_transparency_browsertest.cc +++ b/chrome/browser/ssl/certificate_transparency_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/certificate_transparency/features.h" #include "components/certificate_transparency/single_tree_tracker.h" +#include "components/certificate_transparency/sth_distributor.h" #include "components/certificate_transparency/tree_state_tracker.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/browser_test_utils.h" @@ -23,7 +24,6 @@ #include "net/cert/ct_serialization.h" #include "net/cert/mock_cert_verifier.h" #include "net/cert/signed_tree_head.h" -#include "net/cert/sth_distributor.h" #include "net/dns/mock_host_resolver.h" #include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h"
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 7c0cd51..bee8656 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -165,6 +165,7 @@ url_(url), reason_(reason), initial_page_load_(initial_page_load), + proceeded_(false), callback_(callback), scoped_observer_(this), weak_ptr_factory_(this) {} @@ -337,7 +338,11 @@ features::kSupervisedUserCommittedInterstitials)) { ProceedInternal(); } else { - interstitial_page_->Proceed(); + // Interstitial page deletes the interstitial when proceeding but not + // synchronously, so a check is required to avoid calling proceed twice. + if (!proceeded_) + interstitial_page_->Proceed(); + proceeded_ = true; } } }
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.h b/chrome/browser/supervised_user/supervised_user_interstitial.h index 005e5aa..df67241 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.h +++ b/chrome/browser/supervised_user/supervised_user_interstitial.h
@@ -118,6 +118,9 @@ // Interstitials behave very differently in those cases. bool initial_page_load_; + // True if we have already called Proceed() on the interstitial page. + bool proceeded_; + base::Callback<void(bool)> callback_; ScopedObserver<SupervisedUserService, SupervisedUserInterstitial>
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 814a0a53..9143842 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2527,9 +2527,15 @@ "cocoa/extensions/chooser_dialog_cocoa.mm", "cocoa/extensions/chooser_dialog_cocoa_controller.h", "cocoa/extensions/chooser_dialog_cocoa_controller.mm", + "cocoa/extensions/extension_install_dialog_controller.h", + "cocoa/extensions/extension_install_dialog_controller.mm", + "cocoa/extensions/extension_install_view_controller.h", + "cocoa/extensions/extension_install_view_controller.mm", "cocoa/extensions/extension_installed_bubble_controller.h", "cocoa/extensions/extension_installed_bubble_controller.mm", "cocoa/extensions/extension_uninstall_dialog_cocoa.mm", + "cocoa/extensions/windowed_install_dialog_controller.h", + "cocoa/extensions/windowed_install_dialog_controller.mm", "cocoa/external_protocol_dialog_views_mac.mm", "cocoa/global_error_bubble_controller.h", "cocoa/global_error_bubble_controller.mm", @@ -2865,6 +2871,8 @@ "views/harmony/harmony_layout_provider.h", "views/harmony/harmony_typography_provider.cc", "views/harmony/harmony_typography_provider.h", + "views/harmony/material_refresh_layout_provider.cc", + "views/harmony/material_refresh_layout_provider.h", "views/harmony/textfield_layout.cc", "views/harmony/textfield_layout.h", "views/hover_button.cc", @@ -3567,6 +3575,7 @@ deps += [ "//ui/app_list", "//ui/app_list/vector_icons", + "//ui/views/mus/remote_view:remote_view_provider", ] if (is_chromeos) { @@ -3619,10 +3628,10 @@ "app_list/crostini/crostini_installer_view.h", "app_list/crostini/crostini_util.cc", "app_list/crostini/crostini_util.h", + "app_list/internal_app/internal_app_metadata.cc", + "app_list/internal_app/internal_app_metadata.h", "app_list/search/arc_app_result.cc", "app_list/search/arc_app_result.h", - "app_list/search/internal_app_metadata.cc", - "app_list/search/internal_app_metadata.h", "app_list/search/internal_app_result.cc", "app_list/search/internal_app_result.h", "ash/launcher/arc_app_deferred_launcher_controller.cc",
diff --git a/chrome/browser/ui/android/overlay/overlay_window_android.cc b/chrome/browser/ui/android/overlay/overlay_window_android.cc index a6b9df5e..3ce7dcd 100644 --- a/chrome/browser/ui/android/overlay/overlay_window_android.cc +++ b/chrome/browser/ui/android/overlay/overlay_window_android.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/overlay/overlay_window.h" +#include "content/public/browser/overlay_window.h" // static -std::unique_ptr<OverlayWindow> OverlayWindow::Create() { +std::unique_ptr<content::OverlayWindow> content::OverlayWindow::Create() { return nullptr; }
diff --git a/chrome/browser/ui/android/tab_model/tab_model.h b/chrome/browser/ui/android/tab_model/tab_model.h index 80ef5c0..5ca0a31f 100644 --- a/chrome/browser/ui/android/tab_model/tab_model.h +++ b/chrome/browser/ui/android/tab_model/tab_model.h
@@ -64,6 +64,10 @@ // Return true if we are currently restoring sessions asynchronously. virtual bool IsSessionRestoreInProgress() const = 0; + // Return true if this class is the currently selected in the correspond + // tab model selector. + virtual bool IsCurrentModel() const = 0; + protected: explicit TabModel(Profile* profile, bool is_tabbed_activity); ~TabModel() override;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc index 3811f64..987e09c1 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -145,6 +145,11 @@ env, java_object_.get(env)); } +bool TabModelJniBridge::IsCurrentModel() const { + JNIEnv* env = AttachCurrentThread(); + return Java_TabModelJniBridge_isCurrentModel(env, java_object_.get(env)); +} + void TabModelJniBridge::BroadcastSessionRestoreComplete( JNIEnv* env, const JavaParamRef<jobject>& obj) {
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h index a3bfa52d..9391fa1 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h
@@ -59,6 +59,10 @@ // Return true if we are currently restoring sessions asynchronously. bool IsSessionRestoreInProgress() const override; + // Return true if this class is the currently selected in the correspond + // tab model selector. + bool IsCurrentModel() const override; + // Instructs the TabModel to broadcast a notification that all tabs are now // loaded from storage. void BroadcastSessionRestoreComplete(
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc index 44c0215..8fcf599 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc
@@ -29,6 +29,7 @@ return nullptr; } bool IsSessionRestoreInProgress() const override { return false; } + bool IsCurrentModel() const override { return false; } TabAndroid* GetTabAt(int index) const override { return nullptr; } void SetActiveIndex(int index) override {} void CloseTabAt(int index) override {}
diff --git a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc index a42a1219..e8869b1 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
@@ -42,6 +42,7 @@ return NULL; } bool IsSessionRestoreInProgress() const override { return false; } + bool IsCurrentModel() const override { return false; } TabAndroid* GetTabAt(int index) const override { return NULL; } void SetActiveIndex(int index) override {} void CloseTabAt(int index) override {}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index 64d3bfd..3b0a9683 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -630,8 +630,9 @@ if (SetNotificationsEnabledDeferred(prefs_).Get(app_id, &deferred)) notifications_enabled = deferred; - arc::mojom::OrientationLock orientation_lock = - static_cast<arc::mojom::OrientationLock>(orientation_lock_value); + arc::mojom::OrientationLockDeprecated orientation_lock = + static_cast<arc::mojom::OrientationLockDeprecated>( + orientation_lock_value); return std::make_unique<AppInfo>( name, package_name, activity, intent_uri, icon_resource_id, @@ -818,17 +819,12 @@ if (tracked_apps_.count(app_id)) continue; const ArcDefaultAppList::AppInfo& app_info = *default_app.second.get(); - AddAppAndShortcut(false /* app_ready */, - app_info.name, - app_info.package_name, - app_info.activity, - std::string() /* intent_uri */, - std::string() /* icon_resource_id */, - false /* sticky */, - false /* notifications_enabled */, - false /* shortcut */, - true /* launchable */, - arc::mojom::OrientationLock::NONE); + AddAppAndShortcut( + false /* app_ready */, app_info.name, app_info.package_name, + app_info.activity, std::string() /* intent_uri */, + std::string() /* icon_resource_id */, false /* sticky */, + false /* notifications_enabled */, false /* shortcut */, + true /* launchable */, arc::mojom::OrientationLockDeprecated::NONE); } } @@ -910,7 +906,7 @@ std::string() /* icon_resource_id */, false /* sticky */, false /* notifications_enabled */, false /* shortcut */, false /* launchable */, - arc::mojom::OrientationLock::NONE); + arc::mojom::OrientationLockDeprecated::NONE); } } @@ -925,7 +921,7 @@ const bool notifications_enabled, const bool shortcut, const bool launchable, - const arc::mojom::OrientationLock orientation_lock) { + const arc::mojom::OrientationLockDeprecated orientation_lock) { const std::string app_id = shortcut ? GetAppId(package_name, intent_uri) : GetAppId(package_name, activity); @@ -1112,18 +1108,11 @@ ready_apps_.clear(); for (const auto& app : apps) { // TODO(oshima): Do we have to update orientation? - AddAppAndShortcut( - true /* app_ready */, - app->name, - app->package_name, - app->activity, - std::string() /* intent_uri */, - std::string() /* icon_resource_id */, - app->sticky, - app->notifications_enabled, - false /* shortcut */, - true /* launchable */, - app->orientation_lock); + AddAppAndShortcut(true /* app_ready */, app->name, app->package_name, + app->activity, std::string() /* intent_uri */, + std::string() /* icon_resource_id */, app->sticky, + app->notifications_enabled, false /* shortcut */, + true /* launchable */, app->orientation_lock_deprecated); } // Detect removed ARC apps after current refresh. @@ -1187,17 +1176,12 @@ return; } - AddAppAndShortcut(true /* app_ready */, - app_info.name, - app_info.package_name, - app_info.activity, - std::string() /* intent_uri */, - std::string() /* icon_resource_id */, - app_info.sticky, - app_info.notifications_enabled, - false /* shortcut */, + AddAppAndShortcut(true /* app_ready */, app_info.name, app_info.package_name, + app_info.activity, std::string() /* intent_uri */, + std::string() /* icon_resource_id */, app_info.sticky, + app_info.notifications_enabled, false /* shortcut */, true /* launchable */, - app_info.orientation_lock); + app_info.orientation_lock_deprecated); } void ArcAppListPrefs::OnAppAddedDeprecated(arc::mojom::AppInfoPtr app) { @@ -1257,17 +1241,12 @@ return; } - AddAppAndShortcut(true /* app_ready */, - shortcut->name, - shortcut->package_name, - std::string() /* activity */, - shortcut->intent_uri, - shortcut->icon_resource_id, - false /* sticky */, - false /* notifications_enabled */, - true /* shortcut */, - true /* launchable */, - arc::mojom::OrientationLock::NONE); + AddAppAndShortcut(true /* app_ready */, shortcut->name, + shortcut->package_name, std::string() /* activity */, + shortcut->intent_uri, shortcut->icon_resource_id, + false /* sticky */, false /* notifications_enabled */, + true /* shortcut */, true /* launchable */, + arc::mojom::OrientationLockDeprecated::NONE); } void ArcAppListPrefs::OnUninstallShortcut(const std::string& package_name, @@ -1420,11 +1399,12 @@ observer.OnTaskDestroyed(task_id); } -void ArcAppListPrefs::OnTaskOrientationLockRequested( +void ArcAppListPrefs::OnTaskOrientationLockRequestedDeprecated( int32_t task_id, - const arc::mojom::OrientationLock orientation_lock) { + const arc::mojom::OrientationLockDeprecated orientation_lock) { for (auto& observer : observer_list_) - observer.OnTaskOrientationLockRequested(task_id, orientation_lock); + observer.OnTaskOrientationLockRequestedDeprecated(task_id, + orientation_lock); } void ArcAppListPrefs::OnTaskSetActive(int32_t task_id) { @@ -1611,20 +1591,21 @@ observer.OnAppReadyChanged(app_id, ready); } -ArcAppListPrefs::AppInfo::AppInfo(const std::string& name, - const std::string& package_name, - const std::string& activity, - const std::string& intent_uri, - const std::string& icon_resource_id, - const base::Time& last_launch_time, - const base::Time& install_time, - bool sticky, - bool notifications_enabled, - bool ready, - bool showInLauncher, - bool shortcut, - bool launchable, - arc::mojom::OrientationLock orientation_lock) +ArcAppListPrefs::AppInfo::AppInfo( + const std::string& name, + const std::string& package_name, + const std::string& activity, + const std::string& intent_uri, + const std::string& icon_resource_id, + const base::Time& last_launch_time, + const base::Time& install_time, + bool sticky, + bool notifications_enabled, + bool ready, + bool showInLauncher, + bool shortcut, + bool launchable, + arc::mojom::OrientationLockDeprecated orientation_lock) : name(name), package_name(package_name), activity(activity),
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h index babb4b4..b4859991 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
@@ -70,7 +70,7 @@ bool showInLauncher, bool shortcut, bool launchable, - arc::mojom::OrientationLock orientation_lock); + arc::mojom::OrientationLockDeprecated orientation_lock); ~AppInfo(); std::string name; @@ -86,7 +86,7 @@ bool showInLauncher; bool shortcut; bool launchable; - arc::mojom::OrientationLock orientation_lock; + arc::mojom::OrientationLockDeprecated orientation_lock; }; struct PackageInfo { @@ -137,9 +137,9 @@ const std::vector<uint8_t>& icon_png_data) {} // Notifies that task has been destroyed. virtual void OnTaskDestroyed(int32_t task_id) {} - virtual void OnTaskOrientationLockRequested( + virtual void OnTaskOrientationLockRequestedDeprecated( int32_t task_id, - const arc::mojom::OrientationLock orientation_lock) {} + const arc::mojom::OrientationLockDeprecated orientation_lock) {} // Notifies that task has been activated and moved to the front. virtual void OnTaskSetActive(int32_t task_id) {} @@ -320,9 +320,9 @@ const std::string& label, const std::vector<uint8_t>& icon_png_data) override; void OnTaskDestroyed(int32_t task_id) override; - void OnTaskOrientationLockRequested( + void OnTaskOrientationLockRequestedDeprecated( int32_t task_id, - const arc::mojom::OrientationLock orientation_lock) override; + const arc::mojom::OrientationLockDeprecated orientation_lock) override; void OnTaskSetActive(int32_t task_id) override; void OnNotificationsEnabledChanged(const std::string& package_name, bool enabled) override; @@ -349,17 +349,18 @@ bool installed) const; void AddApp(const arc::mojom::AppInfo& app_info); - void AddAppAndShortcut(bool app_ready, - const std::string& name, - const std::string& package_name, - const std::string& activity, - const std::string& intent_uri, - const std::string& icon_resource_id, - const bool sticky, - const bool notifications_enabled, - const bool shortcut, - const bool launchable, - arc::mojom::OrientationLock orientation_lock); + void AddAppAndShortcut( + bool app_ready, + const std::string& name, + const std::string& package_name, + const std::string& activity, + const std::string& intent_uri, + const std::string& icon_resource_id, + const bool sticky, + const bool notifications_enabled, + const bool shortcut, + const bool launchable, + arc::mojom::OrientationLockDeprecated orientation_lock); // Adds or updates local pref for given package. void AddOrUpdatePackagePrefs(PrefService* prefs, const arc::mojom::ArcPackageInfo& package);
diff --git a/chrome/browser/ui/app_list/arc/arc_usb_host_permission_browsertest.cc b/chrome/browser/ui/app_list/arc/arc_usb_host_permission_browsertest.cc index 4727957f..d8275204 100644 --- a/chrome/browser/ui/app_list/arc/arc_usb_host_permission_browsertest.cc +++ b/chrome/browser/ui/app_list/arc/arc_usb_host_permission_browsertest.cc
@@ -124,14 +124,30 @@ package_name, usb_device_entry, allowed); } + void GrantTemporayUsbAccessPermission( + const std::string& package_name, + const ArcUsbHostPermissionManager::UsbDeviceEntry& usb_device_entry) { + arc_usb_permission_manager_->GrantUsbAccessPermission( + package_name, usb_device_entry.guid, usb_device_entry.vendor_id, + usb_device_entry.product_id); + } + + std::unordered_set<std::string> GetEventPackageList( + const ArcUsbHostPermissionManager::UsbDeviceEntry& usb_device_entry) + const { + return arc_usb_permission_manager_->GetEventPackageList( + usb_device_entry.guid, usb_device_entry.serial_number, + usb_device_entry.vendor_id, usb_device_entry.product_id); + } + bool HasUsbScanDeviceListPermission(const std::string& package_name) const { return arc_usb_permission_manager_->HasUsbScanDeviceListPermission( package_name); } - bool HasUsbAccessPermission( - const std::string& package_name, - const ArcUsbHostPermissionManager::UsbDeviceEntry& usb_device_entry) { + bool HasUsbAccessPermission(const std::string& package_name, + const ArcUsbHostPermissionManager::UsbDeviceEntry& + usb_device_entry) const { return arc_usb_permission_manager_->HasUsbAccessPermission( package_name, usb_device_entry); } @@ -149,6 +165,28 @@ DISALLOW_COPY_AND_ASSIGN(ArcUsbHostPermissionTest); }; +IN_PROC_BROWSER_TEST_F(ArcUsbHostPermissionTest, UsbTemporayPermissionTest) { + AddArcApp(kAppName, kPackageName, kAppActivity); + AddArcPackage(kPackageName); + // Persistent device0. + const std::string guid0 = "TestGuidXXXXXX0"; + const base::string16 device_name0 = base::UTF8ToUTF16("TestDevice0"); + const base::string16 serial_number0 = base::UTF8ToUTF16("TestSerialNumber0"); + uint16_t vendor_id0 = 123; + uint16_t product_id0 = 456; + + ArcUsbHostPermissionManager::UsbDeviceEntry testDevice0( + guid0, device_name0, serial_number0, vendor_id0, product_id0); + + GrantTemporayUsbAccessPermission(kPackageName, testDevice0); + EXPECT_TRUE(HasUsbAccessPermission(kPackageName, testDevice0)); + EXPECT_EQ(1u, GetEventPackageList(testDevice0).size()); + + DeviceRemoved(guid0); + EXPECT_FALSE(HasUsbAccessPermission(kPackageName, testDevice0)); + EXPECT_EQ(0u, GetEventPackageList(testDevice0).size()); +} + IN_PROC_BROWSER_TEST_F(ArcUsbHostPermissionTest, UsbChromePrefsTest) { AddArcApp(kAppName, kPackageName, kAppActivity); AddArcPackage(kPackageName);
diff --git a/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.cc b/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.cc index 199d2d1..8d6008b 100644 --- a/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.cc +++ b/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.cc
@@ -256,12 +256,47 @@ const std::string& guid, const base::string16& serial_number, uint16_t vendor_id, - uint16_t product_id) { - UsbDeviceEntry usb_device_entry(guid, base::string16(), serial_number, - vendor_id, product_id); + uint16_t product_id) const { + UsbDeviceEntry usb_device_entry(guid, base::string16() /*device_name*/, + serial_number, vendor_id, product_id); return HasUsbAccessPermission(package_name, usb_device_entry); } +void ArcUsbHostPermissionManager::GrantUsbAccessPermission( + const std::string& package_name, + const std::string& guid, + uint16_t vendor_id, + uint16_t product_id) { + // Create non-persistent usb device entry with empty serial_number. + UsbDeviceEntry usb_device_entry(guid, base::string16() /*device_name*/, + base::string16() /*serial_number*/, vendor_id, + product_id); + DCHECK(!usb_device_entry.IsPersistent()); + UpdateArcUsbAccessPermission(package_name, usb_device_entry, + true /*allowed*/); +} + +std::unordered_set<std::string> +ArcUsbHostPermissionManager::GetEventPackageList( + const std::string& guid, + const base::string16& serial_number, + uint16_t vendor_id, + uint16_t product_id) const { + // Packages with USB device scan permission should receive USB events. + std::unordered_set<std::string> event_packages( + usb_scan_devicelist_permission_packages_); + + // Packages have USB access permission to this device should receive USB + // events for this USB device. + UsbDeviceEntry usb_device_entry(guid, base::string16() /*device_name*/, + serial_number, vendor_id, product_id); + for (const auto& entry : usb_access_permission_dict_) { + if (entry.second.Matches(usb_device_entry)) + event_packages.emplace(entry.first); + } + return event_packages; +} + void ArcUsbHostPermissionManager::DeviceRemoved(const std::string& guid) { // Remove pending requests. pending_requests_.erase( @@ -359,7 +394,7 @@ bool ArcUsbHostPermissionManager::HasUsbAccessPermission( const std::string& package_name, - const UsbDeviceEntry& usb_device_entry) { + const UsbDeviceEntry& usb_device_entry) const { auto range = usb_access_permission_dict_.equal_range(package_name); for (auto iter = range.first; iter != range.second; iter++) { if (iter->second.Matches(usb_device_entry))
diff --git a/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.h b/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.h index f9f6a8b..9bfca3f 100644 --- a/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.h +++ b/chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.h
@@ -118,7 +118,16 @@ const std::string& guid, const base::string16& serial_number, uint16_t vendor_id, - uint16_t product_id) override; + uint16_t product_id) const override; + void GrantUsbAccessPermission(const std::string& package_name, + const std::string& guid, + uint16_t vendor_id, + uint16_t product_id) override; + std::unordered_set<std::string> GetEventPackageList( + const std::string& guid, + const base::string16& serial_number, + uint16_t vendor_id, + uint16_t product_id) const override; void DeviceRemoved(const std::string& guid) override; void ClearPermissionRequests() override; @@ -156,7 +165,7 @@ bool HasUsbScanDeviceListPermission(const std::string& package_name) const; bool HasUsbAccessPermission(const std::string& package_name, - const UsbDeviceEntry& usb_device_entry); + const UsbDeviceEntry& usb_device_entry) const; // Callback for UI permission dialog. void OnUsbPermissionReceived(UsbPermissionRequest request, bool allowed);
diff --git a/chrome/browser/ui/app_list/search/internal_app_metadata.cc b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc similarity index 64% rename from chrome/browser/ui/app_list/search/internal_app_metadata.cc rename to chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc index 247caeb..f67301f 100644 --- a/chrome/browser/ui/app_list/search/internal_app_metadata.cc +++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/app_list/search/internal_app_metadata.h" +#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" +#include "ash/public/cpp/app_list/internal_app_id_constants.h" +#include "ash/resources/grit/ash_resources.h" #include "base/no_destructor.h" -#include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h" namespace app_list { @@ -13,8 +14,10 @@ const std::vector<InternalApp>& GetInternalAppList() { static const base::NoDestructor<std::vector<InternalApp>> internal_app_list( {{kInternalAppIdKeyboardShortcutViewer, - IDS_LAUNCHER_SEARCHABLE_APP_KEYBOARD_SHORTCUT_VIEWER, - IDR_KEYBOARD_SHORTCUT_VIEWER_LOGO_192}}); + IDS_INTERNAL_APP_KEYBOARD_SHORTCUT_VIEWER, + IDR_KEYBOARD_SHORTCUT_VIEWER_LOGO_192}, + {kInternalAppIdSettings, IDS_INTERNAL_APP_SETTINGS, + IDR_SETTINGS_LOGO_192}}); return *internal_app_list; }
diff --git a/chrome/browser/ui/app_list/search/internal_app_metadata.h b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h similarity index 71% rename from chrome/browser/ui/app_list/search/internal_app_metadata.h rename to chrome/browser/ui/app_list/internal_app/internal_app_metadata.h index 3df1c3c3a..d14be227 100644 --- a/chrome/browser/ui/app_list/search/internal_app_metadata.h +++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h
@@ -2,17 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_INTERNAL_APP_METADATA_H_ -#define CHROME_BROWSER_UI_APP_LIST_SEARCH_INTERNAL_APP_METADATA_H_ +#ifndef CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_METADATA_H_ +#define CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_METADATA_H_ #include <string> #include <vector> namespace app_list { -constexpr char kInternalAppIdKeyboardShortcutViewer[] = - "internal://keyboard_shortcut_viewer"; - // Metadata about an internal app. // Internal apps are these apps can run in Chrome OS directly, e.g. Keyboard // Shortcut Viewer. @@ -31,4 +28,4 @@ } // namespace app_list -#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_INTERNAL_APP_METADATA_H_ +#endif // CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_METADATA_H_
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_contents.h b/chrome/browser/ui/app_list/search/answer_card/answer_card_contents.h index 6d4a1cb7..8c13d5b 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_contents.h +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_contents.h
@@ -36,7 +36,9 @@ bool has_answer_card, const std::string& result_title, const std::string& issued_query) = 0; - virtual void DidStopLoading(const AnswerCardContents* source) = 0; + + // Invoked when |source| is ready to be shown. + virtual void OnContentsReady(const AnswerCardContents* source) = 0; private: DISALLOW_COPY_AND_ASSIGN(Delegate);
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc index e404d6e..dc95b6ad5 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc
@@ -162,7 +162,7 @@ base::TimeTicks::Now() - server_request_start_time_); } -void AnswerCardSearchProvider::DidStopLoading( +void AnswerCardSearchProvider::OnContentsReady( const AnswerCardContents* source) { NavigationContext& context_for_loading = GetNavigationContextForLoading(); DCHECK_EQ(source, context_for_loading.contents.get());
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h index 247f525..70b1993 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h
@@ -43,7 +43,7 @@ bool has_answer_card, const std::string& result_title, const std::string& issued_query) override; - void DidStopLoading(const AnswerCardContents* source) override; + void OnContentsReady(const AnswerCardContents* source) override; private: enum class RequestState {
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc index 5fd26df..86d43bd 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc
@@ -94,7 +94,7 @@ has_error, has_answer_card, title, issued_query); - provider()->DidStopLoading(contents); + provider()->OnContentsReady(contents); EXPECT_EQ(expected_result_count, results().size()); @@ -191,7 +191,7 @@ provider()->Start(base::UTF8ToUTF16(kCatQuery)); provider()->DidFinishNavigation(contents1(), GetSearchUrl(kCatQuery), false, true, kCatCardTitle, kCatQuery); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Basic Result", kCatCardId, token1(), kCatCardTitle); @@ -215,7 +215,7 @@ provider()->Start(base::UTF8ToUTF16(kCatQuery)); provider()->DidFinishNavigation(contents1(), GetSearchUrl(kCatQuery), false, true, kCatCardTitle, kCatQuery); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Cat Result 1", kCatCardId, token1(), kCatCardTitle); @@ -232,7 +232,7 @@ // The cat still stays. VerifyResult("Cat Result 3", kCatCardId, token1(), kCatCardTitle); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); // Once the dog finishes loading, it replaces the cat. VerifyResult("Dog Result 1", kDogCardId, token0(), kDogCardTitle); @@ -249,7 +249,7 @@ VerifyResult("Dog Result 3", kDogCardId, token0(), kDogCardTitle); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Shark Result", kSharkCardId, token1(), kSharkCardTitle); } @@ -261,7 +261,7 @@ provider()->Start(base::UTF8ToUTF16(kCatQuery)); provider()->DidFinishNavigation(contents1(), GetSearchUrl(kCatQuery), false, true, kCatCardTitle, kCatQuery); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Cat Result 1", kCatCardId, token1(), kCatCardTitle); @@ -276,7 +276,7 @@ EXPECT_EQ(0UL, results().size()); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); EXPECT_EQ(0UL, results().size()); @@ -291,7 +291,7 @@ EXPECT_EQ(0UL, results().size()); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); VerifyResult("Shark Result", kSharkCardId, token0(), kSharkCardTitle); } @@ -304,7 +304,7 @@ provider()->Start(base::UTF8ToUTF16(kCatQuery)); provider()->DidFinishNavigation(contents1(), GetSearchUrl(kCatQuery), false, true, kCatCardTitle, kCatQuery); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Cat Result 1", kCatCardId, token1(), kCatCardTitle); @@ -319,7 +319,7 @@ EXPECT_EQ(0UL, results().size()); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); EXPECT_EQ(0UL, results().size()); @@ -334,7 +334,7 @@ EXPECT_EQ(0UL, results().size()); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); VerifyResult("Shark Result", kSharkCardId, token0(), kSharkCardTitle); } @@ -357,17 +357,17 @@ provider()->DidFinishNavigation(contents1(), GetSearchUrl("c"), false, true, "Title c", "c"); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); EXPECT_EQ(0UL, results().size()); provider()->DidFinishNavigation(contents1(), GetSearchUrl("ca"), false, true, "Title ca", "ca"); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); EXPECT_EQ(0UL, results().size()); provider()->DidFinishNavigation(contents1(), GetSearchUrl(kCatQuery), false, true, kCatCardTitle, kCatQuery); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Cat Result", kCatCardId, token1(), kCatCardTitle); } @@ -379,7 +379,7 @@ provider()->Start(base::UTF8ToUTF16(kCatQuery)); provider()->DidFinishNavigation(contents1(), GetSearchUrl(kCatQuery), false, true, kCatCardTitle, kCatQuery); - provider()->DidStopLoading(contents1()); + provider()->OnContentsReady(contents1()); VerifyResult("Cat Result 1", kCatCardId, token1(), kCatCardTitle); @@ -400,19 +400,19 @@ provider()->DidFinishNavigation(contents0(), GetSearchUrl("d"), false, true, "Title d", "d"); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); VerifyResult("Cat Result 5", kCatCardId, token1(), kCatCardTitle); provider()->DidFinishNavigation(contents0(), GetSearchUrl("do"), false, true, "Title do", "do"); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); VerifyResult("Cat Result 5", kCatCardId, token1(), kCatCardTitle); provider()->DidFinishNavigation(contents0(), GetSearchUrl(kDogQuery), false, true, kDogCardTitle, kDogQuery); - provider()->DidStopLoading(contents0()); + provider()->OnContentsReady(contents0()); VerifyResult("Dog Result", kDogCardId, token0(), kDogCardTitle); }
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc index be1c6b4..8fcc7895 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/bind.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "chrome/browser/profiles/profile.h" @@ -27,6 +28,7 @@ #include "ui/views/controls/native/native_view_host.h" #include "ui/views/controls/webview/web_contents_set_background_color.h" #include "ui/views/controls/webview/webview.h" +#include "ui/views/mus/remote_view/remote_view_provider.h" #include "ui/views/widget/widget.h" namespace app_list { @@ -135,12 +137,12 @@ } // namespace AnswerCardWebContents::AnswerCardWebContents(Profile* profile) - : web_view_(std::make_unique<SearchAnswerWebView>(profile)), - web_contents_( + : web_contents_( content::WebContents::Create(content::WebContents::CreateParams( profile, content::SiteInstance::Create(profile)))), - profile_(profile) { + profile_(profile), + weak_ptr_factory_(this) { content::RendererPreferences* renderer_prefs = web_contents_->GetMutableRendererPrefs(); renderer_prefs->can_accept_load_drops = false; @@ -150,9 +152,6 @@ Observe(web_contents_.get()); web_contents_->SetDelegate(this); - web_view_->set_owned_by_client(); - web_view_->SetWebContents(web_contents_.get()); - web_view_->SetResizeBackgroundColor(SK_ColorTRANSPARENT); // Make the webview transparent since it's going to be shown on top of a // highlightable button. @@ -163,8 +162,17 @@ if (rvh) AttachToHost(rvh->GetWidget()); - if (AnswerCardContentsRegistry::Get()) + if (AnswerCardContentsRegistry::Get()) { + web_view_ = std::make_unique<SearchAnswerWebView>(profile); + web_view_->set_owned_by_client(); + web_view_->SetWebContents(web_contents_.get()); + web_view_->SetResizeBackgroundColor(SK_ColorTRANSPARENT); + token_ = AnswerCardContentsRegistry::Get()->Register(web_view_.get()); + } else { + remote_view_provider_ = std::make_unique<views::RemoteViewProvider>( + web_contents_->GetNativeView()); + } } AnswerCardWebContents::~AnswerCardWebContents() { @@ -194,7 +202,10 @@ content::WebContents* web_contents, const gfx::Size& new_size) { delegate()->UpdatePreferredSize(this); - web_view_->SetPreferredSize(new_size); + if (web_view_) + web_view_->SetPreferredSize(new_size); + + // TODO(https://crbug.com/812434): Support preferred size change for mash. } content::WebContents* AnswerCardWebContents::OpenURLFromTab( @@ -254,7 +265,14 @@ } void AnswerCardWebContents::DidStopLoading() { - delegate()->DidStopLoading(this); + if (!remote_view_provider_) { + delegate()->OnContentsReady(this); + return; + } + + remote_view_provider_->GetEmbedToken( + base::BindOnce(&AnswerCardWebContents::OnGotEmbedTokenAndNotify, + weak_ptr_factory_.GetWeakPtr())); } void AnswerCardWebContents::DidGetUserInteraction( @@ -298,4 +316,11 @@ host_ = nullptr; } +void AnswerCardWebContents::OnGotEmbedTokenAndNotify( + const base::UnguessableToken& token) { + token_ = token; + web_contents_->GetNativeView()->Show(); + delegate()->OnContentsReady(this); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.h b/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.h index d3380edb..d784534 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.h +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/memory/weak_ptr.h" #include "base/unguessable_token.h" #include "chrome/browser/ui/app_list/search/answer_card/answer_card_contents.h" #include "content/public/browser/render_widget_host.h" @@ -16,6 +17,7 @@ class Profile; namespace views { +class RemoteViewProvider; class WebView; } @@ -55,19 +57,31 @@ void AttachToHost(content::RenderWidgetHost* host); void DetachFromHost(); - // Web view for the web contents managed by this class. - const std::unique_ptr<views::WebView> web_view_; + void OnGotEmbedTokenAndNotify(const base::UnguessableToken& token); // Web contents managed by this class. const std::unique_ptr<content::WebContents> web_contents_; + // Web view for the web contents managed by this class. + // Note this is only used for classic ash. + std::unique_ptr<views::WebView> web_view_; + // Current widget host. content::RenderWidgetHost* host_ = nullptr; Profile* const profile_; // Unowned + // Token to embed the web contents. On classic ash, it is a token registered + // with AnswerCardContentsRegistry. On mash, it is the embedding token for + // the native window of |web_contents_|. base::UnguessableToken token_; + // Helper to prepare the native view of |web_contents_| to be embedded under + // mash. + std::unique_ptr<views::RemoteViewProvider> remote_view_provider_; + + base::WeakPtrFactory<AnswerCardWebContents> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(AnswerCardWebContents); };
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index 5f7d9263..a8d51206 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -32,9 +32,9 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" +#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" #include "chrome/browser/ui/app_list/search/arc_app_result.h" #include "chrome/browser/ui/app_list/search/extension_app_result.h" -#include "chrome/browser/ui/app_list/search/internal_app_metadata.h" #include "chrome/browser/ui/app_list/search/internal_app_result.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h"
diff --git a/chrome/browser/ui/app_list/search/arc_app_result.cc b/chrome/browser/ui/app_list/search/arc_app_result.cc index 8c718e7..fda48d8 100644 --- a/chrome/browser/ui/app_list/search/arc_app_result.cc +++ b/chrome/browser/ui/app_list/search/arc_app_result.cc
@@ -59,14 +59,13 @@ } std::unique_ptr<ChromeSearchResult> ArcAppResult::Duplicate() const { - ArcAppResult* copy = new ArcAppResult( + std::unique_ptr<ArcAppResult> copy = std::make_unique<ArcAppResult>( profile(), app_id(), controller(), display_type() == ash::SearchResultDisplayType::kRecommendation); copy->set_title(title()); copy->set_title_tags(title_tags()); copy->set_relevance(relevance()); - - return base::WrapUnique(copy); + return copy; } ui::MenuModel* ArcAppResult::GetContextMenuModel() {
diff --git a/chrome/browser/ui/app_list/search/internal_app_result.cc b/chrome/browser/ui/app_list/search/internal_app_result.cc index 8f86ae6..2ced3445 100644 --- a/chrome/browser/ui/app_list/search/internal_app_result.cc +++ b/chrome/browser/ui/app_list/search/internal_app_result.cc
@@ -4,11 +4,13 @@ #include "chrome/browser/ui/app_list/search/internal_app_result.h" +#include "ash/public/cpp/app_list/internal_app_id_constants.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" -#include "chrome/browser/ui/app_list/search/internal_app_metadata.h" +#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" #include "chrome/browser/ui/app_list/search/search_util.h" #include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h" +#include "chrome/browser/ui/chrome_pages.h" #include "ui/app_list/app_list_constants.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_skia_operations.h" @@ -55,8 +57,11 @@ if (display_type() != DisplayType::kRecommendation) RecordHistogram(APP_SEARCH_RESULT); - if (id() == kInternalAppIdKeyboardShortcutViewer) + if (id() == kInternalAppIdKeyboardShortcutViewer) { keyboard_shortcut_viewer_util::ShowKeyboardShortcutViewer(); + } else if (id() == kInternalAppIdSettings) { + chrome::ShowSettingsSubPageForProfile(profile(), std::string()); + } } std::unique_ptr<ChromeSearchResult> InternalAppResult::Duplicate() const {
diff --git a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc index 2c605b0c..75f4f68 100644 --- a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
@@ -47,6 +47,7 @@ "com.google.android.gm.ConversationListActivityGmail"; constexpr char kKeyboardShortcutHelperInternalName[] = "Keyboard Shortcut Helper"; +constexpr char kSettingsInternalName[] = "Settings"; } // namespace @@ -104,7 +105,8 @@ app_info.activity = activity; app_info.sticky = false; app_info.notifications_enabled = false; - app_info.orientation_lock = arc::mojom::OrientationLock::NONE; + app_info.orientation_lock_deprecated = + arc::mojom::OrientationLockDeprecated::NONE; arc_test_.app_instance()->SendAppAdded(app_info); return ArcAppListPrefs::GetAppId(package, activity); } @@ -262,22 +264,28 @@ prefs->SetLastLaunchTime(kHostedAppId, base::Time::FromInternalValue(20)); prefs->SetLastLaunchTime(kPackagedApp1Id, base::Time::FromInternalValue(10)); prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(5)); - EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Keyboard Shortcut Helper", - RunQuery("")); + EXPECT_EQ( + "Hosted App,Packaged App 1,Packaged App 2,Keyboard Shortcut " + "Helper,Settings", + RunQuery("")); prefs->SetLastLaunchTime(kHostedAppId, base::Time::FromInternalValue(5)); prefs->SetLastLaunchTime(kPackagedApp1Id, base::Time::FromInternalValue(10)); prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(20)); - EXPECT_EQ("Packaged App 2,Packaged App 1,Hosted App,Keyboard Shortcut Helper", - RunQuery("")); + EXPECT_EQ( + "Packaged App 2,Packaged App 1,Hosted App,Keyboard Shortcut " + "Helper,Settings", + RunQuery("")); // Times in the future should just be handled as highest priority. prefs->SetLastLaunchTime(kHostedAppId, kTestCurrentTime + base::TimeDelta::FromSeconds(5)); prefs->SetLastLaunchTime(kPackagedApp1Id, base::Time::FromInternalValue(10)); prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(5)); - EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Keyboard Shortcut Helper", - RunQuery("")); + EXPECT_EQ( + "Hosted App,Packaged App 1,Packaged App 2,Keyboard Shortcut " + "Helper,Settings", + RunQuery("")); } TEST_F(AppSearchProviderTest, FetchUnlaunchedRecommendations) { @@ -291,8 +299,10 @@ prefs->SetLastLaunchTime(kHostedAppId, base::Time::Now()); prefs->SetLastLaunchTime(kPackagedApp1Id, base::Time::FromInternalValue(0)); prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(0)); - EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Keyboard Shortcut Helper", - RunQuery("")); + EXPECT_EQ( + "Hosted App,Packaged App 1,Packaged App 2,Keyboard Shortcut " + "Helper,Settings", + RunQuery("")); } TEST_F(AppSearchProviderTest, FilterDuplicate) { @@ -331,9 +341,15 @@ TEST_F(AppSearchProviderTest, FetchInternalApp) { CreateSearch(); + + // Search Keyboard Shortcut Helper. EXPECT_EQ(kKeyboardShortcutHelperInternalName, RunQuery("Keyboard")); EXPECT_EQ(kKeyboardShortcutHelperInternalName, RunQuery("Shortcut")); EXPECT_EQ(kKeyboardShortcutHelperInternalName, RunQuery("Helper")); + + // Search Settings. + EXPECT_EQ(kSettingsInternalName, RunQuery("Settings")); + EXPECT_EQ(kSettingsInternalName, RunQuery("Set")); } } // namespace test
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc b/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc index 8aa8a97..e7b617b 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc +++ b/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc
@@ -188,10 +188,10 @@ if (!match.Calculate(query, title)) return nullptr; - WebstoreResult* result = new WebstoreResult(profile_, app_id, icon_url, - is_paid, item_type, controller_); + std::unique_ptr<ChromeSearchResult> result = std::make_unique<WebstoreResult>( + profile_, app_id, icon_url, is_paid, item_type, controller_); result->UpdateFromMatch(title, match); - return base::WrapUnique(result); + return result; } } // namespace app_list
diff --git a/chrome/browser/ui/ash/ash_util.cc b/chrome/browser/ui/ash/ash_util.cc index c6c2567b1..88a1b9fb 100644 --- a/chrome/browser/ui/ash/ash_util.cc +++ b/chrome/browser/ui/ash/ash_util.cc
@@ -7,14 +7,20 @@ #include "ash/accelerators/accelerator_controller.h" #include "ash/mojo_interface_factory.h" #include "ash/public/cpp/config.h" +#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/interfaces/event_properties.mojom.h" #include "ash/shell.h" #include "base/macros.h" #include "chrome/browser/chromeos/ash_config.h" +#include "mojo/public/cpp/bindings/type_converter.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/mojom/interface_provider_spec.mojom.h" +#include "services/ui/public/cpp/property_type_converters.h" +#include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" namespace ash_util { @@ -74,4 +80,22 @@ ash::mojom::kWillProcessAccelerator_KeyEventProperty); } +void SetupWidgetInitParamsForContainer(views::Widget::InitParams* params, + int container_id) { + DCHECK_GE(container_id, ash::kShellWindowId_MinContainer); + DCHECK_LE(container_id, ash::kShellWindowId_MaxContainer); + + if (chromeos::GetAshConfig() == ash::Config::MASH) { + using ui::mojom::WindowManager; + params->mus_properties[WindowManager::kContainerId_InitProperty] = + mojo::ConvertTo<std::vector<uint8_t>>(container_id); + params->mus_properties[WindowManager::kDisplayId_InitProperty] = + mojo::ConvertTo<std::vector<uint8_t>>( + display::Screen::GetScreen()->GetPrimaryDisplay().id()); + } else { + params->parent = ash::Shell::GetContainer( + ash::Shell::GetPrimaryRootWindow(), container_id); + } +} + } // namespace ash_util
diff --git a/chrome/browser/ui/ash/ash_util.h b/chrome/browser/ui/ash/ash_util.h index 2ec382b..5fbd9a3 100644 --- a/chrome/browser/ui/ash/ash_util.h +++ b/chrome/browser/ui/ash/ash_util.h
@@ -10,6 +10,7 @@ #include "ash/public/cpp/config.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" +#include "ui/views/widget/widget.h" namespace service_manager { class Service; @@ -41,6 +42,13 @@ // Returns true if ash has an accelerator for |key_event| that is enabled. bool WillAshProcessAcceleratorForEvent(const ui::KeyEvent& key_event); +// Sets up |params| to place the widget in an ash shell window container on +// the primary display. See ash/public/cpp/shell_window_ids.h for |container_id| +// values. +// TODO(jamescook): Extend to take a display_id. +void SetupWidgetInitParamsForContainer(views::Widget::InitParams* params, + int container_id); + } // namespace ash_util #endif // CHROME_BROWSER_UI_ASH_ASH_UTIL_H_
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc index 04160ef..d56867a 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -36,23 +36,23 @@ constexpr size_t kMaxIconPngSize = 64 * 1024; // 64 kb ash::OrientationLockType OrientationLockTypeFromMojo( - arc::mojom::OrientationLock orientation_lock) { + arc::mojom::OrientationLockDeprecated orientation_lock) { switch (orientation_lock) { - case arc::mojom::OrientationLock::NONE: + case arc::mojom::OrientationLockDeprecated::NONE: return ash::OrientationLockType::kAny; - case arc::mojom::OrientationLock::CURRENT: + case arc::mojom::OrientationLockDeprecated::CURRENT: return ash::OrientationLockType::kCurrent; - case arc::mojom::OrientationLock::PORTRAIT: + case arc::mojom::OrientationLockDeprecated::PORTRAIT: return ash::OrientationLockType::kPortrait; - case arc::mojom::OrientationLock::LANDSCAPE: + case arc::mojom::OrientationLockDeprecated::LANDSCAPE: return ash::OrientationLockType::kLandscape; - case arc::mojom::OrientationLock::LANDSCAPE_PRIMARY: + case arc::mojom::OrientationLockDeprecated::LANDSCAPE_PRIMARY: return ash::OrientationLockType::kLandscapePrimary; - case arc::mojom::OrientationLock::LANDSCAPE_SECONDARY: + case arc::mojom::OrientationLockDeprecated::LANDSCAPE_SECONDARY: return ash::OrientationLockType::kLandscapeSecondary; - case arc::mojom::OrientationLock::PORTRAIT_PRIMARY: + case arc::mojom::OrientationLockDeprecated::PORTRAIT_PRIMARY: return ash::OrientationLockType::kPortraitPrimary; - case arc::mojom::OrientationLock::PORTRAIT_SECONDARY: + case arc::mojom::OrientationLockDeprecated::PORTRAIT_SECONDARY: return ash::OrientationLockType::kPortraitSecondary; } NOTREACHED(); @@ -97,12 +97,13 @@ return has_requested_orientation_lock_; } - void set_requested_orientation_lock(arc::mojom::OrientationLock lock) { + void set_requested_orientation_lock( + arc::mojom::OrientationLockDeprecated lock) { has_requested_orientation_lock_ = true; requested_orientation_lock_ = lock; } - arc::mojom::OrientationLock requested_orientation_lock() const { + arc::mojom::OrientationLockDeprecated requested_orientation_lock() const { return requested_orientation_lock_; } @@ -119,8 +120,8 @@ const std::string launch_intent_; bool has_requested_orientation_lock_ = false; - arc::mojom::OrientationLock requested_orientation_lock_ = - arc::mojom::OrientationLock::NONE; + arc::mojom::OrientationLockDeprecated requested_orientation_lock_ = + arc::mojom::OrientationLockDeprecated::NONE; // Keeps overridden window title. std::string title_; // Keeps overridden window icon. @@ -377,9 +378,9 @@ task_id_to_app_window_info_.erase(it); } -void ArcAppWindowLauncherController::OnTaskOrientationLockRequested( +void ArcAppWindowLauncherController::OnTaskOrientationLockRequestedDeprecated( int32_t task_id, - const arc::mojom::OrientationLock orientation_lock) { + const arc::mojom::OrientationLockDeprecated orientation_lock) { // Don't save to AppInfo in prefs because this is requested in runtime. AppWindowInfo* info = GetAppWindowInfoForTask(task_id); DCHECK(info);
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h index ce204e5..8a26cbb0 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
@@ -70,9 +70,9 @@ const std::string& label, const std::vector<uint8_t>& icon_png_data) override; void OnTaskDestroyed(int task_id) override; - void OnTaskOrientationLockRequested( + void OnTaskOrientationLockRequestedDeprecated( int32_t task_id, - const arc::mojom::OrientationLock orientation_lock) override; + const arc::mojom::OrientationLockDeprecated orientation_lock) override; void OnTaskSetActive(int32_t task_id) override; int active_task_id() const { return active_task_id_; }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index 91f6c5a..0f7e81b 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -120,7 +120,7 @@ using extensions::Extension; using extensions::Manifest; using extensions::UnloadedExtensionReason; -using arc::mojom::OrientationLock; +using arc::mojom::OrientationLockDeprecated; namespace { constexpr char kOfflineGmailUrl[] = "https://mail.google.com/mail/mu/u"; @@ -954,12 +954,12 @@ arc::mojom::AppInfo CreateAppInfo(const std::string& name, const std::string& activity, const std::string& package_name, - OrientationLock lock) { + OrientationLockDeprecated lock) { arc::mojom::AppInfo appinfo; appinfo.name = name; appinfo.package_name = package_name; appinfo.activity = activity; - appinfo.orientation_lock = lock; + appinfo.orientation_lock_deprecated = lock; return appinfo; } @@ -971,7 +971,7 @@ app_info.activity, std::string() /* intent_uri */, std::string() /* icon_resource_id */, false /* sticky */, true /* notifications_enabled */, false /* shortcut */, - true /* launchable */, app_info.orientation_lock); + true /* launchable */, app_info.orientation_lock_deprecated); const std::string app_id = ArcAppListPrefs::GetAppId(app_info.package_name, app_info.activity); EXPECT_TRUE(prefs->GetApp(app_id)); @@ -986,9 +986,9 @@ } void NotifyOnTaskOrientationLockRequested(int32_t task_id, - OrientationLock lock) { + OrientationLockDeprecated lock) { ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs(); - prefs->OnTaskOrientationLockRequested(task_id, lock); + prefs->OnTaskOrientationLockRequestedDeprecated(task_id, lock); } // Needed for extension service & friends to work. @@ -2167,7 +2167,7 @@ SendListOfArcApps(); arc::mojom::AppInfo app_info = CreateAppInfo("Play Store", arc::kPlayStoreActivity, - arc::kPlayStorePackage, OrientationLock::NONE); + arc::kPlayStorePackage, OrientationLockDeprecated::NONE); EXPECT_EQ(arc::kPlayStoreAppId, AddArcAppAndShortcut(app_info)); std::string window_app_id("org.chromium.arc.1"); @@ -3787,8 +3787,9 @@ TEST_P(ChromeLauncherControllerWithArcTest, ArcAppPinPolicy) { InitLauncherControllerWithBrowser(); - arc::mojom::AppInfo appinfo = CreateAppInfo( - "Some App", "SomeActivity", "com.example.app", OrientationLock::NONE); + arc::mojom::AppInfo appinfo = + CreateAppInfo("Some App", "SomeActivity", "com.example.app", + OrientationLockDeprecated::NONE); const std::string app_id = AddArcAppAndShortcut(appinfo); // Set policy, that makes pins ARC app. Unlike native extension, for ARC app @@ -3870,8 +3871,8 @@ TEST_P(ChromeLauncherControllerWithArcTest, ShelfItemWithMultipleWindows) { InitLauncherControllerWithBrowser(); - arc::mojom::AppInfo appinfo = - CreateAppInfo("Test1", "test", "com.example.app", OrientationLock::NONE); + arc::mojom::AppInfo appinfo = CreateAppInfo( + "Test1", "test", "com.example.app", OrientationLockDeprecated::NONE); AddArcAppAndShortcut(appinfo); // Widgets will be deleted by the system. @@ -3934,15 +3935,16 @@ protected: void InitApps() { - appinfo_none_ = - CreateAppInfo("None", "None", "com.example.app", OrientationLock::NONE); + appinfo_none_ = CreateAppInfo("None", "None", "com.example.app", + OrientationLockDeprecated::NONE); appinfo_landscape_ = CreateAppInfo("Landscape", "Landscape", "com.example.app", - OrientationLock::LANDSCAPE); + OrientationLockDeprecated::LANDSCAPE); appinfo_portrait_ = CreateAppInfo("Portrait", "Portrait", "com.example.app", - OrientationLock::PORTRAIT); - appinfo_current_ = CreateAppInfo( - "LockCurrent", "current", "com.example.app", OrientationLock::CURRENT); + OrientationLockDeprecated::PORTRAIT); + appinfo_current_ = + CreateAppInfo("LockCurrent", "current", "com.example.app", + OrientationLockDeprecated::CURRENT); AddArcAppAndShortcut(appinfo_none_); AddArcAppAndShortcut(appinfo_landscape_); @@ -4066,12 +4068,13 @@ std::string app_id1("org.chromium.arc.1"); int task_id1 = 1; - arc::mojom::AppInfo appinfo1 = - CreateAppInfo("Test1", "test", "com.example.app", OrientationLock::NONE); + arc::mojom::AppInfo appinfo1 = CreateAppInfo( + "Test1", "test", "com.example.app", OrientationLockDeprecated::NONE); AddArcAppAndShortcut(appinfo1); NotifyOnTaskCreated(appinfo1, task_id1); - NotifyOnTaskOrientationLockRequested(task_id1, OrientationLock::PORTRAIT); + NotifyOnTaskOrientationLockRequested(task_id1, + OrientationLockDeprecated::PORTRAIT); // Widgets will be deleted by the system. CreateArcWindow(app_id1); @@ -4085,12 +4088,13 @@ std::string app_id2("org.chromium.arc.2"); int task_id2 = 2; - arc::mojom::AppInfo appinfo2 = - CreateAppInfo("Test2", "test", "com.example.app", OrientationLock::NONE); + arc::mojom::AppInfo appinfo2 = CreateAppInfo( + "Test2", "test", "com.example.app", OrientationLockDeprecated::NONE); // Create in tablet mode. AddArcAppAndShortcut(appinfo2); NotifyOnTaskCreated(appinfo2, task_id2); - NotifyOnTaskOrientationLockRequested(task_id2, OrientationLock::LANDSCAPE); + NotifyOnTaskOrientationLockRequested(task_id2, + OrientationLockDeprecated::LANDSCAPE); EXPECT_TRUE(controller->rotation_locked()); EXPECT_EQ(display::Display::ROTATE_270, display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); @@ -4151,20 +4155,20 @@ // OnTaskOrientationLockRequested can overwrite the current lock. NotifyOnTaskOrientationLockRequested(task_id_landscape_, - OrientationLock::NONE); + OrientationLockDeprecated::NONE); EXPECT_FALSE(controller->rotation_locked()); EXPECT_EQ(display::Display::ROTATE_0, display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); NotifyOnTaskOrientationLockRequested(task_id_landscape_, - OrientationLock::PORTRAIT); + OrientationLockDeprecated::PORTRAIT); EXPECT_TRUE(controller->rotation_locked()); EXPECT_EQ(display::Display::ROTATE_270, display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); // Non active window won't change the lock. NotifyOnTaskOrientationLockRequested(task_id_none_, - OrientationLock::LANDSCAPE); + OrientationLockDeprecated::LANDSCAPE); EXPECT_TRUE(controller->rotation_locked()); EXPECT_EQ(display::Display::ROTATE_270, display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); @@ -4182,7 +4186,7 @@ display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); NotifyOnTaskOrientationLockRequested(task_id_none_, - OrientationLock::PORTRAIT); + OrientationLockDeprecated::PORTRAIT); EXPECT_FALSE(controller->rotation_locked()); EXPECT_EQ(display::Display::ROTATE_0, display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); @@ -4195,7 +4199,8 @@ display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); // Manually unlock first. - NotifyOnTaskOrientationLockRequested(task_id_none_, OrientationLock::NONE); + NotifyOnTaskOrientationLockRequested(task_id_none_, + OrientationLockDeprecated::NONE); EXPECT_FALSE(controller->rotation_locked()); }
diff --git a/chrome/browser/ui/ash/launcher/settings_window_observer.cc b/chrome/browser/ui/ash/launcher/settings_window_observer.cc index 3ea75f6..f278d2f 100644 --- a/chrome/browser/ui/ash/launcher/settings_window_observer.cc +++ b/chrome/browser/ui/ash/launcher/settings_window_observer.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/ash/launcher/settings_window_observer.h" +#include "ash/public/cpp/app_list/internal_app_id_constants.h" #include "ash/public/cpp/shelf_item.h" #include "ash/public/cpp/window_properties.h" #include "ash/resources/grit/ash_resources.h" @@ -51,17 +52,14 @@ void SettingsWindowObserver::OnNewSettingsWindow(Browser* settings_browser) { aura::Window* window = settings_browser->window()->GetNativeWindow(); window->SetTitle(l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE)); - // An app id for settings windows, also used to identify the shelf item. - // Generated as crx_file::id_util::GenerateId("org.chromium.settings_ui") - static constexpr char kSettingsId[] = "dhnmfjegnohoakobpikffnelcemaplkm"; - const ash::ShelfID shelf_id(kSettingsId); + const ash::ShelfID shelf_id(app_list::kInternalAppIdSettings); window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize())); window->SetProperty<int>(ash::kShelfItemTypeKey, ash::TYPE_DIALOG); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); // The new gfx::ImageSkia instance is owned by the window itself. window->SetProperty( aura::client::kWindowIconKey, - new gfx::ImageSkia(*rb.GetImageSkiaNamed(IDR_ASH_SHELF_ICON_SETTINGS))); + new gfx::ImageSkia(*rb.GetImageSkiaNamed(IDR_SETTINGS_LOGO_192))); window->SetProperty(aura::client::kHasOverviewIcon, true); aura_window_tracker_->Add(window); }
diff --git a/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc b/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc index 0fcff65..3b67620 100644 --- a/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc +++ b/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc
@@ -734,10 +734,10 @@ } TEST_F(BlockTabUnderTest, ControlledByPrefs) { - // Turn feature off via prefs. + // Turn feature off via prefs, via allowing tab-unders. PrefService* prefs = user_prefs::UserPrefs::Get(web_contents()->GetBrowserContext()); - prefs->SetBoolean(prefs::kTabUnderProtection, false); + prefs->SetBoolean(prefs::kTabUnderAllowed, true); EXPECT_TRUE(NavigateAndCommitWithoutGesture(GURL("https://first.test/"))); SimulatePopup(); @@ -745,7 +745,7 @@ ExpectUIShown(false); // Turn feature back on. - prefs->SetBoolean(prefs::kTabUnderProtection, true); + prefs->SetBoolean(prefs::kTabUnderAllowed, false); EXPECT_FALSE(NavigateAndCommitWithoutGesture(GURL("https://example.test2/"))); ExpectUIShown(true); }
diff --git a/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc index 7cf5160..7c5af8e 100644 --- a/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/tab_under_blocker_browsertest.cc
@@ -53,12 +53,11 @@ ASSERT_TRUE(embedded_test_server()->Start()); } - void UpdatePolicy(bool enable_protection) { + void UpdatePolicy(bool allow_tab_under) { policy::PolicyMap policy; - policy.Set(policy::key::kTabUnderProtectionEnabled, - policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, - std::make_unique<base::Value>(enable_protection), + policy.Set(policy::key::kTabUnderAllowed, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>(allow_tab_under), nullptr /* external_data_fetcher */); provider_.UpdateChromePolicy(policy); } @@ -197,8 +196,8 @@ IN_PROC_BROWSER_TEST_F(TabUnderBlockerBrowserTest, ControlledByEnterprisePolicy) { - // Disable the enterprise policy, should disable tab-under blocking. - UpdatePolicy(false /* enable_protection */); + // Allow tab-unders via enterprise policy, should disable tab-under blocking. + UpdatePolicy(true /* allow_tab_under */); ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL("/title1.html")); content::WebContents* opener = @@ -223,10 +222,10 @@ EXPECT_FALSE(IsUiShownForUrl(opener, cross_origin_url)); } - // Enable the policy and try to tab-under again in the background tab. Should - // fail to navigate. + // Disallow tab-unders via policy and try to tab-under again in the background + // tab. Should fail to navigate. { - UpdatePolicy(true /* enable_protection */); + UpdatePolicy(false /* allow_tab_under */); content::TestNavigationObserver tab_under_observer(opener, 1); const GURL cross_origin_url = embedded_test_server()->GetURL("b.com", "/title1.html");
diff --git a/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc b/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc index bc5c597..f3debe5d 100644 --- a/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc +++ b/chrome/browser/ui/blocked_content/tab_under_navigation_throttle.cc
@@ -116,8 +116,8 @@ // static void TabUnderNavigationThrottle::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterBooleanPref(prefs::kTabUnderProtection, - true /* default_value */); + registry->RegisterBooleanPref(prefs::kTabUnderAllowed, + false /* default_value */); } // static @@ -140,9 +140,9 @@ off_the_record_( handle->GetWebContents()->GetBrowserContext()->IsOffTheRecord()), block_(base::FeatureList::IsEnabled(kBlockTabUnders) && - user_prefs::UserPrefs::Get( - handle->GetWebContents()->GetBrowserContext()) - ->GetBoolean(prefs::kTabUnderProtection)), + !user_prefs::UserPrefs::Get( + handle->GetWebContents()->GetBrowserContext()) + ->GetBoolean(prefs::kTabUnderAllowed)), has_opened_popup_since_last_user_gesture_at_start_( HasOpenedPopupSinceLastUserGesture()), started_in_foreground_(handle->GetWebContents()->GetVisibility() ==
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index d9b57765..e8af4749 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -66,7 +66,6 @@ #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/pepper_broker_infobar_delegate.h" #include "chrome/browser/permissions/permission_request_manager.h" -#include "chrome/browser/picture_in_picture/picture_in_picture_window_controller.h" #include "chrome/browser/plugins/plugin_finder.h" #include "chrome/browser/plugins/plugin_metadata.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" @@ -174,6 +173,7 @@ #include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "components/toolbar/toolbar_model_impl.h" #include "components/translate/core/browser/language_state.h" +#include "components/viz/common/surfaces/surface_id.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "components/zoom/zoom_controller.h" #include "content/public/browser/devtools_agent_host.h" @@ -185,6 +185,7 @@ #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/overscroll_configuration.h" +#include "content/public/browser/picture_in_picture_window_controller.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -1403,10 +1404,11 @@ url, FramebustBlockTabHelper::ClickCallback()); } -void Browser::UpdatePictureInPictureSurfaceId(viz::SurfaceId surface_id) { +void Browser::UpdatePictureInPictureSurfaceId( + const viz::SurfaceId& surface_id) { if (!pip_window_controller_) pip_window_controller_.reset( - PictureInPictureWindowController::GetOrCreateForWebContents( + content::PictureInPictureWindowController::GetOrCreateForWebContents( tab_strip_model_->GetActiveWebContents())); pip_window_controller_->EmbedSurface(surface_id); pip_window_controller_->Show();
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 459436b..a57ff5c5 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -70,7 +70,6 @@ class BrowserWindow; class FastUnloadController; class FindBarController; -class PictureInPictureWindowController; class Profile; class ScopedKeepAlive; class StatusBubble; @@ -83,6 +82,7 @@ } namespace content { +class PictureInPictureWindowController; class SessionStorageNamespace; } @@ -500,7 +500,8 @@ bool is_audible) override; void OnDidBlockFramebust(content::WebContents* web_contents, const GURL& url) override; - void UpdatePictureInPictureSurfaceId(viz::SurfaceId surface_id) override; + void UpdatePictureInPictureSurfaceId( + const viz::SurfaceId& surface_id) override; void ExitPictureInPicture() override; bool is_type_tabbed() const { return type_ == TYPE_TABBED; } @@ -995,7 +996,8 @@ std::unique_ptr<chrome::BrowserCommandController> command_controller_; - std::unique_ptr<PictureInPictureWindowController> pip_window_controller_; + std::unique_ptr<content::PictureInPictureWindowController> + pip_window_controller_; // True if the browser window has been shown at least once. bool window_has_shown_;
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm index 9c637a7..a44a5f9 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
@@ -99,15 +99,6 @@ // static ExtensionInstallPrompt::ShowDialogCallback -ExtensionInstallPrompt::GetDefaultShowDialogCallbackCocoa() { - if (chrome::ShowAllDialogsWithViewsToolkit()) - return ExtensionInstallPrompt::GetViewsShowDialogCallback(); - return base::Bind(&ShowExtensionInstallDialogImpl); -} - -#if !BUILDFLAG(MAC_VIEWS_BROWSER) -ExtensionInstallPrompt::ShowDialogCallback ExtensionInstallPrompt::GetDefaultShowDialogCallback() { - return GetDefaultShowDialogCallbackCocoa(); + return base::BindRepeating(&ShowExtensionInstallDialogImpl); } -#endif
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_background_view.h b/chrome/browser/ui/cocoa/infobars/infobar_background_view.h index 062bd49..1e8938a 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_background_view.h +++ b/chrome/browser/ui/cocoa/infobars/infobar_background_view.h
@@ -5,16 +5,10 @@ #ifndef CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_BACKGROUND_VIEW_H_ #define CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_BACKGROUND_VIEW_H_ -#import "chrome/browser/ui/cocoa/vertical_gradient_view.h" -#include "third_party/skia/include/core/SkColor.h" - #import <Cocoa/Cocoa.h> -// A custom view that draws the background gradient for an infobar. -@interface InfoBarBackgroundView : VerticalGradientView - -// Sets the infobar background color. -- (void)setInfobarBackgroundColor:(SkColor)color; +// A custom view that draws the background for an infobar. +@interface InfoBarBackgroundView : NSView @end
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_background_view.mm b/chrome/browser/ui/cocoa/infobars/infobar_background_view.mm index 1d905be..8438218 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_background_view.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_background_view.mm
@@ -26,14 +26,6 @@ return self; } -- (void)setInfobarBackgroundColor:(SkColor)color { - // TODO(ellyjones): no need to use a gradient here. - base::scoped_nsobject<NSGradient> gradient([[NSGradient alloc] - initWithStartingColor:skia::SkColorToCalibratedNSColor(color) - endingColor:skia::SkColorToCalibratedNSColor(color)]); - [self setGradient:gradient]; -} - - (NSColor*)strokeColor { const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; if (!themeProvider) @@ -41,24 +33,17 @@ BOOL active = [[self window] isMainWindow]; return themeProvider->GetNSColor( - active ? ThemeProperties::COLOR_TOOLBAR_STROKE : - ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE); + active ? ThemeProperties::COLOR_TOOLBAR_STROKE + : ThemeProperties::COLOR_TOOLBAR_STROKE_INACTIVE); } - (void)drawRect:(NSRect)rect { NSRect bounds = [self bounds]; - // Around the bounds of the infobar, continue drawing the path into which the - // gradient will be drawn. - NSBezierPath* infoBarPath = [NSBezierPath bezierPath]; - [infoBarPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds))]; - [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))]; - [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMinY(bounds))]; - [infoBarPath lineToPoint:NSMakePoint(NSMinX(bounds), NSMinY(bounds))]; - [infoBarPath closePath]; - - // Draw the gradient. - [[self gradient] drawInBezierPath:infoBarPath angle:270]; + // Draw the background. + // TODO(ellyjones): Use the detached bookmark bar color here. + [[NSColor whiteColor] set]; + NSRectFill([self bounds]); NSColor* strokeColor = [self strokeColor]; if (strokeColor) { @@ -69,14 +54,6 @@ NSDivideRect(bounds, &borderRect, &contentRect, 1, NSMinYEdge); NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); } - - // Add an inner stroke. - NSBezierPath* highlightPath = [NSBezierPath bezierPath]; - [highlightPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds) - 1)]; - [highlightPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds) - 1)]; - - [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] setStroke]; - [highlightPath stroke]; } - (BOOL)mouseDownCanMoveWindow {
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/infobar_controller.mm index 5e8b895..43e105b 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_controller.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_controller.mm
@@ -81,7 +81,6 @@ [nextSubview setFrame:frame]; } - [infoBarView_ setInfobarBackgroundColor:SK_ColorWHITE]; [infoBarView_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; cocoa_l10n_util::FlipAllSubviewsIfNecessary( base::mac::ObjCCast<NSView>(infoBarView_));
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc index e7bd3cd0..f2b1097 100644 --- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc +++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
@@ -22,7 +22,8 @@ #include "content/public/browser/render_frame_host.h" #include "ui/gfx/text_elider.h" #if defined(OS_ANDROID) -#include "chrome/browser/android/tab_android.h" +#include "chrome/browser/ui/android/tab_model/tab_model.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" #endif DEFINE_WEB_CONTENTS_USER_DATA_KEY(JavaScriptDialogTabHelper); @@ -35,8 +36,9 @@ bool IsWebContentsForemost(content::WebContents* web_contents) { #if defined(OS_ANDROID) - TabAndroid* tab = TabAndroid::FromWebContents(web_contents); - return tab && tab->IsUserInteractable(); + TabModel* tab_model = TabModelList::GetTabModelForWebContents(web_contents); + return tab_model && tab_model->IsCurrentModel() && + tab_model->GetActiveWebContents() == web_contents; #else Browser* browser = BrowserList::GetInstance()->GetLastActive(); DCHECK(browser);
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index a54e4aa..f1f7210 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -118,6 +118,7 @@ CONTENT_SETTINGS_TYPE_AUTOPLAY, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, CONTENT_SETTINGS_TYPE_CLIPBOARD_READ, + CONTENT_SETTINGS_TYPE_USB_GUARD, }; // Checks whether this permission is currently the factory default, as set by @@ -835,6 +836,12 @@ for (const ChooserUIInfo& ui_info : kChooserUIInfo) { ChooserContextBase* context = ui_info.get_context(profile_); const GURL origin = site_url_.GetOrigin(); + + // Hide individual object permissions because when the chooser is blocked + // previously granted device permissions are also ignored. + if (!context->CanRequestObjectPermission(origin, origin)) + continue; + auto chosen_objects = context->GetGrantedObjects(origin, origin); for (std::unique_ptr<base::DictionaryValue>& object : chosen_objects) { chosen_object_info_list.push_back(
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index ce643dd..4eb66e24 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -129,6 +129,7 @@ {CONTENT_SETTINGS_TYPE_SOUND, IDS_PAGE_INFO_TYPE_SOUND}, {CONTENT_SETTINGS_TYPE_CLIPBOARD_READ, IDS_PAGE_INFO_TYPE_CLIPBOARD}, {CONTENT_SETTINGS_TYPE_SENSORS, IDS_PAGE_INFO_TYPE_SENSORS}, + {CONTENT_SETTINGS_TYPE_USB_GUARD, IDS_PAGE_INFO_TYPE_USB}, }; std::unique_ptr<PageInfoUI::SecurityDescription> CreateSecurityDescription( @@ -475,6 +476,9 @@ case CONTENT_SETTINGS_TYPE_SENSORS: icon = &kSensorsIcon; break; + case CONTENT_SETTINGS_TYPE_USB_GUARD: + icon = &vector_icons::kUsbIcon; + break; default: // All other |ContentSettingsType|s do not have icons on desktop or are // not shown in the Page Info bubble.
diff --git a/chrome/browser/ui/page_info/permission_menu_model.cc b/chrome/browser/ui/page_info/permission_menu_model.cc index 49f09cc..8e943a32 100644 --- a/chrome/browser/ui/page_info/permission_menu_model.cc +++ b/chrome/browser/ui/page_info/permission_menu_model.cc
@@ -73,16 +73,7 @@ AddCheckItem(CONTENT_SETTING_DEFAULT, label); // Retrieve the string to show for allowing the permission. - // Notifications does not support CONTENT_SETTING_ALLOW in incognito. - bool allow_disabled_for_notifications = - permission_.is_incognito && - permission_.type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS; - // Media only supports CONTENT_SETTTING_ALLOW for secure origins. - bool is_media_permission = - permission_.type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || - permission_.type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA; - if (!allow_disabled_for_notifications && - (!is_media_permission || content::IsOriginSecure(url))) { + if (ShouldShowAllow(url)) { label = l10n_util::GetStringUTF16(IDS_PAGE_INFO_MENU_ITEM_ALLOW); if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { label = PageInfoUI::PermissionActionToUIString( @@ -113,6 +104,18 @@ info.source); } AddCheckItem(CONTENT_SETTING_BLOCK, label); + + // Retrieve the string to show for allowing the user to be asked about the + // permission. + if (ShouldShowAsk(url)) { + label = l10n_util::GetStringUTF16(IDS_PAGE_INFO_MENU_ITEM_ASK); + if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { + label = PageInfoUI::PermissionActionToUIString( + profile, info.type, CONTENT_SETTING_ASK, effective_default_setting, + info.source); + } + AddCheckItem(CONTENT_SETTING_ASK, label); + } } PermissionMenuModel::~PermissionMenuModel() {} @@ -136,3 +139,28 @@ permission_.setting = static_cast<ContentSetting>(command_id); callback_.Run(permission_); } + +bool PermissionMenuModel::ShouldShowAllow(const GURL& url) { + // Notifications does not support CONTENT_SETTING_ALLOW in incognito. + if (permission_.is_incognito && + permission_.type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { + return false; + } + + // Media only supports CONTENT_SETTING_ALLOW for secure origins. + if ((permission_.type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || + permission_.type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) && + !content::IsOriginSecure(url)) { + return false; + } + + // Chooser permissions do not support CONTENT_SETTING_ALLOW. + if (permission_.type == CONTENT_SETTINGS_TYPE_USB_GUARD) + return false; + + return true; +} + +bool PermissionMenuModel::ShouldShowAsk(const GURL& url) { + return permission_.type == CONTENT_SETTINGS_TYPE_USB_GUARD; +}
diff --git a/chrome/browser/ui/page_info/permission_menu_model.h b/chrome/browser/ui/page_info/permission_menu_model.h index d34d9ae..1a406a8 100644 --- a/chrome/browser/ui/page_info/permission_menu_model.h +++ b/chrome/browser/ui/page_info/permission_menu_model.h
@@ -34,6 +34,9 @@ void ExecuteCommand(int command_id, int event_flags) override; private: + bool ShouldShowAllow(const GURL& url); + bool ShouldShowAsk(const GURL& url); + HostContentSettingsMap* host_content_settings_map_; // The permission info represented by the menu model.
diff --git a/chrome/browser/ui/page_info/permission_menu_model_unittest.cc b/chrome/browser/ui/page_info/permission_menu_model_unittest.cc index 72b9c3f7..c16d1e6 100644 --- a/chrome/browser/ui/page_info/permission_menu_model_unittest.cc +++ b/chrome/browser/ui/page_info/permission_menu_model_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/ui/page_info/permission_menu_model.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -42,6 +43,7 @@ permission.default_setting = CONTENT_SETTING_ALLOW; permission.source = content_settings::SETTING_SOURCE_USER; permission.is_incognito = false; + PermissionMenuModel model(profile(), GURL("http://www.google.com"), permission, callback.callback()); EXPECT_EQ(3, model.GetItemCount()); @@ -82,3 +84,17 @@ permission, callback.callback()); EXPECT_EQ(2, incognito_model.GetItemCount()); } + +TEST_F(PermissionMenuModelTest, TestUsbGuard) { + TestCallback callback; + PageInfoUI::PermissionInfo permission; + permission.type = CONTENT_SETTINGS_TYPE_USB_GUARD; + permission.setting = CONTENT_SETTING_ASK; + permission.default_setting = CONTENT_SETTING_ASK; + permission.source = content_settings::SETTING_SOURCE_USER; + permission.is_incognito = false; + + PermissionMenuModel model(profile(), GURL("http://www.google.com"), + permission, callback.callback()); + EXPECT_EQ(3, model.GetItemCount()); +}
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc index 7622e5d..3e62e5a6 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/extensions/chrome_app_icon_service.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/views/accelerator_table.h" #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h" #include "components/favicon/content/content_favicon_driver.h" #include "components/zoom/page_zoom.h" @@ -35,12 +36,6 @@ const int kDefaultPanelWidth = 200; const int kDefaultPanelHeight = 300; -struct AcceleratorMapping { - ui::KeyboardCode keycode; - int modifiers; - int command_id; -}; - const AcceleratorMapping kAppWindowAcceleratorMap[] = { { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index 7b11836..bf2a681 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -168,18 +168,7 @@ int container_id = create_params.is_ime_window ? ash::kShellWindowId_ImeWindowParentContainer : ash::kShellWindowId_LockActionHandlerContainer; - if (ash_util::IsRunningInMash()) { - init_params->mus_properties - [ui::mojom::WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(container_id); - int display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); - init_params - ->mus_properties[ui::mojom::WindowManager::kDisplayId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(display_id); - } else { - init_params->parent = ash::Shell::GetContainer( - ash::Shell::GetPrimaryRootWindow(), container_id); - } + ash_util::SetupWidgetInitParamsForContainer(init_params, container_id); } DCHECK_NE(AppWindow::WINDOW_TYPE_PANEL, create_params.window_type); init_params->mus_properties
diff --git a/chrome/browser/ui/views/browser_dialogs_views.cc b/chrome/browser/ui/views/browser_dialogs_views.cc index bac61cb..e8b2016 100644 --- a/chrome/browser/ui/views/browser_dialogs_views.cc +++ b/chrome/browser/ui/views/browser_dialogs_views.cc
@@ -44,16 +44,6 @@ configuration); } -// static -ExtensionInstallPrompt::ShowDialogCallback -ExtensionInstallPrompt::GetDefaultShowDialogCallback() { -#if defined(OS_MACOSX) - if (views_mode_controller::IsViewsBrowserCocoa()) - return GetDefaultShowDialogCallbackCocoa(); -#endif - return ExtensionInstallPrompt::GetViewsShowDialogCallback(); -} - void ChromeDevicePermissionsPrompt::ShowDialog() { ShowDialogViews(); }
diff --git a/chrome/browser/ui/views/chrome_web_dialog_view.cc b/chrome/browser/ui/views/chrome_web_dialog_view.cc index 1f7f57d5..46cc4ce3 100644 --- a/chrome/browser/ui/views/chrome_web_dialog_view.cc +++ b/chrome/browser/ui/views/chrome_web_dialog_view.cc
@@ -9,12 +9,8 @@ #include "ui/views/widget/widget.h" #if defined(OS_CHROMEOS) -// gn check complains on Linux Ozone. -#include "ash/public/cpp/shell_window_ids.h" // nogncheck -#include "ash/shell.h" +#include "ash/public/cpp/shell_window_ids.h" #include "chrome/browser/ui/ash/ash_util.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" #endif // defined(OS_CHROMEOS) namespace chrome { @@ -59,14 +55,7 @@ new views::WebDialogView(context, delegate, new ChromeWebContentsHandler); views::Widget::InitParams params; params.delegate = view; - if (ash_util::IsRunningInMash()) { - using ui::mojom::WindowManager; - params.mus_properties[WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(container_id); - } else { - params.parent = ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), - container_id); - } + ash_util::SetupWidgetInitParamsForContainer(¶ms, container_id); return ShowWebDialogWidget(params, view); } #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc index 8634cb1..2c4a208 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -635,6 +635,6 @@ // static ExtensionInstallPrompt::ShowDialogCallback -ExtensionInstallPrompt::GetViewsShowDialogCallback() { +ExtensionInstallPrompt::GetDefaultShowDialogCallback() { return base::Bind(&ShowExtensionInstallDialogImpl); }
diff --git a/chrome/browser/ui/views/global_error_bubble_view.cc b/chrome/browser/ui/views/global_error_bubble_view.cc index ecf7200c..f470e88 100644 --- a/chrome/browser/ui/views/global_error_bubble_view.cc +++ b/chrome/browser/ui/views/global_error_bubble_view.cc
@@ -47,7 +47,7 @@ #if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER) -views::View* GetBubbleAnchorView(Browser* browser) { +views::View* GetGlobalErrorBubbleAnchorView(Browser* browser) { #if BUILDFLAG(MAC_VIEWS_BROWSER) if (views_mode_controller::IsViewsBrowserCocoa()) return nullptr; @@ -56,7 +56,7 @@ return browser_view->button_provider()->GetAppMenuButton(); } -gfx::Rect GetBubbleAnchorRect(Browser* browser) { +gfx::Rect GetGlobalErrorBubbleAnchorRect(Browser* browser) { #if BUILDFLAG(MAC_VIEWS_BROWSER) if (views_mode_controller::IsViewsBrowserCocoa()) return bubble_anchor_util::GetAppMenuAnchorRectCocoa(browser); @@ -75,10 +75,10 @@ GlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowStandardBubbleView( Browser* browser, const base::WeakPtr<GlobalErrorWithStandardBubble>& error) { - views::View* anchor_view = GetBubbleAnchorView(browser); + views::View* anchor_view = GetGlobalErrorBubbleAnchorView(browser); gfx::Rect anchor_rect; if (!anchor_view) - anchor_rect = GetBubbleAnchorRect(browser); + anchor_rect = GetGlobalErrorBubbleAnchorRect(browser); GlobalErrorBubbleView* bubble_view = new GlobalErrorBubbleView( anchor_view, anchor_rect, views::BubbleBorder::TOP_RIGHT, browser, error); views::BubbleDialogDelegateView::CreateBubble(bubble_view);
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc index acbf8b2..3dba5720 100644 --- a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc +++ b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/harmony/harmony_layout_provider.h" +#include "chrome/browser/ui/views/harmony/material_refresh_layout_provider.h" #include "ui/base/material_design/material_design_controller.h" namespace { @@ -37,6 +38,9 @@ // static std::unique_ptr<views::LayoutProvider> ChromeLayoutProvider::CreateLayoutProvider() { + if (ui::MaterialDesignController::GetMode() == + ui::MaterialDesignController::MATERIAL_REFRESH) + return std::make_unique<MaterialRefreshLayoutProvider>(); return ui::MaterialDesignController::IsSecondaryUiMaterial() ? std::make_unique<HarmonyLayoutProvider>() : std::make_unique<ChromeLayoutProvider>();
diff --git a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc new file mode 100644 index 0000000..77d5d78 --- /dev/null +++ b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc
@@ -0,0 +1,21 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/harmony/material_refresh_layout_provider.h" + +int MaterialRefreshLayoutProvider::GetCornerRadiusMetric( + ChromeEmphasisMetric emphasis_metric, + const gfx::Rect& bounds) const { + switch (emphasis_metric) { + case EMPHASIS_LOW: + return 4; + case EMPHASIS_MEDIUM: + return 8; + case EMPHASIS_HIGH: + return std::min(bounds.width(), bounds.height()) / 2; + default: + NOTREACHED(); + return 0; + } +}
diff --git a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h new file mode 100644 index 0000000..47ef6cf --- /dev/null +++ b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h
@@ -0,0 +1,21 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ +#define CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/views/harmony/harmony_layout_provider.h" + +class MaterialRefreshLayoutProvider : public HarmonyLayoutProvider { + public: + MaterialRefreshLayoutProvider() = default; + ~MaterialRefreshLayoutProvider() override = default; + + int GetCornerRadiusMetric( + ChromeEmphasisMetric emphasis_metric, + const gfx::Rect& bounds = gfx::Rect()) const override; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_
diff --git a/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc b/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc index 6684f7a..37be40e 100644 --- a/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc +++ b/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc
@@ -36,7 +36,23 @@ AlternateNavInfoBarView::AlternateNavInfoBarView( std::unique_ptr<AlternateNavInfoBarDelegate> delegate) - : InfoBarView(std::move(delegate)) {} + : InfoBarView(std::move(delegate)) { + auto* delegate_ptr = GetDelegate(); + size_t offset; + base::string16 message_text = delegate_ptr->GetMessageTextWithOffset(&offset); + DCHECK_NE(base::string16::npos, offset); + label_1_text_ = message_text.substr(0, offset); + label_1_ = CreateLabel(label_1_text_); + AddChildView(label_1_); + + link_text_ = delegate_ptr->GetLinkText(); + link_ = CreateLink(link_text_, this); + AddChildView(link_); + + label_2_text_ = message_text.substr(offset); + label_2_ = CreateLabel(label_2_text_); + AddChildView(label_2_); +} AlternateNavInfoBarView::~AlternateNavInfoBarView() { } @@ -77,31 +93,6 @@ label_2_->SetPosition(gfx::Point(link_->bounds().right(), OffsetY(label_2_))); } -void AlternateNavInfoBarView::ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) { - if (details.is_add && (details.child == this) && (label_1_ == NULL)) { - AlternateNavInfoBarDelegate* delegate = GetDelegate(); - size_t offset; - base::string16 message_text = delegate->GetMessageTextWithOffset(&offset); - DCHECK_NE(base::string16::npos, offset); - label_1_text_ = message_text.substr(0, offset); - label_1_ = CreateLabel(label_1_text_); - AddChildView(label_1_); - - link_text_ = delegate->GetLinkText(); - link_ = CreateLink(link_text_, this); - AddChildView(link_); - - label_2_text_ = message_text.substr(offset); - label_2_ = CreateLabel(label_2_text_); - AddChildView(label_2_); - } - - // This must happen after adding all other children so InfoBarView can ensure - // the close button is the last child. - InfoBarView::ViewHierarchyChanged(details); -} - int AlternateNavInfoBarView::ContentMinimumWidth() const { int label_1_width = label_1_->GetMinimumSize().width(); return label_1_width ? label_1_width : link_->GetMinimumSize().width();
diff --git a/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.h b/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.h index e4634eaa..2483d7f 100644 --- a/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.h +++ b/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.h
@@ -33,8 +33,6 @@ // InfoBarView: void Layout() override; - void ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) override; int ContentMinimumWidth() const override; // views::LinkListener:
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.cc b/chrome/browser/ui/views/infobars/confirm_infobar.cc index 03ed618..1247f60 100644 --- a/chrome/browser/ui/views/infobars/confirm_infobar.cc +++ b/chrome/browser/ui/views/infobars/confirm_infobar.cc
@@ -36,7 +36,31 @@ // ConfirmInfoBar ------------------------------------------------------------- ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate) - : InfoBarView(std::move(delegate)) {} + : InfoBarView(std::move(delegate)) { + auto* delegate_ptr = GetDelegate(); + label_ = CreateLabel(delegate_ptr->GetMessageText()); + AddChildView(label_); + + const auto buttons = delegate_ptr->GetButtons(); + if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) { + ok_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_OK); + ok_button_->SetProminent(true); + if (delegate_ptr->OKButtonTriggersUACPrompt()) { + elevation_icon_setter_.reset(new ElevationIconSetter( + ok_button_, + base::BindOnce(&ConfirmInfoBar::Layout, base::Unretained(this)))); + } + } + + if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) { + cancel_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_CANCEL); + if (buttons == ConfirmInfoBarDelegate::BUTTON_CANCEL) + cancel_button_->SetProminent(true); + } + + link_ = CreateLink(delegate_ptr->GetLinkText(), this); + AddChildView(link_); +} ConfirmInfoBar::~ConfirmInfoBar() { // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|. @@ -73,39 +97,6 @@ link_->SetPosition(gfx::Point(EndX() - link_->width(), OffsetY(link_))); } -void ConfirmInfoBar::ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) { - if (details.is_add && details.child == this && (label_ == nullptr)) { - ConfirmInfoBarDelegate* delegate = GetDelegate(); - label_ = CreateLabel(delegate->GetMessageText()); - AddChildView(label_); - - if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) { - ok_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_OK); - ok_button_->SetProminent(true); - if (delegate->OKButtonTriggersUACPrompt()) { - elevation_icon_setter_.reset(new ElevationIconSetter( - ok_button_, - base::BindOnce(&ConfirmInfoBar::Layout, base::Unretained(this)))); - } - } - - if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) { - cancel_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_CANCEL); - if (delegate->GetButtons() == ConfirmInfoBarDelegate::BUTTON_CANCEL) - cancel_button_->SetProminent(true); - } - - base::string16 link_text(delegate->GetLinkText()); - link_ = CreateLink(link_text, this); - AddChildView(link_); - } - - // This must happen after adding all other children so InfoBarView can ensure - // the close button is the last child. - InfoBarView::ViewHierarchyChanged(details); -} - void ConfirmInfoBar::ButtonPressed(views::Button* sender, const ui::Event& event) { if (!owner())
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.h b/chrome/browser/ui/views/infobars/confirm_infobar.h index 0d31e3c..e590b71 100644 --- a/chrome/browser/ui/views/infobars/confirm_infobar.h +++ b/chrome/browser/ui/views/infobars/confirm_infobar.h
@@ -31,8 +31,6 @@ private: // InfoBarView: void Layout() override; - void ViewHierarchyChanged( - const ViewHierarchyChangedDetails& details) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override; int ContentMinimumWidth() const override;
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index 1d582bd..8be58b1 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -97,8 +97,47 @@ // animation. SetPaintToLayer(); layer()->SetMasksToBounds(true); + + gfx::Image image = this->delegate()->GetIcon(); + if (!image.IsEmpty()) { + icon_ = new views::ImageView; + icon_->SetImage(image.ToImageSkia()); + icon_->SizeToPreferredSize(); + icon_->SetProperty( + views::kMarginsKey, + new gfx::Insets(ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_TOAST_LABEL_VERTICAL), + 0)); + AddChildView(icon_); + } + + close_button_ = views::CreateVectorImageButton(this); + // This is the wrong color, but allows the button's size to be computed + // correctly. We'll reset this with the correct color in OnThemeChanged(). + views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, + gfx::kPlaceholderColor); + close_button_->SetAccessibleName( + l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); + close_button_->SetFocusForPlatform(); + gfx::Insets close_button_spacing = GetCloseButtonSpacing(); + close_button_->SetProperty(views::kMarginsKey, + new gfx::Insets(close_button_spacing.top(), 0, + close_button_spacing.bottom(), 0)); + AddChildView(close_button_); } +void InfoBarView::RecalculateHeight() { + // Ensure the infobar is tall enough to display its contents. + int height = 0; + for (int i = 0; i < child_count(); ++i) { + View* child = child_at(i); + const gfx::Insets* const margins = child->GetProperty(views::kMarginsKey); + const int margin_height = margins ? margins->height() : 0; + height = std::max(height, child->height() + margin_height); + } + SetTargetHeight(height + InfoBarContainerDelegate::kSeparatorLineHeight); +} + InfoBarView::~InfoBarView() { // We should have closed any open menus in PlatformSpecificHide(), then // subclasses' RunMenu() functions should have prevented opening any new ones @@ -157,44 +196,11 @@ const ViewHierarchyChangedDetails& details) { View::ViewHierarchyChanged(details); - if (details.is_add && (details.child == this) && (close_button_ == NULL)) { - gfx::Image image = delegate()->GetIcon(); - if (!image.IsEmpty()) { - icon_ = new views::ImageView; - icon_->SetImage(image.ToImageSkia()); - icon_->SizeToPreferredSize(); - icon_->SetProperty( - views::kMarginsKey, - new gfx::Insets(ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_TOAST_LABEL_VERTICAL), - 0)); - AddChildView(icon_); - } - - close_button_ = views::CreateVectorImageButton(this); - views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, - GetColor(kTextColor)); - close_button_->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); - close_button_->SetFocusForPlatform(); - gfx::Insets close_button_spacing = GetCloseButtonSpacing(); - close_button_->SetProperty( - views::kMarginsKey, new gfx::Insets(close_button_spacing.top(), 0, - close_button_spacing.bottom(), 0)); - // Subclasses should already be done adding child views by this point (see - // related DCHECK in Layout()). - AddChildView(close_button_); + // Anything that needs to happen once after all subclasses add their children. + if (details.is_add && (details.child == this)) { + ReorderChildView(close_button_, -1); + RecalculateHeight(); } - - // Ensure the infobar is tall enough to display its contents. - int height = 0; - for (int i = 0; i < child_count(); ++i) { - View* child = child_at(i); - const gfx::Insets* const margins = child->GetProperty(views::kMarginsKey); - const int margin_height = margins ? margins->height() : 0; - height = std::max(height, child->height() + margin_height); - } - SetTargetHeight(height + InfoBarContainerDelegate::kSeparatorLineHeight); } void InfoBarView::OnThemeChanged() { @@ -202,10 +208,8 @@ background()->SetNativeControlColor(background_color); const SkColor text_color = GetColor(kTextColor); - if (close_button_) { - views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, - text_color); - } + views::SetImageFromVectorIcon(close_button_, vector_icons::kClose16Icon, + text_color); for (int i = 0; i < child_count(); ++i) { View* child = child_at(i); @@ -220,7 +224,13 @@ } void InfoBarView::OnNativeThemeChanged(const ui::NativeTheme* theme) { + // The constructor could not set initial colors correctly, since the + // ThemeProvider wasn't available yet. When this function is called, the view + // has been added to a Widget, so that ThemeProvider is now present. OnThemeChanged(); + + // Native theme changes can affect font sizes. + RecalculateHeight(); } void InfoBarView::ButtonPressed(views::Button* sender,
diff --git a/chrome/browser/ui/views/infobars/infobar_view.h b/chrome/browser/ui/views/infobars/infobar_view.h index 9768a3f2..c4c1426 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.h +++ b/chrome/browser/ui/views/infobars/infobar_view.h
@@ -30,6 +30,9 @@ public: explicit InfoBarView(std::unique_ptr<infobars::InfoBarDelegate> delegate); + // Requests that the infobar recompute its target height. + void RecalculateHeight(); + protected: using Labels = std::vector<views::Label*>;
diff --git a/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc b/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc index bbb91d8d..f7805e4a 100644 --- a/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc +++ b/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc
@@ -451,14 +451,9 @@ // Disabled for being flaky. Tracked in: // TODO(erg): Fix DND tests on linux_aura. http://crbug.com/163931. // TODO(tapted): De-flake and run on Mac. http://crbug.com/449058. -#if defined(OS_WIN) -#define MAYBE_MenuViewDragAndDropNestedDrag MenuViewDragAndDropNestedDrag -#else -#define MAYBE_MenuViewDragAndDropNestedDrag \ - DISABLED_MenuViewDragAndDropNestedDrag -#endif +// TODO(crbug.com/829922): Flaky on Windows. VIEW_TEST(MenuViewDragAndDropTestNestedDrag, - MAYBE_MenuViewDragAndDropNestedDrag) + DISABLED_MenuViewDragAndDropNestedDrag) class MenuViewDragAndDropForDropStayOpen : public MenuViewDragAndDropTest { public:
diff --git a/chrome/browser/ui/views/overlay/OWNERS b/chrome/browser/ui/views/overlay/OWNERS index f40e8170..2d095db3 100644 --- a/chrome/browser/ui/views/overlay/OWNERS +++ b/chrome/browser/ui/views/overlay/OWNERS
@@ -1 +1,4 @@ -file://chrome/browser/overlay/OWNERS +apacible@chromium.org +mlamouri@chromium.org + +# COMPONENT: Internals>Media>UI \ No newline at end of file
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index 0ee06544..d49525e 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -14,7 +14,7 @@ #include "ui/views/widget/widget_delegate.h" // static -std::unique_ptr<OverlayWindow> OverlayWindow::Create() { +std::unique_ptr<content::OverlayWindow> content::OverlayWindow::Create() { return base::WrapUnique(new OverlayWindowViews()); }
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.h b/chrome/browser/ui/views/overlay/overlay_window_views.h index 17dbbde6..910f7a8 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.h +++ b/chrome/browser/ui/views/overlay/overlay_window_views.h
@@ -5,13 +5,14 @@ #ifndef CHROME_BROWSER_UI_VIEWS_OVERLAY_OVERLAY_WINDOW_VIEWS_H_ #define CHROME_BROWSER_UI_VIEWS_OVERLAY_OVERLAY_WINDOW_VIEWS_H_ -#include "chrome/browser/overlay/overlay_window.h" +#include "content/public/browser/overlay_window.h" #include "ui/gfx/geometry/size.h" #include "ui/views/widget/widget.h" -// The Views implementation of OverlayWindow. -class OverlayWindowViews : public OverlayWindow, public views::Widget { +// The Chrome desktop implementation of OverlayWindow. This will only be +// implemented in views, which will support all desktop platforms. +class OverlayWindowViews : public content::OverlayWindow, public views::Widget { public: OverlayWindowViews(); ~OverlayWindowViews() override;
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc index cf68e4324..cc272d7 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -118,7 +118,7 @@ views::View* view = GetPermissionSelectorAt(selector_index)->button(); DCHECK_EQ(views::Combobox::kViewClassName, view->GetClassName()); views::Combobox* combobox = static_cast<views::Combobox*>(view); - combobox->SetSelectedIndex(menu_index); + combobox->SetSelectedRow(menu_index); } // Simulates updating the number of cookies. @@ -314,6 +314,10 @@ // However, since the setting is now default, recreating the dialog with those // settings should omit the permission from the UI. + // + // TODO(https://crbug.com/829576): Reconcile the comment above with the fact + // that |num_expected_children| is not, at this point, 0 and therefore the + // permission is not being omitted from the UI. api_->SetPermissionInfo(list); EXPECT_EQ(num_expected_children, api_->permissions_view()->child_count()); } @@ -358,6 +362,74 @@ EXPECT_FALSE(store->HasDevicePermission(origin, origin, device)); } +TEST_F(PageInfoBubbleViewTest, SetPermissionInfoForUsbGuard) { + // This test exercises PermissionSelectorRow in a way that it is not used in + // practice. In practice, every setting in PermissionSelectorRow starts off + // "set", so there is always one option checked in the resulting MenuModel. + // This test creates settings that are left at their defaults, leading to zero + // checked options, and checks that the text on the MenuButtons is right. On + // Mac, the behavior matches, but only when SecondaryUiMd is enabled. + const bool is_md = base::FeatureList::IsEnabled(features::kSecondaryUiMd); +#if defined(OS_MACOSX) + if (!is_md) + return; +#endif + + PermissionInfoList list(1); + list.back().type = CONTENT_SETTINGS_TYPE_USB_GUARD; + list.back().source = content_settings::SETTING_SOURCE_USER; + list.back().is_incognito = false; + list.back().setting = CONTENT_SETTING_ASK; + + // Initially, no permissions are shown because they are all set to default. + int num_expected_children = 0; + EXPECT_EQ(num_expected_children, api_->permissions_view()->child_count()); + + // Verify calling SetPermissionInfo() directly updates the UI. + num_expected_children += kViewsPerPermissionRow * list.size(); + list.back().setting = CONTENT_SETTING_BLOCK; + api_->SetPermissionInfo(list); + EXPECT_EQ(base::ASCIIToUTF16("Block"), api_->GetPermissionButtonTextAt(0)); + + // Simulate a user selection via the UI. Note this will also cover logic in + // PageInfo to update the pref. + if (is_md) { + // Under MD, the changed setting is always read from the combobox selected + // index when changed in the UI. PermissionSelectorRow::PermissionChanged() + // ignores the argument, except to detect whether it is the default. + api_->SimulateUserSelectingComboboxItemAt(0, 2); + } else { + list.back().setting = CONTENT_SETTING_ASK; + api_->GetPermissionSelectorAt(0)->PermissionChanged(list.back()); + } + EXPECT_EQ(num_expected_children, api_->permissions_view()->child_count()); + EXPECT_EQ(base::ASCIIToUTF16("Ask"), api_->GetPermissionButtonTextAt(0)); + + // Setting to the default via the UI should keep the button around. + if (is_md) { + api_->SimulateUserSelectingComboboxItemAt(0, 0); + // Under MD, PermissionMenuModel gets strings using PageInfoUI:: + // PermissionActionToUIString(..) rather than directly from the + // ResourceBundle. + EXPECT_EQ(base::ASCIIToUTF16("Ask (default)"), + api_->GetPermissionButtonTextAt(0)); + } else { + list.back().setting = CONTENT_SETTING_ASK; + api_->GetPermissionSelectorAt(0)->PermissionChanged(list.back()); + EXPECT_EQ(base::ASCIIToUTF16("Ask"), api_->GetPermissionButtonTextAt(0)); + } + EXPECT_EQ(num_expected_children, api_->permissions_view()->child_count()); + + // However, since the setting is now default, recreating the dialog with those + // settings should omit the permission from the UI. + // + // TODO(https://crbug.com/829576): Reconcile the comment above with the fact + // that |num_expected_children| is not, at this point, 0 and therefore the + // permission is not being omitted from the UI. + api_->SetPermissionInfo(list); + EXPECT_EQ(num_expected_children, api_->permissions_view()->child_count()); +} + // Test that updating the number of cookies used by the current page doesn't add // any extra views to Page Info. TEST_F(PageInfoBubbleViewTest, UpdatingSiteDataRetainsLayout) {
diff --git a/chrome/browser/ui/views/page_info/permission_selector_row.cc b/chrome/browser/ui/views/page_info/permission_selector_row.cc index 531a790..b460f8fc 100644 --- a/chrome/browser/ui/views/page_info/permission_selector_row.cc +++ b/chrome/browser/ui/views/page_info/permission_selector_row.cc
@@ -175,13 +175,15 @@ }; void ComboboxModelAdapter::OnPerformAction(int index) { - model_->ExecuteCommand(index, 0); + int command_id = model_->GetCommandIdAt(index); + model_->ExecuteCommand(command_id, 0); } int ComboboxModelAdapter::GetCheckedIndex() { int checked_index = -1; for (int i = 0; i < model_->GetItemCount(); ++i) { - if (model_->IsCommandIdChecked(i)) { + int command_id = model_->GetCommandIdAt(i); + if (model_->IsCommandIdChecked(command_id)) { // This function keeps track of |checked_index| instead of returning early // here so that it can DCHECK that there's exactly one selected item, // which is not normally guaranteed by MenuModel, but *is* true of
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 0504a9b..9ab17b84 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -410,8 +410,9 @@ SkColor GetForegroundColorForBackground(SkColor background_color) { constexpr double kLightForegroundRatioThreshold = 3; - if (color_utils::GetContrastRatio(background_color, SK_ColorWHITE) >= - kLightForegroundRatioThreshold) { + if (background_color != 0 && + color_utils::GetContrastRatio(background_color, SK_ColorWHITE) >= + kLightForegroundRatioThreshold) { return SK_ColorWHITE; } views::Label label;
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index 7175c33..f8c78066 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -85,9 +85,9 @@ #if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER) // Returns the app menu view, except when the browser window is Cocoa; Cocoa -// browser windows always have a null anchor view and use GetBubbleAnchorRect() -// instead. -views::View* GetBubbleAnchorView(Browser* browser) { +// browser windows always have a null anchor view and use +// GetSessionCrashedBubbleAnchorRect() instead. +views::View* GetSessionCrashedBubbleAnchorView(Browser* browser) { #if BUILDFLAG(MAC_VIEWS_BROWSER) if (views_mode_controller::IsViewsBrowserCocoa()) return nullptr; @@ -97,12 +97,12 @@ ->GetAppMenuButton(); } #else // OS_MACOSX && !MAC_VIEWS_BROWSER -views::View* GetBubbleAnchorView(Browser* browser) { +views::View* GetSessionCrashedBubbleAnchorView(Browser* browser) { return nullptr; } #endif -gfx::Rect GetBubbleAnchorRect(Browser* browser) { +gfx::Rect GetSessionCrashedBubbleAnchorRect(Browser* browser) { #if BUILDFLAG(MAC_VIEWS_BROWSER) if (views_mode_controller::IsViewsBrowserCocoa()) return bubble_anchor_util::GetAppMenuAnchorRectCocoa(browser); @@ -187,8 +187,8 @@ } SessionCrashedBubbleView* crash_bubble = new SessionCrashedBubbleView( - GetBubbleAnchorView(browser), GetBubbleAnchorRect(browser), browser, - offer_uma_optin); + GetSessionCrashedBubbleAnchorView(browser), + GetSessionCrashedBubbleAnchorRect(browser), browser, offer_uma_optin); views::BubbleDialogDelegateView::CreateBubble(crash_bubble)->Show(); #if defined(OS_MACOSX) if (views_mode_controller::IsViewsBrowserCocoa())
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc index 270006388..39a714f 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -818,14 +818,14 @@ bool MediaRouterUI::UserSelectedTabMirroringForCurrentOrigin() const { const base::ListValue* origins = Profile::FromWebUI(web_ui())->GetPrefs()->GetList( - prefs::kMediaRouterTabMirroringSources); + ::prefs::kMediaRouterTabMirroringSources); return origins->Find(base::Value(GetSerializedInitiatorOrigin())) != origins->end(); } void MediaRouterUI::RecordCastModeSelection(MediaCastMode cast_mode) { ListPrefUpdate update(Profile::FromWebUI(web_ui())->GetPrefs(), - prefs::kMediaRouterTabMirroringSources); + ::prefs::kMediaRouterTabMirroringSources); switch (cast_mode) { case MediaCastMode::PRESENTATION:
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 ab3315c..9ddbcb59 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
@@ -1381,6 +1381,9 @@ {"exportMenuItem", IDS_SETTINGS_PASSWORDS_EXPORT_MENU_ITEM}, {"undoRemovePassword", IDS_SETTINGS_PASSWORD_UNDO}, {"passwordDeleted", IDS_SETTINGS_PASSWORD_DELETED_PASSWORD}, + {"passwordRowMoreActionsButton", IDS_SETTINGS_PASSWORD_ROW_MORE_ACTIONS}, + {"passwordRowFederatedMoreActionsButton", + IDS_SETTINGS_PASSWORD_ROW_FEDERATED_MORE_ACTIONS}, {"exportPasswordsTitle", IDS_SETTINGS_PASSWORDS_EXPORT_TITLE}, {"exportPasswordsDescription", IDS_SETTINGS_PASSWORDS_EXPORT_DESCRIPTION}, {"exportPasswords", IDS_SETTINGS_PASSWORDS_EXPORT}, @@ -1528,6 +1531,7 @@ {"syncedToName", IDS_SETTINGS_PEOPLE_SYNCED_AS_NAME}, {"turnOffSync", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF}, {"syncNotWorking", IDS_SETTINGS_PEOPLE_SYNC_NOT_WORKING}, + {"syncPaused", IDS_SETTINGS_PEOPLE_SYNC_PAUSED}, {"syncSignInPrompt", IDS_SETTINGS_SYNC_SIGN_IN_PROMPT}, {"syncSignInPromptSecondary", IDS_SETTINGS_SYNC_SIGN_IN_PROMPT_SECONDARY}, #endif @@ -1550,6 +1554,8 @@ {"syncDisconnectExplanation", IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION}, {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM}, {"sync", IDS_SETTINGS_SYNC}, + {"syncDescription", IDS_SETTINGS_SYNC_DESCRIPTION}, + {"syncExpandA11yLabel", IDS_SETTINGS_SYNC_SECTION_ACCESSIBILITY_LABEL}, {"syncAndPersonalization", IDS_SETTINGS_SYNC_SYNC_AND_PERSONALIZATION}, {"syncPageTitle", IDS_SETTINGS_SYNC_PAGE_TITLE}, {"syncLoading", IDS_SETTINGS_SYNC_LOADING}, @@ -2068,6 +2074,11 @@ {"siteSettingsMidiDevicesBlock", IDS_SETTINGS_SITE_SETTINGS_MIDI_DEVICES_BLOCK}, {"siteSettingsUsbDevices", IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES}, + {"siteSettingsUsbDevicesAsk", IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK}, + {"siteSettingsUsbDevicesAskRecommended", + IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED}, + {"siteSettingsUsbDevicesBlock", + IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_BLOCK}, {"siteSettingsRemoveZoomLevel", IDS_SETTINGS_SITE_SETTINGS_REMOVE_ZOOM_LEVEL}, {"siteSettingsZoomLevels", IDS_SETTINGS_SITE_SETTINGS_ZOOM_LEVELS},
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 6211aaa..22d730a 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -282,6 +282,8 @@ if (signin_manager) signin_observer_.Add(signin_manager); + // This is intentionally not using GetSyncService(), to go around the + // Profile::IsSyncAllowed() check. ProfileSyncService* sync_service( ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_)); if (sync_service) @@ -625,15 +627,19 @@ void PeopleHandler::HandleShowSetupUI(const base::ListValue* args) { AllowJavascript(); + ProfileSyncService* service = GetSyncService(); + // Just let the page open for now, even when the user's not signed in. // TODO(scottchen): finish the UI for signed-out users // (https://crbug.com/800972). if (IsUnifiedConsentEnabled(profile_) && IsProfileAuthNeededOrHasErrors()) { + if (service && !sync_blocker_) + sync_blocker_ = service->GetSetupInProgressHandle(); + FireWebUIListener("sync-prefs-changed", base::DictionaryValue()); return; } - ProfileSyncService* service = GetSyncService(); if (!service) { CloseUI(); return; @@ -871,13 +877,17 @@ } #endif + // This is intentionally not using GetSyncService(), in order to access more + // nuanced information, since GetSyncService() returns nullptr if anything + // makes Profile::IsSyncAllowed() false. ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_); sync_status->SetBoolean("signinAllowed", signin->IsSigninAllowed()); sync_status->SetBoolean("syncSystemEnabled", (service != nullptr)); - sync_status->SetBoolean( - "setupInProgress", - service && !service->IsManaged() && service->IsFirstSetupInProgress()); + sync_status->SetBoolean("setupInProgress", + service && !service->IsManaged() && + service->IsFirstSetupInProgress() && + signin->IsAuthenticated()); base::string16 status_label; base::string16 link_label;
diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc index 7dcad65..c6e1e92 100644 --- a/chrome/browser/ui/webui/site_settings_helper.cc +++ b/chrome/browser/ui/webui/site_settings_helper.cc
@@ -76,6 +76,7 @@ {CONTENT_SETTINGS_TYPE_CLIPBOARD_READ, "clipboard"}, {CONTENT_SETTINGS_TYPE_SENSORS, "sensors"}, {CONTENT_SETTINGS_TYPE_PAYMENT_HANDLER, "payment-handler"}, + {CONTENT_SETTINGS_TYPE_USB_GUARD, "usb-devices"}, // Add new content settings here if a corresponding Javascript string // representation for it is not required. Note some exceptions, such as @@ -101,7 +102,6 @@ {CONTENT_SETTINGS_TYPE_ACCESSIBILITY_EVENTS, nullptr}, {CONTENT_SETTINGS_TYPE_CLIPBOARD_WRITE, nullptr}, {CONTENT_SETTINGS_TYPE_PLUGINS_DATA, nullptr}, - {CONTENT_SETTINGS_TYPE_USB_GUARD, nullptr}, }; static_assert(arraysize(kContentSettingsTypeGroupNames) == // ContentSettingsType starts at -1, so add 1 here.
diff --git a/chrome/browser/upgrade_detector.h b/chrome/browser/upgrade_detector.h index cfef0694..140d399 100644 --- a/chrome/browser/upgrade_detector.h +++ b/chrome/browser/upgrade_detector.h
@@ -80,8 +80,8 @@ return upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU; } - // Notifify this object that the user has acknowledged the critical update - // so we don't need to complain about it for now. + // Notify this object that the user has acknowledged the critical update so we + // don't need to complain about it for now. void acknowledge_critical_update() { critical_update_acknowledged_ = true; }
diff --git a/chrome/browser/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector_impl.cc index 512048dc..ed40d2a 100644 --- a/chrome/browser/upgrade_detector_impl.cc +++ b/chrome/browser/upgrade_detector_impl.cc
@@ -6,8 +6,8 @@ #include <stdint.h> +#include <algorithm> #include <string> -#include <utility> #include "base/bind.h" #include "base/build_time.h" @@ -160,9 +160,12 @@ upgrade_notification_timer_(this->tick_clock()), is_unstable_channel_(false), is_auto_update_enabled_(true), + simulating_outdated_(SimulatingOutdated()), + is_testing_(simulating_outdated_ || IsTesting()), build_date_(base::GetBuildTime()), weak_factory_(this) { - base::CommandLine command_line(*base::CommandLine::ForCurrentProcess()); + InitializeThresholds(); + const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess(); // The different command line switches that affect testing can't be used // simultaneously, if they do, here's the precedence order, based on the order // of the if statements below: @@ -172,17 +175,17 @@ // - kSimulateCriticalUpdate has precedence over kSimulateOutdated. // - kSimulateOutdatedNoAU has precedence over kSimulateOutdated. // - kSimulateOutdated[NoAu] can work on its own, or with a specified date. - if (command_line.HasSwitch(switches::kDisableBackgroundNetworking)) + if (cmd_line.HasSwitch(switches::kDisableBackgroundNetworking)) return; - if (command_line.HasSwitch(switches::kSimulateUpgrade)) { + if (cmd_line.HasSwitch(switches::kSimulateUpgrade)) { UpgradeDetected(UPGRADE_AVAILABLE_REGULAR); return; } - if (command_line.HasSwitch(switches::kSimulateCriticalUpdate)) { + if (cmd_line.HasSwitch(switches::kSimulateCriticalUpdate)) { UpgradeDetected(UPGRADE_AVAILABLE_CRITICAL); return; } - if (SimulatingOutdated()) { + if (simulating_outdated_) { // The outdated simulation can work without a value, which means outdated // now, or with a value that must be a well formed date/time string that // overrides the build date. @@ -191,13 +194,13 @@ // command line switch must also be specified for the service to be // available on non GOOGLE_CHROME_BUILD. std::string switch_name; - if (command_line.HasSwitch(switches::kSimulateOutdatedNoAU)) { + if (cmd_line.HasSwitch(switches::kSimulateOutdatedNoAU)) { is_auto_update_enabled_ = false; switch_name = switches::kSimulateOutdatedNoAU; } else { switch_name = switches::kSimulateOutdated; } - std::string build_date = command_line.GetSwitchValueASCII(switch_name); + std::string build_date = cmd_line.GetSwitchValueASCII(switch_name); base::Time maybe_build_time; bool result = base::Time::FromString(build_date.c_str(), &maybe_build_time); if (result && !maybe_build_time.is_null()) { @@ -314,46 +317,78 @@ if (upgrade_notification_timer_.IsRunning()) return; - // Ensure that the thresholds used by NotifyOnUpgrade have been initialized. - InitializeThresholds(); - if (upgrade_detected_time().is_null()) set_upgrade_detected_time(tick_clock()->NowTicks()); // Start the repeating timer for notifying the user after a certain period. - // The called function will eventually figure out that enough time has passed - // and stop the timer. upgrade_notification_timer_.Start( - FROM_HERE, IsTesting() ? kNotifyCycleTimeForTesting : kNotifyCycleTime, + FROM_HERE, is_testing_ ? kNotifyCycleTimeForTesting : kNotifyCycleTime, this, &UpgradeDetectorImpl::NotifyOnUpgrade); } void UpgradeDetectorImpl::InitializeThresholds() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!low_threshold_.is_zero()) + if (!stages_.empty()) return; + DoInitializeThresholds(); +#if DCHECK_IS_ON() + // |stages_| must have at least one element, and must be sorted in decreasing + // order of time. + DCHECK(!stages_.empty()); + for (auto scan = stages_.begin() + 1; scan != stages_.end(); ++scan) + DCHECK_GT((scan - 1)->first, scan->first); + + // elevated_threshold_ must be greater than low_threshold (the last item in) + // |stages_|. + DCHECK_GT(elevated_threshold_, stages_.back().first); + + // high_threshold_ must be greater than elevated_threshold_. + DCHECK_GT(high_threshold_, elevated_threshold_); + + // If elevated_threshold_ and high_threshold_ are present in |stages_|, they + // must be equal. + if (stages_.size() != 1) { + DCHECK(!is_unstable_channel_); + DCHECK_EQ(stages_.size(), 3U); + DCHECK_EQ(stages_[1].first, elevated_threshold_); + DCHECK_EQ(stages_[0].first, high_threshold_); + } else { + DCHECK(is_unstable_channel_); + } +#endif // DCHECK_IS_ON() +} + +void UpgradeDetectorImpl::DoInitializeThresholds() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(stages_.empty()); + + base::TimeDelta low_threshold; + // Use a custom notification period for the "high" level, dividing it evenly // to set the "low" and "elevated" levels. Such overrides trump all else. const base::TimeDelta custom_high = GetRelaunchNotificationPeriod(); if (!custom_high.is_zero()) { - low_threshold_ = custom_high / 3; - elevated_threshold_ = custom_high - low_threshold_; + low_threshold = custom_high / 3; + elevated_threshold_ = custom_high - low_threshold; high_threshold_ = custom_high; + // Stages must be sorted by decreasing TimeDelta. + stages_.emplace_back(high_threshold_, UPGRADE_ANNOYANCE_HIGH); + stages_.emplace_back(elevated_threshold_, UPGRADE_ANNOYANCE_ELEVATED); + stages_.emplace_back(low_threshold, UPGRADE_ANNOYANCE_LOW); return; } // Use the default values when no override is set. - low_threshold_ = kDefaultLowThreshold; + low_threshold = kDefaultLowThreshold; elevated_threshold_ = kDefaultElevatedThreshold; high_threshold_ = kDefaultHighThreshold; // When testing, scale everything back so that a day passes in ten seconds. - const bool is_testing = IsTesting(); - if (is_testing) { + if (is_testing_) { static constexpr int64_t scale_factor = base::TimeDelta::FromDays(1) / base::TimeDelta::FromSeconds(10); - low_threshold_ /= scale_factor; + low_threshold /= scale_factor; elevated_threshold_ /= scale_factor; high_threshold_ /= scale_factor; } @@ -361,9 +396,16 @@ // Canary and dev channels are extra special, and reach "low" annoyance after // one hour (one second in testing) and never advance beyond that. if (is_unstable_channel_) { - low_threshold_ = is_testing ? base::TimeDelta::FromSeconds(1) + low_threshold = is_testing_ ? base::TimeDelta::FromSeconds(1) : base::TimeDelta::FromHours(1); + // High and elevated thresholds are not added to |stages_| on unstable + // channels. + } else { + // Stages must be sorted by decreasing TimeDelta. + stages_.emplace_back(high_threshold_, UPGRADE_ANNOYANCE_HIGH); + stages_.emplace_back(elevated_threshold_, UPGRADE_ANNOYANCE_ELEVATED); } + stages_.emplace_back(low_threshold, UPGRADE_ANNOYANCE_LOW); } void UpgradeDetectorImpl::CheckForUpgrade() { @@ -396,8 +438,7 @@ // Don't show the bubble if we have a brand code that is NOT organic, unless // an outdated build is being simulated by command line switches. - static bool simulate_outdated = SimulatingOutdated(); - if (!simulate_outdated) { + if (!simulating_outdated_) { std::string brand; if (google_brand::GetBrand(&brand) && !google_brand::IsOrganic(brand)) return false; @@ -433,7 +474,7 @@ } // If we simlated an outdated install with a date, we don't want to keep // checking for version upgrades, which happens on non-official builds. - return simulate_outdated; + return simulating_outdated_; } void UpgradeDetectorImpl::UpgradeDetected(UpgradeAvailable upgrade_available) { @@ -457,47 +498,62 @@ void UpgradeDetectorImpl::NotifyOnUpgradeWithTimePassed( base::TimeDelta time_passed) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const bool is_critical_or_outdated = - upgrade_available() > UPGRADE_AVAILABLE_REGULAR || - critical_experiment_updates_available(); - // There's only one threat level for dev and canary channels. - const UpgradeNotificationAnnoyanceLevel max_stage = - is_unstable_channel_ ? UPGRADE_ANNOYANCE_LOW : UPGRADE_ANNOYANCE_HIGH; - bool notify = true; + const UpgradeNotificationAnnoyanceLevel last_stage = + upgrade_notification_stage(); - // These if statements must be sorted (highest interval first). - if (is_critical_or_outdated) - set_upgrade_notification_stage(UPGRADE_ANNOYANCE_CRITICAL); - else if (!is_unstable_channel_ && time_passed >= high_threshold_) - set_upgrade_notification_stage(UPGRADE_ANNOYANCE_HIGH); - else if (!is_unstable_channel_ && time_passed >= elevated_threshold_) - set_upgrade_notification_stage(UPGRADE_ANNOYANCE_ELEVATED); - else if (time_passed >= low_threshold_) - set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW); - else if (upgrade_notification_stage() != UPGRADE_ANNOYANCE_NONE) - set_upgrade_notification_stage(UPGRADE_ANNOYANCE_NONE); - else - notify = false; // Not ready to recommend upgrade. + // Figure out which stage the detector is now in (new_stage) and how far away + // the next highest stage is (next_delay). + UpgradeNotificationAnnoyanceLevel new_stage = UPGRADE_ANNOYANCE_NONE; + base::TimeDelta next_delay; - // Stop the timer if the highest threshold has been reached. Otherwise, make - // sure it is running. It is possible that a change in the notification period - // (via administrative policy) has moved the detector from high annoyance back - // down to a lower level, in which case the timer must be restarted. - if (upgrade_notification_stage() >= max_stage) + if (upgrade_available() > UPGRADE_AVAILABLE_REGULAR || + critical_experiment_updates_available()) { + new_stage = UPGRADE_ANNOYANCE_CRITICAL; + } else { + // |stages_| must be sorted by decreasing TimeDelta. + auto it = std::find_if(stages_.begin(), stages_.end(), + [time_passed](const DeltaAndStage& delta_and_stage) { + return time_passed >= delta_and_stage.first; + }); + if (it != stages_.end()) + new_stage = it->second; + if (it != stages_.begin()) + next_delay = (it - 1)->first - time_passed; + } + + set_upgrade_notification_stage(new_stage); + if (!next_delay.is_zero()) { + // Schedule the next wakeup in 20 minutes or when the next change to the + // notification stage should take place. + upgrade_notification_timer_.Start( + FROM_HERE, + std::min(next_delay, + is_testing_ ? kNotifyCycleTimeForTesting : kNotifyCycleTime), + this, &UpgradeDetectorImpl::NotifyOnUpgrade); + } else if (upgrade_notification_timer_.IsRunning()) { + // Explicitly stop the timer in case this call is due to a change (e.g., in + // the RelaunchNotificationPeriod) that brought the instance up to or above + // the "high" annoyance level. upgrade_notification_timer_.Stop(); - else - StartUpgradeNotificationTimer(); + } - if (notify) + // Issue a notification if the stage is above "none" or if it's dropped down + // to "none" from something higher. + if (new_stage != UPGRADE_ANNOYANCE_NONE || + last_stage != UPGRADE_ANNOYANCE_NONE) { NotifyUpgrade(); + } } base::TimeDelta UpgradeDetectorImpl::GetThresholdForLevel( UpgradeNotificationAnnoyanceLevel level) { + DCHECK(!stages_.empty()); switch (level) { case UPGRADE_ANNOYANCE_LOW: - return low_threshold_; + // Low is always the last item in |stages_|. + return stages_.back().first; case UPGRADE_ANNOYANCE_ELEVATED: + // Elevated is not present in |stages_| on unstable channels. return elevated_threshold_; case UPGRADE_ANNOYANCE_HIGH: break; @@ -506,6 +562,7 @@ NOTREACHED(); break; } + // High is not present in |stages_| on unstable channels. return high_threshold_; } @@ -513,7 +570,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Force a recomputation of the thresholds. - low_threshold_ = {}; + stages_.clear(); InitializeThresholds(); // Broadcast the appropriate notification if an upgrade has been detected. @@ -546,13 +603,13 @@ base::TimeDelta UpgradeDetectorImpl::GetHighAnnoyanceLevelDelta() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - InitializeThresholds(); + // Elevated and high thresholds are not present in |stages_| for unstable + // channels, but their delta is still valid in such case. return high_threshold_ - elevated_threshold_; } base::TimeTicks UpgradeDetectorImpl::GetHighAnnoyanceDeadline() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - InitializeThresholds(); const base::TimeTicks detected_time = upgrade_detected_time(); if (detected_time.is_null()) return detected_time;
diff --git a/chrome/browser/upgrade_detector_impl.h b/chrome/browser/upgrade_detector_impl.h index db24faac..03cd93e 100644 --- a/chrome/browser/upgrade_detector_impl.h +++ b/chrome/browser/upgrade_detector_impl.h
@@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_UPGRADE_DETECTOR_IMPL_H_ #define CHROME_BROWSER_UPGRADE_DETECTOR_IMPL_H_ +#include <utility> +#include <vector> + #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -64,6 +67,10 @@ // A callback that receives the results of |DetectUpgradeTask|. using UpgradeDetectedCallback = base::OnceCallback<void(UpgradeAvailable)>; + using DeltaAndStage = + std::pair<base::TimeDelta, UpgradeNotificationAnnoyanceLevel>; + using Stages = std::vector<DeltaAndStage>; + // UpgradeDetector: void OnRelaunchNotificationPeriodPrefChanged() override; @@ -86,6 +93,7 @@ // Lazy-initialization for the various threshold deltas (idempotent). void InitializeThresholds(); + void DoInitializeThresholds(); // Returns true after calling UpgradeDetected if current install is outdated. bool DetectOutdatedInstall(); @@ -109,9 +117,9 @@ // We periodically check to see if Chrome has been upgraded. base::RepeatingTimer detect_upgrade_timer_; - // After we detect an upgrade we start a recurring timer to see if enough time - // has passed and we should start notifying the user. - base::RepeatingTimer upgrade_notification_timer_; + // A timer used to move through the various upgrade notification stages and + // schedule calls to NotifyUpgrade. + base::OneShotTimer upgrade_notification_timer_; // True if this build is a dev or canary channel build. bool is_unstable_channel_; @@ -119,11 +127,18 @@ // True if auto update is turned on. bool is_auto_update_enabled_; + // True if test switches that simulate an outdated install are present on the + // command line. + const bool simulating_outdated_; + + // True if test switches are present on the command line. + const bool is_testing_; + // The various deltas from detection time to the different annoyance levels; // lazy-initialized by InitializeThresholds. base::TimeDelta high_threshold_; base::TimeDelta elevated_threshold_; - base::TimeDelta low_threshold_; + Stages stages_; // The date the binaries were built. base::Time build_date_;
diff --git a/chrome/browser/upgrade_detector_impl_unittest.cc b/chrome/browser/upgrade_detector_impl_unittest.cc index f71059e..49f2b9d 100644 --- a/chrome/browser/upgrade_detector_impl_unittest.cc +++ b/chrome/browser/upgrade_detector_impl_unittest.cc
@@ -4,8 +4,13 @@ #include "chrome/browser/upgrade_detector_impl.h" +#include <initializer_list> +#include <utility> +#include <vector> + #include "base/macros.h" #include "base/test/scoped_task_environment.h" +#include "base/time/tick_clock.h" #include "chrome/browser/upgrade_observer.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/scoped_testing_local_state.h" @@ -27,6 +32,7 @@ using UpgradeDetectorImpl::OnExperimentChangesDetected; using UpgradeDetectorImpl::NotifyOnUpgradeWithTimePassed; using UpgradeDetectorImpl::GetThresholdForLevel; + using UpgradeDetectorImpl::tick_clock; // UpgradeDetector: void TriggerCriticalUpdate() override { @@ -251,7 +257,11 @@ EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), UpgradeDetector::UPGRADE_ANNOYANCE_HIGH); - // Bring it back up. + // Expect no new notifications even if some time passes. + FastForwardBy(base::TimeDelta::FromHours(1)); + ::testing::Mock::VerifyAndClear(&mock_observer); + + // Bring the period back up. EXPECT_CALL(mock_observer, OnUpgradeRecommended()); SetNotificationPeriodPref(base::TimeDelta()); ::testing::Mock::VerifyAndClear(&mock_observer); @@ -277,3 +287,104 @@ EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), UpgradeDetector::UPGRADE_ANNOYANCE_NONE); } + +// Appends the time and stage from detector to |notifications|. +ACTION_P2(AppendTicksAndStage, detector, notifications) { + notifications->emplace_back(detector->tick_clock()->NowTicks(), + detector->upgrade_notification_stage()); +} + +// A value parameterized test fixture for running tests with different +// RelaunchNotificationPeriod settings. +class UpgradeDetectorImplTimerTest : public UpgradeDetectorImplTest, + public ::testing::WithParamInterface<int> { + protected: + UpgradeDetectorImplTimerTest() { + const int period_ms = GetParam(); + if (period_ms) + SetNotificationPeriodPref(base::TimeDelta::FromMilliseconds(period_ms)); + } + + private: + DISALLOW_COPY_AND_ASSIGN(UpgradeDetectorImplTimerTest); +}; + +INSTANTIATE_TEST_CASE_P(, + UpgradeDetectorImplTimerTest, + ::testing::Values(0, // Default period of 7d. + 11100000)); // 3:05:00. + +// Tests that the notification timer is handled as desired. +TEST_P(UpgradeDetectorImplTimerTest, TestNotificationTimer) { + using TimeAndStage = + std::pair<base::TimeTicks, + UpgradeDetector::UpgradeNotificationAnnoyanceLevel>; + using Notifications = std::vector<TimeAndStage>; + + // Fast forward a little bit to get away from zero ticks, which has special + // meaning in the detector. + FastForwardBy(base::TimeDelta::FromHours(1)); + + TestUpgradeDetectorImpl detector(GetMockTickClock()); + ::testing::StrictMock<MockUpgradeObserver> mock_observer(&detector); + + // Cache the thresholds for the detector's annoyance levels. + const base::TimeDelta thresholds[3] = { + detector.GetThresholdForLevel(UpgradeDetector::UPGRADE_ANNOYANCE_LOW), + detector.GetThresholdForLevel( + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED), + detector.GetThresholdForLevel(UpgradeDetector::UPGRADE_ANNOYANCE_HIGH), + }; + + // Pretend that there's an update. + detector.UpgradeDetected(TestUpgradeDetectorImpl::UPGRADE_AVAILABLE_REGULAR); + ::testing::Mock::VerifyAndClear(&mock_observer); + + // Fast foward to the time that low annoyance should be reached. One + // notification should come in at exactly the low annoyance threshold. + Notifications notifications; + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .WillOnce(AppendTicksAndStage(&detector, ¬ifications)); + FastForwardBy(thresholds[0]); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_THAT(notifications, + ::testing::ContainerEq(Notifications({TimeAndStage( + detector.upgrade_detected_time() + thresholds[0], + UpgradeDetector::UPGRADE_ANNOYANCE_LOW)}))); + + // Move to the time that elevated annoyance should be reached. Notifications + // at low annoyance should arrive every 20 minutes with one final notification + // at elevated annoyance. + notifications.clear(); + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .WillRepeatedly(AppendTicksAndStage(&detector, ¬ifications)); + FastForwardBy(thresholds[1] - thresholds[0]); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_THAT(notifications.size(), ::testing::Gt(1U)); + EXPECT_THAT((notifications.end() - 2)->second, + ::testing::Eq(UpgradeDetector::UPGRADE_ANNOYANCE_LOW)); + EXPECT_THAT(notifications.back(), + ::testing::Eq( + TimeAndStage(detector.upgrade_detected_time() + thresholds[1], + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED))); + + // Move to the time that high annoyance should be reached. Notifications at + // elevated annoyance should arrive every 20 minutes with one final + // notification at high annoyance. + notifications.clear(); + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .WillRepeatedly(AppendTicksAndStage(&detector, ¬ifications)); + FastForwardBy(thresholds[2] - thresholds[1]); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_THAT(notifications.size(), ::testing::Gt(1U)); + EXPECT_THAT((notifications.end() - 2)->second, + ::testing::Eq(UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED)); + EXPECT_THAT(notifications.back(), + ::testing::Eq( + TimeAndStage(detector.upgrade_detected_time() + thresholds[2], + UpgradeDetector::UPGRADE_ANNOYANCE_HIGH))); + + // No new notifications after high annoyance has been reached. + FastForwardBy(thresholds[2]); + ::testing::Mock::VerifyAndClear(&mock_observer); +}
diff --git a/chrome/browser/usb/usb_chooser_controller.cc b/chrome/browser/usb/usb_chooser_controller.cc index 4b103044..390eb2c6 100644 --- a/chrome/browser/usb/usb_chooser_controller.cc +++ b/chrome/browser/usb/usb_chooser_controller.cc
@@ -8,13 +8,13 @@ #include <utility> #include "base/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/browser/net/referrer.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" #include "chrome/browser/usb/usb_blocklist.h" #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" -#include "chrome/browser/usb/usb_util.h" #include "chrome/browser/usb/web_usb_histograms.h" #include "chrome/browser/usb/web_usb_permission_provider.h" #include "chrome/common/url_constants.h" @@ -29,10 +29,43 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" +#if !defined(OS_ANDROID) +#include "device/usb/usb_ids.h" +#endif // !defined(OS_ANDROID) + using content::RenderFrameHost; using content::WebContents; using device::UsbDevice; +namespace { + +base::string16 FormatUsbDeviceName(scoped_refptr<device::UsbDevice> device) { + base::string16 device_name = device->product_string(); + if (device_name.empty()) { + uint16_t vendor_id = device->vendor_id(); + uint16_t product_id = device->product_id(); +#if !defined(OS_ANDROID) + if (const char* product_name = + device::UsbIds::GetProductName(vendor_id, product_id)) { + return base::UTF8ToUTF16(product_name); + } else if (const char* vendor_name = + device::UsbIds::GetVendorName(vendor_id)) { + return l10n_util::GetStringFUTF16( + IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_NAME, + base::UTF8ToUTF16(vendor_name)); + } +#endif // !defined(OS_ANDROID) + device_name = l10n_util::GetStringFUTF16( + IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_ID_AND_PRODUCT_ID, + base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id)), + base::ASCIIToUTF16(base::StringPrintf("%04x", product_id))); + } + + return device_name; +} + +} // namespace + UsbChooserController::UsbChooserController( RenderFrameHost* render_frame_host, std::vector<device::mojom::UsbDeviceFilterPtr> device_filters, @@ -42,6 +75,7 @@ IDS_USB_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME), filters_(std::move(device_filters)), callback_(std::move(callback)), + web_contents_(WebContents::FromRenderFrameHost(render_frame_host)), usb_service_observer_(this), weak_factory_(this) { device::UsbService* usb_service = @@ -52,13 +86,11 @@ weak_factory_.GetWeakPtr())); } - WebContents* web_contents = - WebContents::FromRenderFrameHost(render_frame_host); - RenderFrameHost* main_frame = web_contents->GetMainFrame(); + RenderFrameHost* main_frame = web_contents_->GetMainFrame(); requesting_origin_ = render_frame_host->GetLastCommittedURL().GetOrigin(); embedding_origin_ = main_frame->GetLastCommittedURL().GetOrigin(); Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); + Profile::FromBrowserContext(web_contents_->GetBrowserContext()); chooser_context_ = UsbChooserContextFactory::GetForProfile(profile)->AsWeakPtr(); } @@ -130,7 +162,7 @@ void UsbChooserController::Close() {} void UsbChooserController::OpenHelpCenterUrl() const { - GetBrowser()->OpenURL(content::OpenURLParams( + web_contents_->OpenURL(content::OpenURLParams( GURL(chrome::kChooserUsbOverviewURL), content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initialized */));
diff --git a/chrome/browser/usb/usb_chooser_controller.h b/chrome/browser/usb/usb_chooser_controller.h index b52b9b57..4971574 100644 --- a/chrome/browser/usb/usb_chooser_controller.h +++ b/chrome/browser/usb/usb_chooser_controller.h
@@ -20,6 +20,7 @@ namespace content { class RenderFrameHost; +class WebContents; } namespace device { @@ -64,6 +65,7 @@ GURL requesting_origin_; GURL embedding_origin_; + content::WebContents* const web_contents_; base::WeakPtr<UsbChooserContext> chooser_context_; ScopedObserver<device::UsbService, device::UsbService::Observer> usb_service_observer_;
diff --git a/chrome/browser/usb/usb_util.cc b/chrome/browser/usb/usb_util.cc deleted file mode 100644 index 9a803b9..0000000 --- a/chrome/browser/usb/usb_util.cc +++ /dev/null
@@ -1,54 +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 "chrome/browser/usb/usb_util.h" - -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "chrome/grit/generated_resources.h" -#include "device/usb/usb_device.h" -#include "ui/base/l10n/l10n_util.h" - -#if !defined(OS_ANDROID) -#include "device/usb/usb_ids.h" -#endif // !defined(OS_ANDROID) - -base::string16 FormatUsbDeviceName(scoped_refptr<device::UsbDevice> device) { - base::string16 device_name = device->product_string(); - if (device_name.empty()) { - uint16_t vendor_id = device->vendor_id(); - uint16_t product_id = device->product_id(); -#if !defined(OS_ANDROID) - if (const char* product_name = - device::UsbIds::GetProductName(vendor_id, product_id)) { - return base::UTF8ToUTF16(product_name); - } else if (const char* vendor_name = - device::UsbIds::GetVendorName(vendor_id)) { - return l10n_util::GetStringFUTF16( - IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_NAME, - base::UTF8ToUTF16(vendor_name)); - } -#endif // !defined(OS_ANDROID) - device_name = l10n_util::GetStringFUTF16( - IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_ID_AND_PRODUCT_ID, - base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id)), - base::ASCIIToUTF16(base::StringPrintf("%04x", product_id))); - } - - return device_name; -} - -Browser* GetBrowser() { -#if defined(OS_ANDROID) - return nullptr; -#else - chrome::ScopedTabbedBrowserDisplayer browser_displayer( - ProfileManager::GetLastUsedProfileAllowedByPolicy()); - DCHECK(browser_displayer.browser()); - return browser_displayer.browser(); -#endif // !defined(OS_ANDROID) -}
diff --git a/chrome/browser/usb/usb_util.h b/chrome/browser/usb/usb_util.h deleted file mode 100644 index 3402327..0000000 --- a/chrome/browser/usb/usb_util.h +++ /dev/null
@@ -1,21 +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_USB_USB_UTIL_H_ -#define CHROME_BROWSER_USB_USB_UTIL_H_ - -#include "base/memory/ref_counted.h" -#include "base/strings/string16.h" - -class Browser; - -namespace device { -class UsbDevice; -} - -base::string16 FormatUsbDeviceName(scoped_refptr<device::UsbDevice> device); - -Browser* GetBrowser(); - -#endif // CHROME_BROWSER_USB_USB_UTIL_H_
diff --git a/chrome/browser/usb/web_usb_chooser_service_desktop.cc b/chrome/browser/usb/web_usb_chooser_service_desktop.cc index ba2565e..44f5903 100644 --- a/chrome/browser/usb/web_usb_chooser_service_desktop.cc +++ b/chrome/browser/usb/web_usb_chooser_service_desktop.cc
@@ -18,20 +18,20 @@ : WebUsbChooserService(render_frame_host) {} WebUsbChooserServiceDesktop::~WebUsbChooserServiceDesktop() { - for (const auto& bubble : bubbles_) { - if (bubble) - bubble->CloseBubble(BUBBLE_CLOSE_FORCED); - } + if (bubble_) + bubble_->CloseBubble(BUBBLE_CLOSE_FORCED); } void WebUsbChooserServiceDesktop::ShowChooser( std::unique_ptr<UsbChooserController> controller) { + // Only one chooser bubble may be shown at a time. + if (bubble_) + bubble_->CloseBubble(BUBBLE_CLOSE_FORCED); + auto delegate = std::make_unique<ChooserBubbleDelegate>( render_frame_host(), std::move(controller)); auto* web_contents = content::WebContents::FromRenderFrameHost(render_frame_host()); Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - BubbleReference bubble_reference = - browser->GetBubbleManager()->ShowBubble(std::move(delegate)); - bubbles_.push_back(bubble_reference); + bubble_ = browser->GetBubbleManager()->ShowBubble(std::move(delegate)); }
diff --git a/chrome/browser/usb/web_usb_chooser_service_desktop.h b/chrome/browser/usb/web_usb_chooser_service_desktop.h index 2f6715d..fe33292 100644 --- a/chrome/browser/usb/web_usb_chooser_service_desktop.h +++ b/chrome/browser/usb/web_usb_chooser_service_desktop.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_USB_WEB_USB_CHOOSER_SERVICE_DESKTOP_H_ #define CHROME_BROWSER_USB_WEB_USB_CHOOSER_SERVICE_DESKTOP_H_ -#include <vector> - #include "base/macros.h" #include "chrome/browser/usb/web_usb_chooser_service.h" #include "components/bubble/bubble_reference.h" @@ -23,7 +21,7 @@ void ShowChooser(std::unique_ptr<UsbChooserController> controller) override; private: - std::vector<BubbleReference> bubbles_; + BubbleReference bubble_; DISALLOW_COPY_AND_ASSIGN(WebUsbChooserServiceDesktop); };
diff --git a/chrome/browser/usb/web_usb_detector.cc b/chrome/browser/usb/web_usb_detector.cc index 36ebd699..78e9640d 100644 --- a/chrome/browser/usb/web_usb_detector.cc +++ b/chrome/browser/usb/web_usb_detector.cc
@@ -17,9 +17,9 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/usb/usb_util.h" #include "chrome/grit/generated_resources.h" #include "components/url_formatter/elide_url.h" #include "components/vector_icons/vector_icons.h" @@ -83,7 +83,9 @@ } void OpenURL(const GURL& url) { - GetBrowser()->OpenURL(content::OpenURLParams( + chrome::ScopedTabbedBrowserDisplayer browser_displayer( + ProfileManager::GetLastUsedProfileAllowedByPolicy()); + browser_displayer.browser()->OpenURL(content::OpenURLParams( url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initialized */)); }
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index 0919450..3d81b30 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -82,6 +82,7 @@ static constexpr float kToastCornerRadiusDMM = 0.004f; static constexpr float kToastTextFontHeightDMM = 0.023f; static constexpr int kToastTimeoutSeconds = 6; +static constexpr float kPlatformToastVerticalOffset = 0.5f; static constexpr float kSplashScreenTextDistance = 2.5f; static constexpr float kSplashScreenTextFontHeightDMM = 0.05f;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 85316f39..8a9cf77 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -2952,25 +2952,25 @@ } void UiSceneCreator::CreateToasts() { - auto layout = Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kLeft); - layout->set_contributes_to_parent_bounds(false); - layout->set_y_anchoring(TOP); - layout->SetTranslate(0, kIndicatorVerticalOffset, kIndicatorDistanceOffset); - layout->set_margin(kWebVrPermissionMargin); - auto platform_toast = CreateTextToast( kPlatformToastTransientParent, kPlatformToast, model_, base::string16()); + platform_toast->set_contributes_to_parent_bounds(false); + platform_toast->set_y_anchoring(BOTTOM); + platform_toast->set_y_centering(TOP); + platform_toast->SetTranslate(0, kPlatformToastVerticalOffset, + kIndicatorDistanceOffset); platform_toast->AddBinding(std::make_unique<Binding<const PlatformToast*>>( VR_BIND_LAMBDA([](Model* m) { return m->platform_toast.get(); }, base::Unretained(model_)), VR_BIND_LAMBDA( [](TransientElement* t, const PlatformToast* const& value) { - SetVisibleInLayout(t, value); + t->SetVisible(value); if (value) { t->RefreshVisible(); } }, base::Unretained(platform_toast.get())))); + Text* text_element = static_cast<Text*>(platform_toast->GetDescendantByType(kTypeToastText)); DCHECK(text_element); @@ -2984,9 +2984,8 @@ } }, base::Unretained(text_element)))); - layout->AddChild(std::move(platform_toast)); - scene_->AddUiElement(k2dBrowsingContentGroup, std::move(layout)); + scene_->AddUiElement(k2dBrowsingContentGroup, std::move(platform_toast)); } } // namespace vr
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 8465993..60902014 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -407,10 +407,9 @@ #endif // Enables the use of native notification centers instead of using the Message -// Center for displaying the toasts. +// Center for displaying the toasts. Note that OS_LINUX includes Chrome OS. #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) -#if defined(OS_MACOSX) || defined(OS_ANDROID) || \ - (defined(OS_LINUX) && !defined(OS_CHROMEOS)) +#if defined(OS_MACOSX) || defined(OS_ANDROID) || defined(OS_LINUX) const base::Feature kNativeNotifications{"NativeNotifications", base::FEATURE_ENABLED_BY_DEFAULT}; #else
diff --git a/chrome/common/extensions/permissions/permissions_data_unittest.cc b/chrome/common/extensions/permissions/permissions_data_unittest.cc index f78aac17..7522bf0 100644 --- a/chrome/common/extensions/permissions/permissions_data_unittest.cc +++ b/chrome/common/extensions/permissions/permissions_data_unittest.cc
@@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/extensions/extension_test_util.h" #include "components/crx_file/id_util.h" @@ -377,7 +378,7 @@ crx_file::id_util::GenerateIdForPath( base::FilePath(FILE_PATH_LITERAL("foo")))), settings_url("chrome://settings"), - about_url("about:flags") { + about_flags_url("about:flags") { urls_.insert(http_url); urls_.insert(http_url_with_path); urls_.insert(https_url); @@ -388,7 +389,7 @@ urls_.insert(favicon_url); urls_.insert(extension_url); urls_.insert(settings_url); - urls_.insert(about_url); + urls_.insert(about_flags_url); // Ignore the policy delegate for this test. PermissionsData::SetPolicyDelegate(NULL); } @@ -408,8 +409,8 @@ const GURL& url, int tab_id) { bool allowed_script = IsAllowedScript(extension, url, tab_id); - bool allowed_capture = - extension->permissions_data()->CanCaptureVisiblePage(tab_id, nullptr); + bool allowed_capture = extension->permissions_data()->CanCaptureVisiblePage( + url, extension, tab_id, nullptr); if (allowed_script && allowed_capture) return ALLOWED_SCRIPT_AND_CAPTURE; @@ -430,11 +431,14 @@ int tab_id) { std::vector<std::string> errors; for (const GURL& url : urls_) { - bool allowed = IsAllowedScript(extension, url, tab_id); - if (allowed && !allowed_urls.count(url)) - errors.push_back("Script unexpectedly disallowed on " + url.spec()); - else if (!allowed && allowed_urls.count(url)) - errors.push_back("Script unexpectedly allowed on " + url.spec()); + AccessType access = GetExtensionAccess(extension, url, tab_id); + AccessType expected_access = + allowed_urls.count(url) ? ALLOWED_SCRIPT_ONLY : DISALLOWED; + if (access != expected_access) { + errors.push_back( + base::StringPrintf("Error for url '%s': expected %d, found %d", + url.spec().c_str(), expected_access, access)); + } } if (!errors.empty()) @@ -459,7 +463,7 @@ // URLs that regular extensions should never get access to. const GURL extension_url; const GURL settings_url; - const GURL about_url; + const GURL about_flags_url; private: bool IsAllowedScript(const Extension* extension, @@ -482,16 +486,11 @@ GetExtensionAccess(extension.get(), http_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), https_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), file_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), settings_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), about_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), extension_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), extension_url)); // Test access to iframed content. GURL within_extension_url = extension->GetResourceURL("page.html"); @@ -506,7 +505,8 @@ EXPECT_FALSE(IsAllowedScript(extension.get(), extension_url)); EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); - EXPECT_FALSE(extension->permissions_data()->HasHostPermission(about_url)); + EXPECT_FALSE( + extension->permissions_data()->HasHostPermission(about_flags_url)); EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); // Test * for scheme, which implies just the http/https schemes. @@ -516,7 +516,7 @@ EXPECT_EQ(ALLOWED_SCRIPT_ONLY, GetExtensionAccess(extension.get(), https_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); extension = @@ -538,14 +538,15 @@ warnings[0].message); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); // Having chrome://favicon/* should not give you chrome://* extension = LoadManifestStrict("script_and_capture", "extension_chrome_favicon_wildcard.json"); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); + EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); // Having http://favicon should not give you chrome://favicon @@ -564,7 +565,7 @@ EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, - GetExtensionAccess(extension.get(), about_url)); + GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), favicon_url)); EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); @@ -578,7 +579,7 @@ EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), extension_url)); EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); } @@ -596,17 +597,13 @@ GetExtensionAccess(extension.get(), http_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), https_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), file_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), settings_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ( ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), favicon_url)); // chrome:// requested - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), about_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), extension_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), extension_url)); // Test access to iframed content. GURL within_extension_url = extension->GetResourceURL("page.html"); @@ -618,7 +615,7 @@ const PermissionsData* permissions_data = extension->permissions_data(); EXPECT_FALSE(permissions_data->HasHostPermission(settings_url)); - EXPECT_FALSE(permissions_data->HasHostPermission(about_url)); + EXPECT_FALSE(permissions_data->HasHostPermission(about_flags_url)); EXPECT_TRUE(permissions_data->HasHostPermission(favicon_url)); // Test * for scheme, which implies just the http/https schemes. @@ -628,7 +625,7 @@ EXPECT_EQ(ALLOWED_SCRIPT_ONLY, GetExtensionAccess(extension.get(), https_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); extension = @@ -647,7 +644,7 @@ EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), https_url)); EXPECT_EQ(ALLOWED_SCRIPT_ONLY, GetExtensionAccess(extension.get(), settings_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); EXPECT_EQ(ALLOWED_SCRIPT_ONLY, GetExtensionAccess(extension.get(), favicon_url)); @@ -658,7 +655,7 @@ EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(ALLOWED_SCRIPT_ONLY, GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); // Having http://favicon should not give you chrome://favicon @@ -677,7 +674,7 @@ EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, - GetExtensionAccess(extension.get(), about_url)); + GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), favicon_url)); EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); @@ -691,7 +688,7 @@ EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), extension_url)); EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); } @@ -743,9 +740,12 @@ std::set<GURL> more_allowed_urls = allowed_urls; more_allowed_urls.insert(https_url); + more_allowed_urls.insert(file_url); URLPatternSet more_allowed_hosts = allowed_hosts; more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL, https_url.spec())); + more_allowed_hosts.AddPattern( + URLPattern(URLPattern::SCHEME_ALL, file_url.spec())); { PermissionSet permissions1(APIPermissionSet(), ManifestPermissionSet(), @@ -784,6 +784,60 @@ EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); } +// Test that activeTab is required for capturing chrome:// urls with +// tabs.captureVisibleTab. https://crbug.com/810220. +TEST_F(ExtensionScriptAndCaptureVisibleTest, CaptureChromeURLs) { + const int kTabId = 42; + scoped_refptr<const Extension> all_urls = + ExtensionBuilder("all urls").AddPermission("<all_urls>").Build(); + EXPECT_EQ(DISALLOWED, + GetExtensionAccess(all_urls.get(), settings_url, kTabId)); + + scoped_refptr<const Extension> active_tab = + ExtensionBuilder("active tab").AddPermission("activeTab").Build(); + EXPECT_EQ(DISALLOWED, + GetExtensionAccess(active_tab.get(), settings_url, kTabId)); + { + APIPermissionSet tab_api_permissions; + tab_api_permissions.insert(APIPermission::kTab); + URLPatternSet tab_hosts; + tab_hosts.AddOrigin(UserScript::ValidUserScriptSchemes(), + settings_url.GetOrigin()); + PermissionSet tab_permissions(tab_api_permissions, ManifestPermissionSet(), + tab_hosts, tab_hosts); + active_tab->permissions_data()->UpdateTabSpecificPermissions( + kTabId, tab_permissions); + } + EXPECT_EQ(ALLOWED_CAPTURE_ONLY, + GetExtensionAccess(active_tab.get(), settings_url, kTabId)); +} + +TEST_F(ExtensionScriptAndCaptureVisibleTest, CaptureFileURLs) { + const int kTabId = 42; + scoped_refptr<const Extension> all_urls = + ExtensionBuilder("all urls").AddPermission("<all_urls>").Build(); + // Currently, the extension has not been granted file access, so it should + // not have access to a file:// URL. + EXPECT_EQ(DISALLOWED, GetExtensionAccess(all_urls.get(), file_url, kTabId)); + + scoped_refptr<const Extension> active_tab = + ExtensionBuilder("active tab").AddPermission("activeTab").Build(); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(active_tab.get(), file_url, kTabId)); + { + APIPermissionSet tab_api_permissions; + tab_api_permissions.insert(APIPermission::kTab); + URLPatternSet tab_hosts; + tab_hosts.AddOrigin(UserScript::ValidUserScriptSchemes(), + file_url.GetOrigin()); + PermissionSet tab_permissions(tab_api_permissions, ManifestPermissionSet(), + tab_hosts, tab_hosts); + active_tab->permissions_data()->UpdateTabSpecificPermissions( + kTabId, tab_permissions); + } + EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, + GetExtensionAccess(active_tab.get(), file_url, kTabId)); +} + // Check that the webstore url is inaccessible. TEST(PermissionsDataTest, ChromeWebstoreUrl) { scoped_refptr<const Extension> normal_extension = @@ -869,9 +923,8 @@ // The default policy applies to all extensions at this point. The extension // should be able to access test.example.com but be blocked from // accessing any other subdomains of example.com or example.com itself. - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), example_com)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), example_com)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), sample_example_com)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), test_example_com)); @@ -887,8 +940,7 @@ GetExtensionAccess(extension.get(), example_com)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), sample_example_com)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), test_example_com)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), test_example_com)); blocked.AddPattern(example_com_pattern); allowed.AddPattern(test_example_com_pattern); @@ -899,9 +951,8 @@ // Since the whitelist overrides a blacklist we expect to allow access to // test.example.com but block access to all other example.com subdomains // (sample.example.com) and example.com itself. - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), example_com)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), example_com)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), sample_example_com)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), test_example_com)); @@ -926,9 +977,8 @@ // Make sure the default policy has the same effect as before we defined an // individual policy. Access to test.example.com should be allowed, but all // other subdomains and example.com itself should be blocked. - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), example_com)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), example_com)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), sample_example_com)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), test_example_com)); @@ -957,22 +1007,16 @@ GetExtensionAccess(extension.get(), http_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), https_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), example_com)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), example_com)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), test_example_com)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), sample_example_com)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), file_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), settings_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), favicon_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), about_url)); - EXPECT_EQ(ALLOWED_CAPTURE_ONLY, - GetExtensionAccess(extension.get(), extension_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), extension_url)); // Test access to iframed content. GURL within_extension_url = extension->GetResourceURL("page.html"); @@ -992,7 +1036,8 @@ EXPECT_TRUE( extension->permissions_data()->HasHostPermission(test_example_com)); EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); - EXPECT_FALSE(extension->permissions_data()->HasHostPermission(about_url)); + EXPECT_FALSE( + extension->permissions_data()->HasHostPermission(about_flags_url)); EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); // Test * for scheme, which implies just the http/https schemes. @@ -1009,7 +1054,7 @@ EXPECT_EQ(ALLOWED_SCRIPT_ONLY, GetExtensionAccess(extension.get(), https_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), settings_url)); - EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_url)); + EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), file_url)); EXPECT_EQ(DISALLOWED, GetExtensionAccess(extension.get(), favicon_url)); extension = @@ -1037,7 +1082,7 @@ EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), settings_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, - GetExtensionAccess(extension.get(), about_url)); + GetExtensionAccess(extension.get(), about_flags_url)); EXPECT_EQ(ALLOWED_SCRIPT_AND_CAPTURE, GetExtensionAccess(extension.get(), favicon_url)); EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));
diff --git a/chrome/common/importer/BUILD.gn b/chrome/common/importer/BUILD.gn index 74e4eab3..9fbb7030f 100644 --- a/chrome/common/importer/BUILD.gn +++ b/chrome/common/importer/BUILD.gn
@@ -11,7 +11,6 @@ public_deps = [ "//components/autofill/content/common:mojo_types", - "//mojo/common:common_custom_types", "//mojo/public/mojom/base", "//url/mojom:url_mojom_gurl", ]
diff --git a/chrome/common/importer/profile_import.mojom b/chrome/common/importer/profile_import.mojom index ce703fd88..e37446a 100644 --- a/chrome/common/importer/profile_import.mojom +++ b/chrome/common/importer/profile_import.mojom
@@ -6,7 +6,7 @@ import "components/autofill/content/common/autofill_types.mojom"; import "mojo/public/mojom/base/string16.mojom"; -import "mojo/common/values.mojom"; +import "mojo/public/mojom/base/values.mojom"; import "url/mojom/url.mojom"; const string kProfileImportServiceName = "profile_import"; @@ -76,7 +76,7 @@ StartImport( SourceProfile source_profile, uint16 items, - mojo.common.mojom.DictionaryValue localized_strings, + mojo_base.mojom.DictionaryValue localized_strings, ProfileImportObserver observer); // Stop the importer.
diff --git a/chrome/common/offline_pages/BUILD.gn b/chrome/common/offline_pages/BUILD.gn deleted file mode 100644 index 1760cda..0000000 --- a/chrome/common/offline_pages/BUILD.gn +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2018 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. - -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("mojo_bindings") { - sources = [ - "mhtml_page_notifier.mojom", - ] - - public_deps = [ - "//mojo/public/mojom/base", - "//url/mojom:url_mojom_gurl", - ] -}
diff --git a/chrome/common/offline_pages/OWNERS b/chrome/common/offline_pages/OWNERS deleted file mode 100644 index 08850f4..0000000 --- a/chrome/common/offline_pages/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 9db087c..85dafaa 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -118,7 +118,7 @@ // A boolean pref to indicate whether or not Chrome should be performing // tab-under protection (i.e. blocking navigations it detects as tab-unders). -const char kTabUnderProtection[] = "tab_under_protection"; +const char kTabUnderAllowed[] = "tab_under_allowed"; // The URLs to restore on startup or when the home button is pressed. The URLs // are only restored on startup if kRestoreOnStartup is 4.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 53cade8..3511b428 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -55,7 +55,7 @@ extern const char kSupervisedUserSecondCustodianProfileURL[]; extern const char kSupervisedUserSharedSettings[]; extern const char kSupervisedUserWhitelists[]; -extern const char kTabUnderProtection[]; +extern const char kTabUnderAllowed[]; extern const char kURLsToRestoreOnStartup[]; #if BUILDFLAG(ENABLE_RLZ)
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 91c93f7..2b355d9 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc
@@ -1291,11 +1291,11 @@ return installer::CPU_NOT_SUPPORTED; // Persist histograms so they can be uploaded later. The storage directory is - // created during installation when the main WorkItemList is evaluated. So + // created during installation when the main WorkItemList is evaluated so // disable storage directory creation in PersistentHistogramStorage. base::PersistentHistogramStorage persistent_histogram_storage( installer::kSetupHistogramAllocatorName, - base::PersistentHistogramStorage::StorageDirCreation::kDisable); + base::PersistentHistogramStorage::StorageDirManagement::kUseExisting); // The exit manager is in charge of calling the dtors of singletons. base::AtExitManager exit_manager; @@ -1306,6 +1306,9 @@ switches::kProcessType); if (process_type == crash_reporter::switches::kCrashpadHandler) { + // Histogram storage is enabled at the very top of this wWinMain. Disable it + // when this process is decicated to crashpad as there is no directory in + // which to write them nor a browser to subsequently upload them. persistent_histogram_storage.Disable(); return crash_reporter::RunAsCrashpadHandler( *base::CommandLine::ForCurrentProcess(), base::FilePath(), @@ -1351,8 +1354,9 @@ const bool is_uninstall = cmd_line.HasSwitch(installer::switches::kUninstall); - // Disable histogram storage during uninstall since there's neither a - // directory in which to write them nor a browser to subsequently upload them. + // Histogram storage is enabled at the very top of this wWinMain. Disable it + // during uninstall since there's neither a directory in which to write them + // nor a browser to subsequently upload them. if (is_uninstall) persistent_histogram_storage.Disable();
diff --git a/chrome/service/service_ipc_server_unittest.cc b/chrome/service/service_ipc_server_unittest.cc index f648144b..759f238 100644 --- a/chrome/service/service_ipc_server_unittest.cc +++ b/chrome/service/service_ipc_server_unittest.cc
@@ -22,9 +22,7 @@ namespace { void PumpCurrentLoop() { - base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower( - base::MessageLoop::current()); - base::RunLoop().RunUntilIdle(); + base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); } class FakeServiceIPCServerClient : public ServiceIPCServer::Client {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index becd4003..31ab256 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -653,6 +653,7 @@ "../browser/policy/cloud/cloud_policy_test_utils.h", "../browser/policy/cloud/component_cloud_policy_browsertest.cc", "../browser/policy/cloud/device_management_service_browsertest.cc", + "../browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc", "../browser/policy/cloud/test_request_interceptor.cc", "../browser/policy/cloud/test_request_interceptor.h", "../browser/policy/policy_browsertest.cc", @@ -1712,6 +1713,9 @@ # chromeos does not use the desktop user manager "../browser/ui/webui/signin/user_manager_ui_browsertest.cc", + + # chromeos does not support machine level user cloud policies + "../browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc", ] deps += [ "//ash:test_support_with_content", @@ -2902,7 +2906,6 @@ "../browser/resource_coordinator/tab_metrics_logger_unittest.cc", # Android does not use the Message Center notification system. - "../browser/net/firefox_proxy_settings_unittest.cc", "../browser/notifications/message_center_notifications_unittest.cc", "../browser/platform_util_unittest.cc", "../browser/policy/policy_path_parser_unittest.cc", @@ -3080,6 +3083,7 @@ "../browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc", "../browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc", "../browser/media/router/event_page_request_manager_unittest.cc", + "../browser/media/router/media_router_feature_unittest.cc", "../browser/media/router/mojo/media_route_controller_unittest.cc", "../browser/media/router/mojo/media_router_desktop_unittest.cc", "../browser/media/router/mojo/media_router_mojo_impl_unittest.cc", @@ -4080,6 +4084,7 @@ "../browser/ui/cocoa/content_settings/cookie_details_unittest.mm", "../browser/ui/cocoa/content_settings/cookie_details_view_controller_unittest.mm", "../browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller_unittest.mm", + "../browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm", "../browser/ui/cocoa/extensions/extension_installed_bubble_controller_unittest.mm", "../browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_unittest.mm", "../browser/ui/cocoa/page_info/page_info_bubble_controller_unittest.mm",
diff --git a/chrome/test/data/client_hints/accept_ch_with_lifetime.html.mock-http-headers b/chrome/test/data/client_hints/accept_ch_with_lifetime.html.mock-http-headers index eacebe30..79c04b9 100644 --- a/chrome/test/data/client_hints/accept_ch_with_lifetime.html.mock-http-headers +++ b/chrome/test/data/client_hints/accept_ch_with_lifetime.html.mock-http-headers
@@ -1,3 +1,3 @@ HTTP/1.1 200 OK -Accept-CH: dpr,device-memory,viewport-width +Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect Accept-CH-Lifetime: 3600 \ No newline at end of file
diff --git a/chrome/test/data/client_hints/accept_ch_without_lifetime.html.mock-http-headers b/chrome/test/data/client_hints/accept_ch_without_lifetime.html.mock-http-headers index 3c600b4..9e5f7cfc 100644 --- a/chrome/test/data/client_hints/accept_ch_without_lifetime.html.mock-http-headers +++ b/chrome/test/data/client_hints/accept_ch_without_lifetime.html.mock-http-headers
@@ -1,2 +1,2 @@ HTTP/1.1 200 OK -Accept-CH: dpr,device-memory,viewport-width \ No newline at end of file +Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect \ No newline at end of file
diff --git a/chrome/test/data/client_hints/accept_ch_without_lifetime_img_localhost.html.mock-http-headers b/chrome/test/data/client_hints/accept_ch_without_lifetime_img_localhost.html.mock-http-headers index 3c600b4..9e5f7cfc 100644 --- a/chrome/test/data/client_hints/accept_ch_without_lifetime_img_localhost.html.mock-http-headers +++ b/chrome/test/data/client_hints/accept_ch_without_lifetime_img_localhost.html.mock-http-headers
@@ -1,2 +1,2 @@ HTTP/1.1 200 OK -Accept-CH: dpr,device-memory,viewport-width \ No newline at end of file +Accept-CH: dpr,device-memory,viewport-width,rtt,downlink,ect \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/tabs/capture_visible_tab/test_disabled.js b/chrome/test/data/extensions/api_test/tabs/capture_visible_tab/test_disabled.js index 6ec651c9..4d392a2c 100644 --- a/chrome/test/data/extensions/api_test/tabs/capture_visible_tab/test_disabled.js +++ b/chrome/test/data/extensions/api_test/tabs/capture_visible_tab/test_disabled.js
@@ -16,28 +16,32 @@ 'height': 400 }; -var fail_url = "file:///nosuch.html"; - -chrome.test.runTests([ - function captureVisibleDisabled() { - createWindow([fail_url], kWindowRect, pass(function(winId, tabIds) { - waitForAllTabs(pass(function() { - chrome.tabs.getSelected(winId, pass(function(tab) { - assertEq('complete', tab.status); - chrome.tabs.captureVisibleTab(winId, fail( - 'Taking screenshots has been disabled')); +chrome.test.getConfig((config) => { + const kError = 'Taking screenshots has been disabled'; + const kUrl = `localhost:${config.testServer.port}/simple.html`; + chrome.test.runTests([ + function captureVisibleDisabled() { + createWindow([kUrl], kWindowRect, pass(function(winId, tabIds) { + waitForAllTabs(pass(function() { + chrome.tabs.getSelected(winId, pass(function(tab) { + assertEq('complete', tab.status); + chrome.tabs.captureVisibleTab(winId, fail(kError)); + })); })); })); - })); - }, + }, - function captureVisibleDisabledInNullWindow() { - chrome.tabs.captureVisibleTab(null, fail( - 'Taking screenshots has been disabled')); - }, + function captureVisibleDisabledInNullWindow() { + chrome.tabs.create({url: kUrl}, pass(() => { + waitForAllTabs(pass(() => { + chrome.tabs.captureVisibleTab(null, fail(kError)); + })); + })); + }, - function captureVisibleDisabledInCurrentWindow() { - chrome.tabs.captureVisibleTab(chrome.windows.WINDOW_ID_CURRENT, - fail('Taking screenshots has been disabled')); - } -]); + function captureVisibleDisabledInCurrentWindow() { + chrome.tabs.captureVisibleTab(chrome.windows.WINDOW_ID_CURRENT, + fail(kError)); + } + ]); +});
diff --git a/chrome/test/data/extensions/api_test/tabs/capture_visible_tab_null_window/background.js b/chrome/test/data/extensions/api_test/tabs/capture_visible_tab_null_window/background.js index ccaee201..e3a752c 100644 --- a/chrome/test/data/extensions/api_test/tabs/capture_visible_tab_null_window/background.js +++ b/chrome/test/data/extensions/api_test/tabs/capture_visible_tab_null_window/background.js
@@ -5,13 +5,22 @@ // API test for chrome.tabs.captureVisibleTab(), when current window is null // browser_tests.exe --gtest_filter=ExtensionApiTest.CaptureNullWindow -var fail = chrome.test.callbackFail; - chrome.test.runTests([function captureNullWindow() { // Create a new window so we don't close the only active window. chrome.windows.create(function(newWindow) { - chrome.windows.remove(newWindow.id); - chrome.tabs.captureVisibleTab( - newWindow.id, fail('Failed to capture tab: view is invisible')); + chrome.windows.remove(newWindow.id, function() { + chrome.tabs.captureVisibleTab( + newWindow.id, function() { + // The error message is non-deterministic based on how far we've gone + // in removing the window. + const error1 = `No window with id: ${newWindow.id}.`; + const error2 = 'No active web contents to capture'; + chrome.test.assertTrue(!!chrome.runtime.lastError); + let actualError = chrome.runtime.lastError.message; + chrome.test.assertTrue(actualError == error1 || actualError == error2, + actualError); + chrome.test.succeed(); + }); + }); }); }]);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index ef0c4e0..b45d3717c 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2232,6 +2232,22 @@ ] }, + "CertificateTransparencyEnforcementDisabledForCas": { + "os": ["win", "linux", "mac", "chromeos", "android"], + "test_policy": { "CertificateTransparencyEnforcementDisabledForCas": ["sha256/AAAAAAAAAAAAAAAAAAAAAA=="] }, + "pref_mappings": [ + { "pref": "certificate_transparency.excluded_spkis" } + ] + }, + + "CertificateTransparencyEnforcementDisabledForLegacyCas": { + "os": ["win", "linux", "mac", "chromeos", "android"], + "test_policy": { "CertificateTransparencyEnforcementDisabledForLegacyCas": ["sha256/AAAAAAAAAAAAAAAAAAAAAA=="] }, + "pref_mappings": [ + { "pref": "certificate_transparency.excluded_legacy_spkis" } + ] + }, + "RC4Enabled": { "note": "This policy is retired, see https://crbug.com/375342." }, @@ -2306,6 +2322,16 @@ ] }, + "MediaRouterCastAllowAllIPs": { + "os": ["win", "linux", "mac", "chromeos"], + "test_policy": { "MediaRouterCastAllowAllIPs": false }, + "pref_mappings": [ + { "pref": "media_router.cast_allow_all_ips", + "local_state": true + } + ] + }, + "NTPContentSuggestionsEnabled": { "os": ["android"], "test_policy": { "NTPContentSuggestionsEnabled": false }, @@ -3663,13 +3689,13 @@ ] }, - "TabUnderProtectionEnabled": { + "TabUnderAllowed": { "os": ["win", "linux", "mac", "chromeos"], "test_policy": { - "TabUnderProtectionEnabled": false + "TabUnderAllowed": false }, "pref_mappings": [ - { "pref": "tab_under_protection"} + { "pref": "tab_under_allowed"} ] },
diff --git a/chrome/test/data/webui/cr_elements/cr_dialog_test.js b/chrome/test/data/webui/cr_elements/cr_dialog_test.js index ab33a4c0..08c31d9 100644 --- a/chrome/test/data/webui/cr_elements/cr_dialog_test.js +++ b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
@@ -13,12 +13,12 @@ test('focuses title on show', function() { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body"><button>button</button></div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); const button = document.body.querySelector('button'); assertNotEquals(dialog, document.activeElement); @@ -32,15 +32,15 @@ test('enter keys should trigger action buttons once', function() { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body"> <button class="action-button">button</button> <button id="other-button">other button</button> </div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); const actionButton = document.body.querySelector('.action-button'); dialog.showModal(); @@ -69,7 +69,7 @@ test('enter keys find the first non-hidden non-disabled button', function() { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body"> <button id="hidden" class="action-button" hidden>hidden</button> @@ -77,9 +77,9 @@ <button class="action-button" disabled hidden>disabled hidden</button> <button id="active" class="action-button">active</button> </div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); const hiddenButton = document.body.querySelector('#hidden'); const actionButton = document.body.querySelector('#active'); dialog.showModal(); @@ -99,16 +99,16 @@ test('enter keys from paper-inputs (only) are processed', function() { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body"> <paper-input></paper-input> <foobar></foobar> <button class="action-button">active</button> </div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); const inputElement = document.body.querySelector('paper-input'); const otherElement = document.body.querySelector('foobar'); @@ -132,12 +132,12 @@ test('focuses [autofocus] instead of title when present', function() { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body"><button autofocus>button</button></div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); const button = document.body.querySelector('button'); assertNotEquals(dialog, document.activeElement); @@ -153,12 +153,12 @@ // dialog has been opened. test('body scrollable border not added before modal shown', function(done) { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body">body</div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); assertFalse(dialog.open); const bodyContainer = dialog.$$('.body-container'); assertTrue(!!bodyContainer); @@ -174,14 +174,14 @@ test('dialog body scrollable border when appropriate', function(done) { document.body.innerHTML = ` - <dialog is="cr-dialog"> + <cr-dialog> <div slot="title">title</div> <div slot="body"> <div style="height: 100px">tall content</div> </div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); const bodyContainer = dialog.$$('.body-container'); assertTrue(!!bodyContainer); @@ -225,11 +225,11 @@ test('dialog cannot be cancelled when `no-cancel` is set', function() { document.body.innerHTML = ` - <dialog is="cr-dialog" no-cancel> + <cr-dialog no-cancel> <div slot="title">title</div> - </dialog>`; + </cr-dialog>`; - const dialog = document.body.querySelector('dialog'); + const dialog = document.body.querySelector('cr-dialog'); dialog.showModal(); // The paper-icon-button-light is the hidden element which is the
diff --git a/chrome/test/data/webui/extensions/extension_load_error_test.js b/chrome/test/data/webui/extensions/extension_load_error_test.js index edb3ad8..32d3b984 100644 --- a/chrome/test/data/webui/extensions/extension_load_error_test.js +++ b/chrome/test/data/webui/extensions/extension_load_error_test.js
@@ -38,7 +38,7 @@ }); test(assert(TestNames.RetryError), function() { - var dialogElement = loadError.$$('dialog'); + var dialogElement = loadError.$$('cr-dialog').getNative(); expectFalse(extension_test_util.isElementVisible(dialogElement)); loadError.show(); expectTrue(extension_test_util.isElementVisible(dialogElement)); @@ -54,7 +54,7 @@ }); test(assert(TestNames.RetrySuccess), function() { - var dialogElement = loadError.$$('dialog'); + var dialogElement = loadError.$$('cr-dialog').getNative(); expectFalse(extension_test_util.isElementVisible(dialogElement)); loadError.show(); expectTrue(extension_test_util.isElementVisible(dialogElement));
diff --git a/chrome/test/data/webui/extensions/extension_options_dialog_test.js b/chrome/test/data/webui/extensions/extension_options_dialog_test.js index 6433c686..d51b038 100644 --- a/chrome/test/data/webui/extensions/extension_options_dialog_test.js +++ b/chrome/test/data/webui/extensions/extension_options_dialog_test.js
@@ -31,7 +31,7 @@ }); function isDialogVisible() { - var dialogElement = optionsDialog.$$('dialog'); + var dialogElement = optionsDialog.$.dialog.getNative(); var rect = dialogElement.getBoundingClientRect(); return rect.width * rect.height > 0; } @@ -40,10 +40,15 @@ // Try showing the dialog. assertFalse(isDialogVisible()); optionsDialog.show(data); + const dialogElement = optionsDialog.$.dialog.getNative(); return test_util.whenAttributeIs( - optionsDialog.$.dialog, 'open', '').then(function() { + dialogElement, 'open', '').then(function() { assertTrue(isDialogVisible()); + const rect = dialogElement.getBoundingClientRect(); + assertGE(rect.width, extensions.OptionsDialogMinWidth); + assertLE(rect.height, extensions.OptionsDialogMaxHeight); + assertEquals( data.name, assert(optionsDialog.$$('#icon-and-name-wrapper span'))
diff --git a/chrome/test/data/webui/extensions/extension_pack_dialog_test.js b/chrome/test/data/webui/extensions/extension_pack_dialog_test.js index b2da000..b5cf222 100644 --- a/chrome/test/data/webui/extensions/extension_pack_dialog_test.js +++ b/chrome/test/data/webui/extensions/extension_pack_dialog_test.js
@@ -65,7 +65,7 @@ }); test(assert(TestNames.Interaction), function() { - var dialogElement = packDialog.$$('dialog'); + var dialogElement = packDialog.$$('cr-dialog').getNative(); expectFalse(extension_test_util.isElementVisible(dialogElement)); packDialog.show(); @@ -104,7 +104,7 @@ }); test(assert(TestNames.PackSuccess), function() { - var dialogElement = packDialog.$$('dialog'); + var dialogElement = packDialog.$$('cr-dialog').getNative(); var packDialogAlert; var alertElement; @@ -128,7 +128,7 @@ }) .then(() => { packDialogAlert = packDialog.$$('extensions-pack-dialog-alert'); - alertElement = packDialogAlert.$.dialog; + alertElement = packDialogAlert.$.dialog.getNative(); expectTrue(extension_test_util.isElementVisible(alertElement)); expectTrue(extension_test_util.isElementVisible(dialogElement)); expectTrue(!!packDialogAlert.$$('.action-button')); @@ -144,7 +144,7 @@ }); test(assert(TestNames.PackError), function() { - var dialogElement = packDialog.$$('dialog'); + var dialogElement = packDialog.$$('cr-dialog').getNative(); var packDialogAlert; var alertElement; @@ -166,7 +166,7 @@ // Make sure new alert and the appropriate buttons are visible. packDialogAlert = packDialog.$$('extensions-pack-dialog-alert'); - alertElement = packDialogAlert.$.dialog; + alertElement = packDialogAlert.$.dialog.getNative(); expectTrue(extension_test_util.isElementVisible(alertElement)); expectTrue(extension_test_util.isElementVisible(dialogElement)); expectTrue(!!packDialogAlert.$$('.action-button')); @@ -181,7 +181,7 @@ }); test(assert(TestNames.PackWarning), function() { - var dialogElement = packDialog.$$('dialog'); + var dialogElement = packDialog.$$('cr-dialog').getNative(); var packDialogAlert; var alertElement; @@ -207,7 +207,7 @@ // Make sure new alert and the appropriate buttons are visible. packDialogAlert = packDialog.$$('extensions-pack-dialog-alert'); - alertElement = packDialogAlert.$.dialog; + alertElement = packDialogAlert.$.dialog.getNative(); expectTrue(extension_test_util.isElementVisible(alertElement)); expectTrue(extension_test_util.isElementVisible(dialogElement)); expectFalse(packDialogAlert.$$('.cancel-button').hidden);
diff --git a/chrome/test/data/webui/net_internals/log_view_painter.js b/chrome/test/data/webui/net_internals/log_view_painter.js index 3b9469c..72d0e9e 100644 --- a/chrome/test/data/webui/net_internals/log_view_painter.js +++ b/chrome/test/data/webui/net_internals/log_view_painter.js
@@ -69,8 +69,7 @@ testCase.tickOffset = '1337911098446'; testCase.logCreationTime = 1338864634013; testCase.loadFlags = LoadFlag.MAIN_FRAME_DEPRECATED | - LoadFlag.MAYBE_USER_GESTURE | - LoadFlag.VERIFY_EV_CERT; + LoadFlag.MAYBE_USER_GESTURE; testCase.logEntries = [ { @@ -617,16 +616,14 @@ 't=1338864633238 [st= 14] URL_REQUEST_START_JOB [dt=8]\n' + ' --> load_flags = ' + testCase.loadFlags.toString() + - ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE ' + - '| VERIFY_EV_CERT)\n' + + ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' + ' --> method = "GET"\n' + ' --> priority = 4\n' + ' --> url = "http://www.google.com/"\n' + 't=1338864633248 [st= 24] +URL_REQUEST_START_JOB [dt=279]\n' + ' --> load_flags = ' + testCase.loadFlags.toString() + - ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE ' + - '| VERIFY_EV_CERT)\n' + + ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' + ' --> method = "GET"\n' + ' --> priority = 4\n' + ' --> url = "http://www.google.com/"\n' + @@ -778,8 +775,7 @@ var testCase = {}; testCase.tickOffset = '1337911098446'; testCase.loadFlags = LoadFlag.MAIN_FRAME_DEPRECATED | - LoadFlag.MAYBE_USER_GESTURE | - LoadFlag.VERIFY_EV_CERT; + LoadFlag.MAYBE_USER_GESTURE; testCase.logEntries = [ { @@ -954,16 +950,14 @@ 't=1338864773901 [st= 7] URL_REQUEST_START_JOB [dt=5]\n' + ' --> load_flags = ' + testCase.loadFlags.toString() + - ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE ' + - '| VERIFY_EV_CERT)\n' + + ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' + ' --> method = "GET"\n' + ' --> priority = 4\n' + ' --> url = "http://www.doesnotexistdomain.com/"\n' + 't=1338864773906 [st= 12] +URL_REQUEST_START_JOB [dt=245]\n' + ' --> load_flags = ' + testCase.loadFlags.toString() + - ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE ' + - '| VERIFY_EV_CERT)\n' + + ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' + ' --> method = "GET"\n' + ' --> priority = 4\n' + ' --> url = "http://www.doesnotexistdomain.com/"\n' + @@ -1669,8 +1663,7 @@ var testCase = {}; testCase.tickOffset = '1337911098446'; testCase.loadFlags = LoadFlag.MAIN_FRAME_DEPRECATED | - LoadFlag.MAYBE_USER_GESTURE | - LoadFlag.VERIFY_EV_CERT; + LoadFlag.MAYBE_USER_GESTURE; testCase.logEntries = [ { @@ -1721,8 +1714,7 @@ 't=1338864773994 [st= 0] +REQUEST_ALIVE [dt=375]\n' + ' --> load_flags = ' + testCase.loadFlags.toString() + - ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE ' + - '| VERIFY_EV_CERT)\n' + + ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' + ' --> load_state = ' + LoadState.READING_RESPONSE + ' (READING_RESPONSE)\n' + ' --> method = "GET"\n' +
diff --git a/chrome/test/data/webui/settings/basic_page_browsertest.js b/chrome/test/data/webui/settings/basic_page_browsertest.js index 75cc5e7b..2e8155c 100644 --- a/chrome/test/data/webui/settings/basic_page_browsertest.js +++ b/chrome/test/data/webui/settings/basic_page_browsertest.js
@@ -45,7 +45,8 @@ /** @override */ search(text, page) { if (this.searchRequest_ == null || !this.searchRequest_.isSame(text)) { - this.searchRequest_ = new settings.SearchRequest(text); + this.searchRequest_ = new settings.SearchRequest( + text, document.createElement('div')); this.searchRequest_.finished = true; this.searchRequest_.updateMatches(false); @@ -65,9 +66,6 @@ } return this.searchRequest_.resolver.promise; } - - /** @override */ - registerObserver(observer) {} } // Register mocha tests.
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index e08381f2..cd2b965e 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -119,7 +119,75 @@ .then(testNavigateBack) .then(testDetach) .then(testRecreate); - }), + }); + + test('SyncSectionLayout_NoUnifiedConsent_SignedIn', function() { + const ironCollapse = syncPage.$$('#sync-section'); + const otherItems = syncPage.$$('#other-sync-items'); + const syncSectionToggle = syncPage.$$('#sync-section-toggle'); + + // When unified-consent is disabled and signed in, sync-section should be + // visible and open by default. Accordion toggle row should not be present + // and bottom items should not have classes used for indentation. + syncPage.syncStatus = {signedIn: true}; + syncPage.unifiedConsentEnabled = false; + Polymer.dom.flush(); + assertTrue(ironCollapse.opened); + assertFalse(ironCollapse.hidden); + assertTrue(syncSectionToggle.hidden); + assertFalse(otherItems.classList.contains('list-frame')); + assertFalse(!!otherItems.querySelector('list-item')); + }); + + test('SyncSectionLayout_UnifiedConsentEnabled_SignedIn', function() { + const ironCollapse = syncPage.$$('#sync-section'); + const otherItems = syncPage.$$('#other-sync-items'); + const syncSectionToggle = syncPage.$$('#sync-section-toggle'); + const expandIcon = syncSectionToggle.querySelector('cr-expand-button'); + + // When unified-consent is enabled and signed in, sync-section should be + // visible and open by default. Accordion toggle row should be present, + // and bottom items should have classes used for indentation. + syncPage.syncStatus = {signedIn: true}; + syncPage.unifiedConsentEnabled = true; + Polymer.dom.flush(); + assertTrue(ironCollapse.opened); + assertFalse(ironCollapse.hidden); + assertFalse(syncSectionToggle.hidden); + assertTrue(syncSectionToggle.hasAttribute('actionable')); + assertTrue(expandIcon.expanded); + assertFalse(expandIcon.disabled); + assertTrue(otherItems.classList.contains('list-frame')); + assertEquals( + otherItems.querySelectorAll(':scope > .list-item').length, 3); + + // Tapping on the toggle row should toggle ironCollapse. + MockInteractions.tap(syncSectionToggle); + Polymer.dom.flush(); + assertFalse(ironCollapse.opened); + assertFalse(expandIcon.expanded); + MockInteractions.tap(syncSectionToggle); + Polymer.dom.flush(); + assertTrue(ironCollapse.opened); + assertTrue(expandIcon.expanded); + }); + + test('SyncSectionLayout_UnifiedConsentEnabled_SignedOut', function() { + const ironCollapse = syncPage.$$('#sync-section'); + const syncSectionToggle = syncPage.$$('#sync-section-toggle'); + const expandIcon = syncSectionToggle.querySelector('cr-expand-button'); + + // When unified-consent is enabled and signed out, sync-section should be + // hidden, and the accordion toggle row should be visible not actionable. + syncPage.syncStatus = {signedIn: false}; + syncPage.unifiedConsentEnabled = true; + Polymer.dom.flush(); + assertTrue(ironCollapse.hidden); + assertFalse(syncSectionToggle.hidden); + assertFalse(syncSectionToggle.hasAttribute('actionable')); + assertFalse(expandIcon.expanded); + assertTrue(expandIcon.disabled); + }); test('LoadingAndTimeout', function() { const configurePage = syncPage.$$('#' + settings.PageStatus.CONFIGURE);
diff --git a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js index 634e7e23..eecd1e5c 100644 --- a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js +++ b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
@@ -21,6 +21,11 @@ } element = element.parentElement; + + // cr-dialog itself will always be 0x0. It's the inner native <dialog> + // that has actual dimensions. + if (element && element.tagName == 'CR-DIALOG') + element = element.getNative(); } return true;
diff --git a/chrome/test/data/webui/settings/search_settings_test.js b/chrome/test/data/webui/settings/search_settings_test.js index 9e250f43..6a5fe1e0 100644 --- a/chrome/test/data/webui/settings/search_settings_test.js +++ b/chrome/test/data/webui/settings/search_settings_test.js
@@ -37,32 +37,29 @@ const div = document.querySelector('#mydiv'); assertTrue(section.hiddenBySearch); - return searchManager.search('settings', [section]) - .then(function() { - assertFalse(section.hiddenBySearch); + return searchManager.search('settings', section).then(function() { + assertFalse(section.hiddenBySearch); - const highlightWrapper = - div.querySelector('.search-highlight-wrapper'); - assertTrue(!!highlightWrapper); + const highlightWrapper = div.querySelector('.search-highlight-wrapper'); + assertTrue(!!highlightWrapper); - const originalContent = highlightWrapper.querySelector( - '.search-highlight-original-content'); - assertTrue(!!originalContent); - assertEquals(optionText, originalContent.textContent); + const originalContent = highlightWrapper.querySelector( + '.search-highlight-original-content'); + assertTrue(!!originalContent); + assertEquals(optionText, originalContent.textContent); - const searchHits = - highlightWrapper.querySelectorAll('.search-highlight-hit'); - assertEquals(1, searchHits.length); - assertEquals('Settings', searchHits[0].textContent); + const searchHits = highlightWrapper.querySelectorAll( + '.search-highlight-hit'); + assertEquals(1, searchHits.length); + assertEquals('Settings', searchHits[0].textContent); - // Check that original DOM structure is restored when search - // highlights are cleared. - return searchManager.search('', [section]); - }) - .then(function() { - assertEquals(0, div.children.length); - assertEquals(optionText, div.textContent); - }); + // Check that original DOM structure is restored when search + // highlights are cleared. + return searchManager.search('', section); + }).then(function() { + assertEquals(0, div.children.length); + assertEquals(optionText, div.textContent); + }); }); /** @@ -84,25 +81,23 @@ const select = section.querySelector('select'); assertTrue(section.hiddenBySearch); - return searchManager.search('settings', [section]) - .then(function() { - assertFalse(section.hiddenBySearch); + return searchManager.search('settings', section).then(function() { + assertFalse(section.hiddenBySearch); - const highlightWrapper = - select.querySelector('.search-highlight-wrapper'); - assertFalse(!!highlightWrapper); + const highlightWrapper = select.querySelector( + '.search-highlight-wrapper'); + assertFalse(!!highlightWrapper); - // Check that original DOM structure is present even after search - // highlights are cleared. - return searchManager.search('', [section]); - }) - .then(function() { - const options = select.querySelectorAll('option'); - assertEquals(3, options.length); - assertEquals('Foo', options[0].textContent); - assertEquals('Settings', options[1].textContent); - assertEquals('Baz', options[2].textContent); - }); + // Check that original DOM structure is present even after search + // highlights are cleared. + return searchManager.search('', section); + }).then(function() { + const options = select.querySelectorAll('option'); + assertEquals(3, options.length); + assertEquals('Foo', options[0].textContent); + assertEquals('Settings', options[1].textContent); + assertEquals('Baz', options[2].textContent); + }); }); test('ignored elements are ignored', function() { @@ -124,7 +119,7 @@ const section = document.querySelector('settings-section'); assertTrue(section.hiddenBySearch); - return searchManager.search(text, [section]).then(function() { + return searchManager.search(text, section).then(function() { assertTrue(section.hiddenBySearch); }); }); @@ -146,95 +141,15 @@ const sections = Array.prototype.slice.call( document.querySelectorAll('settings-section')); - return Promise.all(sections.map(s => searchManager.search('there', [s]))) - .then(function(results) { - assertTrue(results[0].didFindMatches); + return Promise.all(sections.map(s => searchManager.search('there', s))) + .then(function(requests) { + assertTrue(requests[0].didFindMatches()); assertFalse(sections[0].hiddenBySearch); - assertTrue(results[1].didFindMatches); + assertTrue(requests[1].didFindMatches()); assertFalse(sections[1].hiddenBySearch); - assertFalse(results[2].didFindMatches); + assertFalse(requests[2].didFindMatches()); assertTrue(sections[2].hiddenBySearch); }); }); - - test('search is redone when text is changed', function() { - const observer = /** @type {!settings.SearchManagerObserver} */ ((() => { - let resolver; - return { - onSearchStart() {}, - onSearchComplete(searchResult) { - resolver.resolve(searchResult); - }, - waitForSearchComplete(doSearch) { - resolver = new PromiseResolver(); - doSearch(); - return resolver.promise; - } - }; - })()); - searchManager.registerObserver(observer); - - const originalText = 'FooSettingsFoo'; - - document.body.innerHTML = `<settings-section hidden-by-search> - <div id="mydiv">${originalText}</div> - </settings-section>`; - - const section = document.querySelector('settings-section'); - const div = document.querySelector('#mydiv'); - assertTrue(section.hiddenBySearch); - return observer - .waitForSearchComplete(() => { - searchManager.search('settings', [document.body]); - }) - .then(searchResult => { - assertFalse(section.hiddenBySearch); - const expected = { - canceled: false, - didFindMatches: true, - rawQuery: 'settings', - wasClearSearch: false, - }; - assertDeepEquals(expected, searchResult); - const highlightWrapper = - div.querySelector('.search-highlight-wrapper'); - assertTrue(!!highlightWrapper); - const originalContent = highlightWrapper.querySelector( - '.search-highlight-original-content'); - assertTrue(!!originalContent); - return observer.waitForSearchComplete(() => { - originalContent.childNodes[0].nodeValue = 'Foo'; - }); - }) - .then(searchResult => { - assertTrue(section.hiddenBySearch); - const expected = { - canceled: false, - didFindMatches: false, - rawQuery: 'settings', - wasClearSearch: false, - }; - assertDeepEquals(expected, searchResult); - const highlightWrapper = - div.querySelector('.search-highlight-wrapper'); - assertTrue(!highlightWrapper); - return observer.waitForSearchComplete(() => { - div.childNodes[0].nodeValue = originalText; - }); - }) - .then(searchResult => { - assertFalse(section.hiddenBySearch); - const expected = { - canceled: false, - didFindMatches: true, - rawQuery: 'settings', - wasClearSearch: false, - }; - assertDeepEquals(expected, searchResult); - const highlightWrapper = - div.querySelector('.search-highlight-wrapper'); - assertTrue(!!highlightWrapper); - }); - }); }); });
diff --git a/chrome/test/data/webui/settings/settings_main_test.js b/chrome/test/data/webui/settings/settings_main_test.js index 792a3992..ae5c707 100644 --- a/chrome/test/data/webui/settings/settings_main_test.js +++ b/chrome/test/data/webui/settings/settings_main_test.js
@@ -22,9 +22,6 @@ /** @private {?settings.SearchRequest} */ this.searchRequest_ = null; - - /** @private {?settings.SearchManagerObserver} */ - this.observer_ = null; } /** @@ -36,7 +33,6 @@ /** @override */ search(text, page) { - this.observer_.onSearchStart(); this.methodCalled('search', text); if (this.searchRequest_ == null || !this.searchRequest_.isSame(text)) { @@ -44,15 +40,9 @@ this.searchRequest_.finished = true; this.searchRequest_.updateMatches(this.matchesFound_); this.searchRequest_.resolver.resolve(this.searchRequest_); - this.observer_.onSearchComplete(this.searchRequest_.result()); } return this.searchRequest_.resolver.promise; } - - /** @override */ - registerObserver(observer) { - this.observer_ = observer; - } } let settingsPrefs = null;
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js index 25a1324..bbb904ea 100644 --- a/chrome/test/data/webui/settings/site_details_tests.js +++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -86,6 +86,9 @@ test_util.createContentSettingTypeToValuePair( settings.ContentSettingsTypes.PAYMENT_HANDLER, [test_util.createRawSiteException('https://foo.com:443')]), + test_util.createContentSettingTypeToValuePair( + settings.ContentSettingsTypes.USB_DEVICES, + [test_util.createRawSiteException('https://foo.com:443')]), ]); browserProxy = new TestSiteSettingsPrefsBrowserProxy(); @@ -106,7 +109,6 @@ const nonSiteDetailsContentSettingsTypes = [ settings.ContentSettingsTypes.COOKIES, settings.ContentSettingsTypes.PROTOCOL_HANDLERS, - settings.ContentSettingsTypes.USB_DEVICES, settings.ContentSettingsTypes.ZOOM_LEVELS, ]; if (!cr.isChromeOS)
diff --git a/chrome/test/data/webui/settings/sync_account_control_test.js b/chrome/test/data/webui/settings/sync_account_control_test.js index bb1399c..3fbeb41 100644 --- a/chrome/test/data/webui/settings/sync_account_control_test.js +++ b/chrome/test/data/webui/settings/sync_account_control_test.js
@@ -149,8 +149,7 @@ assertEquals(email, 'foo@foo.com'); assertVisible(testElement.$$('paper-icon-button-light'), true); - assertFalse(testElement.$$('#sync-icon-container') - .hasAttribute('signed-in')); + assertTrue(testElement.$$('#sync-icon-container').hidden); testElement.$$('#dropdown-arrow').click(); Polymer.dom.flush(); @@ -204,8 +203,7 @@ assertVisible(testElement.$$('#avatar-row'), true); assertVisible(testElement.$$('paper-icon-button-light'), false); assertVisible(testElement.$$('#promo-headers'), false); - assertTrue( - testElement.$$('#sync-icon-container').hasAttribute('signed-in')); + assertFalse(testElement.$$('#sync-icon-container').hidden); assertFalse(!!testElement.$$('#menu')); @@ -226,13 +224,28 @@ testElement.syncStatus = { signedIn: true, signedInUsername: 'bar@bar.com', - hasError: true + hasError: true, + statusAction: settings.StatusAction.CONFIRM_SYNC_SETTINGS, }; - assertTrue( - testElement.$$('#sync-icon-container').hasAttribute('has-error')); + assertTrue(testElement.$$('#sync-icon-container') + .classList.contains('sync-problem')); + assertTrue(!!testElement.$$('[icon=\'settings:sync-problem\']')); assertFalse(userInfo.textContent.includes('barName')); assertFalse(userInfo.textContent.includes('fooName')); assertTrue(userInfo.textContent.includes('Sync isn\'t working')); + + testElement.syncStatus = { + signedIn: true, + signedInUsername: 'bar@bar.com', + hasError: true, + statusAction: settings.StatusAction.REAUTHENTICATE, + }; + assertTrue(testElement.$$('#sync-icon-container') + .classList.contains('sync-disabled')); + assertTrue(!!testElement.$$('[icon=\'settings:sync-disabled\']')); + assertFalse(userInfo.textContent.includes('barName')); + assertFalse(userInfo.textContent.includes('fooName')); + assertTrue(userInfo.textContent.includes('Sync is paused')); }); }); });
diff --git a/chrome/test/data/webui/settings/test_util.js b/chrome/test/data/webui/settings/test_util.js index 386b69507..a8a9e5f 100644 --- a/chrome/test/data/webui/settings/test_util.js +++ b/chrome/test/data/webui/settings/test_util.js
@@ -163,6 +163,8 @@ settings.ContentSetting.BLOCK; defaults[settings.ContentSettingsTypes.SENSORS].setting = settings.ContentSetting.ALLOW; + defaults[settings.ContentSettingsTypes.USB_DEVICES].setting = + settings.ContentSetting.ASK; defaultsList.forEach((override) => { defaults[override.setting] = override.value; });
diff --git a/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc b/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc index 760ab45..bccc9061 100644 --- a/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc +++ b/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc
@@ -106,8 +106,14 @@ RunReconnectSessionTest(); } +// TODO(crbug.com/826016): Crashes on ASAN. +#if defined(ADDRESS_SANITIZER) +#define MAYBE_ReconnectSessionSameTab MANUAL_ReconnectSessionSameTab +#else +#define MAYBE_ReconnectSessionSameTab ReconnectSessionSameTab +#endif IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUANoReceiverBrowserTest, - ReconnectSessionSameTab) { + MAYBE_ReconnectSessionSameTab) { RunReconnectSessionSameTabTest(); }
diff --git a/chrome/test/mini_installer/config/config.config b/chrome/test/mini_installer/config/config.config index e9c07c86..e89f5e4 100644 --- a/chrome/test/mini_installer/config/config.config +++ b/chrome/test/mini_installer/config/config.config
@@ -197,6 +197,14 @@ "actions": [ ["test_chrome_with_chromedriver_user", "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], + ["test_chrome_with_chromedriver_system", + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], + ["test_chrome_with_chromedriver_beta", + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET \"$LOCAL_APPDATA\\$CHROME_DIR_BETA\\Application\\chrome.exe\""], + ["test_chrome_with_chromedriver_canary", + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], + ["test_chrome_with_chromedriver_dev", + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET \"$LOCAL_APPDATA\\$CHROME_DIR_DEV\\Application\\chrome.exe\""], ["install_chrome_beta", "\"$MINI_INSTALLER\" --chrome-beta --verbose-logging --do-not-launch-chrome"], ["install_chrome_canary", @@ -244,21 +252,12 @@ ], "tests": [ { - "name": "ChromedriverTestUserLevel", - "description": "Tests chrome using chromedriver to load real pages.", - "traversal": [ - "no_pv", - "install_chrome_user", "chrome_user_installed_not_inuse", - "test_chrome_with_chromedriver_user", "chrome_user_installed_not_inuse", - "uninstall_chrome_user", "clean" - ] - }, - { "name": "ChromeUserLevel", "description": "Verifies that user-level Chrome can be installed and uninstalled.", "traversal": [ "no_pv", "install_chrome_user", "chrome_user_installed_not_inuse", + "test_chrome_with_chromedriver_user", "chrome_user_installed_not_inuse", "uninstall_chrome_user", "clean" ] }, @@ -279,6 +278,7 @@ "traversal": [ "no_pv", "install_chrome_beta", "chrome_beta_installed_not_inuse", + "test_chrome_with_chromedriver_beta", "chrome_beta_installed_not_inuse", "uninstall_chrome_beta", "clean" ] }, @@ -289,6 +289,7 @@ "traversal": [ "no_pv", "install_chrome_canary", "chrome_canary_installed_not_inuse", + "test_chrome_with_chromedriver_canary", "chrome_canary_installed_not_inuse", "uninstall_chrome_canary", "clean" ] }, @@ -310,6 +311,7 @@ "traversal": [ "no_pv", "install_chrome_dev", "chrome_dev_installed_not_inuse", + "test_chrome_with_chromedriver_dev", "chrome_dev_installed_not_inuse", "uninstall_chrome_dev", "clean" ] }, @@ -319,6 +321,7 @@ "traversal": [ "no_pv", "install_chrome_system", "chrome_system_installed_not_inuse", + "test_chrome_with_chromedriver_system", "chrome_system_installed_not_inuse", "uninstall_chrome_system", "clean" ] }, @@ -339,9 +342,13 @@ "traversal": [ "no_pv", "install_chrome_user", "chrome_user_installed_not_inuse", + "test_chrome_with_chromedriver_user", "chrome_user_installed_not_inuse", "install_chrome_beta", "chrome_user_and_beta_installed_not_inuse", + "test_chrome_with_chromedriver_beta", "chrome_user_and_beta_installed_not_inuse", "install_chrome_dev", "chrome_user_and_beta_and_dev_installed_not_inuse", + "test_chrome_with_chromedriver_dev", "chrome_user_and_beta_and_dev_installed_not_inuse", "install_chrome_canary", "chrome_user_and_beta_and_dev_and_canary_installed_not_inuse", + "test_chrome_with_chromedriver_canary", "chrome_user_and_beta_and_dev_and_canary_installed_not_inuse", "uninstall_chrome_user", "chrome_beta_and_dev_and_canary_installed_not_inuse", "uninstall_chrome_beta", "chrome_dev_and_canary_installed_not_inuse", "uninstall_chrome_dev", "chrome_canary_installed_not_inuse",
diff --git a/chrome/tools/build/win/TESTS b/chrome/tools/build/win/TESTS index 883fd77..96d14ad 100644 --- a/chrome/tools/build/win/TESTS +++ b/chrome/tools/build/win/TESTS
@@ -5,5 +5,4 @@ icudt46.dll icudt.dll icudtl.dat -plugins\np_test_netscape_plugin.dll fonts\*
diff --git a/chrome/utility/importer/external_process_importer_bridge.cc b/chrome/utility/importer/external_process_importer_bridge.cc index 38a8e7a..2ee0140c 100644 --- a/chrome/utility/importer/external_process_importer_bridge.cc +++ b/chrome/utility/importer/external_process_importer_bridge.cc
@@ -32,12 +32,10 @@ } // namespace ExternalProcessImporterBridge::ExternalProcessImporterBridge( - const base::DictionaryValue& localized_strings, + base::Value localized_strings, scoped_refptr<chrome::mojom::ThreadSafeProfileImportObserverPtr> observer) : observer_(std::move(observer)) { - // Bridge needs to make its own copy because OS 10.6 autoreleases the - // localized_strings value that is passed in (see http://crbug.com/46003 ). - localized_strings_.reset(localized_strings.DeepCopy()); + localized_strings_ = std::move(localized_strings); } void ExternalProcessImporterBridge::AddBookmarks( @@ -179,9 +177,10 @@ base::string16 ExternalProcessImporterBridge::GetLocalizedString( int message_id) { - base::string16 message; - localized_strings_->GetString(base::IntToString(message_id), &message); - return message; + base::Value* message_value = + localized_strings_.FindKey(base::IntToString(message_id)); + DCHECK(message_value); + return base::UTF8ToUTF16(message_value->GetString()); } ExternalProcessImporterBridge::~ExternalProcessImporterBridge() {}
diff --git a/chrome/utility/importer/external_process_importer_bridge.h b/chrome/utility/importer/external_process_importer_bridge.h index 7e05c4e..d137743e 100644 --- a/chrome/utility/importer/external_process_importer_bridge.h +++ b/chrome/utility/importer/external_process_importer_bridge.h
@@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/values.h" #include "build/build_config.h" #include "chrome/common/importer/importer_bridge.h" #include "chrome/common/importer/profile_import.mojom.h" @@ -19,10 +20,6 @@ class GURL; struct ImportedBookmarkEntry; -namespace base { -class DictionaryValue; -} - namespace importer { #if defined(OS_WIN) struct ImporterIE7PasswordInfo; @@ -44,7 +41,7 @@ public: // |observer| must outlive this object. ExternalProcessImporterBridge( - const base::DictionaryValue& localized_strings, + base::Value localized_strings, scoped_refptr<chrome::mojom::ThreadSafeProfileImportObserverPtr> observer); @@ -89,7 +86,7 @@ // Holds strings needed by the external importer because the resource // bundle isn't available to the external process. - std::unique_ptr<base::DictionaryValue> localized_strings_; + base::Value localized_strings_; scoped_refptr<chrome::mojom::ThreadSafeProfileImportObserverPtr> observer_;
diff --git a/chrome/utility/importer/profile_import_impl.cc b/chrome/utility/importer/profile_import_impl.cc index 97fafc0..3e3655f 100644 --- a/chrome/utility/importer/profile_import_impl.cc +++ b/chrome/utility/importer/profile_import_impl.cc
@@ -29,7 +29,7 @@ void ProfileImportImpl::StartImport( const importer::SourceProfile& source_profile, uint16_t items, - std::unique_ptr<base::DictionaryValue> localized_strings, + base::Value localized_strings, chrome::mojom::ProfileImportObserverPtr observer) { content::UtilityThread::Get()->EnsureBlinkInitialized(); importer_ = importer::CreateImporterByType(source_profile.importer_type); @@ -50,7 +50,7 @@ ImporterCleanup(); } bridge_ = new ExternalProcessImporterBridge( - *localized_strings, + std::move(localized_strings), ThreadSafeProfileImportObserverPtr::Create(std::move(observer))); import_thread_->task_runner()->PostTask( FROM_HERE,
diff --git a/chrome/utility/importer/profile_import_impl.h b/chrome/utility/importer/profile_import_impl.h index e37c604..effad17 100644 --- a/chrome/utility/importer/profile_import_impl.h +++ b/chrome/utility/importer/profile_import_impl.h
@@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "base/values.h" #include "chrome/common/importer/profile_import.mojom.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "services/service_manager/public/cpp/service_context_ref.h" @@ -19,7 +20,6 @@ class Importer; namespace base { -class DictionaryValue; class Thread; } // namespace base @@ -37,7 +37,7 @@ // chrome::mojom::ProfileImport: void StartImport(const importer::SourceProfile& source_profile, uint16_t items, - std::unique_ptr<base::DictionaryValue> localized_strings, + base::Value localized_strings, chrome::mojom::ProfileImportObserverPtr observer) override; void CancelImport() override; void ReportImportItemFinished(importer::ImportItem item) override;
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index bd3d580..22ec3fa 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -149,6 +149,7 @@ "cast_features_unittest.cc", "device_capabilities_impl_unittest.cc", "error_codes_unittest.cc", + "metrics/cast_metrics_helper_unittest.cc", "observer_unittest.cc", "path_utils_unittest.cc", "process_utils_unittest.cc",
diff --git a/chromecast/base/cast_sys_info_android.cc b/chromecast/base/cast_sys_info_android.cc index ed7cd12..c449b2d9 100644 --- a/chromecast/base/cast_sys_info_android.cc +++ b/chromecast/base/cast_sys_info_android.cc
@@ -54,9 +54,9 @@ if (!base::StringToInt(CAST_BUILD_INCREMENTAL, &build_number)) build_number = 0; - // Note: no way to determine which channel was used on play store. + const std::string channel(GetSystemReleaseChannel()); if (strcmp(build_info_->build_type(), kBuildTypeUser) == 0 && - build_number > 0) { + build_number > 0 && (channel.empty() || channel == "stable-channel")) { return BUILD_PRODUCTION; }
diff --git a/chromecast/base/metrics/BUILD.gn b/chromecast/base/metrics/BUILD.gn index 8751383a..f1bde85 100644 --- a/chromecast/base/metrics/BUILD.gn +++ b/chromecast/base/metrics/BUILD.gn
@@ -22,8 +22,6 @@ testonly = true sources = [ - "cast_metrics_test_helper.cc", - "cast_metrics_test_helper.h", "mock_cast_metrics_helper.cc", "mock_cast_metrics_helper.h", ]
diff --git a/chromecast/base/metrics/cast_metrics_helper.cc b/chromecast/base/metrics/cast_metrics_helper.cc index 269ff089..2a9144c3 100644 --- a/chromecast/base/metrics/cast_metrics_helper.cc +++ b/chromecast/base/metrics/cast_metrics_helper.cc
@@ -4,22 +4,18 @@ #include "chromecast/base/metrics/cast_metrics_helper.h" -#include <memory> -#include <string> #include <utility> #include <vector> #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/json/json_string_value_serializer.h" +#include "base/json/json_writer.h" #include "base/location.h" #include "base/metrics/histogram.h" #include "base/metrics/user_metrics.h" -#include "base/single_thread_task_runner.h" +#include "base/sequenced_task_runner.h" #include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/time/time.h" -#include "base/values.h" +#include "base/time/tick_clock.h" #include "chromecast/base/metrics/cast_histograms.h" #include "chromecast/base/metrics/grouped_histogram.h" @@ -27,8 +23,8 @@ namespace metrics { // A useful macro to make sure current member function runs on the valid thread. -#define MAKE_SURE_THREAD(callback, ...) \ - if (!task_runner_->BelongsToCurrentThread()) { \ +#define MAKE_SURE_SEQUENCE(callback, ...) \ + if (!task_runner_->RunsTasksInCurrentSequence()) { \ task_runner_->PostTask( \ FROM_HERE, base::BindOnce(&CastMetricsHelper::callback, \ base::Unretained(this), ##__VA_ARGS__)); \ @@ -37,32 +33,14 @@ namespace { -CastMetricsHelper* g_instance = NULL; +CastMetricsHelper* g_instance = nullptr; const char kMetricsNameAppInfoDelimiter = '#'; -std::unique_ptr<std::string> SerializeToJson(const base::Value& value) { - std::unique_ptr<std::string> json_str(new std::string()); - JSONStringValueSerializer serializer(json_str.get()); - if (!serializer.Serialize(value)) - json_str.reset(nullptr); - return json_str; -} - -std::unique_ptr<base::DictionaryValue> CreateEventBase( - const std::string& name) { - std::unique_ptr<base::DictionaryValue> cast_event( - new base::DictionaryValue()); - cast_event->SetString("name", name); - cast_event->SetDouble("time", base::TimeTicks::Now().ToInternalValue()); - - return cast_event; -} +constexpr base::TimeDelta kAppLoadTimeout = base::TimeDelta::FromMinutes(5); } // namespace -// static - // NOTE(gfhuang): This is a hacky way to encode/decode app infos into a // string. Mainly because it's hard to add another metrics serialization type // into components/metrics/serialization/. @@ -115,53 +93,65 @@ } CastMetricsHelper::CastMetricsHelper( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : task_runner_(task_runner), - metrics_sink_(NULL), + scoped_refptr<base::SequencedTaskRunner> task_runner, + const base::TickClock* tick_clock) + : task_runner_(std::move(task_runner)), + tick_clock_(tick_clock), + metrics_sink_(nullptr), logged_first_audio_(false), record_action_callback_( base::BindRepeating(&base::RecordComputedAction)) { - DCHECK(task_runner_.get()); - DCHECK(!g_instance); - g_instance = this; -} - -CastMetricsHelper::CastMetricsHelper() - : metrics_sink_(NULL), logged_first_audio_(false) { + DCHECK(task_runner_); DCHECK(!g_instance); g_instance = this; } CastMetricsHelper::~CastMetricsHelper() { DCHECK_EQ(g_instance, this); - g_instance = NULL; + g_instance = nullptr; } void CastMetricsHelper::DidStartLoad(const std::string& app_id) { - loading_app_id_ = app_id; - app_load_start_time_ = base::TimeTicks::Now(); + MAKE_SURE_SEQUENCE(DidStartLoad, app_id); + const base::TimeTicks now = Now(); + + // Remove start times for apps that never became the current app. + for (auto it = app_load_start_times_.cbegin(); + it != app_load_start_times_.cend();) { + if (now - it->second >= kAppLoadTimeout) { + it = app_load_start_times_.erase(it); + } else { + ++it; + } + } + + app_load_start_times_[app_id] = now; } void CastMetricsHelper::DidCompleteLoad(const std::string& app_id, const std::string& session_id) { - MAKE_SURE_THREAD(DidCompleteLoad, app_id, session_id); - DCHECK_EQ(app_id, loading_app_id_); - loading_app_id_ = std::string(); + MAKE_SURE_SEQUENCE(DidCompleteLoad, app_id, session_id); + auto it = app_load_start_times_.find(app_id); + if (it == app_load_start_times_.end()) { + LOG(ERROR) << "No start time for app: app_id=" << app_id; + return; + } app_id_ = app_id; - app_start_time_ = app_load_start_time_; session_id_ = session_id; + app_start_time_ = it->second; + app_load_start_times_.erase(it); logged_first_audio_ = false; TagAppStartForGroupedHistograms(app_id_); sdk_version_.clear(); } void CastMetricsHelper::UpdateSDKInfo(const std::string& sdk_version) { - MAKE_SURE_THREAD(UpdateSDKInfo, sdk_version); + MAKE_SURE_SEQUENCE(UpdateSDKInfo, sdk_version); sdk_version_ = sdk_version; } void CastMetricsHelper::LogMediaPlay() { - MAKE_SURE_THREAD(LogMediaPlay); + MAKE_SURE_SEQUENCE(LogMediaPlay); RecordSimpleAction(EncodeAppInfoIntoMetricsName( "MediaPlay", app_id_, @@ -170,7 +160,7 @@ } void CastMetricsHelper::LogMediaPause() { - MAKE_SURE_THREAD(LogMediaPause); + MAKE_SURE_SEQUENCE(LogMediaPause); RecordSimpleAction(EncodeAppInfoIntoMetricsName( "MediaPause", app_id_, @@ -179,10 +169,10 @@ } void CastMetricsHelper::LogTimeToFirstPaint() { - MAKE_SURE_THREAD(LogTimeToFirstPaint); + MAKE_SURE_SEQUENCE(LogTimeToFirstPaint); if (app_id_.empty()) return; - base::TimeDelta launch_time = base::TimeTicks::Now() - app_start_time_; + base::TimeDelta launch_time = Now() - app_start_time_; const std::string uma_name(GetMetricsNameWithAppName("Startup", "TimeToFirstPaint")); LogMediumTimeHistogramEvent(uma_name, launch_time); @@ -190,13 +180,12 @@ } void CastMetricsHelper::LogTimeToFirstAudio() { - MAKE_SURE_THREAD(LogTimeToFirstAudio); + MAKE_SURE_SEQUENCE(LogTimeToFirstAudio); if (logged_first_audio_) return; if (app_id_.empty()) return; - base::TimeDelta time_to_first_audio = - base::TimeTicks::Now() - app_start_time_; + base::TimeDelta time_to_first_audio = Now() - app_start_time_; const std::string uma_name( GetMetricsNameWithAppName("Startup", "TimeToFirstAudio")); LogMediumTimeHistogramEvent(uma_name, time_to_first_audio); @@ -207,8 +196,8 @@ void CastMetricsHelper::LogTimeToBufferAv(BufferingType buffering_type, base::TimeDelta time) { - MAKE_SURE_THREAD(LogTimeToBufferAv, buffering_type, time); - if (time < base::TimeDelta::FromSeconds(0)) { + MAKE_SURE_SEQUENCE(LogTimeToBufferAv, buffering_type, time); + if (time < base::TimeDelta()) { LOG(WARNING) << "Negative time"; return; } @@ -234,7 +223,7 @@ std::string CastMetricsHelper::GetMetricsNameWithAppName( const std::string& prefix, const std::string& suffix) const { - DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); std::string metrics_name(prefix); if (!app_id_.empty()) { if (!metrics_name.empty()) @@ -250,22 +239,22 @@ } void CastMetricsHelper::SetMetricsSink(MetricsSink* delegate) { - MAKE_SURE_THREAD(SetMetricsSink, delegate); + MAKE_SURE_SEQUENCE(SetMetricsSink, delegate); metrics_sink_ = delegate; } void CastMetricsHelper::SetRecordActionCallback(RecordActionCallback callback) { - DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); record_action_callback_ = std::move(callback); } void CastMetricsHelper::SetDummySessionIdForTesting() { - DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); session_id_ = "00000000-0000-0000-0000-000000000000"; } void CastMetricsHelper::RecordSimpleAction(const std::string& action) { - MAKE_SURE_THREAD(RecordSimpleAction, action); + MAKE_SURE_SEQUENCE(RecordSimpleAction, action); if (metrics_sink_) { metrics_sink_->OnAction(action); @@ -276,7 +265,7 @@ void CastMetricsHelper::LogEnumerationHistogramEvent( const std::string& name, int value, int num_buckets) { - MAKE_SURE_THREAD(LogEnumerationHistogramEvent, name, value, num_buckets); + MAKE_SURE_SEQUENCE(LogEnumerationHistogramEvent, name, value, num_buckets); if (metrics_sink_) { metrics_sink_->OnEnumerationEvent(name, value, num_buckets); @@ -286,11 +275,11 @@ } void CastMetricsHelper::LogTimeHistogramEvent(const std::string& name, - const base::TimeDelta& value, - const base::TimeDelta& min, - const base::TimeDelta& max, + base::TimeDelta value, + base::TimeDelta min, + base::TimeDelta max, int num_buckets) { - MAKE_SURE_THREAD(LogTimeHistogramEvent, name, value, min, max, num_buckets); + MAKE_SURE_SEQUENCE(LogTimeHistogramEvent, name, value, min, max, num_buckets); if (metrics_sink_) { metrics_sink_->OnTimeEvent(name, value, min, max, num_buckets); @@ -299,9 +288,8 @@ } } -void CastMetricsHelper::LogMediumTimeHistogramEvent( - const std::string& name, - const base::TimeDelta& value) { +void CastMetricsHelper::LogMediumTimeHistogramEvent(const std::string& name, + base::TimeDelta value) { // Follow UMA_HISTOGRAM_MEDIUM_TIMES definition. LogTimeHistogramEvent(name, value, base::TimeDelta::FromMilliseconds(10), @@ -309,34 +297,49 @@ 50); } +base::Value CastMetricsHelper::CreateEventBase(const std::string& name) { + base::Value cast_event(base::Value::Type::DICTIONARY); + cast_event.SetKey("name", base::Value(name)); + const double time = (Now() - base::TimeTicks()).InMicroseconds(); + cast_event.SetKey("time", base::Value(time)); + return cast_event; +} + void CastMetricsHelper::RecordEventWithValue(const std::string& event, int value) { - std::unique_ptr<base::DictionaryValue> cast_event(CreateEventBase(event)); - cast_event->SetInteger("value", value); - const std::string message = *SerializeToJson(*cast_event); + base::Value cast_event = CreateEventBase(event); + cast_event.SetKey("value", base::Value(value)); + std::string message; + base::JSONWriter::Write(cast_event, &message); RecordSimpleAction(message); } void CastMetricsHelper::RecordApplicationEvent(const std::string& event) { - std::unique_ptr<base::DictionaryValue> cast_event(CreateEventBase(event)); - cast_event->SetString("app_id", app_id_); - cast_event->SetString("session_id", session_id_); - cast_event->SetString("sdk_version", sdk_version_); - const std::string message = *SerializeToJson(*cast_event); + base::Value cast_event = CreateEventBase(event); + cast_event.SetKey("app_id", base::Value(app_id_)); + cast_event.SetKey("session_id", base::Value(session_id_)); + cast_event.SetKey("sdk_version", base::Value(sdk_version_)); + std::string message; + base::JSONWriter::Write(cast_event, &message); RecordSimpleAction(message); } void CastMetricsHelper::RecordApplicationEventWithValue( const std::string& event, int value) { - std::unique_ptr<base::DictionaryValue> cast_event(CreateEventBase(event)); - cast_event->SetString("app_id", app_id_); - cast_event->SetString("session_id", session_id_); - cast_event->SetString("sdk_version", sdk_version_); - cast_event->SetInteger("value", value); - const std::string message = *SerializeToJson(*cast_event); + base::Value cast_event = CreateEventBase(event); + cast_event.SetKey("app_id", base::Value(app_id_)); + cast_event.SetKey("session_id", base::Value(session_id_)); + cast_event.SetKey("sdk_version", base::Value(sdk_version_)); + cast_event.SetKey("value", base::Value(value)); + std::string message; + base::JSONWriter::Write(cast_event, &message); RecordSimpleAction(message); } +base::TimeTicks CastMetricsHelper::Now() { + return tick_clock_ ? tick_clock_->NowTicks() : base::TimeTicks::Now(); +} + } // namespace metrics } // namespace chromecast
diff --git a/chromecast/base/metrics/cast_metrics_helper.h b/chromecast/base/metrics/cast_metrics_helper.h index 61f9b3cf..818e678 100644 --- a/chromecast/base/metrics/cast_metrics_helper.h +++ b/chromecast/base/metrics/cast_metrics_helper.h
@@ -5,16 +5,21 @@ #ifndef CHROMECAST_BASE_METRICS_CAST_METRICS_HELPER_H_ #define CHROMECAST_BASE_METRICS_CAST_METRICS_HELPER_H_ +#include <memory> #include <string> #include "base/callback.h" +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" +#include "base/values.h" namespace base { -class SingleThreadTaskRunner; -} +class SequencedTaskRunner; +class TickClock; +} // namespace base namespace chromecast { namespace metrics { @@ -35,15 +40,15 @@ class MetricsSink { public: - virtual ~MetricsSink() {} + virtual ~MetricsSink() = default; virtual void OnAction(const std::string& action) = 0; virtual void OnEnumerationEvent(const std::string& name, int value, int num_buckets) = 0; virtual void OnTimeEvent(const std::string& name, - const base::TimeDelta& value, - const base::TimeDelta& min, - const base::TimeDelta& max, + base::TimeDelta value, + base::TimeDelta min, + base::TimeDelta max, int num_buckets) = 0; }; @@ -59,8 +64,9 @@ static CastMetricsHelper* GetInstance(); - explicit CastMetricsHelper( - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + CastMetricsHelper(scoped_refptr<base::SequencedTaskRunner> task_runner = + base::SequencedTaskRunnerHandle::Get(), + const base::TickClock* tick_clock = nullptr); virtual ~CastMetricsHelper(); // This records the startup time of an app load (note: another app @@ -119,12 +125,6 @@ // Sets an all-0's session ID for running browser tests. void SetDummySessionIdForTesting(); - protected: - // Creates a CastMetricsHelper instance with no task runner. This should only - // be used by tests, since invoking any non-overridden methods on this - // instance will cause a failure. - CastMetricsHelper(); - private: static std::string EncodeAppInfoIntoMetricsName( const std::string& action_name, @@ -135,25 +135,25 @@ void LogEnumerationHistogramEvent(const std::string& name, int value, int num_buckets); void LogTimeHistogramEvent(const std::string& name, - const base::TimeDelta& value, - const base::TimeDelta& min, - const base::TimeDelta& max, + base::TimeDelta value, + base::TimeDelta min, + base::TimeDelta max, int num_buckets); void LogMediumTimeHistogramEvent(const std::string& name, - const base::TimeDelta& value); + base::TimeDelta value); + base::Value CreateEventBase(const std::string& name); + base::TimeTicks Now(); - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + const base::TickClock* const tick_clock_; - // Start time for loading the next app. - base::TimeTicks app_load_start_time_; + // Start times for loading the next apps. + base::flat_map<std::string /* app_id */, base::TimeTicks> + app_load_start_times_; + // Start time for the currently running app. base::TimeTicks app_start_time_; - // The app id for the app that is currently loading and, if the load is - // successful, will replace the currently running app. The currently running - // app is still collecting metrics. - std::string loading_app_id_; - // Currently running app id. Used to construct histogram name. std::string app_id_; std::string session_id_;
diff --git a/chromecast/base/metrics/cast_metrics_helper_unittest.cc b/chromecast/base/metrics/cast_metrics_helper_unittest.cc new file mode 100644 index 0000000..2bf53aac --- /dev/null +++ b/chromecast/base/metrics/cast_metrics_helper_unittest.cc
@@ -0,0 +1,174 @@ +// Copyright 2018 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 "chromecast/base/metrics/cast_metrics_helper.h" + +#include <string> + +#include "base/json/json_reader.h" +#include "base/test/scoped_task_environment.h" +#include "base/time/time.h" +#include "base/values.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::AllOf; +using ::testing::HasSubstr; +using ::testing::SaveArg; +using ::testing::_; + +namespace chromecast { +namespace metrics { + +namespace { + +constexpr char kAppId1[] = "APP_ID_1"; +constexpr char kAppId2[] = "APP_ID_2"; +constexpr char kAppId3[] = "APP_ID_3"; +constexpr char kEvent[] = "EVENT"; +constexpr char kSdkVersion[] = "SDK_VERSION"; +constexpr char kSessionId1[] = "SESSION_ID_1"; +constexpr char kSessionId2[] = "SESSION_ID_2"; +constexpr char kSessionId3[] = "SESSION_ID_3"; +constexpr int kValue = 123; + +constexpr base::TimeDelta kAppLoadTimeout = base::TimeDelta::FromMinutes(5); + +MATCHER_P2(HasDouble, key, value, "") { + auto v = base::JSONReader::Read(arg); + return v && v->FindKey(key) && v->FindKey(key)->is_double() && + v->FindKey(key)->GetDouble() == value; +} + +MATCHER_P2(HasInt, key, value, "") { + auto v = base::JSONReader::Read(arg); + return v && v->FindKey(key) && v->FindKey(key)->is_int() && + v->FindKey(key)->GetInt() == value; +} + +MATCHER_P2(HasString, key, value, "") { + auto v = base::JSONReader::Read(arg); + return v && v->FindKey(key) && v->FindKey(key)->is_string() && + v->FindKey(key)->GetString() == value; +} + +} // namespace + +class MockMetricsSink : public CastMetricsHelper::MetricsSink { + public: + MOCK_METHOD1(OnAction, void(const std::string&)); + MOCK_METHOD3(OnEnumerationEvent, void(const std::string&, int, int)); + MOCK_METHOD5(OnTimeEvent, + void(const std::string&, + base::TimeDelta, + base::TimeDelta, + base::TimeDelta, + int)); +}; + +class CastMetricsHelperTest : public ::testing::Test { + public: + CastMetricsHelperTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME), + metrics_helper_(scoped_task_environment_.GetMainThreadTaskRunner(), + scoped_task_environment_.GetMockTickClock()) { + metrics_helper_.SetMetricsSink(&metrics_sink_); + } + + base::test::ScopedTaskEnvironment scoped_task_environment_; + MockMetricsSink metrics_sink_; + CastMetricsHelper metrics_helper_; +}; + +TEST_F(CastMetricsHelperTest, RecordEventWithValue) { + const base::TimeDelta time = base::TimeDelta::FromSeconds(5); + scoped_task_environment_.FastForwardBy(time); + + EXPECT_CALL(metrics_sink_, + OnAction(AllOf(HasString("name", kEvent), + HasDouble("time", time.InMicroseconds()), + HasInt("value", kValue)))); + metrics_helper_.RecordApplicationEventWithValue(kEvent, kValue); +} + +TEST_F(CastMetricsHelperTest, RecordApplicationEvent) { + metrics_helper_.DidStartLoad(kAppId1); + metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1); + metrics_helper_.UpdateSDKInfo(kSdkVersion); + + const base::TimeDelta time = base::TimeDelta::FromSeconds(5); + scoped_task_environment_.FastForwardBy(time); + + EXPECT_CALL( + metrics_sink_, + OnAction(AllOf( + HasString("name", kEvent), HasDouble("time", time.InMicroseconds()), + HasString("app_id", kAppId1), HasString("session_id", kSessionId1), + HasString("sdk_version", kSdkVersion)))); + metrics_helper_.RecordApplicationEvent(kEvent); +} + +TEST_F(CastMetricsHelperTest, RecordApplicationEventWithValue) { + metrics_helper_.DidStartLoad(kAppId1); + metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1); + metrics_helper_.UpdateSDKInfo(kSdkVersion); + + const base::TimeDelta time = base::TimeDelta::FromSeconds(5); + scoped_task_environment_.FastForwardBy(time); + + EXPECT_CALL( + metrics_sink_, + OnAction(AllOf( + HasString("name", kEvent), HasDouble("time", time.InMicroseconds()), + HasString("app_id", kAppId1), HasString("session_id", kSessionId1), + HasString("sdk_version", kSdkVersion), HasInt("value", kValue)))); + metrics_helper_.RecordApplicationEventWithValue(kEvent, kValue); +} + +TEST_F(CastMetricsHelperTest, LogTimeToFirstPaint) { + metrics_helper_.DidStartLoad(kAppId1); + metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1); + + const base::TimeDelta time_to_first_paint = base::TimeDelta::FromSeconds(5); + scoped_task_environment_.FastForwardBy(time_to_first_paint); + + EXPECT_CALL(metrics_sink_, OnTimeEvent(AllOf(HasSubstr(kAppId1), + HasSubstr("TimeToFirstPaint")), + time_to_first_paint, _, _, _)); + metrics_helper_.LogTimeToFirstPaint(); +} + +TEST_F(CastMetricsHelperTest, LogTimeToFirstAudio) { + metrics_helper_.DidStartLoad(kAppId1); + metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1); + + const base::TimeDelta time_to_first_audio = base::TimeDelta::FromSeconds(5); + scoped_task_environment_.FastForwardBy(time_to_first_audio); + + EXPECT_CALL(metrics_sink_, OnTimeEvent(AllOf(HasSubstr(kAppId1), + HasSubstr("TimeToFirstAudio")), + time_to_first_audio, _, _, _)); + metrics_helper_.LogTimeToFirstAudio(); +} + +TEST_F(CastMetricsHelperTest, MultipleApps) { + metrics_helper_.DidStartLoad(kAppId1); + scoped_task_environment_.FastForwardBy(kAppLoadTimeout); + metrics_helper_.DidStartLoad(kAppId2); + metrics_helper_.DidStartLoad(kAppId3); + metrics_helper_.DidCompleteLoad(kAppId3, kSessionId3); + // kAppId2 should become the current app. + metrics_helper_.DidCompleteLoad(kAppId2, kSessionId2); + // kAppId1 should not become the current app because it timed out. + metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1); + + EXPECT_CALL(metrics_sink_, + OnAction(AllOf(HasString("app_id", kAppId2), + HasString("session_id", kSessionId2)))); + metrics_helper_.RecordApplicationEvent(kEvent); +} + +} // namespace metrics +} // namespace chromecast
diff --git a/chromecast/base/metrics/cast_metrics_test_helper.cc b/chromecast/base/metrics/cast_metrics_test_helper.cc deleted file mode 100644 index 763bb82..0000000 --- a/chromecast/base/metrics/cast_metrics_test_helper.cc +++ /dev/null
@@ -1,99 +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 "chromecast/base/metrics/cast_metrics_test_helper.h" - -#include <string> - -#include "base/logging.h" -#include "base/macros.h" -#include "chromecast/base/metrics/cast_metrics_helper.h" - -namespace chromecast { -namespace metrics { - -namespace { - -class CastMetricsHelperStub : public CastMetricsHelper { - public: - CastMetricsHelperStub(); - ~CastMetricsHelperStub() override; - - void DidStartLoad(const std::string& app_id) override; - void DidCompleteLoad(const std::string& app_id, - const std::string& session_id) override; - void UpdateSDKInfo(const std::string& sdk_version) override; - void LogMediaPlay() override; - void LogMediaPause() override; - void LogTimeToFirstAudio() override; - void LogTimeToBufferAv(BufferingType buffering_type, - base::TimeDelta time) override; - std::string GetMetricsNameWithAppName( - const std::string& prefix, const std::string& suffix) const override; - void SetMetricsSink(MetricsSink* delegate) override; - void RecordSimpleAction(const std::string& action) override; - - private: - DISALLOW_COPY_AND_ASSIGN(CastMetricsHelperStub); -}; - -bool stub_instance_exists = false; - -CastMetricsHelperStub::CastMetricsHelperStub() - : CastMetricsHelper() { - DCHECK(!stub_instance_exists); - stub_instance_exists = true; -} - -CastMetricsHelperStub::~CastMetricsHelperStub() { - DCHECK(stub_instance_exists); - stub_instance_exists = false; -} - -void CastMetricsHelperStub::DidStartLoad(const std::string& app_id) { -} - -void CastMetricsHelperStub::DidCompleteLoad( - const std::string& app_id, - const std::string& session_id) { -} - -void CastMetricsHelperStub::UpdateSDKInfo(const std::string& sdk_version) { -} - -void CastMetricsHelperStub::LogMediaPlay() { -} - -void CastMetricsHelperStub::LogMediaPause() { -} - -void CastMetricsHelperStub::LogTimeToFirstAudio() { -} - -void CastMetricsHelperStub::LogTimeToBufferAv(BufferingType buffering_type, - base::TimeDelta time) { -} - -std::string CastMetricsHelperStub::GetMetricsNameWithAppName( - const std::string& prefix, - const std::string& suffix) const { - return ""; -} - -void CastMetricsHelperStub::SetMetricsSink(MetricsSink* delegate) { -} - -} // namespace - -void CastMetricsHelperStub::RecordSimpleAction(const std::string& action) { -} - -void InitializeMetricsHelperForTesting() { - if (!stub_instance_exists) { - new CastMetricsHelperStub(); - } -} - -} // namespace metrics -} // namespace chromecast
diff --git a/chromecast/base/metrics/cast_metrics_test_helper.h b/chromecast/base/metrics/cast_metrics_test_helper.h deleted file mode 100644 index a1eafed..0000000 --- a/chromecast/base/metrics/cast_metrics_test_helper.h +++ /dev/null
@@ -1,19 +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 CHROMECAST_BASE_METRICS_CAST_METRICS_TEST_HELPER_H_ -#define CHROMECAST_BASE_METRICS_CAST_METRICS_TEST_HELPER_H_ - -namespace chromecast { -namespace metrics { - -// Creates and initializes a metrics helper stub for the current process, in -// which all operations are no-ops. May be safely called multiple times per -// process. -void InitializeMetricsHelperForTesting(); - -} // namespace metrics -} // namespace chromecast - -#endif // CHROMECAST_BASE_METRICS_CAST_METRICS_TEST_HELPER_H_
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 92a2fb17..9c8af01 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -122,6 +122,7 @@ "//components/network_session_configurator/common", "//components/prefs", "//components/proxy_config", + "//components/viz/service", "//content", "//content/public/browser", "//content/public/common", @@ -138,6 +139,7 @@ "//ui/compositor", "//ui/display", "//ui/events", + "//ui/events/devices", "//ui/gl", ]
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS index 216a7b1..5d3eeb1 100644 --- a/chromecast/browser/DEPS +++ b/chromecast/browser/DEPS
@@ -51,4 +51,9 @@ # TODO(slan): Remove this when the network service is shipped on Cast. "+services/network", + + # Needed to insert video plane callback. + # TODO(halliwell): Need to re-work this dependency otherwise Cast can't run + # with Viz out of process. + "+components/viz/service/display/overlay_strategy_underlay_cast.h", ]
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 03a3095..e144279 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -90,8 +90,8 @@ // callback. #include "chromecast/browser/cast_display_configurator.h" #include "chromecast/graphics/cast_screen.h" +#include "components/viz/service/display/overlay_strategy_underlay_cast.h" // nogncheck #include "ui/display/screen.h" -#include "ui/ozone/platform/cast/overlay_manager_cast.h" // nogncheck #endif #if BUILDFLAG(ENABLE_CHROMECAST_EXTENSIONS) @@ -518,9 +518,9 @@ display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel(); video_plane_controller_.reset(new media::VideoPlaneController( Size(display_size.width(), display_size.height()), GetMediaTaskRunner())); - ui::OverlayManagerCast::SetOverlayCompositedCallback( - base::Bind(&media::VideoPlaneController::SetGeometry, - base::Unretained(video_plane_controller_.get()))); + viz::OverlayStrategyUnderlayCast::SetOverlayCompositedCallback( + base::BindRepeating(&media::VideoPlaneController::SetGeometryGfx, + base::Unretained(video_plane_controller_.get()))); #endif window_manager_ = CastWindowManager::Create(
diff --git a/chromecast/media/DEPS b/chromecast/media/DEPS index 4e0f954f..8b80df6 100644 --- a/chromecast/media/DEPS +++ b/chromecast/media/DEPS
@@ -4,4 +4,5 @@ "+media/base", "+media/cdm", "+ui/gfx/geometry", + "+ui/gfx/overlay_transform.h", ]
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc index 5671745..64ed7d1 100644 --- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc +++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -10,10 +10,10 @@ #include <utility> #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/time/time.h" -#include "chromecast/base/metrics/cast_metrics_test_helper.h" +#include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/media/audio/cast_audio_manager.h" #include "chromecast/media/audio/cast_audio_mixer.h" #include "chromecast/media/cma/backend/cma_backend.h" @@ -206,8 +206,6 @@ protected: void SetUp() override { - metrics::InitializeMetricsHelperForTesting(); - CHECK(media_thread_.Start()); auto backend_factory = std::make_unique<NiceMock<MockCmaBackendFactory>>(); ON_CALL(*backend_factory, CreateBackend(_)) @@ -248,12 +246,13 @@ base::TimeDelta duration = audio_params.GetBufferDuration() * frames; base::RunLoop run_loop; - message_loop_.task_runner()->PostDelayedTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostDelayedTask( FROM_HERE, run_loop.QuitClosure(), duration); run_loop.Run(); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + metrics::CastMetricsHelper cast_metrics_helper_; base::Thread media_thread_; std::unique_ptr<CastAudioManager> audio_manager_; FakeCmaBackend* media_pipeline_backend_;
diff --git a/chromecast/media/base/BUILD.gn b/chromecast/media/base/BUILD.gn index 9237b8c..bc5fe5b 100644 --- a/chromecast/media/base/BUILD.gn +++ b/chromecast/media/base/BUILD.gn
@@ -106,5 +106,7 @@ deps = [ "//base", "//chromecast/media:libcast_media", + "//ui/gfx", + "//ui/gfx/geometry", ] }
diff --git a/chromecast/media/base/video_plane_controller.cc b/chromecast/media/base/video_plane_controller.cc index 26d231b..bb3952e 100644 --- a/chromecast/media/base/video_plane_controller.cc +++ b/chromecast/media/base/video_plane_controller.cc
@@ -38,6 +38,30 @@ return s.width >= 0 && s.height >= 0; } +// Translates a gfx::OverlayTransform into a VideoPlane::Transform. +// Could be just a lookup table once we have unit tests for this code +// to ensure it stays in sync with OverlayTransform. +chromecast::media::VideoPlane::Transform ConvertTransform( + gfx::OverlayTransform transform) { + switch (transform) { + case gfx::OVERLAY_TRANSFORM_NONE: + return chromecast::media::VideoPlane::TRANSFORM_NONE; + case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + return chromecast::media::VideoPlane::FLIP_HORIZONTAL; + case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL: + return chromecast::media::VideoPlane::FLIP_VERTICAL; + case gfx::OVERLAY_TRANSFORM_ROTATE_90: + return chromecast::media::VideoPlane::ROTATE_90; + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + return chromecast::media::VideoPlane::ROTATE_180; + case gfx::OVERLAY_TRANSFORM_ROTATE_270: + return chromecast::media::VideoPlane::ROTATE_270; + default: + NOTREACHED(); + return chromecast::media::VideoPlane::TRANSFORM_NONE; + } +} + } // namespace // Helper class for calling VideoPlane::SetGeometry with rate-limiting. @@ -155,6 +179,13 @@ VideoPlaneController::~VideoPlaneController() {} +void VideoPlaneController::SetGeometryGfx(const gfx::RectF& display_rect, + gfx::OverlayTransform transform) { + chromecast::RectF rect(display_rect.x(), display_rect.y(), + display_rect.width(), display_rect.height()); + SetGeometry(rect, ConvertTransform(transform)); +} + void VideoPlaneController::SetGeometry(const RectF& display_rect, VideoPlane::Transform transform) { DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chromecast/media/base/video_plane_controller.h b/chromecast/media/base/video_plane_controller.h index 3d08d14a..e926c78 100644 --- a/chromecast/media/base/video_plane_controller.h +++ b/chromecast/media/base/video_plane_controller.h
@@ -11,6 +11,8 @@ #include "base/threading/thread_checker.h" #include "chromecast/public/graphics_types.h" #include "chromecast/public/video_plane.h" +#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/overlay_transform.h" namespace base { class SingleThreadTaskRunner; @@ -36,9 +38,13 @@ const Size& graphics_resolution, scoped_refptr<base::SingleThreadTaskRunner> media_task_runner); ~VideoPlaneController(); + // Sets the video plane geometry in *graphics plane coordinates*. If there is // no change to video plane parameters from the last call to this method, it // is a no-op. + void SetGeometryGfx(const gfx::RectF& display_rect, + gfx::OverlayTransform transform); + void SetGeometry(const RectF& display_rect, VideoPlane::Transform transform); // Sets physical screen resolution. This must be called at least once when
diff --git a/chromecast/media/cma/base/buffering_controller_unittest.cc b/chromecast/media/cma/base/buffering_controller_unittest.cc index 503b430..d982d04 100644 --- a/chromecast/media/cma/base/buffering_controller_unittest.cc +++ b/chromecast/media/cma/base/buffering_controller_unittest.cc
@@ -10,7 +10,9 @@ #include "base/callback_helpers.h" #include "base/logging.h" #include "base/macros.h" +#include "base/test/scoped_task_environment.h" #include "base/time/time.h" +#include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/media/cma/base/buffering_state.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,29 +24,17 @@ class MockBufferingControllerClient { public: - MockBufferingControllerClient(); - ~MockBufferingControllerClient(); - MOCK_METHOD1(OnBufferingNotification, void(bool is_buffering)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockBufferingControllerClient); }; -MockBufferingControllerClient::MockBufferingControllerClient() { -} - -MockBufferingControllerClient::~MockBufferingControllerClient() { -} - } // namespace class BufferingControllerTest : public testing::Test { public: BufferingControllerTest(); - ~BufferingControllerTest() override; - protected: + base::test::ScopedTaskEnvironment scoped_task_environment_; + metrics::CastMetricsHelper cast_metrics_helper_; std::unique_ptr<BufferingController> buffering_controller_; MockBufferingControllerClient client_; @@ -57,9 +47,6 @@ // Buffer level above the high level. base::TimeDelta d3_; - - private: - DISALLOW_COPY_AND_ASSIGN(BufferingControllerTest); }; BufferingControllerTest::BufferingControllerTest() { @@ -80,9 +67,6 @@ base::Unretained(&client_)))); } -BufferingControllerTest::~BufferingControllerTest() { -} - TEST_F(BufferingControllerTest, OneStream_Typical) { EXPECT_CALL(client_, OnBufferingNotification(true)).Times(1); scoped_refptr<BufferingState> buffering_state =
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc index 9c6985b..def6c89 100644 --- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc +++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -7,9 +7,10 @@ #include <vector> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" +#include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/media/base/decrypt_context_impl.h" #include "chromecast/media/cdm/cast_cdm_context.h" #include "chromecast/media/cma/pipeline/av_pipeline_client.h" @@ -269,7 +270,8 @@ pipeline_helper_->Setup(); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + metrics::CastMetricsHelper cast_metrics_helper_; std::unique_ptr<PipelineHelper> pipeline_helper_; DISALLOW_COPY_AND_ASSIGN(AudioVideoPipelineImplTest); @@ -290,7 +292,7 @@ TEST_P(AudioVideoPipelineImplTest, Play) { base::Closure verify_task = base::Bind(&VerifyPlay, base::Unretained(pipeline_helper_.get())); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Start, base::Unretained(pipeline_helper_.get()), verify_task)); @@ -314,11 +316,11 @@ TEST_P(AudioVideoPipelineImplTest, Flush) { base::Closure verify_task = base::Bind(&VerifyFlush, base::Unretained(pipeline_helper_.get())); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Start, base::Unretained(pipeline_helper_.get()), base::Bind(&VerifyNotReached))); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Flush, base::Unretained(pipeline_helper_.get()), verify_task)); @@ -333,7 +335,7 @@ base::Bind(&PipelineHelper::Flush, base::Unretained(pipeline_helper_.get()), stop_task); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Start, base::Unretained(pipeline_helper_.get()), eos_cb)); @@ -360,7 +362,8 @@ pipeline_helper_->Setup(); } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + metrics::CastMetricsHelper cast_metrics_helper_; std::unique_ptr<PipelineHelper> pipeline_helper_; DISALLOW_COPY_AND_ASSIGN(EncryptedAVPipelineImplTest); @@ -370,13 +373,13 @@ TEST_F(EncryptedAVPipelineImplTest, SetCdmWithLicenseBeforeStart) { base::Closure verify_task = base::Bind(&VerifyPlay, base::Unretained(pipeline_helper_.get())); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::SetCdm, base::Unretained(pipeline_helper_.get()))); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::SetCdmLicenseInstalled, base::Unretained(pipeline_helper_.get()))); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Start, base::Unretained(pipeline_helper_.get()), verify_task)); @@ -387,16 +390,16 @@ TEST_F(EncryptedAVPipelineImplTest, SetCdmWithLicenseAfterStart) { base::Closure verify_task = base::Bind(&VerifyPlay, base::Unretained(pipeline_helper_.get())); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Start, base::Unretained(pipeline_helper_.get()), verify_task)); - base::RunLoop().RunUntilIdle(); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.RunUntilIdle(); + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::SetCdmLicenseInstalled, base::Unretained(pipeline_helper_.get()))); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::SetCdm, base::Unretained(pipeline_helper_.get()))); base::RunLoop().Run(); @@ -406,16 +409,16 @@ TEST_F(EncryptedAVPipelineImplTest, SetCdmAndInstallLicenseAfterStart) { base::Closure verify_task = base::Bind(&VerifyPlay, base::Unretained(pipeline_helper_.get())); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::Start, base::Unretained(pipeline_helper_.get()), verify_task)); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::SetCdm, base::Unretained(pipeline_helper_.get()))); - base::RunLoop().RunUntilIdle(); - message_loop_.task_runner()->PostTask( + scoped_task_environment_.RunUntilIdle(); + scoped_task_environment_.GetMainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&PipelineHelper::SetCdmLicenseInstalled, base::Unretained(pipeline_helper_.get()))); base::RunLoop().Run();
diff --git a/chromecast/media/test/run_all_unittests.cc b/chromecast/media/test/run_all_unittests.cc index 19089d2..66279c9 100644 --- a/chromecast/media/test/run_all_unittests.cc +++ b/chromecast/media/test/run_all_unittests.cc
@@ -6,7 +6,6 @@ #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" #include "build/build_config.h" -#include "chromecast/base/metrics/cast_metrics_test_helper.h" #include "media/base/media.h" class CastMediaTestSuite : public base::TestSuite { @@ -23,10 +22,6 @@ // Run TestSuite::Initialize first so that logging is initialized. base::TestSuite::Initialize(); - // Some of the chromecast media unit tests require a metrics helper instance. - // Provide a fake one. - chromecast::metrics::InitializeMetricsHelperForTesting(); - // Initialize the FFMpeg library. // Note: at this time, AtExitManager is already present. media::InitializeMediaLibrary();
diff --git a/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc b/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc index 0c03cc1..ca980c0 100644 --- a/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc +++ b/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc
@@ -36,7 +36,7 @@ : public cryptauth::RemoteDeviceProviderImpl::Factory { public: FakeRemoteDeviceProviderFactory() = default; - virtual ~FakeRemoteDeviceProviderFactory() = default; + ~FakeRemoteDeviceProviderFactory() override = default; // cryptauth::RemoteDeviceProviderImpl::Factory: std::unique_ptr<cryptauth::RemoteDeviceProvider> BuildInstance(
diff --git a/chromeos/dbus/pipe_reader_unittest.cc b/chromeos/dbus/pipe_reader_unittest.cc index 9d9693c..ccaee9b 100644 --- a/chromeos/dbus/pipe_reader_unittest.cc +++ b/chromeos/dbus/pipe_reader_unittest.cc
@@ -41,7 +41,11 @@ class PipeReaderTest : public testing::Test { public: PipeReaderTest() = default; - ~PipeReaderTest() override = default; + ~PipeReaderTest() override { + // Flush the ScopedTaskEnvironment to prevent leaks of PostTaskAndReply + // callbacks. + task_environment_.RunUntilIdle(); + } scoped_refptr<base::TaskRunner> GetTaskRunner() { return task_environment_.GetMainThreadTaskRunner(); @@ -93,7 +97,6 @@ TEST_F(PipeReaderTest, Cancel) { auto reader = std::make_unique<PipeReader>(GetTaskRunner()); - base::RunLoop run_loop; base::ScopedFD write_fd = reader->StartIO(base::BindOnce([](base::Optional<std::string> result) { FAIL(); // Unexpected to be called.
diff --git a/components/OWNERS b/components/OWNERS index 2c20e78c..a071f6c 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -14,10 +14,8 @@ per-file error_page_strings.grdp=file://components/error_page/OWNERS per-file ntp_snippets_strings.grdp=file://components/ntp_snippets/OWNERS per-file omnibox_strings.grdp=file://components/omnibox/OWNERS -per-file page_info_strings.grdp=estark@chromium.org -per-file page_info_strings.grdp=felt@chromium.org -per-file page_info_strings.grdp=meacer@chromium.org -per-file page_info_strings.grdp=patricialor@chromium.org +per-file page_info_strings.grdp=file://chrome/browser/ui/page_info/OWNERS +per-file page_info_strings_grdp=file://chrome/browser/ui/page_info/OWNERS per-file password_manager_strings.grdp=file://components/password_manager/OWNERS per-file payments_strings.grdp=file://components/payments/OWNERS per-file pdf_strings.grdp=raymes@chromium.org
diff --git a/components/arc/common/app.mojom b/components/arc/common/app.mojom index c6b0b206..e4f00485 100644 --- a/components/arc/common/app.mojom +++ b/components/arc/common/app.mojom
@@ -12,8 +12,9 @@ // Describes OrientationLock request. // Note: ChromeOS currently assumes the internal panel is always landscape. // All rotation angles mentioned here are measured clockwise. +// DEPRECATED: OrientationLock passed by Wayland instead. [Extensible] -enum OrientationLock { +enum OrientationLockDeprecated { NONE = 0, // Rotated 90 or 270 deg. PORTRAIT = 1, @@ -44,7 +45,8 @@ string activity; [MinVersion=2] bool sticky; // true if the app cannot be uninstalled [MinVersion=7] bool notifications_enabled; - [MinVersion=12] OrientationLock orientation_lock; + // DEPRECATED: OrientationLock passed by Wayland instead. + [MinVersion=12] OrientationLockDeprecated orientation_lock_deprecated; }; // Describes ARC package. @@ -223,8 +225,9 @@ [MinVersion=4] OnTaskDestroyed@5(int32 task_id); // Notifies that task requested orientation lock. - [MinVersion=12] OnTaskOrientationLockRequested@12(int32 task_id, - OrientationLock lock); + // DEPRECATED: OrientationLock passed by Wayland instead. + [MinVersion=12] OnTaskOrientationLockRequestedDeprecated@12( + int32 task_id, OrientationLockDeprecated lock); // Notifies that task has been activated. [MinVersion=4] OnTaskSetActive@6(int32 task_id);
diff --git a/components/arc/common/bluetooth.mojom b/components/arc/common/bluetooth.mojom index 0371ccf7..c3e0ebf 100644 --- a/components/arc/common/bluetooth.mojom +++ b/components/arc/common/bluetooth.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Next MinVersion: 9 +// Next MinVersion: 10 module arc.mojom; @@ -451,15 +451,19 @@ array<uint8> value); // Bluetooth Gatt Server functions - [MinVersion=3] RequestGattRead@14(BluetoothAddress address, - int32 attribute_handle, - int32 offset, - bool is_long) + [MinVersion=3] RequestGattRead@14( + BluetoothAddress address, + int32 attribute_handle, + int32 offset, + bool is_long, + [MinVersion=9] BluetoothGattDBAttributeType attribute_type) => (BluetoothGattStatus status, array<uint8> value); - [MinVersion=3] RequestGattWrite@15(BluetoothAddress address, - int32 attribute_handle, - int32 offset, - array<uint8> value) + [MinVersion=3] RequestGattWrite@15( + BluetoothAddress address, + int32 attribute_handle, + int32 offset, + array<uint8> value, + [MinVersion=9] BluetoothGattDBAttributeType attribute_type) => (BluetoothGattStatus status); // Bluetooth SDP function
diff --git a/components/arc/test/fake_bluetooth_instance.cc b/components/arc/test/fake_bluetooth_instance.cc index a4836e1..f4c06d3 100644 --- a/components/arc/test/fake_bluetooth_instance.cc +++ b/components/arc/test/fake_bluetooth_instance.cc
@@ -108,17 +108,20 @@ bool is_notify, const std::vector<uint8_t>& value) {} -void FakeBluetoothInstance::RequestGattRead(mojom::BluetoothAddressPtr address, - int32_t attribute_handle, - int32_t offset, - bool is_long, - RequestGattReadCallback callback) {} +void FakeBluetoothInstance::RequestGattRead( + mojom::BluetoothAddressPtr address, + int32_t attribute_handle, + int32_t offset, + bool is_long, + mojom::BluetoothGattDBAttributeType attribute_type, + RequestGattReadCallback callback) {} void FakeBluetoothInstance::RequestGattWrite( mojom::BluetoothAddressPtr address, int32_t attribute_handle, int32_t offset, const std::vector<uint8_t>& value, + mojom::BluetoothGattDBAttributeType attribute_type, RequestGattWriteCallback callback) {} void FakeBluetoothInstance::OnGetSdpRecords(
diff --git a/components/arc/test/fake_bluetooth_instance.h b/components/arc/test/fake_bluetooth_instance.h index abe5cac..41d85e3d 100644 --- a/components/arc/test/fake_bluetooth_instance.h +++ b/components/arc/test/fake_bluetooth_instance.h
@@ -116,12 +116,14 @@ int32_t attribute_handle, int32_t offset, bool is_long, + mojom::BluetoothGattDBAttributeType attribute_type, RequestGattReadCallback callback) override; void RequestGattWrite(mojom::BluetoothAddressPtr address, int32_t attribute_handle, int32_t offset, const std::vector<uint8_t>& value, + mojom::BluetoothGattDBAttributeType attribute_type, RequestGattWriteCallback callback) override; void OnGetSdpRecords(
diff --git a/components/arc/usb/usb_host_ui_delegate.h b/components/arc/usb/usb_host_ui_delegate.h index 3e9b58f..a010ac58 100644 --- a/components/arc/usb/usb_host_ui_delegate.h +++ b/components/arc/usb/usb_host_ui_delegate.h
@@ -39,7 +39,22 @@ const std::string& guid, const base::string16& serial_number, uint16_t vendor_id, - uint16_t product_id) = 0; + uint16_t product_id) const = 0; + + // Temporarily grants package access permission to USB device. This is called + // when Android launches default package for the USB device. Permission + // granted through this method should never persist. + virtual void GrantUsbAccessPermission(const std::string& package_name, + const std::string& guid, + uint16_t vendor_id, + uint16_t product_id) = 0; + + // Gets list of packages which should receive USB device attach/detach event. + virtual std::unordered_set<std::string> GetEventPackageList( + const std::string& guid, + const base::string16& serial_number, + uint16_t vendor_id, + uint16_t product_id) const = 0; // Device is detached. Remove pending permission request to the device and // ephemeral device permission if the device is not persistent.
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index f33a68ec..d58b36c 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -453,9 +453,6 @@ void AutofillAgent::FieldTypePredictionsAvailable( const std::vector<FormDataPredictions>& forms) { - if (element_.IsNull()) - return; - bool attach_predictions_to_dom = base::FeatureList::IsEnabled(features::kAutofillShowTypePredictions); for (const auto& form : forms) {
diff --git a/components/cast_channel/BUILD.gn b/components/cast_channel/BUILD.gn index 26296a3..a73ef8f0 100644 --- a/components/cast_channel/BUILD.gn +++ b/components/cast_channel/BUILD.gn
@@ -10,8 +10,6 @@ "cast_auth_util.h", "cast_channel_enum.cc", "cast_channel_enum.h", - "cast_channel_util.cc", - "cast_channel_util.h", "cast_framer.cc", "cast_framer.h", "cast_message_handler.cc", @@ -35,6 +33,7 @@ "//components/cast_channel/proto:cast_channel_proto", "//components/keyed_service/content", "//components/keyed_service/core", + "//components/prefs", "//components/version_info", "//content/public/browser", "//content/public/common", @@ -64,7 +63,6 @@ testonly = true sources = [ "cast_auth_util_unittest.cc", - "cast_channel_util_unittest.cc", "cast_framer_unittest.cc", "cast_message_handler_unittest.cc", "cast_socket_service_unittest.cc", @@ -81,6 +79,8 @@ "//components/cast_certificate:test_support", "//components/cast_certificate/proto:unittest_proto", "//components/cast_channel/proto:cast_channel_proto", + "//components/prefs", + "//components/prefs:test_support", "//content/test:test_support", "//net:test_support", "//testing/gmock",
diff --git a/components/cast_channel/cast_channel_util.cc b/components/cast_channel/cast_channel_util.cc deleted file mode 100644 index 532ebe6..0000000 --- a/components/cast_channel/cast_channel_util.cc +++ /dev/null
@@ -1,25 +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 "components/cast_channel/cast_channel_util.h" - -namespace cast_channel { - -const base::Feature kCastAllowAllIPsFeature{"CastAllowAllIPs", - base::FEATURE_DISABLED_BY_DEFAULT}; - -bool IsValidCastIPAddress(const net::IPAddress& ip_address) { - // A valid Cast IP address must be private unless all IP addresses are - // explicitly allowed. - return ip_address.IsReserved() || - base::FeatureList::IsEnabled(kCastAllowAllIPsFeature); -} - -bool IsValidCastIPAddressString(const std::string& ip_address_string) { - net::IPAddress ip_address; - return ip_address.AssignFromIPLiteral(ip_address_string) && - IsValidCastIPAddress(ip_address); -} - -} // namespace cast_channel
diff --git a/components/cast_channel/cast_channel_util.h b/components/cast_channel/cast_channel_util.h deleted file mode 100644 index df4ca07..0000000 --- a/components/cast_channel/cast_channel_util.h +++ /dev/null
@@ -1,26 +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 COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_UTIL_H_ -#define COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_UTIL_H_ - -#include "base/feature_list.h" -#include "net/base/ip_address.h" - -namespace cast_channel { - -// If enabled, allows Media Router to connect to Cast devices on all IP -// addresses, not just RFC1918/RFC4913 private addresses. Workaround for -// https://crbug.com/813974. -extern const base::Feature kCastAllowAllIPsFeature; - -// Returns true if |ip_address| represents a valid IP address of a Cast device. -bool IsValidCastIPAddress(const net::IPAddress& ip_address); - -// Similar to above, but takes a std::string as input. -bool IsValidCastIPAddressString(const std::string& ip_address_string); - -} // namespace cast_channel - -#endif // COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_UTIL_H_
diff --git a/components/cast_channel/cast_channel_util_unittest.cc b/components/cast_channel/cast_channel_util_unittest.cc deleted file mode 100644 index badceae..0000000 --- a/components/cast_channel/cast_channel_util_unittest.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2018 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/cast_channel/cast_channel_util.h" - -#include "base/test/scoped_feature_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cast_channel { - -TEST(CastChannelUtilTest, IsValidCastIPAddress) { - std::string private_ip_address_string = "192.168.0.1"; - net::IPAddress private_ip_address; - ASSERT_TRUE( - private_ip_address.AssignFromIPLiteral(private_ip_address_string)); - EXPECT_TRUE(IsValidCastIPAddress(private_ip_address)); - EXPECT_TRUE(IsValidCastIPAddressString(private_ip_address_string)); - - std::string public_ip_address_string = "133.1.2.3"; - net::IPAddress public_ip_address; - ASSERT_TRUE(public_ip_address.AssignFromIPLiteral(public_ip_address_string)); - EXPECT_FALSE(IsValidCastIPAddress(public_ip_address)); - EXPECT_FALSE(IsValidCastIPAddressString(public_ip_address_string)); - - EXPECT_FALSE(IsValidCastIPAddressString("not a valid ip address")); -} - -TEST(CastChannelUtilTest, IsValidCastIPAddressAllowAllIPs) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kCastAllowAllIPsFeature); - - std::string private_ip_address_string = "192.168.0.1"; - net::IPAddress private_ip_address; - ASSERT_TRUE( - private_ip_address.AssignFromIPLiteral(private_ip_address_string)); - EXPECT_TRUE(IsValidCastIPAddress(private_ip_address)); - EXPECT_TRUE(IsValidCastIPAddressString(private_ip_address_string)); - - std::string public_ip_address_string = "133.1.2.3"; - net::IPAddress public_ip_address; - ASSERT_TRUE(public_ip_address.AssignFromIPLiteral(public_ip_address_string)); - EXPECT_TRUE(IsValidCastIPAddress(public_ip_address)); - EXPECT_TRUE(IsValidCastIPAddressString(public_ip_address_string)); - - EXPECT_FALSE(IsValidCastIPAddressString("not a valid ip address")); -} - -} // namespace cast_channel
diff --git a/components/cast_channel/cast_framer.cc b/components/cast_channel/cast_framer.cc index 9b5d6fe5..b2830b9 100644 --- a/components/cast_channel/cast_framer.cc +++ b/components/cast_channel/cast_framer.cc
@@ -58,8 +58,13 @@ } // static +size_t MessageFramer::MessageHeader::max_body_size() { + return 65536; +} + +// static size_t MessageFramer::MessageHeader::max_message_size() { - return 65535; + return header_size() + max_body_size(); } std::string MessageFramer::MessageHeader::ToString() { @@ -73,7 +78,7 @@ DCHECK(message_data); message_proto.SerializeToString(message_data); size_t message_size = message_data->size(); - if (message_size > MessageHeader::max_message_size()) { + if (message_size > MessageHeader::max_body_size()) { message_data->clear(); return false; } @@ -98,8 +103,7 @@ case BODY: bytes_left = (body_size_ + MessageHeader::header_size()) - message_bytes_received_; - DCHECK_LE(bytes_left, MessageHeader::max_message_size() - - MessageHeader::header_size()); + DCHECK_LE(bytes_left, MessageHeader::max_body_size()); VLOG(2) << "Bytes needed for body: " << bytes_left; return bytes_left; default: @@ -129,7 +133,7 @@ if (BytesRequested() == 0) { MessageHeader header; MessageHeader::Deserialize(input_buffer_->StartOfBuffer(), &header); - if (header.message_size > MessageHeader::max_message_size()) { + if (header.message_size > MessageHeader::max_body_size()) { VLOG(1) << "Error parsing header (message size too large)."; *error = ChannelError::INVALID_MESSAGE; error_ = true;
diff --git a/components/cast_channel/cast_framer.h b/components/cast_channel/cast_framer.h index 657f2ad..6352bf0 100644 --- a/components/cast_channel/cast_framer.h +++ b/components/cast_channel/cast_framer.h
@@ -67,6 +67,8 @@ static size_t header_size(); // Maximum size (in bytes) of a message payload on the wire (does not // include header). + static size_t max_body_size(); + // Maximum size (in bytes) of a message (header + payload) on the wire. static size_t max_message_size(); std::string ToString(); // The size of the following protocol message in bytes, in host byte order.
diff --git a/components/cast_channel/cast_framer_unittest.cc b/components/cast_channel/cast_framer_unittest.cc index 660e074..58ae1061 100644 --- a/components/cast_channel/cast_framer_unittest.cc +++ b/components/cast_channel/cast_framer_unittest.cc
@@ -81,7 +81,7 @@ CastMessage big_message; big_message.CopyFrom(cast_message_); std::string payload; - payload.append(MessageFramer::MessageHeader::max_message_size() + 1, 'x'); + payload.append(MessageFramer::MessageHeader::max_body_size() + 1, 'x'); big_message.set_payload_utf8(payload); EXPECT_FALSE(MessageFramer::Serialize(big_message, &serialized)); } @@ -109,6 +109,30 @@ EXPECT_EQ(0u, framer_->BytesRequested()); } +TEST_F(CastFramerTest, TestIngestIllegalLargeMessage2) { + std::string mangled_cast_message = cast_message_str_; + // Header indicates body size is 0x00010001 = 65537 + mangled_cast_message[0] = 0; + mangled_cast_message[1] = 0x1; + mangled_cast_message[2] = 0; + mangled_cast_message[3] = 0x1; + WriteToBuffer(mangled_cast_message); + + size_t bytes_ingested; + ChannelError error; + EXPECT_EQ(4u, framer_->BytesRequested()); + EXPECT_EQ(nullptr, framer_->Ingest(4, &bytes_ingested, &error).get()); + EXPECT_EQ(ChannelError::INVALID_MESSAGE, error); + EXPECT_EQ(0u, framer_->BytesRequested()); + + // Test that the parser enters a terminal error state. + WriteToBuffer(cast_message_str_); + EXPECT_EQ(0u, framer_->BytesRequested()); + EXPECT_EQ(nullptr, framer_->Ingest(4, &bytes_ingested, &error).get()); + EXPECT_EQ(ChannelError::INVALID_MESSAGE, error); + EXPECT_EQ(0u, framer_->BytesRequested()); +} + TEST_F(CastFramerTest, TestUnparsableBodyProto) { // Message header is OK, but the body is replaced with "x"en. std::string mangled_cast_message = cast_message_str_;
diff --git a/components/cast_channel/cast_socket_service.cc b/components/cast_channel/cast_socket_service.cc index c85e487..a95ddf3 100644 --- a/components/cast_channel/cast_socket_service.cc +++ b/components/cast_channel/cast_socket_service.cc
@@ -6,7 +6,6 @@ #include "base/memory/ptr_util.h" #include "base/task_scheduler/post_task.h" -#include "components/cast_channel/cast_channel_util.h" #include "components/cast_channel/cast_socket.h" #include "components/cast_channel/logger.h" #include "content/public/browser/browser_thread.h" @@ -87,8 +86,6 @@ DCHECK(task_runner_->BelongsToCurrentThread()); const net::IPEndPoint& ip_endpoint = open_params.ip_endpoint; - CHECK(IsValidCastIPAddress(ip_endpoint.address())); - auto* socket = GetSocket(ip_endpoint); if (!socket) { // If cast socket does not exist.
diff --git a/components/certificate_transparency/BUILD.gn b/components/certificate_transparency/BUILD.gn index 3be4734..a2dae9e 100644 --- a/components/certificate_transparency/BUILD.gn +++ b/components/certificate_transparency/BUILD.gn
@@ -14,6 +14,10 @@ "pref_names.h", "single_tree_tracker.cc", "single_tree_tracker.h", + "sth_distributor.cc", + "sth_distributor.h", + "sth_observer.h", + "sth_reporter.h", "tree_state_tracker.cc", "tree_state_tracker.h", ] @@ -37,6 +41,7 @@ "mock_log_dns_traffic.cc", "mock_log_dns_traffic.h", "single_tree_tracker_unittest.cc", + "sth_distributor_unittest.cc", "tree_state_tracker_unittest.cc", ] deps = [
diff --git a/components/certificate_transparency/single_tree_tracker.h b/components/certificate_transparency/single_tree_tracker.h index b80fe5f..be36b27 100644 --- a/components/certificate_transparency/single_tree_tracker.h +++ b/components/certificate_transparency/single_tree_tracker.h
@@ -13,11 +13,11 @@ #include "base/memory/memory_pressure_monitor.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "components/certificate_transparency/sth_observer.h" #include "net/base/hash_value.h" #include "net/base/network_change_notifier.h" #include "net/cert/ct_verifier.h" #include "net/cert/signed_tree_head.h" -#include "net/cert/sth_observer.h" #include "net/log/net_log_with_source.h" namespace net { @@ -87,11 +87,10 @@ // // To accomplish this, this class needs to be notified of when new SCTs are // observed (which it does by implementing net::CTVerifier::Observer) and when -// new STHs are observed (which it does by implementing net::ct::STHObserver). +// new STHs are observed (which it does by implementing STHObserver). // Once connected to sources providing that data, the status for a given SCT // can be queried by calling GetLogEntryInclusionCheck. -class SingleTreeTracker : public net::CTVerifier::Observer, - public net::ct::STHObserver { +class SingleTreeTracker : public net::CTVerifier::Observer, public STHObserver { public: enum SCTInclusionStatus { // SCT was not observed by this class and is not currently pending @@ -143,7 +142,7 @@ net::X509Certificate* cert, const net::ct::SignedCertificateTimestamp* sct) override; - // net::ct::STHObserver implementation. + // STHObserver implementation. // After verification of the signature over the |sth|, uses this // STH for future inclusion checks. // Must only be called for STHs issued by the log this instance tracks.
diff --git a/net/cert/sth_distributor.cc b/components/certificate_transparency/sth_distributor.cc similarity index 84% rename from net/cert/sth_distributor.cc rename to components/certificate_transparency/sth_distributor.cc index 3de77d90..3382095 100644 --- a/net/cert/sth_distributor.cc +++ b/components/certificate_transparency/sth_distributor.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 "net/cert/sth_distributor.h" +#include "components/certificate_transparency/sth_distributor.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" @@ -15,18 +15,16 @@ 0xe3, 0x77, 0xcd, 0x0e, 0xc8, 0x0d, 0xdc, 0x10}; } -namespace net { - -namespace ct { +namespace certificate_transparency { STHDistributor::STHDistributor() : observer_list_(base::ObserverListPolicy::EXISTING_ONLY) {} STHDistributor::~STHDistributor() = default; -void STHDistributor::NewSTHObserved(const SignedTreeHead& sth) { +void STHDistributor::NewSTHObserved(const net::ct::SignedTreeHead& sth) { auto it = std::find_if(observed_sths_.begin(), observed_sths_.end(), - [&sth](const SignedTreeHead& other) { + [&sth](const net::ct::SignedTreeHead& other) { return sth.log_id == other.log_id; }); @@ -54,7 +52,7 @@ // Make a local copy, because notifying the |observer| of a // new STH may result in this class being notified of a // (different) new STH, thus invalidating the iterator. - std::vector<SignedTreeHead> local_sths(observed_sths_); + std::vector<net::ct::SignedTreeHead> local_sths(observed_sths_); for (const auto& sth : local_sths) observer->NewSTHObserved(sth); @@ -64,6 +62,4 @@ observer_list_.RemoveObserver(observer); } -} // namespace ct - -} // namespace net +} // namespace certificate_transparency
diff --git a/net/cert/sth_distributor.h b/components/certificate_transparency/sth_distributor.h similarity index 68% rename from net/cert/sth_distributor.h rename to components/certificate_transparency/sth_distributor.h index 0462cd29..37711c1 100644 --- a/net/cert/sth_distributor.h +++ b/components/certificate_transparency/sth_distributor.h
@@ -2,34 +2,36 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_STH_DISTRIBUTOR_H_ -#define NET_CERT_STH_DISTRIBUTOR_H_ +#ifndef COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_DISTRIBUTOR_H_ +#define COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_DISTRIBUTOR_H_ #include <vector> #include "base/observer_list.h" +#include "components/certificate_transparency/sth_observer.h" +#include "components/certificate_transparency/sth_reporter.h" #include "net/base/net_export.h" -#include "net/cert/sth_observer.h" -#include "net/cert/sth_reporter.h" namespace net { - namespace ct { - struct SignedTreeHead; +} // namespace ct +} // namespace net + +namespace certificate_transparency { // A proxy for delegating new STH notifications to all registered // observers. // For each |observer| registered with RegisterObserver, the // NewSTHObserved method will be called whenever the STHDistributor's // NewSTHObserved method is invoked. -class NET_EXPORT STHDistributor : public STHObserver, public STHReporter { +class STHDistributor : public STHObserver, public STHReporter { public: STHDistributor(); ~STHDistributor() override; // STHObserver implementation. - void NewSTHObserved(const SignedTreeHead& sth) override; + void NewSTHObserved(const net::ct::SignedTreeHead& sth) override; // STHReporter implementation // Registers |observer| for new STH notifications. On registration, @@ -43,14 +45,12 @@ private: // STHs from logs, one for each log. - std::vector<SignedTreeHead> observed_sths_; + std::vector<net::ct::SignedTreeHead> observed_sths_; // The observers for new STH notifications. base::ObserverList<STHObserver, true> observer_list_; }; -} // namespace ct +} // namespace certificate_transparency -} // namespace net - -#endif // NET_CERT_STH_DISTRIBUTOR_H_ +#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_DISTRIBUTOR_H_
diff --git a/net/cert/sth_distributor_unittest.cc b/components/certificate_transparency/sth_distributor_unittest.cc similarity index 81% rename from net/cert/sth_distributor_unittest.cc rename to components/certificate_transparency/sth_distributor_unittest.cc index c57b61d7..6e59cf7 100644 --- a/net/cert/sth_distributor_unittest.cc +++ b/components/certificate_transparency/sth_distributor_unittest.cc
@@ -2,21 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/sth_distributor.h" +#include "components/certificate_transparency/sth_distributor.h" #include <map> #include <string> #include "base/test/histogram_tester.h" +#include "components/certificate_transparency/sth_observer.h" #include "crypto/sha2.h" #include "net/cert/signed_tree_head.h" -#include "net/cert/sth_observer.h" #include "net/test/ct_test_util.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { - -namespace ct { +namespace certificate_transparency { namespace { @@ -24,11 +22,11 @@ // observed STHs, keyed by log ID. class StoringSTHObserver : public STHObserver { public: - void NewSTHObserved(const SignedTreeHead& sth) override { + void NewSTHObserved(const net::ct::SignedTreeHead& sth) override { sths[sth.log_id] = sth; } - std::map<std::string, SignedTreeHead> sths; + std::map<std::string, net::ct::SignedTreeHead> sths; }; class STHDistributorTest : public ::testing::Test { @@ -37,12 +35,12 @@ void SetUp() override { ASSERT_TRUE(GetSampleSignedTreeHead(&sample_sth_)); - sample_sth_.log_id = GetTestPublicKeyId(); + sample_sth_.log_id = net::ct::GetTestPublicKeyId(); } protected: STHDistributor distributor_; - SignedTreeHead sample_sth_; + net::ct::SignedTreeHead sample_sth_; }; // Test that when a new observer is registered, the STHDistributor notifies it @@ -52,7 +50,7 @@ // Create an STH that differs from the |sample_sth_| by belonging to a // different log. const std::string other_log = "another log"; - SignedTreeHead second_sth(sample_sth_); + net::ct::SignedTreeHead second_sth(sample_sth_); second_sth.log_id = other_log; // Notify |distributor_| of both STHs. @@ -101,30 +99,30 @@ distributor_.NewSTHObserved(sample_sth_); EXPECT_EQ(1u, observer.sths.size()); - EXPECT_EQ(sample_sth_, observer.sths[GetTestPublicKeyId()]); + EXPECT_EQ(sample_sth_, observer.sths[net::ct::GetTestPublicKeyId()]); // Observe a new STH. "new" simply means that it is a more recently observed // SignedTreeHead for the given log ID, not necessarily that it's newer // chronologically (the timestamp) or the log state (the tree size). // To make sure the more recently observed SignedTreeHead is returned, just // modify some fields. - SignedTreeHead new_sth = sample_sth_; + net::ct::SignedTreeHead new_sth = sample_sth_; new_sth.tree_size++; new_sth.timestamp -= base::TimeDelta::FromSeconds(3); distributor_.NewSTHObserved(new_sth); // The STH should have been broadcast to existing observers. EXPECT_EQ(1u, observer.sths.size()); - EXPECT_NE(sample_sth_, observer.sths[GetTestPublicKeyId()]); - EXPECT_EQ(new_sth, observer.sths[GetTestPublicKeyId()]); + EXPECT_NE(sample_sth_, observer.sths[net::ct::GetTestPublicKeyId()]); + EXPECT_EQ(new_sth, observer.sths[net::ct::GetTestPublicKeyId()]); // Registering a new observer should only receive the most recently observed // STH. StoringSTHObserver new_observer; distributor_.RegisterObserver(&new_observer); EXPECT_EQ(1u, new_observer.sths.size()); - EXPECT_NE(sample_sth_, new_observer.sths[GetTestPublicKeyId()]); - EXPECT_EQ(new_sth, new_observer.sths[GetTestPublicKeyId()]); + EXPECT_NE(sample_sth_, new_observer.sths[net::ct::GetTestPublicKeyId()]); + EXPECT_EQ(new_sth, new_observer.sths[net::ct::GetTestPublicKeyId()]); distributor_.UnregisterObserver(&new_observer); distributor_.UnregisterObserver(&observer); @@ -132,6 +130,4 @@ } // namespace -} // namespace ct - -} // namespace net +} // namespace certificate_transparency
diff --git a/components/certificate_transparency/sth_observer.h b/components/certificate_transparency/sth_observer.h new file mode 100644 index 0000000..62742ea5 --- /dev/null +++ b/components/certificate_transparency/sth_observer.h
@@ -0,0 +1,29 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_OBSERVER_H_ +#define COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_OBSERVER_H_ + +#include <set> + +namespace net { +namespace ct { +struct SignedTreeHead; +} // namespace ct +} // namespace net + +namespace certificate_transparency { + +// Interface for receiving notifications of new STHs observed. +class STHObserver { + public: + virtual ~STHObserver() {} + + // Called with a new |sth| when one is observed. + virtual void NewSTHObserved(const net::ct::SignedTreeHead& sth) = 0; +}; + +} // namespace certificate_transparency + +#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_OBSERVER_H_
diff --git a/components/certificate_transparency/sth_reporter.h b/components/certificate_transparency/sth_reporter.h new file mode 100644 index 0000000..c4eea96 --- /dev/null +++ b/components/certificate_transparency/sth_reporter.h
@@ -0,0 +1,25 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_REPORTER_H_ +#define COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_REPORTER_H_ + +#include <set> + +namespace certificate_transparency { + +class STHObserver; + +// Interface for registering/unregistering observers. +class STHReporter { + public: + virtual ~STHReporter() {} + + virtual void RegisterObserver(STHObserver* observer) = 0; + virtual void UnregisterObserver(STHObserver* observer) = 0; +}; + +} // namespace certificate_transparency + +#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_STH_REPORTER_H_
diff --git a/components/certificate_transparency/tree_state_tracker.h b/components/certificate_transparency/tree_state_tracker.h index 606efbef..90dc795 100644 --- a/components/certificate_transparency/tree_state_tracker.h +++ b/components/certificate_transparency/tree_state_tracker.h
@@ -11,8 +11,8 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "components/certificate_transparency/sth_observer.h" #include "net/cert/ct_verifier.h" -#include "net/cert/sth_observer.h" namespace net { class NetLog; @@ -37,8 +37,7 @@ // TODO(eranm): Export the inclusion check status of SCTs+Certs so it can // be used in the DevTools Security panel, for example. See // https://crbug.com/506227#c22. -class TreeStateTracker : public net::CTVerifier::Observer, - public net::ct::STHObserver { +class TreeStateTracker : public net::CTVerifier::Observer, public STHObserver { public: // Tracks the state of the logs provided in |ct_logs|. An instance of this // class only tracks the logs provided in the constructor. The implementation @@ -56,7 +55,7 @@ net::X509Certificate* cert, const net::ct::SignedCertificateTimestamp* sct) override; - // net::ct::STHObserver implementation. + // STHObserver implementation. // Delegates to the tree tracker corresponding to the log that issued the STH. void NewSTHObserved(const net::ct::SignedTreeHead& sth) override;
diff --git a/components/consent_auditor/consent_auditor.cc b/components/consent_auditor/consent_auditor.cc index 1165f2ff..1ee9f02d 100644 --- a/components/consent_auditor/consent_auditor.cc +++ b/components/consent_auditor/consent_auditor.cc
@@ -103,13 +103,16 @@ break; } + // TODO(msramek): Pass in the actual account id. std::unique_ptr<sync_pb::UserEventSpecifics> specifics = ConstructUserConsent( - feature, description_grd_ids, confirmation_grd_id, status); + /* account_id = */ std::string(), feature, description_grd_ids, + confirmation_grd_id, status); user_event_service_->RecordUserEvent(std::move(specifics)); } std::unique_ptr<sync_pb::UserEventSpecifics> ConsentAuditor::ConstructUserConsent( + const std::string& account_id, Feature feature, const std::vector<int>& description_grd_ids, int confirmation_grd_id, @@ -118,6 +121,7 @@ specifics->set_event_time_usec( base::Time::Now().since_origin().InMicroseconds()); auto* consent = specifics->mutable_user_consent(); + consent->set_account_id(account_id); consent->set_feature(FeatureToProtoEnum(feature)); for (int id : description_grd_ids) { consent->add_description_grd_ids(id);
diff --git a/components/consent_auditor/consent_auditor.h b/components/consent_auditor/consent_auditor.h index 723c2ce7..f3b86a2 100644 --- a/components/consent_auditor/consent_auditor.h +++ b/components/consent_auditor/consent_auditor.h
@@ -82,6 +82,7 @@ private: std::unique_ptr<sync_pb::UserEventSpecifics> ConstructUserConsent( + const std::string& account_id, Feature feature, const std::vector<int>& description_grd_ids, int confirmation_grd_id,
diff --git a/components/consent_auditor/consent_auditor_unittest.cc b/components/consent_auditor/consent_auditor_unittest.cc index 845cb18..ceedb0c 100644 --- a/components/consent_auditor/consent_auditor_unittest.cc +++ b/components/consent_auditor/consent_auditor_unittest.cc
@@ -191,6 +191,9 @@ EXPECT_FALSE(events[0].has_navigation_id()); EXPECT_TRUE(events[0].has_user_consent()); auto& consent = events[0].user_consent(); + // TODO(crbug.com/781765): The |account_id| is not passed into + // ConsentAuditor yet. + EXPECT_EQ("", consent.account_id()); EXPECT_EQ(UserEventSpecifics::UserConsent::CHROME_SYNC, consent.feature()); EXPECT_EQ(3, consent.description_grd_ids_size()); EXPECT_EQ(kDescriptionMessageIds[0], consent.description_grd_ids(0));
diff --git a/components/content_settings/core/browser/cookie_settings.cc b/components/content_settings/core/browser/cookie_settings.cc index 6ee6053d..91415c6f 100644 --- a/components/content_settings/core/browser/cookie_settings.cc +++ b/components/content_settings/core/browser/cookie_settings.cc
@@ -16,6 +16,7 @@ #include "extensions/buildflags/buildflags.h" #include "net/base/net_errors.h" #include "net/base/static_cookie_policy.h" +#include "net/cookies/cookie_util.h" #include "url/gurl.h" namespace { @@ -32,12 +33,6 @@ setting == CONTENT_SETTING_SESSION_ONLY); } -GURL ToHttps(GURL url) { - GURL::Replacements replace_scheme; - replace_scheme.SetSchemeStr(url::kHttpsScheme); - return url.ReplaceComponents(replace_scheme); -} - } // namespace namespace content_settings { @@ -77,18 +72,29 @@ return (setting == CONTENT_SETTING_SESSION_ONLY); } -bool CookieSettings::ShouldDeleteCookieOnExit(const GURL& origin) const { +bool CookieSettings::ShouldDeleteCookieOnExit( + const ContentSettingsForOneType& cookie_settings, + const std::string& domain, + bool is_https) const { + GURL origin = net::cookie_util::CookieOriginToURL(domain, is_https); ContentSetting setting; GetCookieSetting(origin, origin, nullptr, &setting); DCHECK(IsValidSetting(setting)); - - if (setting == CONTENT_SETTING_BLOCK && origin.SchemeIs(url::kHttpScheme)) { - // Keep blocked, non-secure cookies if the secure origin is set to ALLOW. - GURL https_origin = ToHttps(origin); - return ShouldDeleteCookieOnExit(https_origin); + if (setting == CONTENT_SETTING_ALLOW) + return false; + // Check if there is a more precise rule that "domain matches" this cookie. + bool matches_session_only_rule = false; + for (const auto& entry : cookie_settings) { + const std::string& host = entry.primary_pattern.GetHost(); + if (net::cookie_util::IsDomainMatch(domain, host)) { + if (entry.GetContentSetting() == CONTENT_SETTING_ALLOW) { + return false; + } else if (entry.GetContentSetting() == CONTENT_SETTING_SESSION_ONLY) { + matches_session_only_rule = true; + } + } } - return (setting == CONTENT_SETTING_SESSION_ONLY) || - (setting == CONTENT_SETTING_BLOCK); + return setting == CONTENT_SETTING_SESSION_ONLY || matches_session_only_rule; } void CookieSettings::GetCookieSettings(
diff --git a/components/content_settings/core/browser/cookie_settings.h b/components/content_settings/core/browser/cookie_settings.h index 7a15d8d..11b6768 100644 --- a/components/content_settings/core/browser/cookie_settings.h +++ b/components/content_settings/core/browser/cookie_settings.h
@@ -59,14 +59,19 @@ // This may be called on any thread. bool IsCookieSessionOnly(const GURL& url) const; - // Returns true if the cookie set by a page identified by |url| should be - // session only or blocked. - // If an http |url| is BLOCKED, but the https version of |url| is ALLOWED, - // the cookie will not be deleted to allow blocking http cookie without - // affecting cookies from https sites that are not marked as "Secure". + // Returns true if the cookie associated with |domain| should be deleted + // on exit. + // This uses domain matching as described in section 5.1.3 of RFC 6265 to + // identify content setting rules that could have influenced the cookie + // when it was created. + // As |cookie_settings| can be expensive to create, it should be cached if + // multiple calls to ShouldDeleteCookieOnExit() are made. // // This may be called on any thread. - bool ShouldDeleteCookieOnExit(const GURL& url) const; + bool ShouldDeleteCookieOnExit( + const ContentSettingsForOneType& cookie_settings, + const std::string& domain, + bool is_https) const; // Returns all patterns with a non-default cookie setting, mapped to their // actual settings, in the precedence order of the setting rules. |settings|
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc index 87f8fbe04..d77ed58 100644 --- a/components/content_settings/core/browser/cookie_settings_unittest.cc +++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -25,8 +25,13 @@ kFirstPartySite("http://cool.things.com"), kChromeURL("chrome://foo"), kExtensionURL("chrome-extension://deadbeef"), + kDomain("example.com"), + kDotDomain(".example.com"), + kSubDomain("www.example.com"), kHttpSite("http://example.com"), kHttpsSite("https://example.com"), + kHttpsSubdomainSite("https://www.example.com"), + kHttpsSite8080("https://example.com:8080"), kAllHttpsSitesPattern(ContentSettingsPattern::FromString("https://*")) { CookieSettings::RegisterProfilePrefs(prefs_.registry()); HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry()); @@ -40,6 +45,13 @@ ~CookieSettingsTest() override { settings_map_->ShutdownOnUIThread(); } protected: + bool ShouldDeleteCookieOnExit(const std::string& domain, bool is_https) { + ContentSettingsForOneType settings; + cookie_settings_->GetCookieSettings(&settings); + return cookie_settings_->ShouldDeleteCookieOnExit(settings, domain, + is_https); + } + // There must be a valid ThreadTaskRunnerHandle in HostContentSettingsMap's // scope. base::MessageLoop message_loop_; @@ -52,8 +64,13 @@ const GURL kFirstPartySite; const GURL kChromeURL; const GURL kExtensionURL; + const std::string kDomain; + const std::string kDotDomain; + const std::string kSubDomain; const GURL kHttpSite; const GURL kHttpsSite; + const GURL kHttpsSubdomainSite; + const GURL kHttpsSite8080; ContentSettingsPattern kAllHttpsSitesPattern; }; @@ -113,27 +130,105 @@ EXPECT_TRUE(cookie_settings_->IsCookieSessionOnly(kBlockedSite)); } -TEST_F(CookieSettingsTest, CookiesDeleteSessionOnlyAndBlocked) { - // Delete blocked cookies. - cookie_settings_->SetCookieSetting(kBlockedSite, CONTENT_SETTING_BLOCK); - EXPECT_FALSE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpSite)); - EXPECT_TRUE(cookie_settings_->ShouldDeleteCookieOnExit(kBlockedSite)); +TEST_F(CookieSettingsTest, KeepBlocked) { + // Keep blocked cookies. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_ALLOW); + cookie_settings_->SetCookieSetting(kHttpsSite, CONTENT_SETTING_BLOCK); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, true)); +} - // Delete session_only cookies. - cookie_settings_->SetCookieSetting(kHttpSite, CONTENT_SETTING_SESSION_ONLY); +TEST_F(CookieSettingsTest, DeleteSessionOnly) { + // Keep session_only http cookies if https is allowed. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY); cookie_settings_->SetCookieSetting(kHttpsSite, CONTENT_SETTING_ALLOW); - EXPECT_TRUE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpSite)); - EXPECT_FALSE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpsSite)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, true)); - // Keep blocked http cookies if https is allowed. - cookie_settings_->SetCookieSetting(kHttpSite, CONTENT_SETTING_BLOCK); - EXPECT_FALSE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpSite)); - EXPECT_FALSE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpsSite)); - - // Delete cookies if http is blocked and https session only. + // Delete cookies if site is session only. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); cookie_settings_->SetCookieSetting(kHttpsSite, CONTENT_SETTING_SESSION_ONLY); - EXPECT_TRUE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpSite)); - EXPECT_TRUE(cookie_settings_->ShouldDeleteCookieOnExit(kHttpsSite)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, true)); + + // Http blocked, https allowed - keep secure and non secure cookies. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY); + cookie_settings_->SetCookieSetting(kHttpSite, CONTENT_SETTING_BLOCK); + cookie_settings_->SetCookieSetting(kHttpsSite, CONTENT_SETTING_ALLOW); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, true)); + + // Http and https session only, all is deleted. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_ALLOW); + cookie_settings_->SetCookieSetting(kHttpSite, CONTENT_SETTING_SESSION_ONLY); + cookie_settings_->SetCookieSetting(kHttpsSite, CONTENT_SETTING_SESSION_ONLY); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, true)); +} + +TEST_F(CookieSettingsTest, DeletionWithDifferentPorts) { + // Keep cookies for site with special port. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY); + cookie_settings_->SetCookieSetting(kHttpsSite8080, CONTENT_SETTING_ALLOW); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, true)); + + // Delete cookies with special port. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + cookie_settings_->SetCookieSetting(kHttpsSite8080, + CONTENT_SETTING_SESSION_ONLY); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, true)); +} + +TEST_F(CookieSettingsTest, DeletionWithSubDomains) { + // Cookies accessible by subdomains are kept. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY); + cookie_settings_->SetCookieSetting(kHttpsSubdomainSite, + CONTENT_SETTING_ALLOW); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, true)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kSubDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kSubDomain, true)); + + // Cookies that have a session_only subdomain but are accessible by allowed + // domains are kept. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_ALLOW); + cookie_settings_->SetCookieSetting(kHttpsSubdomainSite, + CONTENT_SETTING_SESSION_ONLY); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDotDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kSubDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kSubDomain, true)); + + // Cookies created by session_only subdomains are deleted. + cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); + cookie_settings_->SetCookieSetting(kHttpsSubdomainSite, + CONTENT_SETTING_SESSION_ONLY); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kDotDomain, true)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, false)); + EXPECT_FALSE(ShouldDeleteCookieOnExit(kDomain, true)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kSubDomain, false)); + EXPECT_TRUE(ShouldDeleteCookieOnExit(kSubDomain, true)); } TEST_F(CookieSettingsTest, CookiesThirdPartyBlockedExplicitAllow) {
diff --git a/components/cronet/histogram_manager.cc b/components/cronet/histogram_manager.cc index 1f05f37..4ca3513 100644 --- a/components/cronet/histogram_manager.cc +++ b/components/cronet/histogram_manager.cc
@@ -49,7 +49,7 @@ &histogram_snapshot_manager_); int32_t data_size = uma_proto_.ByteSize(); data->resize(data_size); - if (uma_proto_.SerializeToArray(&(*data)[0], data_size)) + if (data_size == 0 || uma_proto_.SerializeToArray(data->data(), data_size)) return true; } data->clear();
diff --git a/components/cronet/native/cronet.idl b/components/cronet/native/cronet.idl index 99f0073..0a0c12f 100644 --- a/components/cronet/native/cronet.idl +++ b/components/cronet/native/cronet.idl
@@ -430,7 +430,7 @@ /** * The expiration date for the pins in milliseconds since epoch (as in java.util.Date). */ - int64 expiration_date; + int64 expiration_date = 0; }; /** @@ -577,7 +577,7 @@ * The HTTP status code. When a resource is retrieved from the cache, * whether it was revalidated or not, the original status code is returned. */ - int32 http_status_code; + int32 http_status_code = 0; /** * The HTTP status text of the status line. For example, if the @@ -596,7 +596,7 @@ * requests that were revalidated over the network before being retrieved * from the cache, failed otherwise. */ - bool was_cached; + bool was_cached = false; /** * The protocol (for example 'quic/1+spdy/3') negotiated with the server. @@ -617,7 +617,7 @@ * taken prior to decompression (for example GZIP and Brotli) and includes * headers and data from all redirects. */ - int64 received_byte_count; + int64 received_byte_count = 0; }; /** @@ -1087,12 +1087,12 @@ * Upload data provider. Setting this value switches method to "POST" if not * explicitly set. Starting the request will fail if a Content-Type header is not set. */ - UploadDataProvider upload_data_provider; + UploadDataProvider? upload_data_provider; /** * Upload data provider executor that will be used to invoke uploadDataProvider. */ - Executor upload_data_provider_executor; + Executor? upload_data_provider_executor; /** * Marks that the executors this request will use to notify callbacks (for
diff --git a/components/cronet/native/generated/cronet.idl_impl_struct.h b/components/cronet/native/generated/cronet.idl_impl_struct.h index e058ec2..24114b86 100644 --- a/components/cronet/native/generated/cronet.idl_impl_struct.h +++ b/components/cronet/native/generated/cronet.idl_impl_struct.h
@@ -60,7 +60,7 @@ std::string host; std::vector<std::string> pins_sha256; bool include_subdomains = false; - int64_t expiration_date; + int64_t expiration_date = 0; private: DISALLOW_ASSIGN(Cronet_PublicKeyPins); @@ -118,13 +118,13 @@ std::string url; std::vector<std::string> url_chain; - int32_t http_status_code; + int32_t http_status_code = 0; std::string http_status_text; std::vector<Cronet_HttpHeader> all_headers_list; - bool was_cached; + bool was_cached = false; std::string negotiated_protocol; std::string proxy_server; - int64_t received_byte_count; + int64_t received_byte_count = 0; private: DISALLOW_ASSIGN(Cronet_UrlResponseInfo); @@ -143,8 +143,8 @@ bool disable_cache = false; Cronet_UrlRequestParams_REQUEST_PRIORITY priority = Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_MEDIUM; - Cronet_UploadDataProviderPtr upload_data_provider; - Cronet_ExecutorPtr upload_data_provider_executor; + Cronet_UploadDataProviderPtr upload_data_provider = nullptr; + Cronet_ExecutorPtr upload_data_provider_executor = nullptr; bool allow_direct_executor = false; std::vector<Cronet_RawDataPtr> annotations;
diff --git a/components/cronet/native/test/buffer_test.cc b/components/cronet/native/test/buffer_test.cc index 6f774a6..66a5be21 100644 --- a/components/cronet/native/test/buffer_test.cc +++ b/components/cronet/native/test/buffer_test.cc
@@ -72,9 +72,11 @@ ASSERT_FALSE(on_destroy_called()); } -#if defined(ADDRESS_SANITIZER) || defined(OS_FUCHSIA) -// ASAN malloc by default triggers crash instead of returning null on failure. -// Fuchsia malloc() also crashes on allocation failure in some kernel builds. +#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ + defined(OS_FUCHSIA) +// ASAN and MSAN malloc by default triggers crash instead of returning null on +// failure. Fuchsia malloc() also crashes on allocation failure in some kernel +// builds. #define MAYBE_TestInitWithHugeAllocFails DISABLED_TestInitWithHugeAllocFails #else #define MAYBE_TestInitWithHugeAllocFails TestInitWithHugeAllocFails
diff --git a/components/cronet/tools/generators/c_templates/module_impl_struct.h.tmpl b/components/cronet/tools/generators/c_templates/module_impl_struct.h.tmpl index 1a27784..2e3ddd7a5 100644 --- a/components/cronet/tools/generators/c_templates/module_impl_struct.h.tmpl +++ b/components/cronet/tools/generators/c_templates/module_impl_struct.h.tmpl
@@ -42,10 +42,10 @@ std::vector<{{kind.kind|cpp_wrapper_type}}> {{packed_field.field.name}}; {%- else %} {{packed_field.field.kind|cpp_wrapper_type}} {{packed_field.field.name}} -{%- if packed_field.field.default %} = {{packed_field.field|default_value}} {%- endif %}; +{%- if packed_field.field.default %} = {{packed_field.field|default_value}} {%- endif %} +{%- if packed_field.field.kind|is_any_interface_kind %} = nullptr {%- endif %}; {%- endif %} {%- endfor %} - private: DISALLOW_ASSIGN({{struct_name}}); };
diff --git a/components/cryptauth/cryptauth_device_manager_impl.cc b/components/cryptauth/cryptauth_device_manager_impl.cc index 5888d3d..e8afb98 100644 --- a/components/cryptauth/cryptauth_device_manager_impl.cc +++ b/components/cryptauth/cryptauth_device_manager_impl.cc
@@ -341,6 +341,8 @@ factory_instance_ = factory; } +CryptAuthDeviceManagerImpl::Factory::~Factory() = default; + std::unique_ptr<CryptAuthDeviceManager> CryptAuthDeviceManagerImpl::Factory::BuildInstance( base::Clock* clock,
diff --git a/components/cryptauth/cryptauth_device_manager_impl.h b/components/cryptauth/cryptauth_device_manager_impl.h index 260a4d6..4d28d087 100644 --- a/components/cryptauth/cryptauth_device_manager_impl.h +++ b/components/cryptauth/cryptauth_device_manager_impl.h
@@ -38,6 +38,7 @@ static void SetInstanceForTesting(Factory* factory); protected: + virtual ~Factory(); virtual std::unique_ptr<CryptAuthDeviceManager> BuildInstance( base::Clock* clock, std::unique_ptr<CryptAuthClientFactory> client_factory,
diff --git a/components/cryptauth/cryptauth_enrollment_manager_impl.cc b/components/cryptauth/cryptauth_enrollment_manager_impl.cc index 8e6a55c..a956b13 100644 --- a/components/cryptauth/cryptauth_enrollment_manager_impl.cc +++ b/components/cryptauth/cryptauth_enrollment_manager_impl.cc
@@ -80,6 +80,8 @@ factory_instance_ = factory; } +CryptAuthEnrollmentManagerImpl::Factory::~Factory() = default; + std::unique_ptr<CryptAuthEnrollmentManager> CryptAuthEnrollmentManagerImpl::Factory::BuildInstance( base::Clock* clock,
diff --git a/components/cryptauth/cryptauth_enrollment_manager_impl.h b/components/cryptauth/cryptauth_enrollment_manager_impl.h index ce8b142..1b758c5d 100644 --- a/components/cryptauth/cryptauth_enrollment_manager_impl.h +++ b/components/cryptauth/cryptauth_enrollment_manager_impl.h
@@ -46,6 +46,7 @@ static void SetInstanceForTesting(Factory* factory); protected: + virtual ~Factory(); virtual std::unique_ptr<CryptAuthEnrollmentManager> BuildInstance( base::Clock* clock, std::unique_ptr<CryptAuthEnrollerFactory> enroller_factory,
diff --git a/components/cryptauth/cryptauth_gcm_manager_impl.cc b/components/cryptauth/cryptauth_gcm_manager_impl.cc index 813cefa..0de9655f 100644 --- a/components/cryptauth/cryptauth_gcm_manager_impl.cc +++ b/components/cryptauth/cryptauth_gcm_manager_impl.cc
@@ -50,6 +50,8 @@ factory_instance_ = factory; } +CryptAuthGCMManagerImpl::Factory::~Factory() = default; + std::unique_ptr<CryptAuthGCMManager> CryptAuthGCMManagerImpl::Factory::BuildInstance(gcm::GCMDriver* gcm_driver, PrefService* pref_service) {
diff --git a/components/cryptauth/cryptauth_gcm_manager_impl.h b/components/cryptauth/cryptauth_gcm_manager_impl.h index 1498356..7f07534 100644 --- a/components/cryptauth/cryptauth_gcm_manager_impl.h +++ b/components/cryptauth/cryptauth_gcm_manager_impl.h
@@ -34,6 +34,7 @@ static void SetInstanceForTesting(Factory* factory); protected: + virtual ~Factory(); virtual std::unique_ptr<CryptAuthGCMManager> BuildInstance( gcm::GCMDriver* gcm_driver, PrefService* pref_service);
diff --git a/components/cryptauth/remote_device_provider_impl.cc b/components/cryptauth/remote_device_provider_impl.cc index 6e1d805..967bb44 100644 --- a/components/cryptauth/remote_device_provider_impl.cc +++ b/components/cryptauth/remote_device_provider_impl.cc
@@ -34,6 +34,8 @@ factory_instance_ = factory; } +RemoteDeviceProviderImpl::Factory::~Factory() = default; + std::unique_ptr<RemoteDeviceProvider> RemoteDeviceProviderImpl::Factory::BuildInstance( CryptAuthDeviceManager* device_manager,
diff --git a/components/cryptauth/remote_device_provider_impl.h b/components/cryptauth/remote_device_provider_impl.h index 8a8a59d..bc32345 100644 --- a/components/cryptauth/remote_device_provider_impl.h +++ b/components/cryptauth/remote_device_provider_impl.h
@@ -26,6 +26,7 @@ static void SetInstanceForTesting(Factory* factory); protected: + virtual ~Factory(); virtual std::unique_ptr<RemoteDeviceProvider> BuildInstance( CryptAuthDeviceManager* device_manager, const std::string& user_id,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc index ed03440..cdaa80c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/test/histogram_tester.h" #include "base/test/scoped_task_environment.h" #include "base/time/default_clock.h" #include "base/values.h" @@ -177,6 +178,7 @@ } TEST_F(DataReductionProxyConfiguratorTest, TestSecureNonCoreRestricted) { + base::HistogramTester histogram_tester; manager_->SetHasWarmupURLProbeFailed(true, false, true); config_->Enable(*manager_, BuildProxyList("https://www.foo.com:443", ProxyServer::CORE, @@ -184,6 +186,11 @@ CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME, "HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT", std::string()); + + manager_->SetHasWarmupURLProbeFailed(true, false, false); + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.NonCore", + 0, 1); } TEST_F(DataReductionProxyConfiguratorTest, @@ -228,12 +235,32 @@ } TEST_F(DataReductionProxyConfiguratorTest, TestRestrictedQuic) { + base::HistogramTester histogram_tester; manager_->SetHasWarmupURLProbeFailed(true, true, true); config_->Enable(*manager_, BuildProxyList("quic://www.foo.com:443", ProxyServer::CORE, "http://www.bar.com:80", ProxyServer::CORE)); CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME, "PROXY www.bar.com:80;DIRECT", std::string()); + + manager_->SetHasWarmupURLProbeFailed(true, true, false); + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 0, + 1); + + manager_->OnWarmupFetchInitiated(true, true); + manager_->SetHasWarmupURLProbeFailed(true, true, false); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 1, + 1); + + manager_->OnWarmupFetchInitiated(true, true); + manager_->SetHasWarmupURLProbeFailed(true, true, false); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 2, + 1); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 3); } TEST_F(DataReductionProxyConfiguratorTest, TestDisable) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc index af9b115..7fcb621 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -125,8 +125,9 @@ // Add the current resource to these histograms only when the content length // is valid. if (original_content_length >= 0) { - UMA_HISTOGRAM_COUNTS_1M("Net.HttpOriginalContentLengthWithValidOCL", - original_content_length); + // This is only used locally in integration testing. + LOCAL_HISTOGRAM_COUNTS_1000000("Net.HttpOriginalContentLengthWithValidOCL", + original_content_length); UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLengthDifferenceWithValidOCL", original_content_length - received_content_length); } else {
diff --git a/components/data_reduction_proxy/core/browser/network_properties_manager.cc b/components/data_reduction_proxy/core/browser/network_properties_manager.cc index a217e23..bf30d9a 100644 --- a/components/data_reduction_proxy/core/browser/network_properties_manager.cc +++ b/components/data_reduction_proxy/core/browser/network_properties_manager.cc
@@ -360,18 +360,41 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (secure_proxy && is_core_proxy) { + if (!warmup_url_probe_failed) { + UMA_HISTOGRAM_EXACT_LINEAR( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", + warmup_url_fetch_attempt_counts_secure_core_, 10); + } has_warmup_url_succeded_secure_core_ = !warmup_url_probe_failed; network_properties_.mutable_secure_proxy_flags() ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed); } else if (secure_proxy && !is_core_proxy) { + if (!warmup_url_probe_failed) { + UMA_HISTOGRAM_EXACT_LINEAR( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure." + "NonCore", + warmup_url_fetch_attempt_counts_secure_non_core_, 10); + } has_warmup_url_succeded_secure_non_core_ = !warmup_url_probe_failed; network_properties_.mutable_secure_non_core_proxy_flags() ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed); } else if (!secure_proxy && is_core_proxy) { + if (!warmup_url_probe_failed) { + UMA_HISTOGRAM_EXACT_LINEAR( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Insecure." + "Core", + warmup_url_fetch_attempt_counts_insecure_core_, 10); + } has_warmup_url_succeded_insecure_core_ = !warmup_url_probe_failed; network_properties_.mutable_insecure_proxy_flags() ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed); } else { + if (!warmup_url_probe_failed) { + UMA_HISTOGRAM_EXACT_LINEAR( + "DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Insecure." + "NonCore", + warmup_url_fetch_attempt_counts_insecure_non_core_, 10); + } has_warmup_url_succeded_insecure_non_core_ = !warmup_url_probe_failed; network_properties_.mutable_insecure_non_core_proxy_flags() ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed);
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc index 28464c9..04268049 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -208,19 +208,39 @@ DCHECK_LE(0u, previous_attempt_counts_); DCHECK_GE(2u, previous_attempt_counts_); - // The timeout value should always be between kMinTimeout and kMaxTimeout + // The timeout value should always be between |min_timeout| and |max_timeout| // (both inclusive). - constexpr base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(8); - constexpr base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(60); + const base::TimeDelta min_timeout = + base::TimeDelta::FromSeconds(GetFieldTrialParamByFeatureAsInt( + features::kDataReductionProxyRobustConnection, + "warmup_url_fetch_min_timeout_seconds", 8)); + const base::TimeDelta max_timeout = + base::TimeDelta::FromSeconds(GetFieldTrialParamByFeatureAsInt( + features::kDataReductionProxyRobustConnection, + "warmup_url_fetch_max_timeout_seconds", 60)); + DCHECK_LT(base::TimeDelta::FromSeconds(0), min_timeout); + DCHECK_LT(base::TimeDelta::FromSeconds(0), max_timeout); + DCHECK_LE(min_timeout, max_timeout); // Set the timeout based on how many times the fetching of the warmup URL // has been tried. - size_t http_rtt_multiplier = 5; + size_t http_rtt_multiplier = GetFieldTrialParamByFeatureAsInt( + features::kDataReductionProxyRobustConnection, + "warmup_url_fetch_init_http_rtt_multiplier", 5); if (previous_attempt_counts_ == 1) { - http_rtt_multiplier = 10; + http_rtt_multiplier = GetFieldTrialParamByFeatureAsInt( + features::kDataReductionProxyRobustConnection, + "warmup_url_fetch_init_http_rtt_multiplier", 5) * + 2; } else if (previous_attempt_counts_ == 2) { - http_rtt_multiplier = 20; + http_rtt_multiplier = GetFieldTrialParamByFeatureAsInt( + features::kDataReductionProxyRobustConnection, + "warmup_url_fetch_init_http_rtt_multiplier", 5) * + 4; } + // Sanity checks. + DCHECK_LT(0u, http_rtt_multiplier); + DCHECK_GE(1000u, http_rtt_multiplier); const net::NetworkQualityEstimator* network_quality_estimator = url_request_context_getter_->GetURLRequestContext() @@ -229,14 +249,14 @@ base::Optional<base::TimeDelta> http_rtt_estimate = network_quality_estimator->GetHttpRTT(); if (!http_rtt_estimate) - return kMaxTimeout; + return max_timeout; base::TimeDelta timeout = http_rtt_multiplier * http_rtt_estimate.value(); - if (timeout > kMaxTimeout) - return kMaxTimeout; + if (timeout > max_timeout) + return max_timeout; - if (timeout < kMinTimeout) - return kMinTimeout; + if (timeout < min_timeout) + return min_timeout; return timeout; }
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc index daa46742..aa5e31c 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
@@ -58,6 +58,17 @@ features::kDataReductionProxyRobustConnection, params); } + static void InitExperimentWithTimeout( + base::test::ScopedFeatureList* scoped_feature_list) { + std::map<std::string, std::string> params; + params["warmup_fetch_callback_enabled"] = "true"; + params["warmup_url_fetch_min_timeout_seconds"] = "10"; + params["warmup_url_fetch_max_timeout_seconds"] = "60"; + params["warmup_url_fetch_init_http_rtt_multiplier"] = "12"; + scoped_feature_list->InitAndEnableFeatureWithParameters( + features::kDataReductionProxyRobustConnection, params); + } + base::TimeDelta GetFetchWaitTime() const override { if (!fetch_wait_time_) return WarmupURLFetcher::GetFetchWaitTime(); @@ -554,6 +565,51 @@ EXPECT_EQ(http_rtt * 5, warmup_url_fetcher.GetFetchTimeout()); } +TEST(WarmupURLFetcherTest, TestFetchTimeoutIncreasingWithFieldTrial) { + base::test::ScopedFeatureList scoped_feature_list; + WarmupURLFetcherTest::InitExperimentWithTimeout(&scoped_feature_list); + + // Must remain in sync with InitExperimentWithTimeout(). + constexpr base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(10); + constexpr base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(60); + + base::HistogramTester histogram_tester; + base::MessageLoopForIO message_loop; + + std::unique_ptr<net::TestURLRequestContext> test_request_context( + new net::TestURLRequestContext(true)); + + test_request_context->Init(); + scoped_refptr<net::URLRequestContextGetter> request_context_getter = + new net::TestURLRequestContextGetter(message_loop.task_runner(), + std::move(test_request_context)); + net::TestNetworkQualityEstimator estimator; + request_context_getter->GetURLRequestContext()->set_network_quality_estimator( + &estimator); + + WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); + + EXPECT_EQ(kMinTimeout, warmup_url_fetcher.GetFetchTimeout()); + + base::TimeDelta http_rtt = base::TimeDelta::FromSeconds(1); + estimator.SetStartTimeNullHttpRtt(http_rtt); + EXPECT_EQ(http_rtt * 12, warmup_url_fetcher.GetFetchTimeout()); + + warmup_url_fetcher.FetchWarmupURL(1); + EXPECT_EQ(http_rtt * 24, warmup_url_fetcher.GetFetchTimeout()); + + warmup_url_fetcher.FetchWarmupURL(2); + EXPECT_EQ(http_rtt * 48, warmup_url_fetcher.GetFetchTimeout()); + + http_rtt = base::TimeDelta::FromSeconds(5); + estimator.SetStartTimeNullHttpRtt(http_rtt); + EXPECT_EQ(kMaxTimeout, warmup_url_fetcher.GetFetchTimeout()); + + warmup_url_fetcher.FetchWarmupURL(0); + EXPECT_EQ(http_rtt * 12, warmup_url_fetcher.GetFetchTimeout()); +} + } // namespace } // namespace data_reduction_proxy
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn index c1f8f812..26e8622 100644 --- a/components/download/internal/common/BUILD.gn +++ b/components/download/internal/common/BUILD.gn
@@ -85,6 +85,7 @@ "base_file_unittest.cc", "base_file_win_unittest.cc", "download_file_unittest.cc", + "download_item_impl_unittest.cc", "download_stats_unittest.cc", "download_ukm_helper_unittest.cc", "parallel_download_job_unittest.cc",
diff --git a/content/browser/download/download_item_impl_unittest.cc b/components/download/internal/common/download_item_impl_unittest.cc similarity index 65% rename from content/browser/download/download_item_impl_unittest.cc rename to components/download/internal/common/download_item_impl_unittest.cc index eee3143..8515eb82 100644 --- a/content/browser/download/download_item_impl_unittest.cc +++ b/components/download/internal/common/download_item_impl_unittest.cc
@@ -17,7 +17,6 @@ #include "base/callback_helpers.h" #include "base/containers/circular_deque.h" #include "base/containers/queue.h" -#include "base/feature_list.h" #include "base/files/file_util.h" #include "base/memory/ptr_util.h" #include "base/test/histogram_tester.h" @@ -32,12 +31,6 @@ #include "components/download/public/common/download_url_parameters.h" #include "components/download/public/common/mock_download_file.h" #include "components/download/public/common/mock_download_item.h" -#include "content/browser/byte_stream.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/common/content_features.h" -#include "content/public/test/test_browser_context.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "crypto/secure_hash.h" #include "net/http/http_response_headers.h" #include "testing/gmock/include/gmock/gmock.h" @@ -62,7 +55,7 @@ const base::FilePath::CharType kDummyIntermediatePath[] = FILE_PATH_LITERAL("/testpathx"); -namespace content { +namespace download { namespace { @@ -71,37 +64,31 @@ return static_cast<base::HistogramBase::Sample>(t); } -class MockDelegate : public download::DownloadItemImplDelegate { +class MockDelegate : public DownloadItemImplDelegate { public: - MockDelegate() : download::DownloadItemImplDelegate() { - browser_context_.reset(new TestBrowserContext); - SetDefaultExpectations(); - } + MockDelegate() : DownloadItemImplDelegate() { SetDefaultExpectations(); } - MOCK_METHOD2( - DetermineDownloadTarget, - void(download::DownloadItemImpl*, - const download::DownloadItemImplDelegate::DownloadTargetCallback&)); + MOCK_METHOD2(DetermineDownloadTarget, + void(DownloadItemImpl*, + const DownloadItemImplDelegate::DownloadTargetCallback&)); MOCK_METHOD2(ShouldCompleteDownload, - bool(download::DownloadItemImpl*, const base::Closure&)); + bool(DownloadItemImpl*, const base::Closure&)); MOCK_METHOD2(ShouldOpenDownload, - bool(download::DownloadItemImpl*, - const ShouldOpenDownloadCallback&)); + bool(DownloadItemImpl*, const ShouldOpenDownloadCallback&)); MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&)); - MOCK_METHOD1(CheckForFileRemoval, void(download::DownloadItemImpl*)); + MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); - void ResumeInterruptedDownload( - std::unique_ptr<download::DownloadUrlParameters> params, - uint32_t id, - const GURL& site_url) override { + void ResumeInterruptedDownload(std::unique_ptr<DownloadUrlParameters> params, + uint32_t id, + const GURL& site_url) override { MockResumeInterruptedDownload(params.get(), id); } MOCK_METHOD2(MockResumeInterruptedDownload, - void(download::DownloadUrlParameters* params, uint32_t id)); + void(DownloadUrlParameters* params, uint32_t id)); - MOCK_METHOD1(DownloadOpened, void(download::DownloadItemImpl*)); - MOCK_METHOD1(DownloadRemoved, void(download::DownloadItemImpl*)); - MOCK_CONST_METHOD1(AssertStateConsistent, void(download::DownloadItemImpl*)); + MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); + MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); + MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); void VerifyAndClearExpectations() { ::testing::Mock::VerifyAndClearExpectations(this); @@ -110,27 +97,23 @@ private: void SetDefaultExpectations() { - EXPECT_CALL(*this, AssertStateConsistent(_)) - .WillRepeatedly(Return()); + EXPECT_CALL(*this, AssertStateConsistent(_)).WillRepeatedly(Return()); EXPECT_CALL(*this, ShouldOpenFileBasedOnExtension(_)) .WillRepeatedly(Return(false)); - EXPECT_CALL(*this, ShouldOpenDownload(_, _)) - .WillRepeatedly(Return(true)); + EXPECT_CALL(*this, ShouldOpenDownload(_, _)).WillRepeatedly(Return(true)); } - - std::unique_ptr<TestBrowserContext> browser_context_; }; -class MockRequestHandle : public download::DownloadRequestHandleInterface { +class MockRequestHandle : public DownloadRequestHandleInterface { public: MOCK_METHOD0(PauseRequest, void()); MOCK_METHOD0(ResumeRequest, void()); MOCK_METHOD1(CancelRequest, void(bool)); }; -class TestDownloadItemObserver : public download::DownloadItem::Observer { +class TestDownloadItemObserver : public DownloadItem::Observer { public: - explicit TestDownloadItemObserver(download::DownloadItem* item) + explicit TestDownloadItemObserver(DownloadItem* item) : item_(item), last_state_(item->GetState()), removed_(false), @@ -158,34 +141,34 @@ } private: - void OnDownloadRemoved(download::DownloadItem* download) override { + void OnDownloadRemoved(DownloadItem* download) override { SCOPED_TRACE(::testing::Message() << " " << __FUNCTION__ << " download = " << download->DebugString(false)); removed_ = true; } - void OnDownloadUpdated(download::DownloadItem* download) override { + void OnDownloadUpdated(DownloadItem* download) override { DVLOG(20) << " " << __FUNCTION__ << " download = " << download->DebugString(false); updated_ = true; - download::DownloadItem::DownloadState new_state = download->GetState(); - if (last_state_ == download::DownloadItem::IN_PROGRESS && - new_state == download::DownloadItem::INTERRUPTED) { + DownloadItem::DownloadState new_state = download->GetState(); + if (last_state_ == DownloadItem::IN_PROGRESS && + new_state == DownloadItem::INTERRUPTED) { interrupt_count_++; } - if (last_state_ == download::DownloadItem::INTERRUPTED && - new_state == download::DownloadItem::IN_PROGRESS) { + if (last_state_ == DownloadItem::INTERRUPTED && + new_state == DownloadItem::IN_PROGRESS) { resume_count_++; } last_state_ = new_state; } - void OnDownloadOpened(download::DownloadItem* download) override { + void OnDownloadOpened(DownloadItem* download) override { DVLOG(20) << " " << __FUNCTION__ << " download = " << download->DebugString(false); } - void OnDownloadDestroyed(download::DownloadItem* download) override { + void OnDownloadDestroyed(DownloadItem* download) override { DVLOG(20) << " " << __FUNCTION__ << " download = " << download->DebugString(false); destroyed_ = true; @@ -193,8 +176,8 @@ item_ = nullptr; } - download::DownloadItem* item_; - download::DownloadItem::DownloadState last_state_; + DownloadItem* item_; + DownloadItem::DownloadState last_state_; bool removed_; bool destroyed_; bool updated_; @@ -203,25 +186,31 @@ }; // Schedules a task to invoke the RenameCompletionCallback with |new_path| on -// the UI thread. Should only be used as the action for +// the |task_runner|. Should only be used as the action for // MockDownloadFile::RenameAndUniquify as follows: // EXPECT_CALL(download_file, RenameAndUniquify(_,_)) // .WillOnce(ScheduleRenameAndUniquifyCallback( -// download::DOWNLOAD_INTERRUPT_REASON_NONE, new_path)); -ACTION_P2(ScheduleRenameAndUniquifyCallback, interrupt_reason, new_path) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(arg1, interrupt_reason, new_path)); +// DOWNLOAD_INTERRUPT_REASON_NONE, new_path, task_runner)); +ACTION_P3(ScheduleRenameAndUniquifyCallback, + interrupt_reason, + new_path, + task_runner) { + task_runner->PostTask(FROM_HERE, + base::BindOnce(arg1, interrupt_reason, new_path)); } // Schedules a task to invoke the RenameCompletionCallback with |new_path| on -// the UI thread. Should only be used as the action for +// the |task_runner|. Should only be used as the action for // MockDownloadFile::RenameAndAnnotate as follows: // EXPECT_CALL(download_file, RenameAndAnnotate(_,_,_,_,_)) // .WillOnce(ScheduleRenameAndAnnotateCallback( -// download::DOWNLOAD_INTERRUPT_REASON_NONE, new_path)); -ACTION_P2(ScheduleRenameAndAnnotateCallback, interrupt_reason, new_path) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(arg4, interrupt_reason, new_path)); +// DOWNLOAD_INTERRUPT_REASON_NONE, new_path, task_runner)); +ACTION_P3(ScheduleRenameAndAnnotateCallback, + interrupt_reason, + new_path, + task_runner) { + task_runner->PostTask(FROM_HERE, + base::BindOnce(arg4, interrupt_reason, new_path)); } // Schedules a task to invoke a callback that's bound to the specified @@ -229,21 +218,12 @@ // E.g.: // // EXPECT_CALL(foo, Bar(1, _)) -// .WithArg<1>(ScheduleCallbackWithParams(0, 0)); +// .WithArg<1>(ScheduleCallbackWithParams(0, 0, task_runner)); // // .. will invoke the second argument to Bar with 0 as the parameter. -ACTION_P2(ScheduleCallbackWithParams, param1, param2) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(std::move(arg0), param1, param2)); -} - -// Schedules a task to invoke a closure. -// E.g.: -// -// EXPECT_CALL(foo, Bar(1, _)) -// .WillOnce(ScheduleClosure(some_closure)); -ACTION_P(ScheduleClosure, closure) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure); +ACTION_P3(ScheduleCallbackWithParams, param1, param2, task_runner) { + task_runner->PostTask(FROM_HERE, + base::BindOnce(std::move(arg0), param1, param2)); } const char kTestData1[] = {'M', 'a', 'r', 'y', ' ', 'h', 'a', 'd', @@ -264,18 +244,18 @@ : task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::UI, base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED), - next_download_id_(download::DownloadItem::kInvalidId + 1) { - create_info_.reset(new download::DownloadCreateInfo()); - create_info_->save_info = std::unique_ptr<download::DownloadSaveInfo>( - new download::DownloadSaveInfo()); + next_download_id_(DownloadItem::kInvalidId + 1) { + create_info_.reset(new DownloadCreateInfo()); + create_info_->save_info = + std::unique_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); create_info_->save_info->prompt_for_save_location = false; create_info_->url_chain.push_back(GURL("http://example.com/download")); create_info_->etag = "SomethingToSatisfyResumption"; } - download::DownloadItemImpl* CreateDownloadItemWithCreateInfo( - std::unique_ptr<download::DownloadCreateInfo> info) { - download::DownloadItemImpl* download = new download::DownloadItemImpl( + DownloadItemImpl* CreateDownloadItemWithCreateInfo( + std::unique_ptr<DownloadCreateInfo> info) { + DownloadItemImpl* download = new DownloadItemImpl( mock_delegate(), next_download_id_++, *(info.get())); allocated_downloads_[download] = base::WrapUnique(download); return download; @@ -291,30 +271,31 @@ // This class keeps ownership of the created download item; it will // be torn down at the end of the test unless DestroyDownloadItem is // called. - download::DownloadItemImpl* CreateDownloadItem() { + DownloadItemImpl* CreateDownloadItem() { create_info_->download_id = ++next_download_id_; - download::DownloadItemImpl* download = new download::DownloadItemImpl( + DownloadItemImpl* download = new DownloadItemImpl( mock_delegate(), create_info_->download_id, *create_info_); allocated_downloads_[download] = base::WrapUnique(download); return download; } - // Add DownloadFile to download::DownloadItem. - download::MockDownloadFile* CallDownloadItemStart( - download::DownloadItemImpl* item, - download::DownloadItemImplDelegate::DownloadTargetCallback* callback) { - download::MockDownloadFile* mock_download_file = nullptr; - std::unique_ptr<download::DownloadFile> download_file; + // Add DownloadFile to DownloadItem. + MockDownloadFile* CallDownloadItemStart( + DownloadItemImpl* item, + DownloadItemImplDelegate::DownloadTargetCallback* callback) { + MockDownloadFile* mock_download_file = nullptr; + std::unique_ptr<DownloadFile> download_file; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) .WillOnce(SaveArg<1>(callback)); // Only create a DownloadFile if the request was successful. - if (create_info_->result == download::DOWNLOAD_INTERRUPT_REASON_NONE) { - mock_download_file = new StrictMock<download::MockDownloadFile>; + if (create_info_->result == DOWNLOAD_INTERRUPT_REASON_NONE) { + mock_download_file = new StrictMock<MockDownloadFile>; download_file.reset(mock_download_file); EXPECT_CALL(*mock_download_file, Initialize(_, _, _, _)) - .WillOnce(ScheduleCallbackWithParams( - download::DOWNLOAD_INTERRUPT_REASON_NONE, 0)); + .WillOnce( + ScheduleCallbackWithParams(DOWNLOAD_INTERRUPT_REASON_NONE, 0, + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*mock_download_file, FullPath()) .WillRepeatedly(ReturnRefOfCopy(base::FilePath())); } @@ -340,36 +321,35 @@ // Perform the intermediate rename for |item|. The target path for the // download will be set to kDummyTargetPath. Returns the MockDownloadFile* - // that was added to the download::DownloadItem. - download::MockDownloadFile* DoIntermediateRename( - download::DownloadItemImpl* item, - download::DownloadDangerType danger_type) { - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + // that was added to the DownloadItem. + MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item, + DownloadDangerType danger_type) { + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_TRUE(item->GetTargetFilePath().empty()); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); base::FilePath target_path(kDummyTargetPath); base::FilePath intermediate_path(kDummyIntermediatePath); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path)); - callback.Run(target_path, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path, + base::ThreadTaskRunnerHandle::Get())); + callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, danger_type, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); return download_file; } - void DoDestinationComplete(download::DownloadItemImpl* item, - download::MockDownloadFile* download_file) { + void DoDestinationComplete(DownloadItemImpl* item, + MockDownloadFile* download_file) { EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) .WillOnce(Return(true)); base::FilePath final_path(kDummyTargetPath); EXPECT_CALL(*download_file, RenameAndAnnotate(_, _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, final_path)); + DOWNLOAD_INTERRUPT_REASON_NONE, final_path, + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*download_file, FullPath()) .WillRepeatedly(ReturnRefOfCopy(base::FilePath(kDummyTargetPath))); EXPECT_CALL(*download_file, Detach()); @@ -381,12 +361,12 @@ // Cleanup a download item (specifically get rid of the DownloadFile on it). // The item must be in the expected state. - void CleanupItem(download::DownloadItemImpl* item, - download::MockDownloadFile* download_file, - download::DownloadItem::DownloadState expected_state) { + void CleanupItem(DownloadItemImpl* item, + MockDownloadFile* download_file, + DownloadItem::DownloadState expected_state) { EXPECT_EQ(expected_state, item->GetState()); - if (expected_state == download::DownloadItem::IN_PROGRESS) { + if (expected_state == DownloadItem::IN_PROGRESS) { if (download_file) EXPECT_CALL(*download_file, Cancel()); item->Cancel(true); @@ -395,7 +375,7 @@ } // Destroy a previously created download item. - void DestroyDownloadItem(download::DownloadItem* item) { + void DestroyDownloadItem(DownloadItem* item) { allocated_downloads_.erase(item); } @@ -406,23 +386,18 @@ *return_path = path; } - download::DownloadCreateInfo* create_info() { return create_info_.get(); } - - BrowserContext* browser_context() { return &browser_context_; } + DownloadCreateInfo* create_info() { return create_info_.get(); } base::test::ScopedTaskEnvironment task_environment_; private: - TestBrowserThreadBundle thread_bundle_; StrictMock<MockDelegate> mock_delegate_; - std::map<download::DownloadItem*, std::unique_ptr<download::DownloadItem>> - allocated_downloads_; - std::unique_ptr<download::DownloadCreateInfo> create_info_; - uint32_t next_download_id_ = download::DownloadItem::kInvalidId + 1; - TestBrowserContext browser_context_; + std::map<DownloadItem*, std::unique_ptr<DownloadItem>> allocated_downloads_; + std::unique_ptr<DownloadCreateInfo> create_info_; + uint32_t next_download_id_ = DownloadItem::kInvalidId + 1; }; -// Tests to ensure calls that change a download::DownloadItem generate an update +// Tests to ensure calls that change a DownloadItem generate an update // to observers. State changing functions not tested: // void OpenDownload(); // void ShowDownloadInShell(); @@ -430,23 +405,23 @@ // set_* mutators TEST_F(DownloadItemTest, NotificationAfterUpdate) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); TestDownloadItemObserver observer(item); item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, - std::vector<download::DownloadItem::ReceivedSlice>()); + std::vector<DownloadItem::ReceivedSlice>()); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed()); - CleanupItem(item, file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, file, DownloadItem::IN_PROGRESS); } TEST_F(DownloadItemTest, NotificationAfterCancel) { - download::DownloadItemImpl* user_cancel = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; - download::MockDownloadFile* download_file = + DownloadItemImpl* user_cancel = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback target_callback; + MockDownloadFile* download_file = CallDownloadItemStart(user_cancel, &target_callback); EXPECT_CALL(*download_file, Cancel()); @@ -454,7 +429,7 @@ user_cancel->Cancel(true); ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated()); - download::DownloadItemImpl* system_cancel = CreateDownloadItem(); + DownloadItemImpl* system_cancel = CreateDownloadItem(); download_file = CallDownloadItemStart(system_cancel, &target_callback); EXPECT_CALL(*download_file, Cancel()); @@ -464,17 +439,17 @@ } TEST_F(DownloadItemTest, NotificationAfterComplete) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); DoDestinationComplete(item, download_file); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); } TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); item->OnDownloadedFileRemoved(); @@ -482,22 +457,22 @@ } TEST_F(DownloadItemTest, NotificationAfterInterrupted) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); EXPECT_CALL(*download_file, Cancel()); TestDownloadItemObserver observer(item); EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(0); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); } TEST_F(DownloadItemTest, NotificationAfterDestroyed) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); DestroyDownloadItem(item); @@ -505,9 +480,9 @@ } TEST_F(DownloadItemTest, NotificationAfterRemove) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; - download::MockDownloadFile* download_file = + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback target_callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &target_callback); EXPECT_CALL(*download_file, Cancel()); EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); @@ -520,30 +495,28 @@ TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) { // Setting to NOT_DANGEROUS does not trigger a notification. - download::DownloadItemImpl* safe_item = CreateDownloadItem(); - download::MockDownloadFile* download_file = DoIntermediateRename( - safe_item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* safe_item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(safe_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); TestDownloadItemObserver safe_observer(safe_item); safe_item->OnAllDataSaved(0, std::unique_ptr<crypto::SecureHash>()); EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); - safe_item->OnContentCheckCompleted( - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DOWNLOAD_INTERRUPT_REASON_NONE); EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); - CleanupItem(safe_item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(safe_item, download_file, DownloadItem::IN_PROGRESS); // Setting to unsafe url or unsafe file should trigger a notification. - download::DownloadItemImpl* unsafeurl_item = CreateDownloadItem(); - download_file = DoIntermediateRename( - unsafeurl_item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* unsafeurl_item = CreateDownloadItem(); + download_file = + DoIntermediateRename(unsafeurl_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); unsafeurl_item->OnAllDataSaved(0, std::unique_ptr<crypto::SecureHash>()); EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); - unsafeurl_item->OnContentCheckCompleted( - download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, + DOWNLOAD_INTERRUPT_REASON_NONE); EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) @@ -551,19 +524,17 @@ EXPECT_CALL(*download_file, RenameAndAnnotate(_, _, _, _, _)); unsafeurl_item->ValidateDangerousDownload(); EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); - CleanupItem(unsafeurl_item, download_file, - download::DownloadItem::IN_PROGRESS); + CleanupItem(unsafeurl_item, download_file, DownloadItem::IN_PROGRESS); - download::DownloadItemImpl* unsafefile_item = CreateDownloadItem(); - download_file = DoIntermediateRename( - unsafefile_item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* unsafefile_item = CreateDownloadItem(); + download_file = + DoIntermediateRename(unsafefile_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); TestDownloadItemObserver unsafefile_observer(unsafefile_item); unsafefile_item->OnAllDataSaved(0, std::unique_ptr<crypto::SecureHash>()); EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); - unsafefile_item->OnContentCheckCompleted( - download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, + DOWNLOAD_INTERRUPT_REASON_NONE); EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) @@ -571,8 +542,7 @@ EXPECT_CALL(*download_file, RenameAndAnnotate(_, _, _, _, _)); unsafefile_item->ValidateDangerousDownload(); EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); - CleanupItem(unsafefile_item, download_file, - download::DownloadItem::IN_PROGRESS); + CleanupItem(unsafefile_item, download_file, DownloadItem::IN_PROGRESS); } // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run @@ -581,10 +551,9 @@ // name. Check that observers are updated when the new filename is available and // not before. TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); TestDownloadItemObserver observer(item); base::FilePath target_path(kDummyTargetPath); base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); @@ -592,29 +561,28 @@ target_path.InsertBeforeExtensionASCII("y")); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path)); + DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path, + base::ThreadTaskRunnerHandle::Get())); // Currently, a notification would be generated if the danger type is anything // other than NOT_DANGEROUS. - callback.Run(target_path, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); task_environment_.RunUntilIdle(); EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); EXPECT_EQ(new_intermediate_path, item->GetFullPath()); - CleanupItem(item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); } TEST_F(DownloadItemTest, NotificationAfterTogglePause) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* mock_download_file( - new download::MockDownloadFile); - std::unique_ptr<download::DownloadFile> download_file(mock_download_file); - std::unique_ptr<download::DownloadRequestHandleInterface> request_handle( + MockDownloadFile* mock_download_file(new MockDownloadFile); + std::unique_ptr<DownloadFile> download_file(mock_download_file); + std::unique_ptr<DownloadRequestHandleInterface> request_handle( new NiceMock<MockRequestHandle>); EXPECT_CALL(*mock_download_file, Initialize(_, _, _, _)); @@ -632,15 +600,15 @@ task_environment_.RunUntilIdle(); - CleanupItem(item, mock_download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); } // Test that a download is resumed automatically after a continuable interrupt. TEST_F(DownloadItemTest, AutomaticResumption_Continue) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Interrupt the download using a continuable interrupt after writing a single // byte. An intermediate file with data shouldn't be discarding after a @@ -654,15 +622,15 @@ // Resumption attempt should pass the intermediate file along. EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( - AllOf(Property(&download::DownloadUrlParameters::file_path, + AllOf(Property(&DownloadUrlParameters::file_path, Property(&base::FilePath::value, kDummyIntermediatePath)), - Property(&download::DownloadUrlParameters::offset, 1)), + Property(&DownloadUrlParameters::offset, 1)), _)); base::HistogramTester histogram_tester; item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); // Since the download is resumed automatically, the interrupt count doesn't @@ -680,22 +648,22 @@ // finally interrupted. histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR), 1); // The download item is currently in RESUMING_INTERNAL state, which maps to // IN_PROGRESS. - CleanupItem(item, nullptr, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); } // Automatic resumption should restart and discard the intermediate file if the // interrupt reason requires it. TEST_F(DownloadItemTest, AutomaticResumption_Restart) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Interrupt the download, using a restartable interrupt. EXPECT_CALL(*download_file, Cancel()); @@ -704,13 +672,13 @@ // Resumption attempt should have discarded intermediate file. EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( - Property(&download::DownloadUrlParameters::file_path, + Property(&DownloadUrlParameters::file_path, Property(&base::FilePath::empty, true)), _)); base::HistogramTester histogram_tester; item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE, 1, + DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE, 1, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); @@ -723,25 +691,25 @@ // finally interrupted. histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE), 1); - CleanupItem(item, nullptr, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); } // Test that automatic resumption doesn't happen after an interrupt that // requires user action to resolve. TEST_F(DownloadItemTest, AutomaticResumption_NeedsUserAction) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Interrupt the download, using a restartable interrupt. EXPECT_CALL(*download_file, Cancel()); base::HistogramTester histogram_tester; item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1, + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); // Should not try to auto-resume. @@ -749,21 +717,20 @@ ASSERT_EQ(0, observer.resume_count()); task_environment_.RunUntilIdle(); - histogram_tester.ExpectBucketCount( - "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), - 1); - CleanupItem(item, nullptr, download::DownloadItem::INTERRUPTED); + histogram_tester.ExpectBucketCount("Download.InterruptedReason", + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), + 1); + CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); } // Test that a download is resumed automatically after a content length mismatch // error. TEST_F(DownloadItemTest, AutomaticResumption_ContentLengthMismatch) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Interrupt the download with content length mismatch error. The intermediate // file with data shouldn't be discarded. @@ -776,15 +743,15 @@ // Resumption attempt should pass the intermediate file along. EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( - AllOf(Property(&download::DownloadUrlParameters::file_path, + AllOf(Property(&DownloadUrlParameters::file_path, Property(&base::FilePath::value, kDummyIntermediatePath)), - Property(&download::DownloadUrlParameters::offset, 1)), + Property(&DownloadUrlParameters::offset, 1)), _)); base::HistogramTester histogram_tester; item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH, 1, + DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH, 1, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); // Since the download is resumed automatically, the observer shouldn't notice @@ -795,18 +762,18 @@ task_environment_.RunUntilIdle(); histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH), 1); - CleanupItem(item, nullptr, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); } // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. TEST_F(DownloadItemTest, UnresumableInterrupt) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Fail final rename with unresumable reason. EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) @@ -814,7 +781,8 @@ EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyTargetPath), _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, base::FilePath())); + DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, base::FilePath(), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*download_file, Cancel()); // Complete download to trigger final rename. @@ -825,27 +793,27 @@ task_environment_.RunUntilIdle(); histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED), 1); ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); // Should not try to auto-resume. ASSERT_EQ(1, observer.interrupt_count()); ASSERT_EQ(0, observer.resume_count()); - CleanupItem(item, nullptr, download::DownloadItem::INTERRUPTED); + CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); } TEST_F(DownloadItemTest, AutomaticResumption_AttemptLimit) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - base::WeakPtr<download::DownloadDestinationObserver> as_observer( + DownloadItemImpl* item = CreateDownloadItem(); + base::WeakPtr<DownloadDestinationObserver> as_observer( item->DestinationObserverAsWeakPtr()); TestDownloadItemObserver observer(item); - download::MockDownloadFile* mock_download_file_ref = nullptr; - std::unique_ptr<download::MockDownloadFile> mock_download_file; + MockDownloadFile* mock_download_file_ref = nullptr; + std::unique_ptr<MockDownloadFile> mock_download_file; std::unique_ptr<MockRequestHandle> mock_request_handle; - download::DownloadItemImplDelegate::DownloadTargetCallback callback; + DownloadItemImplDelegate::DownloadTargetCallback callback; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) .WillRepeatedly(SaveArg<1>(&callback)); @@ -853,18 +821,16 @@ // All attempts at resumption should pass along the intermediate file. EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( - AllOf(Property(&download::DownloadUrlParameters::file_path, + AllOf(Property(&DownloadUrlParameters::file_path, Property(&base::FilePath::value, kDummyIntermediatePath)), - Property(&download::DownloadUrlParameters::offset, 1)), + Property(&DownloadUrlParameters::offset, 1)), _)) - .Times(download::DownloadItemImpl::kMaxAutoResumeAttempts); - for (int i = 0; i < (download::DownloadItemImpl::kMaxAutoResumeAttempts + 1); - ++i) { + .Times(DownloadItemImpl::kMaxAutoResumeAttempts); + for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { SCOPED_TRACE(::testing::Message() << "Iteration " << i); - mock_download_file = - std::make_unique<NiceMock<download::MockDownloadFile>>(); + mock_download_file = std::make_unique<NiceMock<MockDownloadFile>>(); mock_download_file_ref = mock_download_file.get(); mock_request_handle = std::make_unique<NiceMock<MockRequestHandle>>(); @@ -883,7 +849,8 @@ // Target of RenameAndUniquify is always the intermediate path. ON_CALL(*mock_download_file_ref, RenameAndUniquify(_, _)) .WillByDefault(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path)); + DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path, + base::ThreadTaskRunnerHandle::Get())); // RenameAndUniquify is only called the first time. In all the subsequent // iterations, the intermediate file already has the correct name, hence no @@ -892,15 +859,15 @@ ASSERT_FALSE(callback.is_null()); base::ResetAndReturn(&callback).Run( - target_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // Use a continuable interrupt. EXPECT_CALL(*mock_download_file_ref, Cancel()).Times(0); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); @@ -909,12 +876,12 @@ histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR), - download::DownloadItemImpl::kMaxAutoResumeAttempts + 1); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR), + DownloadItemImpl::kMaxAutoResumeAttempts + 1); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); EXPECT_EQ(1, observer.interrupt_count()); - CleanupItem(item, nullptr, download::DownloadItem::INTERRUPTED); + CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); } // If the download attempts to resume and the resumption request fails, the @@ -934,9 +901,9 @@ create_info()->url_chain.push_back(GURL(kFirstURL)); create_info()->mime_type = kMimeType; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); ASSERT_TRUE(item->GetResponseHeaders()); EXPECT_EQ(kFirstResponseCode, item->GetResponseHeaders()->response_code()); EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); @@ -947,20 +914,20 @@ EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( - AllOf(Property(&download::DownloadUrlParameters::file_path, + AllOf(Property(&DownloadUrlParameters::file_path, Property(&base::FilePath::value, kDummyIntermediatePath)), - Property(&download::DownloadUrlParameters::offset, 1)), + Property(&DownloadUrlParameters::offset, 1)), _)); EXPECT_CALL(*download_file, Detach()); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); // Now change the create info. The changes should not cause the - // download::DownloadItem to be updated. + // DownloadItem to be updated. constexpr int kSecondResponseCode = 418; const char kSecondContentDisposition[] = "attachment; filename=bar"; const char kSecondETag[] = "123"; @@ -974,20 +941,20 @@ create_info()->url_chain.clear(); create_info()->url_chain.push_back(GURL(kSecondURL)); create_info()->mime_type = kSecondMimeType; - create_info()->result = download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; + create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; create_info()->save_info->file_path = base::FilePath(kDummyIntermediatePath); create_info()->save_info->offset = 1; // Calling Start() with a response indicating failure shouldn't cause a target // update, nor should it result in discarding the intermediate file. - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; + DownloadItemImplDelegate::DownloadTargetCallback target_callback; download_file = CallDownloadItemStart(item, &target_callback); ASSERT_FALSE(target_callback.is_null()); target_callback.Run(base::FilePath(kDummyTargetPath), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(kDummyIntermediatePath), - download::DOWNLOAD_INTERRUPT_REASON_NONE); + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); ASSERT_TRUE(item->GetResponseHeaders()); @@ -997,9 +964,8 @@ EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); EXPECT_EQ(kFirstURL, item->GetURL().spec()); EXPECT_EQ(kMimeType, item->GetMimeType()); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, - item->GetLastReason()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); EXPECT_EQ(kDummyIntermediatePath, item->GetFullPath().value()); EXPECT_EQ(1, item->GetReceivedBytes()); } @@ -1020,19 +986,19 @@ create_info()->url_chain.push_back(GURL(kFirstURL)); create_info()->mime_type = kMimeType; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)); EXPECT_CALL(*download_file, Detach()); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); // Now change the create info. The changes should not cause the - // download::DownloadItem to be updated. + // DownloadItem to be updated. constexpr int kSecondResponseCode = 201; const char kSecondContentDisposition[] = "attachment; filename=bar"; const char kSecondETag[] = "123"; @@ -1047,7 +1013,7 @@ create_info()->url_chain.push_back(GURL(kSecondURL)); create_info()->mime_type = kSecondMimeType; - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; + DownloadItemImplDelegate::DownloadTargetCallback target_callback; download_file = CallDownloadItemStart(item, &target_callback); ASSERT_TRUE(item->GetResponseHeaders()); @@ -1058,7 +1024,7 @@ EXPECT_EQ(kSecondURL, item->GetURL().spec()); EXPECT_EQ(kSecondMimeType, item->GetMimeType()); - CleanupItem(item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); } // Ensure when strong validators changed on resumption, the received @@ -1066,13 +1032,13 @@ TEST_F(DownloadItemTest, ClearReceivedSliceIfEtagChanged) { const char kFirstETag[] = "ABC"; const char kSecondETag[] = "123"; - const download::DownloadItem::ReceivedSlices kReceivedSlice = { - download::DownloadItem::ReceivedSlice(0, 10)}; + const DownloadItem::ReceivedSlices kReceivedSlice = { + DownloadItem::ReceivedSlice(0, 10)}; create_info()->etag = kFirstETag; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)); EXPECT_CALL(*download_file, Detach()); @@ -1083,7 +1049,7 @@ EXPECT_EQ(10, item->GetReceivedBytes()); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0, std::unique_ptr<crypto::SecureHash>()); EXPECT_EQ(kReceivedSlice, item->GetReceivedSlices()); @@ -1092,12 +1058,12 @@ // Change the strong validator and resume the download, the received slices // should be cleared. create_info()->etag = kSecondETag; - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; + DownloadItemImplDelegate::DownloadTargetCallback target_callback; download_file = CallDownloadItemStart(item, &target_callback); EXPECT_TRUE(item->GetReceivedSlices().empty()); EXPECT_EQ(0, item->GetReceivedBytes()); - CleanupItem(item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); } // Test that resumption uses the final URL in a URL chain when resuming. @@ -1108,23 +1074,22 @@ create_info()->url_chain.push_back(GURL("http://example.com/b")); create_info()->url_chain.push_back(GURL("http://example.com/c")); - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); TestDownloadItemObserver observer(item); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Interrupt the download, using a continuable interrupt. EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); - EXPECT_CALL(*mock_delegate(), - MockResumeInterruptedDownload( - Property(&download::DownloadUrlParameters::url, - GURL("http://example.com/c")), - _)) + EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( + Property(&DownloadUrlParameters::url, + GURL("http://example.com/c")), + _)) .Times(1); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1, std::unique_ptr<crypto::SecureHash>()); // Test expectations verify that ResumeInterruptedDownload() is called (by way @@ -1135,58 +1100,54 @@ task_environment_.RunUntilIdle(); // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS. - CleanupItem(item, nullptr, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); } TEST_F(DownloadItemTest, DisplayName) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); base::FilePath target_path( base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); - EXPECT_EQ(FILE_PATH_LITERAL(""), - item->GetFileNameToReportUser().value()); + EXPECT_EQ(FILE_PATH_LITERAL(""), item->GetFileNameToReportUser().value()); EXPECT_CALL(*download_file, RenameAndUniquify(_, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path)); - callback.Run(target_path, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path, + base::ThreadTaskRunnerHandle::Get())); + callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"), item->GetFileNameToReportUser().value()); item->SetDisplayName(base::FilePath(FILE_PATH_LITERAL("new.name"))); EXPECT_EQ(FILE_PATH_LITERAL("new.name"), item->GetFileNameToReportUser().value()); - CleanupItem(item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); } // Test to make sure that Start method calls DF initialize properly. TEST_F(DownloadItemTest, Start) { - download::MockDownloadFile* mock_download_file( - new download::MockDownloadFile); - std::unique_ptr<download::DownloadFile> download_file(mock_download_file); - download::DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* mock_download_file(new MockDownloadFile); + std::unique_ptr<DownloadFile> download_file(mock_download_file); + DownloadItemImpl* item = CreateDownloadItem(); EXPECT_CALL(*mock_download_file, Initialize(_, _, _, _)); - std::unique_ptr<download::DownloadRequestHandleInterface> request_handle( + std::unique_ptr<DownloadRequestHandleInterface> request_handle( new NiceMock<MockRequestHandle>); EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); item->Start(std::move(download_file), std::move(request_handle), *create_info(), nullptr, nullptr); task_environment_.RunUntilIdle(); - CleanupItem(item, mock_download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); } // Download file and the request should be cancelled as a result of download // file initialization failing. TEST_F(DownloadItemTest, InitDownloadFileFails) { - download::DownloadItemImpl* item = CreateDownloadItem(); - std::unique_ptr<download::MockDownloadFile> file = - std::make_unique<download::MockDownloadFile>(); + DownloadItemImpl* item = CreateDownloadItem(); + std::unique_ptr<MockDownloadFile> file = std::make_unique<MockDownloadFile>(); std::unique_ptr<MockRequestHandle> request_handle = std::make_unique<MockRequestHandle>(); @@ -1195,10 +1156,10 @@ EXPECT_CALL(*request_handle, CancelRequest(_)); EXPECT_CALL(*file, Initialize(_, _, _, _)) .WillOnce(ScheduleCallbackWithParams( - download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, 0)); + DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, 0, + base::ThreadTaskRunnerHandle::Get())); - download::DownloadItemImplDelegate::DownloadTargetCallback - download_target_callback; + DownloadItemImplDelegate::DownloadTargetCallback download_target_callback; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) .WillOnce(SaveArg<1>(&download_target_callback)); @@ -1206,23 +1167,22 @@ nullptr, nullptr); task_environment_.RunUntilIdle(); - download_target_callback.Run( - base::FilePath(kDummyTargetPath), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - base::FilePath(kDummyIntermediatePath), - download::DOWNLOAD_INTERRUPT_REASON_NONE); + download_target_callback.Run(base::FilePath(kDummyTargetPath), + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + base::FilePath(kDummyIntermediatePath), + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, item->GetLastReason()); EXPECT_FALSE(item->GetTargetFilePath().empty()); EXPECT_TRUE(item->GetFullPath().empty()); histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED), 1); } @@ -1230,49 +1190,47 @@ // will get called with a DownloadCreateInfo with a non-zero interrupt_reason. TEST_F(DownloadItemTest, StartFailedDownload) { base::HistogramTester histogram_tester; - create_info()->result = download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; - download::DownloadItemImpl* item = CreateDownloadItem(); + create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; + DownloadItemImpl* item = CreateDownloadItem(); // DownloadFile and DownloadRequestHandleInterface objects aren't created for // failed downloads. - std::unique_ptr<download::DownloadFile> null_download_file; - std::unique_ptr<download::DownloadRequestHandleInterface> null_request_handle; - download::DownloadItemImplDelegate::DownloadTargetCallback - download_target_callback; + std::unique_ptr<DownloadFile> null_download_file; + std::unique_ptr<DownloadRequestHandleInterface> null_request_handle; + DownloadItemImplDelegate::DownloadTargetCallback download_target_callback; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) .WillOnce(SaveArg<1>(&download_target_callback)); item->Start(std::move(null_download_file), std::move(null_request_handle), *create_info(), nullptr, nullptr); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); task_environment_.RunUntilIdle(); // The DownloadItemImpl should attempt to determine a target path even if the // download was interrupted. ASSERT_FALSE(download_target_callback.is_null()); - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); base::FilePath target_path(FILE_PATH_LITERAL("foo")); - download_target_callback.Run( - target_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + download_target_callback.Run(target_path, + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // Interrupt reason carried in create info should be recorded. histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), 1); EXPECT_EQ(target_path, item->GetTargetFilePath()); - CleanupItem(item, nullptr, download::DownloadItem::INTERRUPTED); + CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); } // Test that the delegate is invoked after the download file is renamed. TEST_F(DownloadItemTest, CallbackAfterRename) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); base::FilePath final_path( base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); @@ -1280,11 +1238,12 @@ final_path.InsertBeforeExtensionASCII("y")); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path)); + DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path, + base::ThreadTaskRunnerHandle::Get())); - callback.Run(final_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // All the callbacks should have happened by now. ::testing::Mock::VerifyAndClearExpectations(download_file); @@ -1294,7 +1253,8 @@ .WillOnce(Return(true)); EXPECT_CALL(*download_file, RenameAndAnnotate(final_path, _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, final_path)); + DOWNLOAD_INTERRUPT_REASON_NONE, final_path, + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); @@ -1308,11 +1268,10 @@ // Test that the delegate is invoked after the download file is renamed and the // download item is in an interrupted state. TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; base::HistogramTester histogram_tester; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); base::FilePath final_path( base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); @@ -1320,65 +1279,61 @@ final_path.InsertBeforeExtensionASCII("y")); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, - new_intermediate_path)); - EXPECT_CALL(*download_file, Cancel()) - .Times(1); + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, new_intermediate_path, + base::ThreadTaskRunnerHandle::Get())); + EXPECT_CALL(*download_file, Cancel()).Times(1); - callback.Run(final_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // All the callbacks should have happened by now. ::testing::Mock::VerifyAndClearExpectations(download_file); mock_delegate()->VerifyAndClearExpectations(); - histogram_tester.ExpectBucketCount( - "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), - 1); + histogram_tester.ExpectBucketCount("Download.InterruptedReason", + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), + 1); } TEST_F(DownloadItemTest, Interrupted) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); - const download::DownloadInterruptReason reason( - download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); + const DownloadInterruptReason reason( + DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); // Confirm interrupt sets state properly. EXPECT_CALL(*download_file, Cancel()); item->DestinationObserverAsWeakPtr()->DestinationError( reason, 0, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); EXPECT_EQ(reason, item->GetLastReason()); // Cancel should kill it. item->Cancel(true); - EXPECT_EQ(download::DownloadItem::CANCELLED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, - item->GetLastReason()); + EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason()); histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>(reason), 1); + ToHistogramSample<DownloadInterruptReason>(reason), 1); } // Destination errors that occur before the intermediate rename shouldn't cause // the download to be marked as interrupted until after the intermediate rename. TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, std::unique_ptr<crypto::SecureHash>()); - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); base::FilePath final_path( base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); @@ -1387,25 +1342,24 @@ final_path.InsertBeforeExtensionASCII("y")); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path)); - EXPECT_CALL(*download_file, Cancel()) - .Times(1); + DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path, + base::ThreadTaskRunnerHandle::Get())); + EXPECT_CALL(*download_file, Cancel()).Times(1); - callback.Run(final_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // All the callbacks should have happened by now. ::testing::Mock::VerifyAndClearExpectations(download_file); mock_delegate()->VerifyAndClearExpectations(); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); EXPECT_TRUE(item->GetFullPath().empty()); EXPECT_EQ(final_path, item->GetTargetFilePath()); - histogram_tester.ExpectBucketCount( - "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), - 1); + histogram_tester.ExpectBucketCount("Download.InterruptedReason", + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), + 1); } // As above. But if the download can be resumed by continuing, then the @@ -1413,17 +1367,16 @@ // the intermediate rename succeeds. TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); // Write some data and interrupt with NETWORK_FAILED. The download shouldn't // transition to INTERRUPTED until the destination callback has been invoked. item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1, + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1, std::unique_ptr<crypto::SecureHash>()); - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); base::FilePath final_path( base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); @@ -1432,25 +1385,26 @@ final_path.InsertBeforeExtensionASCII("y")); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path)); + DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path, + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath(new_intermediate_path))); EXPECT_CALL(*download_file, Detach()); - callback.Run(final_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // All the callbacks should have happened by now. ::testing::Mock::VerifyAndClearExpectations(download_file); mock_delegate()->VerifyAndClearExpectations(); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); EXPECT_EQ(new_intermediate_path, item->GetFullPath()); EXPECT_EQ(final_path, item->GetTargetFilePath()); histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), 1); } @@ -1458,14 +1412,13 @@ // be set to the file error and the intermediate path should be empty. TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 0, + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 0, std::unique_ptr<crypto::SecureHash>()); - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); base::FilePath final_path( base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); @@ -1474,95 +1427,87 @@ final_path.InsertBeforeExtensionASCII("y")); EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) .WillOnce(ScheduleRenameAndUniquifyCallback( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, - new_intermediate_path)); - EXPECT_CALL(*download_file, Cancel()) - .Times(1); + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, new_intermediate_path, + base::ThreadTaskRunnerHandle::Get())); + EXPECT_CALL(*download_file, Cancel()).Times(1); - callback.Run(final_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, - download::DOWNLOAD_INTERRUPT_REASON_NONE); + callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path, + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); // All the callbacks should have happened by now. ::testing::Mock::VerifyAndClearExpectations(download_file); mock_delegate()->VerifyAndClearExpectations(); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, - item->GetLastReason()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, item->GetLastReason()); EXPECT_TRUE(item->GetFullPath().empty()); EXPECT_EQ(final_path, item->GetTargetFilePath()); // Rename error will overwrite the previous network interrupt reason. // TODO(xingliu): See if we should report both interrupted reasons or the // first one, see https://crbug.com/769040. - histogram_tester.ExpectBucketCount( - "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), - 1); + histogram_tester.ExpectBucketCount("Download.InterruptedReason", + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), + 1); histogram_tester.ExpectTotalCount("Download.InterruptedReason", 1); } TEST_F(DownloadItemTest, Canceled) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; - download::MockDownloadFile* download_file = + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback target_callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &target_callback); // Confirm cancel sets state properly. EXPECT_CALL(*download_file, Cancel()); item->Cancel(true); - EXPECT_EQ(download::DownloadItem::CANCELLED, item->GetState()); + EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); } TEST_F(DownloadItemTest, DownloadTargetDetermined_Cancel) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); EXPECT_CALL(*download_file, Cancel()); callback.Run(base::FilePath(FILE_PATH_LITERAL("foo")), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(FILE_PATH_LITERAL("bar")), - download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); - EXPECT_EQ(download::DownloadItem::CANCELLED, item->GetState()); + DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); + EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); } TEST_F(DownloadItemTest, DownloadTargetDetermined_CancelWithEmptyName) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); EXPECT_CALL(*download_file, Cancel()); - callback.Run(base::FilePath(), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(), - download::DOWNLOAD_INTERRUPT_REASON_NONE); - EXPECT_EQ(download::DownloadItem::CANCELLED, item->GetState()); + callback.Run(base::FilePath(), DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(), + DOWNLOAD_INTERRUPT_REASON_NONE); + EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); } TEST_F(DownloadItemTest, DownloadTargetDetermined_Conflict) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::DownloadItemImplDelegate::DownloadTargetCallback callback; - download::MockDownloadFile* download_file = - CallDownloadItemStart(item, &callback); + DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImplDelegate::DownloadTargetCallback callback; + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); base::FilePath target_path(FILE_PATH_LITERAL("/foo/bar")); EXPECT_CALL(*download_file, Cancel()); - callback.Run(target_path, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path, - download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE, + callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path, + DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE, item->GetLastReason()); } TEST_F(DownloadItemTest, FileRemoved) { - download::DownloadItemImpl* item = CreateDownloadItem(); + DownloadItemImpl* item = CreateDownloadItem(); EXPECT_FALSE(item->GetFileExternallyRemoved()); item->OnDownloadedFileRemoved(); @@ -1570,10 +1515,10 @@ } TEST_F(DownloadItemTest, DestinationUpdate) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); - base::WeakPtr<download::DownloadDestinationObserver> as_observer( + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + base::WeakPtr<DownloadDestinationObserver> as_observer( item->DestinationObserverAsWeakPtr()); TestDownloadItemObserver observer(item); @@ -1584,7 +1529,7 @@ item->SetTotalBytes(100l); EXPECT_EQ(100l, item->GetTotalBytes()); - std::vector<download::DownloadItem::ReceivedSlice> received_slices; + std::vector<DownloadItem::ReceivedSlice> received_slices; received_slices.emplace_back(0, 10); as_observer->DestinationUpdate(10, 20, received_slices); EXPECT_EQ(20l, item->CurrentSpeed()); @@ -1601,20 +1546,20 @@ EXPECT_EQ(received_slices, item->GetReceivedSlices()); EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); - CleanupItem(item, file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, file, DownloadItem::IN_PROGRESS); } TEST_F(DownloadItemTest, DestinationError_NoRestartRequired) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); - base::WeakPtr<download::DownloadDestinationObserver> as_observer( + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + base::WeakPtr<DownloadDestinationObserver> as_observer( item->DestinationObserverAsWeakPtr()); TestDownloadItemObserver observer(item); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); std::unique_ptr<crypto::SecureHash> hash( @@ -1622,34 +1567,33 @@ hash->Update(kTestData1, sizeof(kTestData1)); EXPECT_CALL(*download_file, Detach()); - as_observer->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1, std::move(hash)); + as_observer->DestinationError(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1, + std::move(hash)); mock_delegate()->VerifyAndClearExpectations(); EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, - item->GetLastReason()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); EXPECT_EQ( std::string(std::begin(kHashOfTestData1), std::end(kHashOfTestData1)), item->GetHash()); histogram_tester.ExpectBucketCount( "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), 1); } TEST_F(DownloadItemTest, DestinationError_RestartRequired) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); - base::WeakPtr<download::DownloadDestinationObserver> as_observer( + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + base::WeakPtr<DownloadDestinationObserver> as_observer( item->DestinationObserverAsWeakPtr()); TestDownloadItemObserver observer(item); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); std::unique_ptr<crypto::SecureHash> hash( @@ -1657,40 +1601,38 @@ hash->Update(kTestData1, sizeof(kTestData1)); EXPECT_CALL(*download_file, Cancel()); - as_observer->DestinationError(download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, - 1, std::move(hash)); + as_observer->DestinationError(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1, + std::move(hash)); mock_delegate()->VerifyAndClearExpectations(); EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, - item->GetLastReason()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, item->GetLastReason()); EXPECT_EQ(std::string(), item->GetHash()); - histogram_tester.ExpectBucketCount( - "Download.InterruptedReason", - ToHistogramSample<download::DownloadInterruptReason>( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), - 1); + histogram_tester.ExpectBucketCount("Download.InterruptedReason", + ToHistogramSample<DownloadInterruptReason>( + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED), + 1); } TEST_F(DownloadItemTest, DestinationCompleted) { base::HistogramTester histogram_tester; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); - base::WeakPtr<download::DownloadDestinationObserver> as_observer( + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + base::WeakPtr<DownloadDestinationObserver> as_observer( item->DestinationObserverAsWeakPtr()); TestDownloadItemObserver observer(item); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_EQ("", item->GetHash()); EXPECT_FALSE(item->AllDataSaved()); EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); - as_observer->DestinationUpdate( - 10, 20, std::vector<download::DownloadItem::ReceivedSlice>()); + as_observer->DestinationUpdate(10, 20, + std::vector<DownloadItem::ReceivedSlice>()); EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset. - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_EQ("", item->GetHash()); EXPECT_FALSE(item->AllDataSaved()); @@ -1701,28 +1643,28 @@ EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)); as_observer->DestinationCompleted(10, std::move(hash)); mock_delegate()->VerifyAndClearExpectations(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); EXPECT_EQ( std::string(std::begin(kHashOfTestData1), std::end(kHashOfTestData1)), item->GetHash()); EXPECT_TRUE(item->AllDataSaved()); - // Even though the download::DownloadItem receives a DestinationCompleted() + // Even though the DownloadItem receives a DestinationCompleted() // event, target determination hasn't completed, hence the download item is // stuck in TARGET_PENDING. - CleanupItem(item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); histogram_tester.ExpectTotalCount("Download.InterruptedReason", 0); } TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // InProgress - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); ASSERT_FALSE(item->GetTargetFilePath().empty()); EXPECT_TRUE(item->CanShowInFolder()); EXPECT_TRUE(item->CanOpenDownload()); @@ -1730,8 +1672,8 @@ // Complete EXPECT_CALL(*download_file, RenameAndAnnotate(_, _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, - base::FilePath(kDummyTargetPath))); + DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyTargetPath), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) .WillOnce(Return(true)); EXPECT_CALL(*download_file, FullPath()) @@ -1741,7 +1683,7 @@ 0, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); - ASSERT_EQ(download::DownloadItem::COMPLETE, item->GetState()); + ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); EXPECT_TRUE(item->CanShowInFolder()); EXPECT_TRUE(item->CanOpenDownload()); } @@ -1750,12 +1692,12 @@ // A download created with a non-empty FilePath is considered a temporary // download. create_info()->save_info->file_path = base::FilePath(kDummyTargetPath); - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // InProgress Temporary - ASSERT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); ASSERT_FALSE(item->GetTargetFilePath().empty()); ASSERT_TRUE(item->IsTemporary()); EXPECT_FALSE(item->CanShowInFolder()); @@ -1766,8 +1708,8 @@ .WillOnce(Return(true)); EXPECT_CALL(*download_file, RenameAndAnnotate(_, _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, - base::FilePath(kDummyTargetPath))); + DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyTargetPath), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); @@ -1775,38 +1717,38 @@ 0, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); - ASSERT_EQ(download::DownloadItem::COMPLETE, item->GetState()); + ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); EXPECT_FALSE(item->CanShowInFolder()); EXPECT_FALSE(item->CanOpenDownload()); } TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); EXPECT_CALL(*download_file, Cancel()); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, std::unique_ptr<crypto::SecureHash>()); task_environment_.RunUntilIdle(); - ASSERT_EQ(download::DownloadItem::INTERRUPTED, item->GetState()); + ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); ASSERT_FALSE(item->GetTargetFilePath().empty()); EXPECT_FALSE(item->CanShowInFolder()); EXPECT_TRUE(item->CanOpenDownload()); } TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); EXPECT_CALL(*download_file, Cancel()); item->Cancel(true); task_environment_.RunUntilIdle(); - ASSERT_EQ(download::DownloadItem::CANCELLED, item->GetState()); + ASSERT_EQ(DownloadItem::CANCELLED, item->GetState()); EXPECT_FALSE(item->CanShowInFolder()); EXPECT_FALSE(item->CanOpenDownload()); } @@ -1817,31 +1759,31 @@ TEST_F(DownloadItemTest, CompleteDelegate_ReturnTrue) { // Test to confirm that if we have a callback that returns true, // we complete immediately. - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Drive the delegate interaction. EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) .WillOnce(Return(true)); item->DestinationObserverAsWeakPtr()->DestinationCompleted( 0, std::unique_ptr<crypto::SecureHash>()); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_FALSE(item->IsDangerous()); // Make sure the download can complete. EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyTargetPath), _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, - base::FilePath(kDummyTargetPath))); + DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyTargetPath), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) .WillOnce(Return(true)); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::COMPLETE, item->GetState()); + EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); } // Just delaying completion. @@ -1849,56 +1791,54 @@ // Test to confirm that if we have a callback that returns true, // we complete immediately. - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); base::Closure delegate_callback; base::Closure copy_delegate_callback; EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) - .WillOnce(DoAll(SaveArg<1>(&delegate_callback), - Return(false))) + .WillOnce(DoAll(SaveArg<1>(&delegate_callback), Return(false))) .WillOnce(Return(true)); item->DestinationObserverAsWeakPtr()->DestinationCompleted( 0, std::unique_ptr<crypto::SecureHash>()); ASSERT_FALSE(delegate_callback.is_null()); copy_delegate_callback = delegate_callback; delegate_callback.Reset(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); std::move(copy_delegate_callback).Run(); ASSERT_TRUE(delegate_callback.is_null()); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_FALSE(item->IsDangerous()); // Make sure the download can complete. EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyTargetPath), _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, - base::FilePath(kDummyTargetPath))); + DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyTargetPath), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) .WillOnce(Return(true)); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::COMPLETE, item->GetState()); + EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); } // Delay and set danger. TEST_F(DownloadItemTest, CompleteDelegate_SetDanger) { // Test to confirm that if we have a callback that returns true, // we complete immediately. - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Drive the delegate interaction. base::Closure delegate_callback; base::Closure copy_delegate_callback; EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) - .WillOnce(DoAll(SaveArg<1>(&delegate_callback), - Return(false))) + .WillOnce(DoAll(SaveArg<1>(&delegate_callback), Return(false))) .WillOnce(Return(true)); item->DestinationObserverAsWeakPtr()->DestinationCompleted( 0, std::unique_ptr<crypto::SecureHash>()); @@ -1906,88 +1846,85 @@ copy_delegate_callback = delegate_callback; delegate_callback.Reset(); EXPECT_FALSE(item->IsDangerous()); - item->OnContentCheckCompleted(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, - download::DOWNLOAD_INTERRUPT_REASON_NONE); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, + DOWNLOAD_INTERRUPT_REASON_NONE); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); std::move(copy_delegate_callback).Run(); ASSERT_TRUE(delegate_callback.is_null()); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_TRUE(item->IsDangerous()); // Make sure the download doesn't complete until we've validated it. EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyTargetPath), _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, - base::FilePath(kDummyTargetPath))); + DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyTargetPath), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) .WillOnce(Return(true)); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_TRUE(item->IsDangerous()); item->ValidateDangerousDownload(); - EXPECT_EQ(download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED, - item->GetDangerType()); + EXPECT_EQ(DOWNLOAD_DANGER_TYPE_USER_VALIDATED, item->GetDangerType()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::COMPLETE, item->GetState()); + EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); } // Just delaying completion twice. TEST_F(DownloadItemTest, CompleteDelegate_BlockTwice) { // Test to confirm that if we have a callback that returns true, // we complete immediately. - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); // Drive the delegate interaction. base::Closure delegate_callback; base::Closure copy_delegate_callback; EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) - .WillOnce(DoAll(SaveArg<1>(&delegate_callback), - Return(false))) - .WillOnce(DoAll(SaveArg<1>(&delegate_callback), - Return(false))) + .WillOnce(DoAll(SaveArg<1>(&delegate_callback), Return(false))) + .WillOnce(DoAll(SaveArg<1>(&delegate_callback), Return(false))) .WillOnce(Return(true)); item->DestinationObserverAsWeakPtr()->DestinationCompleted( 0, std::unique_ptr<crypto::SecureHash>()); ASSERT_FALSE(delegate_callback.is_null()); copy_delegate_callback = delegate_callback; delegate_callback.Reset(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); copy_delegate_callback.Run(); ASSERT_FALSE(delegate_callback.is_null()); copy_delegate_callback = delegate_callback; delegate_callback.Reset(); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); std::move(copy_delegate_callback).Run(); ASSERT_TRUE(delegate_callback.is_null()); - EXPECT_EQ(download::DownloadItem::IN_PROGRESS, item->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); EXPECT_FALSE(item->IsDangerous()); // Make sure the download can complete. EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyTargetPath), _, _, _, _)) .WillOnce(ScheduleRenameAndAnnotateCallback( - download::DOWNLOAD_INTERRUPT_REASON_NONE, - base::FilePath(kDummyTargetPath))); + DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyTargetPath), + base::ThreadTaskRunnerHandle::Get())); EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) .WillOnce(Return(true)); EXPECT_CALL(*download_file, FullPath()) .WillOnce(ReturnRefOfCopy(base::FilePath())); EXPECT_CALL(*download_file, Detach()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::COMPLETE, item->GetState()); + EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); } TEST_F(DownloadItemTest, StealDangerousDownloadAndDiscard) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); ASSERT_TRUE(item->IsDangerous()); base::FilePath full_path(FILE_PATH_LITERAL("foo.txt")); base::FilePath returned_path; @@ -2007,9 +1944,9 @@ } TEST_F(DownloadItemTest, StealDangerousDownloadAndKeep) { - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); ASSERT_TRUE(item->IsDangerous()); base::FilePath full_path(FILE_PATH_LITERAL("foo.txt")); base::FilePath returned_path; @@ -2023,20 +1960,20 @@ base::Unretained(&returned_path))); task_environment_.RunUntilIdle(); EXPECT_NE(full_path, returned_path); - CleanupItem(item, download_file, download::DownloadItem::IN_PROGRESS); + CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); } TEST_F(DownloadItemTest, StealInterruptedContinuableDangerousDownload) { base::FilePath returned_path; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); base::FilePath full_path = item->GetFullPath(); EXPECT_FALSE(full_path.empty()); EXPECT_CALL(*download_file, FullPath()).WillOnce(ReturnRefOfCopy(full_path)); EXPECT_CALL(*download_file, Detach()); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1, + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(item->IsDangerous()); @@ -2053,12 +1990,12 @@ TEST_F(DownloadItemTest, StealInterruptedNonContinuableDangerousDownload) { base::FilePath returned_path; - download::DownloadItemImpl* item = CreateDownloadItem(); - download::MockDownloadFile* download_file = - DoIntermediateRename(item, download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); + DownloadItemImpl* item = CreateDownloadItem(); + MockDownloadFile* download_file = + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); EXPECT_CALL(*download_file, Cancel()); item->DestinationObserverAsWeakPtr()->DestinationError( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1, + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1, std::unique_ptr<crypto::SecureHash>()); ASSERT_TRUE(item->IsDangerous()); @@ -2121,9 +2058,9 @@ // way allows us to bind a call prior to constructing the object on which the // method would be invoked. This is necessary since we are going to construct // various permutations of observer calls that will then be applied to a -// download::DownloadItem in a state as yet undetermined. +// DownloadItem in a state as yet undetermined. using CurriedObservation = - base::Callback<void(base::WeakPtr<download::DownloadDestinationObserver>)>; + base::Callback<void(base::WeakPtr<DownloadDestinationObserver>)>; // A list of observations that are to be made during some event in the // DownloadItemImpl control flow. Ordering of the observations is significant. @@ -2147,21 +2084,20 @@ void DestinationUpdateInvoker( int64_t bytes_so_far, int64_t bytes_per_sec, - base::WeakPtr<download::DownloadDestinationObserver> observer) { + base::WeakPtr<DownloadDestinationObserver> observer) { DVLOG(20) << "DestinationUpdate(bytes_so_far:" << bytes_so_far << ", bytes_per_sec:" << bytes_per_sec << ") observer:" << !!observer; if (observer) { - observer->DestinationUpdate( - bytes_so_far, bytes_per_sec, - std::vector<download::DownloadItem::ReceivedSlice>()); + observer->DestinationUpdate(bytes_so_far, bytes_per_sec, + std::vector<DownloadItem::ReceivedSlice>()); } } void DestinationErrorInvoker( - download::DownloadInterruptReason reason, + DownloadInterruptReason reason, int64_t bytes_so_far, - base::WeakPtr<download::DownloadDestinationObserver> observer) { + base::WeakPtr<DownloadDestinationObserver> observer) { DVLOG(20) << "DestinationError(reason:" << DownloadInterruptReasonToString(reason) << ", bytes_so_far:" << bytes_so_far << ") observer:" << !!observer; @@ -2172,7 +2108,7 @@ void DestinationCompletedInvoker( int64_t total_bytes, - base::WeakPtr<download::DownloadDestinationObserver> observer) { + base::WeakPtr<DownloadDestinationObserver> observer) { DVLOG(20) << "DestinationComplete(total_bytes:" << total_bytes << ") observer:" << !!observer; if (observer) @@ -2244,9 +2180,8 @@ std::vector<EventList> GenerateFailingEventLists() { std::vector<CurriedObservation> all_observations; all_observations.push_back(base::Bind(&DestinationUpdateInvoker, 100, 100)); - all_observations.push_back( - base::Bind(&DestinationErrorInvoker, - download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 100)); + all_observations.push_back(base::Bind( + &DestinationErrorInvoker, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 100)); return DistributeObservationsIntoEvents(all_observations.begin(), all_observations.end(), kEventCount); } @@ -2258,7 +2193,7 @@ DownloadItemDestinationUpdateRaceTest() : DownloadItemTest(), item_(CreateDownloadItem()), - file_(new ::testing::StrictMock<download::MockDownloadFile>()), + file_(new ::testing::StrictMock<MockDownloadFile>()), request_handle_(new ::testing::StrictMock<MockRequestHandle>()) { DCHECK_EQ(GetParam().size(), static_cast<unsigned>(kEventCount)); } @@ -2282,14 +2217,14 @@ // that are already scheduled. void ScheduleObservations( const ObservationList& observations, - base::WeakPtr<download::DownloadDestinationObserver> observer) { + base::WeakPtr<DownloadDestinationObserver> observer) { for (const auto action : observations) - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(action, observer)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(action, observer)); } - download::DownloadItemImpl* item_; - std::unique_ptr<download::MockDownloadFile> file_; + DownloadItemImpl* item_; + std::unique_ptr<MockDownloadFile> file_; std::unique_ptr<MockRequestHandle> request_handle_; base::queue<base::Closure> successful_update_events_; @@ -2314,36 +2249,35 @@ EXPECT_CALL(*file_, Cancel()); EXPECT_CALL(*request_handle_, CancelRequest(_)); - download::DownloadFile::InitializeCallback initialize_callback; + DownloadFile::InitializeCallback initialize_callback; EXPECT_CALL(*file_, Initialize(_, _, _, _)) .WillOnce(SaveArg<0>(&initialize_callback)); item_->Start(std::move(file_), std::move(request_handle_), *create_info(), nullptr, nullptr); task_environment_.RunUntilIdle(); - base::WeakPtr<download::DownloadDestinationObserver> destination_observer = + base::WeakPtr<DownloadDestinationObserver> destination_observer = item_->DestinationObserverAsWeakPtr(); ScheduleObservations(PreInitializeFileObservations(), destination_observer); task_environment_.RunUntilIdle(); - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; + DownloadItemImplDelegate::DownloadTargetCallback target_callback; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) .WillOnce(SaveArg<1>(&target_callback)); ScheduleObservations(PostInitializeFileObservations(), destination_observer); - std::move(initialize_callback) - .Run(download::DOWNLOAD_INTERRUPT_REASON_NONE, 0); + std::move(initialize_callback).Run(DOWNLOAD_INTERRUPT_REASON_NONE, 0); task_environment_.RunUntilIdle(); ASSERT_FALSE(target_callback.is_null()); ScheduleObservations(PostTargetDeterminationObservations(), destination_observer); - target_callback.Run( - base::FilePath(), download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(), - download::DOWNLOAD_INTERRUPT_REASON_NONE); - EXPECT_EQ(download::DownloadItem::CANCELLED, item_->GetState()); + target_callback.Run(base::FilePath(), + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(), + DOWNLOAD_INTERRUPT_REASON_NONE); + EXPECT_EQ(DownloadItem::CANCELLED, item_->GetState()); task_environment_.RunUntilIdle(); } @@ -2356,12 +2290,12 @@ // Intermediate rename loop is not used immediately, but let's set up the // DownloadFile expectations since we are about to transfer its ownership to - // the download::DownloadItem. - download::DownloadFile::RenameCompletionCallback intermediate_rename_callback; + // the DownloadItem. + DownloadFile::RenameCompletionCallback intermediate_rename_callback; EXPECT_CALL(*file_, RenameAndUniquify(_, _)) .WillOnce(SaveArg<1>(&intermediate_rename_callback)); - download::DownloadFile::InitializeCallback initialize_callback; + DownloadFile::InitializeCallback initialize_callback; EXPECT_CALL(*file_, Initialize(_, _, _, _)) .WillOnce(SaveArg<0>(&initialize_callback)); @@ -2369,18 +2303,17 @@ nullptr, nullptr); task_environment_.RunUntilIdle(); - base::WeakPtr<download::DownloadDestinationObserver> destination_observer = + base::WeakPtr<DownloadDestinationObserver> destination_observer = item_->DestinationObserverAsWeakPtr(); ScheduleObservations(PreInitializeFileObservations(), destination_observer); task_environment_.RunUntilIdle(); - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; + DownloadItemImplDelegate::DownloadTargetCallback target_callback; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) .WillOnce(SaveArg<1>(&target_callback)); ScheduleObservations(PostInitializeFileObservations(), destination_observer); - std::move(initialize_callback) - .Run(download::DOWNLOAD_INTERRUPT_REASON_NONE, 0); + std::move(initialize_callback).Run(DOWNLOAD_INTERRUPT_REASON_NONE, 0); task_environment_.RunUntilIdle(); ASSERT_FALSE(target_callback.is_null()); @@ -2388,21 +2321,21 @@ ScheduleObservations(PostTargetDeterminationObservations(), destination_observer); target_callback.Run(base::FilePath(kDummyTargetPath), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(kDummyIntermediatePath), - download::DOWNLOAD_INTERRUPT_REASON_NONE); + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); ASSERT_FALSE(intermediate_rename_callback.is_null()); ScheduleObservations(PostIntermediateRenameObservations(), destination_observer); - intermediate_rename_callback.Run( - download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, base::FilePath()); + intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, + base::FilePath()); task_environment_.RunUntilIdle(); - EXPECT_EQ(download::DownloadItem::INTERRUPTED, item_->GetState()); + EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState()); } // Run through the DII workflow. Download file initialization, target @@ -2421,12 +2354,12 @@ // Intermediate rename loop is not used immediately, but let's set up the // DownloadFile expectations since we are about to transfer its ownership to - // the download::DownloadItem. - download::DownloadFile::RenameCompletionCallback intermediate_rename_callback; + // the DownloadItem. + DownloadFile::RenameCompletionCallback intermediate_rename_callback; EXPECT_CALL(*file_, RenameAndUniquify(_, _)) .WillOnce(SaveArg<1>(&intermediate_rename_callback)); - download::DownloadFile::InitializeCallback initialize_callback; + DownloadFile::InitializeCallback initialize_callback; EXPECT_CALL(*file_, Initialize(_, _, _, _)) .WillOnce(SaveArg<0>(&initialize_callback)); @@ -2434,18 +2367,17 @@ nullptr, nullptr); task_environment_.RunUntilIdle(); - base::WeakPtr<download::DownloadDestinationObserver> destination_observer = + base::WeakPtr<DownloadDestinationObserver> destination_observer = item_->DestinationObserverAsWeakPtr(); ScheduleObservations(PreInitializeFileObservations(), destination_observer); task_environment_.RunUntilIdle(); - download::DownloadItemImplDelegate::DownloadTargetCallback target_callback; + DownloadItemImplDelegate::DownloadTargetCallback target_callback; EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) .WillOnce(SaveArg<1>(&target_callback)); ScheduleObservations(PostInitializeFileObservations(), destination_observer); - std::move(initialize_callback) - .Run(download::DOWNLOAD_INTERRUPT_REASON_NONE, 0); + std::move(initialize_callback).Run(DOWNLOAD_INTERRUPT_REASON_NONE, 0); task_environment_.RunUntilIdle(); ASSERT_FALSE(target_callback.is_null()); @@ -2453,10 +2385,10 @@ ScheduleObservations(PostTargetDeterminationObservations(), destination_observer); target_callback.Run(base::FilePath(kDummyTargetPath), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadItem::TARGET_DISPOSITION_OVERWRITE, + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(kDummyIntermediatePath), - download::DOWNLOAD_INTERRUPT_REASON_NONE); + DOWNLOAD_INTERRUPT_REASON_NONE); task_environment_.RunUntilIdle(); ASSERT_FALSE(intermediate_rename_callback.is_null()); @@ -2468,7 +2400,7 @@ ScheduleObservations(PostIntermediateRenameObservations(), destination_observer); - intermediate_rename_callback.Run(download::DOWNLOAD_INTERRUPT_REASON_NONE, + intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE, base::FilePath(kDummyIntermediatePath)); task_environment_.RunUntilIdle(); @@ -2477,18 +2409,17 @@ // here. On Debug builds, the DCHECKs will verify that the state transitions // were correct. On Release builds, tests are expected to run to completion // without crashing on success. - EXPECT_TRUE(item_->GetState() == download::DownloadItem::IN_PROGRESS || - item_->GetState() == download::DownloadItem::INTERRUPTED); - if (item_->GetState() == download::DownloadItem::INTERRUPTED) - EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, - item_->GetLastReason()); + EXPECT_TRUE(item_->GetState() == DownloadItem::IN_PROGRESS || + item_->GetState() == DownloadItem::INTERRUPTED); + if (item_->GetState() == DownloadItem::INTERRUPTED) + EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item_->GetLastReason()); item_->Cancel(true); task_environment_.RunUntilIdle(); } TEST(MockDownloadItem, Compiles) { - download::MockDownloadItem mock_item; + MockDownloadItem mock_item; } -} // namespace content +} // namespace download
diff --git a/components/download/internal/common/download_task_runner.cc b/components/download/internal/common/download_task_runner.cc index 297e041..d8b2547 100644 --- a/components/download/internal/common/download_task_runner.cc +++ b/components/download/internal/common/download_task_runner.cc
@@ -25,8 +25,8 @@ base::TaskTraits(base::MayBlock(), base::TaskPriority::USER_VISIBLE)); #endif -base::LazyInstance<scoped_refptr<base::SingleThreadTaskRunner>>::Leaky - g_io_task_runner = LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<scoped_refptr<base::SingleThreadTaskRunner>>:: + DestructorAtExit g_io_task_runner = LAZY_INSTANCE_INITIALIZER; } // namespace @@ -36,7 +36,19 @@ void SetIOTaskRunner( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { - g_io_task_runner.Get() = task_runner; + static int count = 0; + if (task_runner) { + DCHECK(!g_io_task_runner.Get() || + task_runner.get() == g_io_task_runner.Get().get()); + count++; + g_io_task_runner.Get() = task_runner; + return; + } + + count--; + DCHECK_GE(count, 0); + if (count == 0) + g_io_task_runner.Get() = nullptr; } scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() {
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java index e533d34..0ac20f15 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
@@ -63,6 +63,23 @@ public static final String CHROME_HOME_MENU_HEADER_CLICKED = "chrome_home_menu_header_clicked"; /** + * The contextual suggestions bottom sheet was explicitly dismissed via a tap on its close + * button. + */ + public static final String CONTEXTUAL_SUGGESTIONS_DISMISSED = + "contextual_suggestions_dismissed"; + + /** + * The contextual suggestions bottom sheet was opened. + */ + public static final String CONTEXTUAL_SUGGESTIONS_OPENED = "contextual_suggestions_opened"; + + /** + * The contextual suggestions bottom sheet was shown in its peeking state. + */ + public static final String CONTEXTUAL_SUGGESTIONS_PEEKED = "contextual_suggestions_peeked"; + + /** * Screenshot is taken with Chrome in the foreground. */ public static final String SCREENSHOT_TAKEN_CHROME_IN_FOREGROUND =
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java index 43945151..5d66d9b4 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -14,6 +14,7 @@ public static final String DOWNLOAD_HOME_FEATURE = "IPH_DownloadHome"; public static final String CHROME_HOME_EXPAND_FEATURE = "IPH_ChromeHomeExpand"; public static final String CHROME_HOME_PULL_TO_REFRESH_FEATURE = "IPH_ChromeHomePullToRefresh"; + public static final String CONTEXTUAL_SUGGESTIONS_FEATURE = "IPH_ContextualSuggestions"; public static final String DATA_SAVER_PREVIEW_FEATURE = "IPH_DataSaverPreview"; public static final String DATA_SAVER_DETAIL_FEATURE = "IPH_DataSaverDetail";
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index ca3b4ce0..aba16eff 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -39,6 +39,8 @@ "IPH_ContextualSearchPromotePanelOpen", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHContextualSearchOptInFeature{ "IPH_ContextualSearchOptIn", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHContextualSuggestionsFeature{ + "IPH_ContextualSuggestions", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_ANDROID) #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index d7d39f14..fe4fa56 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -33,6 +33,7 @@ extern const base::Feature kIPHContextualSearchPromoteTapFeature; extern const base::Feature kIPHContextualSearchPromotePanelOpenFeature; extern const base::Feature kIPHContextualSearchOptInFeature; +extern const base::Feature kIPHContextualSuggestionsFeature; #endif // defined(OS_ANDROID) #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index c4989dbe..a1cb2e0 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -28,6 +28,7 @@ &kIPHContextualSearchPromoteTapFeature, &kIPHContextualSearchPromotePanelOpenFeature, &kIPHContextualSearchOptInFeature, + &kIPHContextualSuggestionsFeature, #endif // defined(OS_ANDROID) #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP) &kIPHBookmarkFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index 5b71eba6a..dd4d80e 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -64,6 +64,8 @@ "IPH_ContextualSearchPromotePanelOpen"); DEFINE_VARIATION_PARAM(kIPHContextualSearchOptInFeature, "IPH_ContextualSearchOptIn"); +DEFINE_VARIATION_PARAM(kIPHContextualSuggestionsFeature, + "IPH_ContextualSuggestions"); #endif // defined(OS_ANDROID) #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP) DEFINE_VARIATION_PARAM(kIPHBookmarkFeature, "IPH_Bookmark"); @@ -96,6 +98,7 @@ VARIATION_ENTRY(kIPHContextualSearchPromoteTapFeature), VARIATION_ENTRY(kIPHContextualSearchPromotePanelOpenFeature), VARIATION_ENTRY(kIPHContextualSearchOptInFeature), + VARIATION_ENTRY(kIPHContextualSuggestionsFeature), #elif BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP) VARIATION_ENTRY(kIPHBookmarkFeature), VARIATION_ENTRY(kIPHIncognitoWindowFeature),
diff --git a/components/history/core/browser/history_model_worker_unittest.cc b/components/history/core/browser/history_model_worker_unittest.cc index be48908..6888c48 100644 --- a/components/history/core/browser/history_model_worker_unittest.cc +++ b/components/history/core/browser/history_model_worker_unittest.cc
@@ -70,9 +70,16 @@ } ~HistoryModelWorkerTest() override { - // HistoryModelWorker posts a cleanup task to the UI thread in its - // destructor. Run it to prevent a leak. + // Run tasks that might still have a reference to |worker_|. + ui_thread_->RunUntilIdle(); + history_thread_->RunUntilIdle(); + + // Release the last reference to |worker_|. + EXPECT_TRUE(worker_->HasOneRef()); worker_ = nullptr; + + // Run the DeleteSoon() task posted from ~HistoryModelWorker. This prevents + // a leak. ui_thread_->RunUntilIdle(); }
diff --git a/components/ntp_snippets/BUILD.gn b/components/ntp_snippets/BUILD.gn index 06d4ab9..f9b85fd 100644 --- a/components/ntp_snippets/BUILD.gn +++ b/components/ntp_snippets/BUILD.gn
@@ -48,6 +48,8 @@ "content_suggestions_service.h", "contextual/contextual_content_suggestions_service.cc", "contextual/contextual_content_suggestions_service.h", + "contextual/contextual_content_suggestions_service_proxy.cc", + "contextual/contextual_content_suggestions_service_proxy.h", "contextual/contextual_json_request.cc", "contextual/contextual_json_request.h", "contextual/contextual_suggestion.cc", @@ -207,6 +209,7 @@ "category_unittest.cc", "content_suggestions_metrics_unittest.cc", "content_suggestions_service_unittest.cc", + "contextual/contextual_content_suggestions_service_proxy_unittest.cc", "contextual/contextual_content_suggestions_service_unittest.cc", "contextual/contextual_json_request_unittest.cc", "contextual/contextual_suggestions_fetcher_impl_unittest.cc",
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc index 4f9af9b..ba2c0a6 100644 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc
@@ -26,6 +26,9 @@ ContextualContentSuggestionsService::Cluster::Cluster() = default; +ContextualContentSuggestionsService::Cluster::Cluster(const std::string& title) + : title(title) {} + ContextualContentSuggestionsService::Cluster::Cluster(Cluster&& other) = default; @@ -70,19 +73,27 @@ void ContextualContentSuggestionsService::FetchContextualSuggestionImage( const ContentSuggestion::ID& suggestion_id, + const GURL& image_url, + ImageFetchedCallback callback) { + image_fetcher_->FetchSuggestionImage(suggestion_id, image_url, + ImageDataFetchedCallback(), + std::move(callback)); +} + +void ContextualContentSuggestionsService::FetchContextualSuggestionImageLegacy( + const ContentSuggestion::ID& suggestion_id, ImageFetchedCallback callback) { const std::string& id_within_category = suggestion_id.id_within_category(); auto image_url_iterator = image_url_by_id_.find(id_within_category); - if (image_url_iterator != image_url_by_id_.end()) { - GURL image_url = image_url_iterator->second; - image_fetcher_->FetchSuggestionImage(suggestion_id, image_url, - ImageDataFetchedCallback(), - std::move(callback)); - } else { + if (image_url_iterator == image_url_by_id_.end()) { DVLOG(1) << "FetchContextualSuggestionImage unknown image" << " id_within_category: " << id_within_category; std::move(callback).Run(gfx::Image()); + return; } + + GURL image_url = image_url_iterator->second; + FetchContextualSuggestionImage(suggestion_id, image_url, std::move(callback)); } void ContextualContentSuggestionsService::ReportEvent(
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service.h b/components/ntp_snippets/contextual/contextual_content_suggestions_service.h index eecbfe3e..c4dcea9 100644 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service.h +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service.h
@@ -33,6 +33,7 @@ struct Cluster { public: Cluster(); + explicit Cluster(const std::string& title); Cluster(Cluster&& other); ~Cluster(); @@ -64,23 +65,32 @@ std::vector<Cluster> clusters)>; // Asynchronously fetches contextual suggestions for the given URL. - void FetchContextualSuggestions(const GURL& url, - FetchContextualSuggestionsCallback callback); + virtual void FetchContextualSuggestions( + const GURL& url, + FetchContextualSuggestionsCallback callback); // Asynchronously fetches contextual suggestions for the given URL. - void FetchContextualSuggestionClusters( + virtual void FetchContextualSuggestionClusters( const GURL& url, FetchContextualSuggestionClustersCallback callback); + // Fetches an image pointed to by |url| and internally caches it using + // |suggestion_id|. Asynchronous if cache or network is queried. + virtual void FetchContextualSuggestionImage( + const ContentSuggestion::ID& suggestion_id, + const GURL& url, + ImageFetchedCallback callback); + // Fetches an image for a given contextual suggestion ID. // Asynchronous if cache or network is queried. - void FetchContextualSuggestionImage( + virtual void FetchContextualSuggestionImageLegacy( const ContentSuggestion::ID& suggestion_id, ImageFetchedCallback callback); // Used to report events using various metrics (e.g. UMA, UKM). - void ReportEvent(ukm::SourceId sourceId, - contextual_suggestions::ContextualSuggestionsEvent event); + virtual void ReportEvent( + ukm::SourceId sourceId, + contextual_suggestions::ContextualSuggestionsEvent event); // KeyedService overrides. void Shutdown() override;
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.cc new file mode 100644 index 0000000..133082f --- /dev/null +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.cc
@@ -0,0 +1,90 @@ +// Copyright 2018 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/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" + +#include <utility> + +#include "base/bind.h" +#include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" +#include "ui/gfx/image/image.h" +#include "url/gurl.h" + +namespace contextual_suggestions { + +ContextualContentSuggestionsServiceProxy:: + ContextualContentSuggestionsServiceProxy( + ntp_snippets::ContextualContentSuggestionsService* service) + : service_(service), weak_ptr_factory_(this) {} + +ContextualContentSuggestionsServiceProxy:: + ~ContextualContentSuggestionsServiceProxy() {} + +void ContextualContentSuggestionsServiceProxy::FetchContextualSuggestions( + const GURL& url, + ClustersCallback callback) { + service_->FetchContextualSuggestionClusters( + url, base::BindOnce( + &ContextualContentSuggestionsServiceProxy::CacheSuggestions, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} + +void ContextualContentSuggestionsServiceProxy::FetchContextualSuggestionImage( + const std::string& suggestion_id, + ntp_snippets::ImageFetchedCallback callback) { + auto suggestion_iter = suggestions_.find(suggestion_id); + if (suggestion_iter == suggestions_.end()) { + DVLOG(1) << "Unkown suggestion ID: " << suggestion_id; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), gfx::Image())); + return; + } + + // In order to fetch an image or favicon for a suggestion, we are synthesizing + // a suggestion ID for it, so that it could be cached in the cached image + // fetcher inside of the service. + + // Short term implementation. + GURL image_url = suggestion_iter->second.salient_image_url(); + + // This will be the same after this line. + ntp_snippets::ContentSuggestion::ID synthetic_id( + ntp_snippets::Category::FromKnownCategory( + ntp_snippets::KnownCategories::CONTEXTUAL), + suggestion_id); + + service_->FetchContextualSuggestionImage(synthetic_id, image_url, + std::move(callback)); +} + +void ContextualContentSuggestionsServiceProxy::FetchContextualSuggestionFavicon( + const std::string& suggestion_id, + ntp_snippets::ImageFetchedCallback callback) {} + +void ContextualContentSuggestionsServiceProxy::ClearState() { + suggestions_.clear(); + weak_ptr_factory_.InvalidateWeakPtrs(); +} + +void ContextualContentSuggestionsServiceProxy::ReportEvent( + ukm::SourceId ukm_source_id, + ContextualSuggestionsEvent event) { + service_->ReportEvent(ukm_source_id, event); +} + +void ContextualContentSuggestionsServiceProxy::CacheSuggestions( + ClustersCallback callback, + std::string peek_text, + std::vector<Cluster> clusters) { + suggestions_.clear(); + for (auto& cluster : clusters) { + for (auto& suggestion : cluster.suggestions) { + suggestions_.emplace(std::make_pair(suggestion->id(), *suggestion)); + } + } + std::move(callback).Run(peek_text, std::move(clusters)); +} + +} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h new file mode 100644 index 0000000..95f4215 --- /dev/null +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h
@@ -0,0 +1,74 @@ +// Copyright 2018 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_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_PROXY_H_ +#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_PROXY_H_ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" + +class GURL; + +namespace contextual_suggestions { + +// Class providing access to the Contextual Content Suggestions Service and +// caching the list of current suggestions shown in a tab. It is owned by a UI +// object. There could be multiple instances of serivce proxy. Either can be +// torn down with a part of UI that owns it, which doesn't affect other proxies. +class ContextualContentSuggestionsServiceProxy { + public: + using ClustersCallback = ntp_snippets::ContextualContentSuggestionsService:: + FetchContextualSuggestionClustersCallback; + using Cluster = ntp_snippets::ContextualContentSuggestionsService::Cluster; + + explicit ContextualContentSuggestionsServiceProxy( + ntp_snippets::ContextualContentSuggestionsService* service); + ~ContextualContentSuggestionsServiceProxy(); + + // Fetches contextual suggestions for a given |url|. + void FetchContextualSuggestions(const GURL& url, ClustersCallback callback); + + // Fetches an image for a contextual suggestion with specified + // |suggestion_id|. + void FetchContextualSuggestionImage( + const std::string& suggestion_id, + ntp_snippets::ImageFetchedCallback callback); + + // Fetches a favicon for a contextual suggestion with specified + // |suggestion_id|. + void FetchContextualSuggestionFavicon( + const std::string& suggestion_id, + ntp_snippets::ImageFetchedCallback callback); + + // Clears the state of the proxy. + void ClearState(); + + // Reports user interface event to the service. + void ReportEvent(ukm::SourceId, ContextualSuggestionsEvent event); + + private: + void CacheSuggestions(ClustersCallback callback, + std::string peek_text, + std::vector<Cluster> clusters); + // Pointer to the service. + ntp_snippets::ContextualContentSuggestionsService* service_; + // Cache of contextual suggestions. + std::map<std::string, ntp_snippets::ContextualSuggestion> suggestions_; + + // Weak pointer factory to cancel pending callbacks. + base::WeakPtrFactory<ContextualContentSuggestionsServiceProxy> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsServiceProxy); +}; + +} // namespace contextual_suggestions + +#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_PROXY_H_
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy_unittest.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy_unittest.cc new file mode 100644 index 0000000..3c9ab085 --- /dev/null +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy_unittest.cc
@@ -0,0 +1,112 @@ +// Copyright 2018 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/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" + +#include <memory> +#include <string> + +#include "base/bind.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" +#include "components/ntp_snippets/remote/cached_image_fetcher.h" +#include "components/ntp_snippets/remote/remote_suggestions_database.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::IsEmpty; +using testing::Pointee; + +namespace contextual_suggestions { + +using Cluster = ntp_snippets::ContextualContentSuggestionsService::Cluster; +using ClustersCallback = ntp_snippets::ContextualContentSuggestionsService:: + FetchContextualSuggestionClustersCallback; + +namespace { + +static const std::string kTestPeekText("Test peek test"); +static const std::string kValidFromUrl = "http://some.url"; + +class FakeContextualContentSuggestionsService + : public ntp_snippets::ContextualContentSuggestionsService { + public: + FakeContextualContentSuggestionsService(); + ~FakeContextualContentSuggestionsService() override; + + void FetchContextualSuggestionClusters(const GURL& url, + ClustersCallback callback) override { + clusters_callback_ = std::move(callback); + } + + void RunClustersCallback(std::string peek_text, + std::vector<Cluster> clusters) { + std::move(clusters_callback_) + .Run(std::move(peek_text), std::move(clusters)); + } + + private: + ClustersCallback clusters_callback_; +}; + +FakeContextualContentSuggestionsService:: + FakeContextualContentSuggestionsService() + : ContextualContentSuggestionsService(nullptr, nullptr, nullptr, nullptr) {} + +FakeContextualContentSuggestionsService:: + ~FakeContextualContentSuggestionsService() {} + +// GMock does not support movable-only types (Cluster). +// Instead WrappedRun is used as callback and it redirects the call to a +// method without movable-only types, which is then mocked. +class MockClustersCallback { + public: + void WrappedRun(std::string peek_text, std::vector<Cluster> clusters) { + Run(peek_text, &clusters); + } + + ClustersCallback ToOnceCallback() { + return base::BindOnce(&MockClustersCallback::WrappedRun, + base::Unretained(this)); + } + + MOCK_METHOD2(Run, + void(const std::string& peek_text, + std::vector<Cluster>* clusters)); +}; + +} // namespace + +class ContextualContentSuggestionsServiceProxyTest : public testing::Test { + public: + void SetUp() override; + + FakeContextualContentSuggestionsService* service() { return service_.get(); } + + ContextualContentSuggestionsServiceProxy* proxy() { return proxy_.get(); } + + private: + std::unique_ptr<FakeContextualContentSuggestionsService> service_; + std::unique_ptr<ContextualContentSuggestionsServiceProxy> proxy_; +}; + +void ContextualContentSuggestionsServiceProxyTest::SetUp() { + service_ = std::make_unique<FakeContextualContentSuggestionsService>(); + proxy_ = std::make_unique<ContextualContentSuggestionsServiceProxy>( + service_.get()); +} + +TEST_F(ContextualContentSuggestionsServiceProxyTest, + FetchSuggestionsWhenEmpty) { + MockClustersCallback mock_cluster_callback; + + proxy()->FetchContextualSuggestions(GURL(kValidFromUrl), + mock_cluster_callback.ToOnceCallback()); + EXPECT_CALL(mock_cluster_callback, Run(kTestPeekText, Pointee(IsEmpty()))); + service()->RunClustersCallback(kTestPeekText, std::vector<Cluster>()); +} + +// TODO(fgorski): More tests will be added, once we have the suggestions +// restructured. + +} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc index 612e34c..3706fbd 100644 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc
@@ -205,8 +205,8 @@ Category::FromKnownCategory(KnownCategories::CONTEXTUAL), kEmpty); EXPECT_CALL(mock_image_fetched_callback, Run(Property(&gfx::Image::IsEmpty, true))); - source()->FetchContextualSuggestionImage(id, - mock_image_fetched_callback.Get()); + source()->FetchContextualSuggestionImageLegacy( + id, mock_image_fetched_callback.Get()); // TODO(gaschler): Verify with a mock that the image fetcher is not called if // the id is unknown. base::RunLoop().RunUntilIdle(); @@ -235,8 +235,8 @@ base::MockCallback<ImageFetchedCallback> mock_image_fetched_callback; EXPECT_CALL(mock_image_fetched_callback, Run(Property(&gfx::Image::IsEmpty, false))); - source()->FetchContextualSuggestionImage(suggestions[0].id(), - mock_image_fetched_callback.Get()); + source()->FetchContextualSuggestionImageLegacy( + suggestions[0].id(), mock_image_fetched_callback.Get()); base::RunLoop().RunUntilIdle(); }
diff --git a/components/ntp_snippets/contextual/contextual_suggestion.cc b/components/ntp_snippets/contextual/contextual_suggestion.cc index 546d7f1..7d53ebd9 100644 --- a/components/ntp_snippets/contextual/contextual_suggestion.cc +++ b/components/ntp_snippets/contextual/contextual_suggestion.cc
@@ -42,6 +42,9 @@ ContextualSuggestion::ContextualSuggestion(const std::string& id) : id_(id) {} +ContextualSuggestion::ContextualSuggestion(const ContextualSuggestion& other) = + default; + ContextualSuggestion::~ContextualSuggestion() = default; // static
diff --git a/components/ntp_snippets/contextual/contextual_suggestion.h b/components/ntp_snippets/contextual/contextual_suggestion.h index eb48dbe..cddd0d6 100644 --- a/components/ntp_snippets/contextual/contextual_suggestion.h +++ b/components/ntp_snippets/contextual/contextual_suggestion.h
@@ -26,6 +26,7 @@ public: using PtrVector = std::vector<std::unique_ptr<ContextualSuggestion>>; + ContextualSuggestion(const ContextualSuggestion& other); ~ContextualSuggestion(); // Creates a ContextualSuggestion from a dictionary. Returns a null pointer if @@ -56,6 +57,8 @@ // network requests. const GURL& salient_image_url() const { return salient_image_url_; } + const std::string& image_id() const { return image_id_; } + static std::unique_ptr<ContextualSuggestion> CreateForTesting( const std::string& to_url, const std::string& image_url); @@ -72,6 +75,7 @@ GURL url_; std::string publisher_name_; GURL salient_image_url_; + std::string image_id_; std::string snippet_; base::Time publish_date_; };
diff --git a/components/ntp_tiles/most_visited_sites_unittest.cc b/components/ntp_tiles/most_visited_sites_unittest.cc index d8a4aaa..dcc584a 100644 --- a/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -10,6 +10,7 @@ #include <memory> #include <ostream> #include <string> +#include <tuple> #include <utility> #include <vector> @@ -110,7 +111,7 @@ ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - ::std::tr1::get<k>(args).Run(p0); + std::get<k>(args).Run(p0); } NTPTile MakeTile(const std::string& title,
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index b3b34f1..e1321ce 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -242,6 +242,9 @@ <message name="IDS_PAGE_INFO_TYPE_SENSORS" desc="The label used for the sensor permission controls in the Page Info popup. Title case format."> Motion or Light Sensors </message> + <message name="IDS_PAGE_INFO_TYPE_USB" desc="The label used for the USB permission controls in the Page Info popup."> + USB devices + </message> <!-- TODO(crbug.com/716303): A few permissions are missing here. --> <!-- Permission values --> @@ -290,7 +293,10 @@ <message name="IDS_PAGE_INFO_MENU_ITEM_BLOCK" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to allow."> Always block on this site </message> - <message name="IDS_PAGE_INFO_MENU_ITEM_DETECT_IMPORTANT_CONTENT" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to detect important content."> + <message name="IDS_PAGE_INFO_MENU_ITEM_ASK" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to ask."> + Always ask on this site + </message> + <message name="IDS_PAGE_INFO_MENU_ITEM_DETECT_IMPORTANT_CONTENT" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to detect important content."> Always detect important content on this site </message> <message name="IDS_PAGE_INFO_MENU_ITEM_ADS_BLOCK" desc="The text of the menu item of a permissions menu on the Page Info UI for the ads permission in Block mode">
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_MENU_ITEM_ASK.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_MENU_ITEM_ASK.png.sha1 new file mode 100644 index 0000000..7354287b --- /dev/null +++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_MENU_ITEM_ASK.png.sha1
@@ -0,0 +1 @@ +614553f1458fbe4e2de4e581bb0850c8831cf165 \ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_TYPE_USB.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_TYPE_USB.png.sha1 new file mode 100644 index 0000000..7354287b --- /dev/null +++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_TYPE_USB.png.sha1
@@ -0,0 +1 @@ +614553f1458fbe4e2de4e581bb0850c8831cf165 \ No newline at end of file
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 3a835d46..3309194 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -396,6 +396,7 @@ "//components/autofill/core/common", "//components/os_crypt:test_support", "//components/password_manager/core/browser:proto", + "//components/password_manager/core/browser/form_parsing/fuzzer:unit_tests", "//components/password_manager/core/common", "//components/prefs:test_support", "//components/security_state/core",
diff --git a/components/password_manager/core/browser/form_parsing/BUILD.gn b/components/password_manager/core/browser/form_parsing/BUILD.gn index 9d5c5be..1ab9c56 100644 --- a/components/password_manager/core/browser/form_parsing/BUILD.gn +++ b/components/password_manager/core/browser/form_parsing/BUILD.gn
@@ -2,7 +2,14 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -if (is_ios) { +import("//build/config/sanitizers/sanitizers.gni") + +# Determine whetner fuzzer_test targets are built. +does_fuzzer_test_compile = + !disable_libfuzzer && (use_fuzzing_engine || use_drfuzz || is_linux) + +if (does_fuzzer_test_compile || is_ios) { + # Compile for production under iOS and for fuzzing whenever fuzzer_tests are built. static_library("form_parsing") { sources = [ "ios_form_parser.cc", @@ -30,4 +37,4 @@ "//url", ] } -} # if (is_ios) +} # if (does_fuzzer_test_compile || is_ios)
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/BUILD.gn b/components/password_manager/core/browser/form_parsing/fuzzer/BUILD.gn new file mode 100644 index 0000000..c763341 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/BUILD.gn
@@ -0,0 +1,49 @@ +# Copyright 2018 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. + +import("//testing/libfuzzer/fuzzer_test.gni") + +static_library("fuzzer_support") { + sources = [ + "data_accessor.cc", + "data_accessor.h", + "form_data_producer.cc", + "form_data_producer.h", + ] + + deps = [ + "//base", + "//components/autofill/core/common", + "//url", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "data_accessor_unittest.cc", + ] + + deps = [ + ":fuzzer_support", + "//base", + "//testing/gtest", + ] +} + +fuzzer_test("password_manager_form_parser_fuzzer") { + sources = [ + "form_parser_fuzzer.cc", + ] + + deps = [ + ":fuzzer_support", + "//base", + "//base:i18n", + "//components/autofill/core/common", + "//components/password_manager/core/browser/form_parsing", + ] + + dict = "form_parser_fuzzer.dict" +}
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.cc b/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.cc new file mode 100644 index 0000000..2d1df77 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.cc
@@ -0,0 +1,112 @@ +// Copyright 2018 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/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h" + +#include <string.h> + +#include <algorithm> +#include <bitset> + +#include "base/logging.h" + +namespace password_manager { + +namespace { + +// The maximum byte length of a string to be returned by |ConsumeString*|. +constexpr size_t kMaxStringBytes = 256; + +} // namespace + +DataAccessor::DataAccessor(const uint8_t* data, size_t size) + : data_(data), bits_consumed_(0), size_(size) { + DCHECK(data_ || size_ == 0); // Enforce the first invariant for data members. +} + +DataAccessor::~DataAccessor() = default; + +bool DataAccessor::ConsumeBit() { + return ConsumeNumber(1) != 0; +} + +size_t DataAccessor::ConsumeNumber(size_t bit_length) { + CHECK_LE(bit_length, sizeof(size_t) * 8); + + // Fast track. + if (bit_length == 0) + return 0; + + // No genuine input bits left, return padding. + if (size_ == 0) + return 0; + + // Compute the number recursively, processing one byte from |data_| at a time. + std::bitset<8> b(*data_); + if (bits_consumed_ + bit_length < 8) { // Base case: all within |*data_|. + // Shift the |bit_length|-sized interesting window up and down to discard + // uninteresting bits. An alternative approach would be: + // b << bit_length; // Discard consumed bits. + // b &= std::bitset<8>((1 << bit_length) - 1); // Discard the tail. + // But the shifting below avoids the construction of the temproary bitset. + b <<= (8 - bits_consumed_ - bit_length); + b >>= (8 - bit_length); + bits_consumed_ += bit_length; + return b.to_ulong(); + } + // Recursive case: crossing the byte boundary in |data_|. + const size_t original_bits_consumed = bits_consumed_; + bit_length -= (8 - bits_consumed_); + bits_consumed_ = 0; + ++data_; + --size_; + return (b.to_ulong() | (ConsumeNumber(bit_length) << 8)) >> + original_bits_consumed; +} + +void DataAccessor::ConsumeBytesToBuffer(size_t length, uint8_t* string_buffer) { + // First of all, align to a whole byte for efficiency. + if (size_ > 0 && bits_consumed_ != 0) { + bits_consumed_ = 0; + ++data_; + --size_; + } + + size_t non_padded_length = std::min(length, size_); + std::memcpy(string_buffer, data_, non_padded_length); + + if (non_padded_length != length) { + // Pad with zeroes as needed. + std::memset(string_buffer + non_padded_length, 0, + length - non_padded_length); + // The rest of the input string was not enough, so now it's certainly + // depleted. + size_ = 0; + } else { + // There was either more of the input string than needed, or just exactly + // enough bytes of it. Either way, the update below reflects the new + // situation. + size_ -= length; + data_ += length; + } +} + +std::string DataAccessor::ConsumeString(size_t length) { + CHECK_LE(length, kMaxStringBytes); + + uint8_t string_buffer[kMaxStringBytes]; + ConsumeBytesToBuffer(length, string_buffer); + return std::string(reinterpret_cast<const char*>(string_buffer), length); +} + +base::string16 DataAccessor::ConsumeString16(size_t length) { + CHECK_LE(2 * length, kMaxStringBytes); + + uint8_t string_buffer[kMaxStringBytes]; + ConsumeBytesToBuffer(2 * length, string_buffer); + return base::string16( + reinterpret_cast<base::string16::value_type*>(string_buffer), length); +} + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h b/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h new file mode 100644 index 0000000..1130440 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h
@@ -0,0 +1,70 @@ +// Copyright 2018 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_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_FUZZER_DATA_ACCESSOR_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_FUZZER_DATA_ACCESSOR_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <string> + +#include "base/macros.h" +#include "base/strings/string16.h" + +namespace password_manager { + +// DataAccessor is an encapsulation over the input string delivered by the +// fuzzer framework. It pads the input string with zeroes after its end and +// deliveres data based on the consumed string. More details in the design doc +// linked from https://crbug.com/827945#c2. +class DataAccessor { + public: + // Wraps the input string of length |size| at address |data|. Does not own the + // input string. It sets the "reading head" to the start of the string and + // advances it with each Consume* operation to avoid generating data from the + // same part of input twice. + DataAccessor(const uint8_t* data, size_t size); + + ~DataAccessor(); + + // Return the next bit and advance the "reading head" by one bit. + bool ConsumeBit(); + + // Return the number stored on the next |bit_length| bits and advance the + // "reading head" by |bit_length| bits. + size_t ConsumeNumber(size_t bit_length); + + // Advance the "reading head" to the next whole-byte boundary, if needed, then + // return the string stored in the next |length| characters, advancing the + // "reading head" to point past the read data. A "character" means byte for + // std::string and two bytes for base::string16. At most 256 bytes can be + // consumed at once, hence |length| is restricted as noted below. + std::string ConsumeString(size_t length); // |length| <= 256 + base::string16 ConsumeString16(size_t length); // |length| <= 128 + + private: + // Helper for |ConsumeString*|. It combines the |data_| and padding, if + // needed, into |string_buffer|, to provide |length| bytes for creating a new + // string. It also updates |data_|, |bits_consumed_| and |size_| accordingly. + void ConsumeBytesToBuffer(size_t length, uint8_t* string_buffer); + + // The remaining portion of the input string (without padding) starts at + // |data_| without the least significant |bits_consumed_| bits, and lasts + // until |data_ + size_|, exclusively. If |size_| is 0, then there is not a + // single bit left and all available is just the 0-padding. + // Invariants: + // * |data_| is not null as long as |size_| > 0 + // * |bits_consumed_| < 8 + // * if |size_| == 0 then |bits_consumed_| == 0 + const uint8_t* data_; + size_t bits_consumed_; + size_t size_; + + DISALLOW_COPY_AND_ASSIGN(DataAccessor); +}; + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_FUZZER_DATA_ACCESSOR_H_
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor_unittest.cc b/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor_unittest.cc new file mode 100644 index 0000000..ffbf430 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/data_accessor_unittest.cc
@@ -0,0 +1,92 @@ +// Copyright 2018 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/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h" + +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::UTF8ToUTF16; + +namespace password_manager { + +namespace { + +TEST(DataAccessorTest, NullInput) { + DataAccessor accessor(nullptr, 0); + EXPECT_EQ(0u, accessor.ConsumeNumber(13)); + EXPECT_EQ(false, accessor.ConsumeBit()); + EXPECT_EQ(std::string("\0\0\0", 3), accessor.ConsumeString(3)); + EXPECT_EQ(base::string16(), accessor.ConsumeString16(0)); +} + +TEST(DataAccessorTest, Bit) { + const uint8_t x = 0b10110001; + DataAccessor accessor(&x, 1); + EXPECT_EQ(true, accessor.ConsumeBit()); + EXPECT_EQ(false, accessor.ConsumeBit()); + EXPECT_EQ(false, accessor.ConsumeBit()); + EXPECT_EQ(false, accessor.ConsumeBit()); + EXPECT_EQ(true, accessor.ConsumeBit()); + EXPECT_EQ(true, accessor.ConsumeBit()); + EXPECT_EQ(false, accessor.ConsumeBit()); + EXPECT_EQ(true, accessor.ConsumeBit()); +} + +TEST(DataAccessorTest, Number) { + const uint8_t xs[] = {0b01100110, 0b11100110}; + DataAccessor accessor(xs, sizeof(xs)); + accessor.ConsumeBit(); // Just skip the first bit for fun. + EXPECT_EQ(0b011u, accessor.ConsumeNumber(3)); + EXPECT_EQ(0b0u, accessor.ConsumeNumber(1)); + EXPECT_EQ(0b11u, accessor.ConsumeNumber(2)); + // 10 (2nd byte) ++ 0 (1st byte): + EXPECT_EQ(0b100u, accessor.ConsumeNumber(3)); + EXPECT_EQ(0u, accessor.ConsumeNumber(0)); // An empty string represents 0. + EXPECT_EQ(0b11001u, accessor.ConsumeNumber(5)); + EXPECT_EQ(0b01u, accessor.ConsumeNumber(2)); // 1, also reaching padding + EXPECT_EQ(0b0000000u, accessor.ConsumeNumber(7)); // padding +} + +TEST(DataAccessorTest, String) { + const std::string str = "Test string 123."; + DataAccessor accessor(reinterpret_cast<const uint8_t*>(str.c_str()), + str.size()); + EXPECT_EQ("Test", accessor.ConsumeString(4)); + accessor.ConsumeNumber(3); // Skip 3 bits to test re-alignment. + EXPECT_EQ("string 123", accessor.ConsumeString(10)); + EXPECT_EQ(std::string(), accessor.ConsumeString(0)); + // Test also that padding is included. + EXPECT_EQ(std::string(".\0\0", 3), accessor.ConsumeString(3)); +} + +TEST(DataAccessorTest, String16) { + const base::string16 str = UTF8ToUTF16("Test string 123."); + DataAccessor accessor(reinterpret_cast<const uint8_t*>(str.c_str()), + str.size() * 2); + EXPECT_EQ(UTF8ToUTF16("Test"), accessor.ConsumeString16(4)); + accessor.ConsumeNumber(13); // Skip 13 bits to test re-alignment. + EXPECT_EQ(UTF8ToUTF16("string 123"), accessor.ConsumeString16(10)); + EXPECT_EQ(base::string16(), accessor.ConsumeString16(0)); + // Test also that padding is included. + EXPECT_EQ(UTF8ToUTF16(std::string(".\0\0", 3)), accessor.ConsumeString16(3)); +} + +TEST(DataAccessorTest, Mix) { + const uint8_t xs[] = {'a', 'b', 0b11100101, 5, 9, + 0b10000001, 'c', 'd', 'e', 0}; + DataAccessor accessor(xs, sizeof(xs)); + EXPECT_EQ("ab", accessor.ConsumeString(2)); + EXPECT_EQ(true, accessor.ConsumeBit()); + EXPECT_EQ(0b1110010u, accessor.ConsumeNumber(7)); + EXPECT_EQ(5u, accessor.ConsumeNumber(8)); + EXPECT_EQ(9u + (1u << 8), accessor.ConsumeNumber(9)); + EXPECT_EQ(false, accessor.ConsumeBit()); + EXPECT_EQ("cd", accessor.ConsumeString(2)); + EXPECT_EQ(UTF8ToUTF16("e"), accessor.ConsumeString16(1)); +} +} // namespace + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.cc b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.cc new file mode 100644 index 0000000..a99fb6d0 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.cc
@@ -0,0 +1,109 @@ +// Copyright 2018 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/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.h" + +#include "components/autofill/core/common/form_field_data.h" +#include "components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h" +#include "url/gurl.h" +#include "url/origin.h" + +using autofill::FormData; +using autofill::FormFieldData; + +namespace password_manager { + +namespace { + +struct FormFieldDataParams { + size_t form_control_type_length; + size_t autocomplete_attribute_length; + size_t label_length; + size_t name_length; + size_t id_length; + size_t value_length; + // In an array of FormFieldData, all instances with |same_value_field| true + // get the same value as the first such instance. + bool same_value_field; +}; + +} // namespace + +FormData GenerateWithDataAccessor(DataAccessor* accessor) { + FormData result; + + // First determine the main non-string attributes not specific to particular + // fields. + result.is_form_tag = accessor->ConsumeBit(); + result.is_formless_checkout = accessor->ConsumeBit(); + + // To minimize wasting bits, string-based data itself gets extracted after all + // numbers and flags are. Their length can be determined now, however. A + // reasonable range is 0-127 characters, i.e., 7 bits. + const size_t name_length = accessor->ConsumeNumber(7); + const size_t action_length = accessor->ConsumeNumber(7); + const size_t origin_length = accessor->ConsumeNumber(7); + const size_t main_frame_origin_length = accessor->ConsumeNumber(7); + + // Determine how many fields this form will have. 0-15, i.e., 4 bits. + const size_t number_of_fields = accessor->ConsumeNumber(4); + result.fields.resize(number_of_fields); + FormFieldDataParams field_params[15]; + + int first_field_with_same_value = -1; + for (size_t i = 0; i < number_of_fields; ++i) { + // Determine the non-string value for each field. + result.fields[i].is_focusable = accessor->ConsumeBit(); + // And the lengths of the string values. + field_params[i].form_control_type_length = accessor->ConsumeNumber(7); + field_params[i].autocomplete_attribute_length = accessor->ConsumeNumber(7); + field_params[i].label_length = accessor->ConsumeNumber(7); + field_params[i].name_length = accessor->ConsumeNumber(7); + field_params[i].id_length = accessor->ConsumeNumber(7); + field_params[i].same_value_field = accessor->ConsumeBit(); + bool has_value_copy_from_earlier = field_params[i].same_value_field; + if (field_params[i].same_value_field && first_field_with_same_value == -1) { + first_field_with_same_value = static_cast<int>(i); + has_value_copy_from_earlier = false; + } + // Emtpy values are interesting from the parsing perspective. Ensure that a + // big chunk of the cases ends up with an empty value by letting an input + // bit decide. + field_params[i].value_length = 0; + if (!has_value_copy_from_earlier && accessor->ConsumeBit()) { + field_params[i].value_length = accessor->ConsumeNumber(7) + 1; + } + } + + // Now go back and determine the string-based values of the form itself. + result.name = accessor->ConsumeString16(name_length); + result.action = GURL(accessor->ConsumeString(action_length)); + result.origin = GURL(accessor->ConsumeString(origin_length)); + result.main_frame_origin = url::Origin::Create( + GURL(accessor->ConsumeString(main_frame_origin_length))); + + // And finally do the same for all the fields. + for (size_t i = 0; i < number_of_fields; ++i) { + result.fields[i].form_control_type = + accessor->ConsumeString(field_params[i].form_control_type_length); + result.fields[i].autocomplete_attribute = + accessor->ConsumeString(field_params[i].autocomplete_attribute_length); + result.fields[i].label = + accessor->ConsumeString16(field_params[i].label_length); + result.fields[i].name = + accessor->ConsumeString16(field_params[i].name_length); + result.fields[i].id = accessor->ConsumeString16(field_params[i].id_length); + if (field_params[i].same_value_field && + first_field_with_same_value != static_cast<int>(i)) { + result.fields[i].value = result.fields[first_field_with_same_value].value; + } else { + result.fields[i].value = + accessor->ConsumeString16(field_params[i].value_length); + } + } + + return result; +} + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.h b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.h new file mode 100644 index 0000000..3ea1b79 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.h
@@ -0,0 +1,20 @@ +// Copyright 2018 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_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_FUZZER_FORM_DATA_PRODUCER_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_FUZZER_FORM_DATA_PRODUCER_H_ + +#include "components/autofill/core/common/form_data.h" + +namespace password_manager { + +class DataAccessor; + +// Generates a |FormData| object based on values obtained via |accessor|. See +// https://goo.gl/29t6VH for a detailed design. +autofill::FormData GenerateWithDataAccessor(DataAccessor* accessor); + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_FUZZER_FORM_DATA_PRODUCER_H_
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_parser_fuzzer.cc b/components/password_manager/core/browser/form_parsing/fuzzer/form_parser_fuzzer.cc new file mode 100644 index 0000000..2f581e3 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_parser_fuzzer.cc
@@ -0,0 +1,43 @@ +// Copyright 2018 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 <stddef.h> +#include <stdint.h> + +#include <memory> + +#include "base/at_exit.h" +#include "base/i18n/icu_util.h" +#include "components/autofill/core/common/password_form.h" +#include "components/password_manager/core/browser/form_parsing/fuzzer/data_accessor.h" +#include "components/password_manager/core/browser/form_parsing/fuzzer/form_data_producer.h" +#include "components/password_manager/core/browser/form_parsing/ios_form_parser.h" + +namespace password_manager { + +// ICU is used inside GURL parser, which is used by GenerateWithDataAccessor. +struct IcuEnvironment { + IcuEnvironment() { CHECK(base::i18n::InitializeICU()); } + // used by ICU integration. + base::AtExitManager at_exit_manager; +}; + +IcuEnvironment* env = new IcuEnvironment(); + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + DataAccessor accessor(data, size); + FormParsingMode mode = accessor.ConsumeBit() ? FormParsingMode::FILLING + : FormParsingMode::SAVING; + autofill::FormData form_data = GenerateWithDataAccessor(&accessor); + std::unique_ptr<autofill::PasswordForm> result = + ParseFormData(form_data, mode); + if (result) { + // Create a copy of the result -- running the copy-constructor might + // discover some invalid data in |result|. + autofill::PasswordForm copy(*result); + } + return 0; +} + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_parser_fuzzer.dict b/components/password_manager/core/browser/form_parsing/fuzzer/form_parser_fuzzer.dict new file mode 100644 index 0000000..16e4211 --- /dev/null +++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_parser_fuzzer.dict
@@ -0,0 +1,9 @@ +"http://" +"password" +"username" +"current-password" +"new-password" +"cc-name" +"cc-number" +"cc-csc" +"cc-exp"
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index 5fa6d320..6ed8101 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -169,6 +169,8 @@ void UserTriggeredShowAllSavedPasswordsFromContextMenu( autofill::AutofillClient* autofill_client) { + if (!autofill_client) + return; autofill_client->ExecuteCommand( autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY); password_manager::metrics_util::LogContextOfShowAllSavedPasswordsAccepted(
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 8c5e0c5..b118cad 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -73,7 +73,7 @@ // Allows searching for saved passwords in the settings page on mobile devices. const base::Feature kPasswordSearchMobile = {"PasswordSearchMobile", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables the experiment for the password manager to only fill on account // selection, rather than autofilling on page load, with highlighting of fields.
diff --git a/components/policy/core/browser/browser_policy_connector_base.cc b/components/policy/core/browser/browser_policy_connector_base.cc index ccac080..45d7b22 100644 --- a/components/policy/core/browser/browser_policy_connector_base.cc +++ b/components/policy/core/browser/browser_policy_connector_base.cc
@@ -97,6 +97,15 @@ return handler_list_.get(); } +std::vector<ConfigurationPolicyProvider*> +BrowserPolicyConnectorBase::GetPolicyProviders() const { + std::vector<ConfigurationPolicyProvider*> providers; + for (const auto& provider : policy_providers_) + providers.push_back(provider.get()); + + return providers; +} + // static void BrowserPolicyConnectorBase::SetPolicyProviderForTesting( ConfigurationPolicyProvider* provider) {
diff --git a/components/policy/core/browser/browser_policy_connector_base.h b/components/policy/core/browser/browser_policy_connector_base.h index d2d05f7..b8fbfe0 100644 --- a/components/policy/core/browser/browser_policy_connector_base.h +++ b/components/policy/core/browser/browser_policy_connector_base.h
@@ -53,6 +53,8 @@ const ConfigurationPolicyHandlerList* GetHandlerList() const; + std::vector<ConfigurationPolicyProvider*> GetPolicyProviders() const; + // Sets a |provider| that will be included in PolicyServices returned by // GetPolicyService. This is a static method because local state is // created immediately after the connector, and tests don't have a chance to
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 437d594..2ac847bd 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -433,9 +433,10 @@ } void CloudPolicyClient::UploadChromeDesktopReport( - const em::ChromeDesktopReportRequest& chrome_desktop_report, + std::unique_ptr<em::ChromeDesktopReportRequest> chrome_desktop_report, const CloudPolicyClient::StatusCallback& callback) { CHECK(is_registered()); + DCHECK(chrome_desktop_report); std::unique_ptr<DeviceManagementRequestJob> request_job(service_->CreateJob( DeviceManagementRequestJob::TYPE_CHROME_DESKTOP_REPORT, GetRequestContext())); @@ -444,7 +445,8 @@ request_job->SetClientID(client_id_); em::DeviceManagementRequest* request = request_job->GetRequest(); - *request->mutable_chrome_desktop_report_request() = chrome_desktop_report; + request->set_allocated_chrome_desktop_report_request( + chrome_desktop_report.release()); const DeviceManagementRequestJob::Callback job_callback = base::Bind(&CloudPolicyClient::OnReportUploadCompleted,
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h index 1482314..dbe4a8e3 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.h +++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -201,7 +201,7 @@ // in a registered state. |chrome_desktop_report| will be included in the // upload request. The |callback| will be called when the operation completes. virtual void UploadChromeDesktopReport( - const enterprise_management::ChromeDesktopReportRequest& + std::unique_ptr<enterprise_management::ChromeDesktopReportRequest> chrome_desktop_report, const StatusCallback& callback);
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc index 667c249..55b2761a 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -1020,8 +1020,10 @@ CloudPolicyClient::StatusCallback callback = base::Bind(&MockStatusCallbackObserver::OnCallbackComplete, base::Unretained(&callback_observer_)); - em::ChromeDesktopReportRequest chrome_desktop_report; - client_->UploadChromeDesktopReport(chrome_desktop_report, callback); + std::unique_ptr<em::ChromeDesktopReportRequest> chrome_desktop_report = + std::make_unique<em::ChromeDesktopReportRequest>(); + client_->UploadChromeDesktopReport(std::move(chrome_desktop_report), + callback); EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); }
diff --git a/components/policy/core/common/cloud/component_cloud_policy_service.cc b/components/policy/core/common/cloud/component_cloud_policy_service.cc index 5bb4bea5..cf0ffbc 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_service.cc +++ b/components/policy/core/common/cloud/component_cloud_policy_service.cc
@@ -283,6 +283,8 @@ io_task_runner_(io_task_runner), weak_ptr_factory_(this) { DCHECK(policy_type == dm_protocol::kChromeExtensionPolicyType || + policy_type == + dm_protocol::kChromeMachineLevelExtensionCloudPolicyType || policy_type == dm_protocol::kChromeSigninExtensionPolicyType); CHECK(!core_->client());
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 72bc3f0e..6bff323 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -145,7 +145,7 @@ # persistent IDs for all fields (but not for groups!) are needed. These are # specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs, # because doing so would break the deployed wire format! -# For your editing convenience: highest ID currently used: 434 +# For your editing convenience: highest ID currently used: 437 # And don't forget to also update the EnterprisePolicies enum of # histograms.xml (run 'python tools/metrics/histograms/update_policies.py'). # @@ -8940,6 +8940,69 @@ If this policy is not set, any certificate that is required to be disclosed via Certificate Transparency will be treated as untrusted if it is not disclosed according to the Certificate Transparency policy.''', }, { + 'name': 'CertificateTransparencyEnforcementDisabledForCas', + 'type': 'list', + 'schema': { + 'type': 'array', + 'items': { 'type': 'string' }, + }, + 'supported_on': [ + 'chrome.*:67-', + 'chrome_os:67-', + 'android:67-', + ], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': ['sha256/AAAAAAAAAAAAAAAAAAAAAA==', 'sha256//////////////////////w=='], + 'id': 435, + 'caption': '''Disable Certificate Transparency enforcement for a list of subjectPublicKeyInfo hashes''', + 'tags': ['system-security'], + 'desc': '''Disables enforcing Certificate Transparency requirements for a list of subjectPublicKeyInfo hashes. + + This policy allows disabling Certificate Transparency disclosure requirements for certificate chains that contain certificates with one of the specified subjectPublicKeyInfo hashes. This allows certificates that would otherwise be untrusted, because they were not properly publicly disclosed, to continue to be used for Enterprise hosts. + + In order for Certificate Transparency enforcement to be disabled when this policy is set, one of the following conditions must be met: + 1. The hash is of the server certificate's subjectPublicKeyInfo. + 2. The hash is of a subjectPublicKeyInfo that appears in a CA certificate in the certificate chain, that CA certificate is constrained via the X.509v3 nameConstraints extension, one or more directoryName nameConstraints are present in the permittedSubtrees, and the directoryName contains an organizationName attribute. + 3. The hash is of a subjectPublicKeyInfo that appears in a CA certificate in the certificate chain, the CA certificate has one or more organizationName attributes in the certificate Subject, and the server's certificate contains the same number of organizationName attributes, in the same order, and with byte-for-byte identical values. + + A subjectPublicKeyInfo hash is specified by concatenating the hash algorithm name, the "/" character, and the Base64 encoding of that hash algorithm applied to the DER-encoded subjectPublicKeyInfo of the specified certificate. This Base64 encoding is the same format as an SPKI Fingerprint, as defined in RFC 7469, Section 2.4. Unrecognized hash algorithms are ignored. The only supported hash algorithm at this time is "sha256". + + If this policy is not set, any certificate that is required to be disclosed via Certificate Transparency will be treated as untrusted if it is not disclosed according to the Certificate Transparency policy.''', + }, + { + 'name': 'CertificateTransparencyEnforcementDisabledForLegacyCas', + 'type': 'list', + 'schema': { + 'type': 'array', + 'items': { 'type': 'string' }, + }, + 'supported_on': [ + 'chrome.*:67-', + 'chrome_os:67-', + 'android:67-', + ], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': ['sha256/AAAAAAAAAAAAAAAAAAAAAA==', 'sha256//////////////////////w=='], + 'id': 436, + 'caption': '''Disable Certificate Transparency enforcement for a list of Legacy Certificate Authorities''', + 'tags': ['system-security'], + 'desc': '''Disables enforcing Certificate Transparency requirements for a list of Legacy Certificate Authorities. + + This policy allows disabling Certificate Transparency disclosure requirements for certificate chains that contain certificates with one of the specified subjectPublicKeyInfo hashes. This allows certificates that would otherwise be untrusted, because they were not properly publicly disclosed, to continue to be used for Enterprise hosts. + + In order for Certificate Transparency enforcement to be disabled when this policy is set, the hash must be of a subjectPublicKeyInfo appearing in a CA certificate that is recognized as a Legacy Certificate Authority (CA). A Legacy CA is a CA that has been publicly trusted by default one or more operating systems supported by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>, but is not trusted by the Android Open Source Project or <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph>. + + A subjectPublicKeyInfo hash is specified by concatenating the hash algorithm name, the "/" character, and the Base64 encoding of that hash algorithm applied to the DER-encoded subjectPublicKeyInfo of the specified certificate. This Base64 encoding is the same format as an SPKI Fingerprint, as defined in RFC 7469, Section 2.4. Unrecognized hash algorithms are ignored. The only supported hash algorithm at this time is "sha256". + + If this policy is not set, any certificate that is required to be disclosed via Certificate Transparency will be treated as untrusted if it is not disclosed according to the Certificate Transparency policy.''', + }, + { 'name': 'RC4Enabled', 'type': 'main', 'schema': { @@ -9822,12 +9885,33 @@ If the policy "EnableMediaRouter" is set to false, then this policy's value would have no effect, and the toolbar icon would not be shown.''' }, { + 'name': 'MediaRouterCastAllowAllIPs', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome.*:67-', 'chrome_os:67-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': False, + 'id': 437, + 'caption': '''Allows <ph name="PRODUCT_NAME">Google Cast</ph> to connect to Cast devices on all IP addresses.''', + 'tags': [], + 'desc': '''If this policy is set to true, <ph name="PRODUCT_NAME">Google Cast</ph> will connect to Cast devices on all IP addresses, not just RFC1918/RFC4913 private addresses. + + If this policy is set to false, <ph name="PRODUCT_NAME">Google Cast</ph> will connect to Cast devices on RFC1918/RFC4913 private addresses only. + + If this policy is not set, <ph name="PRODUCT_NAME">Google Cast</ph> will connect to Cast devices on RFC1918/RFC4913 private addresses only, unless the CastAllowAllIPs feature is enabled. + + If the policy "EnableMediaRouter" is set to false, then this policy's value would have no effect.''' + }, + { 'name': 'ArcBackupRestoreEnabled', 'type': 'main', 'schema': { 'type': 'boolean' }, 'supported_on': ['chrome_os:53-'], 'features': { - 'dynamic_refresh': True, + 'dynamic_refresh': False, 'per_profile': False, }, 'example_value': False, @@ -9849,7 +9933,7 @@ 'schema': { 'type': 'boolean' }, 'supported_on': ['chrome_os:57-'], 'features': { - 'dynamic_refresh': True, + 'dynamic_refresh': False, 'per_profile': False, }, 'example_value': False, @@ -11577,7 +11661,7 @@ Note that if <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is running and this policy changes, it will be applied only to new opened tabs. Therefore some tabs might still observe the previous behavior.''', }, { - 'name': 'TabUnderProtectionEnabled', + 'name': 'TabUnderAllowed', 'type': 'main', 'schema': { 'type': 'boolean' }, 'supported_on': ['chrome.*:67-', 'chrome_os:67-'], @@ -11587,14 +11671,13 @@ }, 'example_value': True, 'id': 432, - 'caption': '''Enables tab-under protection''', + 'caption': '''Allows sites to simultaneously navigate and open pop-ups''', 'tags': [], - 'desc': '''Enables tab-under protection, which blocks navigations detected as tab-unders. + 'desc': '''Allows sites to simultaneously navigate and open pop-ups. - For an explanation on tab-unders, see https://www.chromestatus.com/features/5675755719622656. - If this policy is set to True, navigations which <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> detects are tab-unders will be blocked. - If this policy is set to False, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will allow sites to perform tab-under navigations. - By default, this policy is set to True.''', + For a full explanation, see https://www.chromestatus.com/features/5675755719622656. + If this policy is enabled, sites will be allowed to simultaneously navigate and open new windows/tabs. + If this policy is disabled or not set, sites will be disallowed from simultaneously navigating and opening a new window/tab.''', }, { 'name': 'UserNativePrintersAllowed',
diff --git a/components/policy/resources/policy_templates_en-GB.xtb b/components/policy/resources/policy_templates_en-GB.xtb index 408870c..f9a210f 100644 --- a/components/policy/resources/policy_templates_en-GB.xtb +++ b/components/policy/resources/policy_templates_en-GB.xtb
@@ -34,6 +34,7 @@ <translation id="1096105751829466145">Default search provider</translation> <translation id="1099282607296956954">Enable Site Isolation for every site</translation> <translation id="1117535567637097036">The protocol handlers set via this policy are not used when handling Android intents.</translation> +<translation id="1118093128235245168">Allow sites to ask the user to grant access to a connected USB device</translation> <translation id="1122282995569868661">Shows the <ph name="PRODUCT_NAME" /> toolbar icon</translation> <translation id="1128903365609589950">Configures the directory that <ph name="PRODUCT_NAME" /> will use for storing cached files on the disk. @@ -74,6 +75,9 @@ If this policy is unset, the default frequency is 3 hours. The minimum allowed frequency is 60 seconds.</translation> <translation id="1204263402976895730">Enabled enterprise printers</translation> +<translation id="1216758672198492382">Allows you to set whether websites are allowed to get access to connected USB devices. Access can be completely blocked, or the user can be asked every time a website wants to get access to connected USB devices. + + If this policy is not left set, '3' will be used, and the user will be able to change it.</translation> <translation id="1219695476179627719">Specifies whether the device should roll back to the version set by <ph name="DEVICE_TARGET_VERSION_PREFIX_POLICY_NAME" /> if it's already running a later version. Default is RollbackDisabled.</translation> @@ -329,6 +333,17 @@ <translation id="2113068765175018713">Limit device uptime by automatically rebooting</translation> <translation id="2127599828444728326">Allow notifications on these sites</translation> <translation id="2131902621292742709">Screen dim delay when running on battery power</translation> +<translation id="2132732175597591362">Controls the whitelist of URL patterns on which auto-play will always be enabled. + + If auto-play is enabled then videos containing audio content can play automatically (without user consent) <ph name="PRODUCT_NAME" />. + + A URL pattern has to be formatted according to https://www.chromium.org/administrators/url-blacklist-filter-format. + + If the Auto-PlayAllowed policy is set to True, then this policy will have no effect. + + If the Auto-PlayAllowed policy is set to False, then any URL patterns set in this policy will still be allowed to play. + + Note that if <ph name="PRODUCT_NAME" /> is running and this policy changes, it will only be applied to newly opened tabs. Therefore, some tabs might still observe the previous behaviour.</translation> <translation id="2134437727173969994">Permit locking the screen</translation> <translation id="2137064848866899664">If this policy is set, each display is rotated to the specified orientation on every reboot and the first time that it is connected @@ -392,6 +407,7 @@ If you set this policy, users cannot change or override it. However, users will still be able to enable/disable an accessibility on-screen keyboard which takes precedence over the virtual keyboard controlled by this policy. See the |VirtualKeyboardEnabled| policy for controlling the accessibility on-screen keyboard. If this policy is left unset, the on-screen keyboard is disabled initially but can be enabled by the user anytime. Heuristic rules may also be used to decide when to display the keyboard.</translation> +<translation id="2278947183573212094">Allows media auto-play on a whitelist of URL patterns</translation> <translation id="228659285074633994">Specifies the length of time without user input after which a warning dialogue is shown when running on AC power. When this policy is set, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME" /> shows a warning dialogue telling the user that the idle action is about to be taken. @@ -615,6 +631,12 @@ <translation id="2801230735743888564">Allow users to play dinosaur easter egg game when device is offline. If this policy is set to False, users will not be able to play the dinosaur Easter egg game when device is offline. If this setting is set to True, users are allowed to play the dinosaur game. If this policy is not set, users are not allowed to play the dinosaur Easter egg game on enrolled Chrome OS, but are allowed to play it under other circumstances.</translation> +<translation id="2802085784857530815">Allows you to control if users can access non-enterprise printers + + If the policy is set to True, or not set at all, users will be able to add, configure and print using their own native printers. + + If the policy is set to False, users will not be able to add and configure their own native printers. They will also not be able to print using any previously configured native printers. + </translation> <translation id="2805707493867224476">Allow all sites to show pop-ups</translation> <translation id="2808013382476173118">Enables usage of STUN servers when remote clients are trying to establish a connection to this machine. @@ -777,6 +799,7 @@ The policy value should be specified in milliseconds. Values are clamped to be less than or equal to the screen off delay (if set) and the idle delay.</translation> <translation id="3264793472749429012">Default search provider encodings</translation> <translation id="3273221114520206906">Default JavaScript setting</translation> +<translation id="3284094172359247914">Control use of the WebUSB API</translation> <translation id="3288595667065905535">Release channel</translation> <translation id="3292147213643666827">Enables <ph name="PRODUCT_NAME" /> to act as a proxy between <ph name="CLOUD_PRINT_NAME" /> and legacy printers connected to the machine. @@ -862,6 +885,7 @@ This policy is only respected if the 'DefaultSearchProviderEnabled' policy is enabled.</translation> <translation id="350797926066071931">Enable Translate</translation> <translation id="3512226956150568738">If the client device model already supported ARC before migration to ext4 was necessary to run ARC and if the ArcEnabled policy is set to true, this option will behave as AskUser (value 3). In all other cases (if the device model did not support ARC before, or if ArcEnabled policy is set to false), this value is equivalent to DisallowArc (value 0).</translation> +<translation id="3524204464536655762">Do not allow any site to request access to USB devices via the WebUSB API</translation> <translation id="3528000905991875314">Enable alternate error pages</translation> <translation id="3547954654003013442">Proxy settings</translation> <translation id="3577251398714997599">Ads setting for sites with intrusive ads</translation> @@ -977,6 +1001,9 @@ Lists extensions that are automatically installed for the Demo user, for devices in retail mode. These extensions are saved in the device and can be installed while offline, after the installation. Each list entry contains a dictionary that must include the extension ID in the 'extension-id' field, and its update URL in the 'update-url' field.</translation> +<translation id="3873159954366380945">Allows you to set the time period over which <ph name="PRODUCT_NAME" /> relaunch notifications are shown to apply a pending update. + + This policy setting can be used to control the time period, in milliseconds, over which a user is progressively informed that <ph name="PRODUCT_NAME" /> must be relaunched (or <ph name="PRODUCT_OS_NAME" /> must be restarted) for an update. Over this time period, the user will be repeatedly informed of the need for an update based on the setting of the <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME" /> policy. If not set, the default period of 345,600,000 milliseconds (four days) is used for <ph name="PRODUCT_OS_NAME" /> and 604,800,000 milliseconds (one week) for all other platforms.</translation> <translation id="3877517141460819966">Integrated second factor authentication mode</translation> <translation id="388237772682176890">This policy is deprecated in M53 and removed in M54, because SPDY/3.1 support is removed. @@ -1329,6 +1356,14 @@ This policy is only respected if the 'DefaultSearchProviderEnabled' policy is enabled.</translation> <translation id="489803897780524242">Parameter controlling search term placement for the default search provider</translation> <translation id="4899708173828500852">Enable Safe Browsing</translation> +<translation id="4899802251198446659">Allows you to control whether videos with audio content can play automatically (without user consent) <ph name="PRODUCT_NAME" />. + + If the policy is set to True, <ph name="PRODUCT_NAME" /> is allowed to auto-play media. + If the policy is set to False, <ph name="PRODUCT_NAME" /> is not allowed to auto-play media. The Auto-PlayWhitelist policy can be used to override this for certain URL patterns. + By default, <ph name="PRODUCT_NAME" /> is not allowed to auto-play media. The Auto-PlayWhitelist policy can be used to override this for certain URL patterns. + + Note that if <ph name="PRODUCT_NAME" /> is running and this policy changes, it will only be applied to newly opened tabs. Therefore, some tabs might still observe the previous behaviour. + </translation> <translation id="4906194810004762807">Refresh rate for Device Policy</translation> <translation id="4917385247580444890">Strong</translation> <translation id="4923806312383904642">Allow WebDriver to Override Incompatible Policies</translation> @@ -2299,6 +2334,7 @@ <ph name="PROXY_HELP_URL" />.</translation> <translation id="7781069478569868053">New Tab Page</translation> <translation id="7788511847830146438">Per Profile</translation> +<translation id="7789637461480472766">Allows access to native CUPS printers</translation> <translation id="7801886189430766248">When this policy is set to true, Android app data is uploaded to Android Backup servers and restored from them upon app re-installations for compatible apps. When this policy is set to false, Android Backup Service will be switched off. @@ -2698,6 +2734,15 @@ <translation id="9112897538922695510">Allows you to register a list of protocol handlers. This can only be a recommended policy. The property |protocol| should be set to the scheme such as 'mailto' and the property |url| should be set to the URL pattern of the application that handles the scheme. The pattern can include a '%s', which if present will be replaced by the handled URL. The protocol handlers registered by policy are merged with the ones registered by the user and both are available for use. The user can override the protocol handlers installed by policy by installing a new default handler, but cannot remove a protocol handler registered by policy.</translation> +<translation id="9123211093995421438">Specifies the minimum number of <ph name="PRODUCT_OS_NAME" /> milestones roll back should be allowed starting from the stable version at any time. + + Default is zero for consumer, four (approx. half a year) for enterprise-enrolled devices. + + Setting this policy prevents roll back protection to apply for at least this number of milestones. + + Setting this policy to a lower value has a permanent effect: the device MAY not be able to roll back to earlier versions even after the policy is reset to a larger value. + + Actual roll back possibilities may also depend on the board and critical vulnerability patches.</translation> <translation id="913195841488580904">Block access to a list of URLs</translation> <translation id="9135033364005346124">Enable <ph name="CLOUD_PRINT_NAME" /> proxy</translation> <translation id="9136253551939494882">A whitelist controlling which quick unlock modes the user can configure and use to unlock the lock screen.
diff --git a/components/services/heap_profiling/public/cpp/BUILD.gn b/components/services/heap_profiling/public/cpp/BUILD.gn index 474cf90..1f0b683 100644 --- a/components/services/heap_profiling/public/cpp/BUILD.gn +++ b/components/services/heap_profiling/public/cpp/BUILD.gn
@@ -8,6 +8,8 @@ "allocator_shim.h", "client.cc", "client.h", + "controller.cc", + "controller.h", "sender_pipe.h", "sender_pipe_posix.cc", "sender_pipe_win.cc", @@ -26,6 +28,8 @@ "//base:debugging_buildflags", "//base/allocator:buildflags", "//mojo/edk", + "//services/resource_coordinator/public/mojom:", + "//services/service_manager/public/cpp", ] }
diff --git a/components/services/heap_profiling/public/cpp/allocator_shim.cc b/components/services/heap_profiling/public/cpp/allocator_shim.cc index 0201f3d..076a845c 100644 --- a/components/services/heap_profiling/public/cpp/allocator_shim.cc +++ b/components/services/heap_profiling/public/cpp/allocator_shim.cc
@@ -34,6 +34,11 @@ #include <sys/prctl.h> #endif +#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ + defined(OFFICIAL_BUILD) +#include "base/trace_event/cfi_backtrace_android.h" +#endif + using base::trace_event::AllocationContext; using base::trace_event::AllocationContextTracker; using CaptureMode = base::trace_event::AllocationContextTracker::CaptureMode; @@ -728,18 +733,24 @@ } void SerializeFramesFromBacktrace(FrameSerializer* serializer) { -#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) +#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ + defined(OFFICIAL_BUILD) + const void* frames[kMaxStackEntries - 1]; + size_t frame_count = + base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()->Unwind( + frames, kMaxStackEntries - 1); +#elif BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) const void* frames[kMaxStackEntries - 1]; size_t frame_count = base::debug::TraceStackFramePointers( frames, kMaxStackEntries - 1, 1); // exclude this function from the trace. -#else // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) +#else // Fall-back to capturing the stack with base::debug::StackTrace, // which is likely slower, but more reliable. base::debug::StackTrace stack_trace(kMaxStackEntries - 1); size_t frame_count = 0u; const void* const* frames = stack_trace.Addresses(&frame_count); -#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) +#endif serializer->AddAllInstructionPointers(frame_count, frames);
diff --git a/components/services/heap_profiling/public/cpp/client.cc b/components/services/heap_profiling/public/cpp/client.cc index 633ba38..3e9b7d1b 100644 --- a/components/services/heap_profiling/public/cpp/client.cc +++ b/components/services/heap_profiling/public/cpp/client.cc
@@ -6,6 +6,8 @@ #include "base/allocator/allocator_interception_mac.h" #include "base/files/platform_file.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" #include "base/trace_event/malloc_dump_provider.h" #include "build/build_config.h" #include "components/services/heap_profiling/public/cpp/allocator_shim.h" @@ -13,13 +15,32 @@ #include "components/services/heap_profiling/public/cpp/stream.h" #include "mojo/public/cpp/system/platform_handle.h" +#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ + defined(OFFICIAL_BUILD) +#include "base/trace_event/cfi_backtrace_android.h" +#endif + namespace heap_profiling { namespace { const int kTimeoutDurationMs = 10000; + +#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ + defined(OFFICIAL_BUILD) +void EnsureCFIInitializedOnBackgroundThread( + scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner, + base::OnceClosure callback) { + bool can_unwind = + base::trace_event::CFIBacktraceAndroid::GetInitializedInstance() + ->can_unwind_stack_frames(); + DCHECK(can_unwind); + callback_task_runner->PostTask(FROM_HERE, std::move(callback)); +} +#endif + } // namespace -Client::Client() : started_profiling_(false) {} +Client::Client() : started_profiling_(false), weak_factory_(this) {} Client::~Client() { StopAllocatorShimDangerous(); @@ -67,11 +88,32 @@ base::allocator::PeriodicallyShimNewMallocZones(); #endif +#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ + defined(OFFICIAL_BUILD) + // On Android the unwinder initialization requires file reading before + // initializing shim. So, post task on background thread. + auto init_callback = + base::BindOnce(&Client::InitAllocatorShimOnUIThread, + weak_factory_.GetWeakPtr(), std::move(params)); + + auto background_task = base::BindOnce(&EnsureCFIInitializedOnBackgroundThread, + base::ThreadTaskRunnerHandle::Get(), + std::move(init_callback)); + base::PostTaskWithTraits(FROM_HERE, + {base::TaskPriority::BACKGROUND, base::MayBlock(), + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + std::move(background_task)); +#else InitAllocatorShim(sender_pipe_.get(), std::move(params)); +#endif } void Client::FlushMemlogPipe(uint32_t barrier_id) { AllocatorShimFlushPipe(barrier_id); } +void Client::InitAllocatorShimOnUIThread(mojom::ProfilingParamsPtr params) { + InitAllocatorShim(sender_pipe_.get(), std::move(params)); +} + } // namespace heap_profiling
diff --git a/components/services/heap_profiling/public/cpp/client.h b/components/services/heap_profiling/public/cpp/client.h index f3eb465..bdff760a 100644 --- a/components/services/heap_profiling/public/cpp/client.h +++ b/components/services/heap_profiling/public/cpp/client.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_CLIENT_H_ #define COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_CLIENT_H_ +#include "base/memory/weak_ptr.h" #include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/system/handle.h" @@ -29,6 +30,8 @@ void BindToInterface(mojom::ProfilingClientRequest request); private: + void InitAllocatorShimOnUIThread(mojom::ProfilingParamsPtr params); + // Ideally, this would be a mojo::Binding that would only keep alive one // client request. However, the service that makes the client requests // [content_browser] is different from the service that dedupes the client @@ -40,6 +43,8 @@ bool started_profiling_; std::unique_ptr<SenderPipe> sender_pipe_; + + base::WeakPtrFactory<Client> weak_factory_; }; } // namespace heap_profiling
diff --git a/components/services/heap_profiling/public/cpp/controller.cc b/components/services/heap_profiling/public/cpp/controller.cc new file mode 100644 index 0000000..2f3f92d --- /dev/null +++ b/components/services/heap_profiling/public/cpp/controller.cc
@@ -0,0 +1,71 @@ +// Copyright 2018 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/services/heap_profiling/public/cpp/controller.h" + +#include "components/services/heap_profiling/public/cpp/sender_pipe.h" +#include "components/services/heap_profiling/public/cpp/settings.h" +#include "components/services/heap_profiling/public/mojom/constants.mojom.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" +#include "services/resource_coordinator/public/mojom/service_constants.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace heap_profiling { + +Controller::Controller(std::unique_ptr<service_manager::Connector> connector, + mojom::StackMode stack_mode, + uint32_t sampling_rate) + : connector_(std::move(connector)), + sampling_rate_(sampling_rate), + stack_mode_(stack_mode) { + DCHECK_NE(sampling_rate, 0u); + + // Start the Heap Profiling service. + connector_->BindInterface(mojom::kServiceName, &heap_profiling_service_); + + // Pass state from command line flags to Heap Profiling service. + SetKeepSmallAllocations(ShouldKeepSmallAllocations()); + + // Grab a HeapProfiler InterfacePtr and pass that to memory instrumentation. + memory_instrumentation::mojom::HeapProfilerPtr heap_profiler; + connector_->BindInterface(mojom::kServiceName, &heap_profiler); + + memory_instrumentation::mojom::CoordinatorPtr coordinator; + connector_->BindInterface(resource_coordinator::mojom::kServiceName, + &coordinator); + coordinator->RegisterHeapProfiler(std::move(heap_profiler)); +} + +Controller::~Controller() = default; + +void Controller::StartProfilingClient(mojom::ProfilingClientPtr client, + base::ProcessId pid, + mojom::ProcessType process_type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + SenderPipe::PipePair pipes; + + mojom::ProfilingParamsPtr params = mojom::ProfilingParams::New(); + params->sampling_rate = sampling_rate_; + params->sender_pipe = + mojo::WrapPlatformFile(pipes.PassSender().release().handle); + params->stack_mode = stack_mode_; + heap_profiling_service_->AddProfilingClient( + pid, std::move(client), + mojo::WrapPlatformFile(pipes.PassReceiver().release().handle), + process_type, std::move(params)); +} + +void Controller::GetProfiledPids(GetProfiledPidsCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + heap_profiling_service_->GetProfiledPids(std::move(callback)); +} + +void Controller::SetKeepSmallAllocations(bool keep_small_allocations) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + heap_profiling_service_->SetKeepSmallAllocations(keep_small_allocations); +} + +} // namespace heap_profiling
diff --git a/components/services/heap_profiling/public/cpp/controller.h b/components/services/heap_profiling/public/cpp/controller.h new file mode 100644 index 0000000..aa278774 --- /dev/null +++ b/components/services/heap_profiling/public/cpp/controller.h
@@ -0,0 +1,74 @@ +// Copyright 2018 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_SERVICES_HEAP_PROFILING_PUBLIC_CPP_CONTROLLER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_CONTROLLER_H_ + +#include "base/macros.h" +#include "base/sequence_checker.h" +#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h" +#include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h" + +namespace service_manager { +class Connector; +} + +namespace heap_profiling { + +// This class is responsible for +// * Starting the Heap Profiling Service +// * Hooking up clients to the service +// * Getting information about profiled clients +// +// This class is sequence-affine. The public non-getter methods must be called +// from a single sequence. Getters return const members set during the +// constructor, so they can be called from any sequence. +// +// This class must be used from a privileged process, as it needs to be able to +// create OS pipes. +class Controller { + public: + // |connector| is used to connect to other services. + // |stack_mode| describes the type of metadata to record for each allocation. + // A |sampling_rate| of 1 indicates that all allocations should be recorded. + // A |sampling_rate| greater than 1 describes the Poisson Process sampling + // interval. If |sampling_rate| is N, then on average, an allocation will be + // recorded every N bytes of allocated objects. + // + // Note: The name |sampling_rate| is a bit confusing. A higher sampling rate + // causes there to be fewer samples taken. This probably should have been + // named |sampling_interval|. + Controller(std::unique_ptr<service_manager::Connector> connector, + mojom::StackMode stack_mode, + uint32_t sampling_rate); + ~Controller(); + + // Starts Heap Profiling for the client. + void StartProfilingClient(mojom::ProfilingClientPtr client, + base::ProcessId pid, + mojom::ProcessType); + + uint32_t sampling_rate() const { return sampling_rate_; } + + // Forwards to HeapProfilingService. + using GetProfiledPidsCallback = + base::OnceCallback<void(const std::vector<base::ProcessId>&)>; + void GetProfiledPids(GetProfiledPidsCallback callback); + void SetKeepSmallAllocations(bool keep_small_allocations); + + private: + std::unique_ptr<service_manager::Connector> connector_; + mojom::ProfilingServicePtr heap_profiling_service_; + + // The same sampling rate and stack mode is used for each client. + const uint32_t sampling_rate_ = 1; + const mojom::StackMode stack_mode_; + + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(Controller); +}; + +} // namespace heap_profiling + +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_CONTROLLER_H_
diff --git a/components/services/heap_profiling/public/cpp/settings.cc b/components/services/heap_profiling/public/cpp/settings.cc index 5655d26e..1d4bbc2c 100644 --- a/components/services/heap_profiling/public/cpp/settings.cc +++ b/components/services/heap_profiling/public/cpp/settings.cc
@@ -27,6 +27,16 @@ const uint32_t kDefaultSamplingRate = 10000; const bool kDefaultShouldSample = false; +bool RecordAllAllocationsForStartup() { + const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); + if (cmdline->HasSwitch(kMemlogSampling)) + return false; + + return !base::GetFieldTrialParamByFeatureAsBool( + kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureSampling, + /*default_value=*/kDefaultShouldSample); +} + } // namespace Mode GetModeForStartup() { @@ -113,17 +123,10 @@ return mojom::StackMode::NATIVE_WITHOUT_THREAD_NAMES; } -bool GetShouldSampleForStartup() { - const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - if (cmdline->HasSwitch(kMemlogSampling)) - return true; - - return base::GetFieldTrialParamByFeatureAsBool( - kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureSampling, - kDefaultShouldSample /* default_value */); -} - uint32_t GetSamplingRateForStartup() { + if (RecordAllAllocationsForStartup()) + return 1; + const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); if (cmdline->HasSwitch(kMemlogSamplingRate)) { std::string rate_as_string = @@ -141,7 +144,7 @@ return base::GetFieldTrialParamByFeatureAsInt( kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureSamplingRate, - kDefaultSamplingRate /* default_value */); + /*default_value=*/kDefaultSamplingRate); } bool IsBackgroundHeapProfilingEnabled() {
diff --git a/components/services/heap_profiling/public/cpp/settings.h b/components/services/heap_profiling/public/cpp/settings.h index e451659..97a5d05a 100644 --- a/components/services/heap_profiling/public/cpp/settings.h +++ b/components/services/heap_profiling/public/cpp/settings.h
@@ -48,7 +48,10 @@ mojom::StackMode GetStackModeForStartup(); mojom::StackMode ConvertStringToStackMode(const std::string& input); -bool GetShouldSampleForStartup(); +// A |sampling_rate| of 1 indicates that all allocations should be recorded. +// A |sampling_rate| greater than 1 describes the Poisson Process sampling +// interval. If |sampling_rate| is N, then on average, an allocation will be +// recorded every N bytes of allocated objects. uint32_t GetSamplingRateForStartup(); bool IsBackgroundHeapProfilingEnabled();
diff --git a/components/strings/components_strings_en-GB.xtb b/components/strings/components_strings_en-GB.xtb index 44518e1..cf244e5 100644 --- a/components/strings/components_strings_en-GB.xtb +++ b/components/strings/components_strings_en-GB.xtb
@@ -1,6 +1,7 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="en-GB"> +<translation id="1005145902654145231">Failed to rename the session.</translation> <translation id="1008557486741366299">Not Now</translation> <translation id="1015730422737071372">Provide additional details.</translation> <translation id="1021110881106174305">Accepted cards</translation> @@ -42,13 +43,22 @@ <translation id="1228893227497259893">Wrong entity identifier</translation> <translation id="1232569758102978740">Untitled</translation> <translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synced)</translation> +<translation id="1256368399071562588"><p>If you try to visit a website and it doesn’t open, first try to fix the error with these troubleshooting steps:</p> + <ol> + <li>Check the web address for typos.</li> + <li>Make sure that your Internet connection is working normally.</li> + <li>Contact the website owner.</li> + </ol></translation> <translation id="1263231323834454256">Reading list</translation> <translation id="1264126396475825575">Crash report captured on <ph name="CRASH_TIME" /> (not yet uploaded or ignored)</translation> <translation id="1270502636509132238">Pickup Method</translation> <translation id="1285320974508926690">Never translate this site</translation> +<translation id="1292701964462482250">'Software on your computer is stopping Chrome from safely connecting to the web' (Windows computers only)</translation> <translation id="1294154142200295408">Command-line variations</translation> <translation id="129553762522093515">Recently closed</translation> <translation id="129863573139666797"><ph name="BEGIN_LINK" />Try clearing your cookies<ph name="END_LINK" /></translation> +<translation id="1314614906530272393">The selected session does not exist.</translation> +<translation id="1323433172918577554">Show More</translation> <translation id="1333989956347591814">Your activity <ph name="BEGIN_EMPHASIS" />might still be visible<ph name="END_EMPHASIS" /> to: <ph name="BEGIN_LIST" /> <ph name="LIST_ITEM" />Websites that you visit @@ -60,6 +70,7 @@ <translation id="1348198688976932919">The site ahead contains dangerous apps</translation> <translation id="1374468813861204354">suggestions</translation> <translation id="1375198122581997741">About Version</translation> +<translation id="1376836354785490390">Show Less</translation> <translation id="1377321085342047638">Card Number</translation> <translation id="139305205187523129"><ph name="HOST_NAME" /> didn’t send any data.</translation> <translation id="1407135791313364759">Open all</translation> @@ -69,6 +80,8 @@ <translation id="1430915738399379752">Print</translation> <translation id="1484290072879560759">Choose delivery address</translation> <translation id="1506687042165942984">Show a saved (i.e. known to be out of date) copy of this page.</translation> +<translation id="1507202001669085618"><p>You'll see this error if you're using a Wi-Fi portal where you have to sign in before you can get online.</p> + <p>To fix the error, click <strong>Connect</strong> on the page that you're trying to open.</p></translation> <translation id="1517433312004943670">Phone number required</translation> <translation id="1517500485252541695">Accepted credit and debit cards</translation> <translation id="1519264250979466059">Build Date</translation> @@ -132,6 +145,7 @@ <translation id="1898423065542865115">Filtering</translation> <translation id="1916770123977586577">To apply your updated settings to this site, reload this page</translation> <translation id="1919345977826869612">Ads</translation> +<translation id="1919367280705858090">Get help with a specific error message</translation> <translation id="192020519938775529">{COUNT,plural, =0{None}=1{1 site}other{# sites}}</translation> <translation id="1927235823738766038">Accepted Credit and Debit Cards</translation> <translation id="194030505837763158">Go to <ph name="LINK" /></translation> @@ -420,6 +434,7 @@ <translation id="3964661563329879394">{COUNT,plural, =0{None}=1{From 1 site }other{From # sites }}</translation> <translation id="397105322502079400">Calculating...</translation> <translation id="3973234410852337861"><ph name="HOST_NAME" /> is blocked</translation> +<translation id="3984550557525787191">This session name already exists.</translation> <translation id="3987940399970879459">Less than 1 MB</translation> <translation id="40103911065039147">{URL_count,plural, =1{1 web page nearby}other{# web pages nearby}}</translation> <translation id="4030383055268325496">&Undo add</translation> @@ -450,6 +465,23 @@ <translation id="4203896806696719780"><ph name="BEGIN_LINK" />Checking firewall and antivirus configurations<ph name="END_LINK" /></translation> <translation id="4220128509585149162">Crashes</translation> <translation id="422022731706691852">Attackers on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites that you visit). <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation> +<translation id="4221630205957821124"><h4>Step 1: Sign in to the portal</h4> + <p>Wi-Fi networks at places such as cafés or airports need you to sign in. To see the sign-in page, visit a page that uses <code>http://</code>.</p> + <ol> + <li>Go to any website starting with <code>http://</code>, such as <a href="http://example.com" target="_blank">http://example.com</a>.</li> + <li>On the sign-in page that opens, sign in to use the Internet.</li> + </ol> + <h4>Step 2: Open the page in Incognito mode (computer only)</h4> + <p>Open the page that you were visiting in an Incognito window.</p> + <p>If the page opens, a Chrome extension isn't working properly. To fix the error, turn off the extension.</p> + <h4>Step 3: Update your operating system</h4> + <p>Make sure that your device is up to date.</p> + <h4>Step 4: Temporarily turn off your antivirus</h4> + <p>You'll see this error if you have antivirus software that provides 'HTTPS protection' or 'HTTPS scanning'. The antivirus is preventing Chrome from providing security.</p> + <p>To fix the problem, turn off your antivirus software. If the page works after turning off the software, turn off this software when you use secure sites.</p> + <p>Remember to turn your antivirus program back on when you've finished.</p> + <h4>Step 5: Get extra help</h4> + <p>If you still see the error, contact the website owner.</p></translation> <translation id="4226937834893929579"><ph name="BEGIN_LINK" />Try running Network Diagnostics<ph name="END_LINK" />.</translation> <translation id="4235360514405112390">Valid</translation> <translation id="4250431568374086873">Your connection to this site is not fully secure</translation> @@ -465,6 +497,7 @@ <translation id="4325863107915753736">Failed to find article</translation> <translation id="4326324639298822553">Check your expiry date and try again</translation> <translation id="4331708818696583467">Not Secure</translation> +<translation id="4340982228985273705">This computer is not detected as enterprise managed, so policy can only automatically install extensions hosted on the Chrome Web Store. The Chrome Web Store update URL is '<ph name="CWS_UPDATE_URL" />'.</translation> <translation id="4346197816712207223">Accepted Credit Cards</translation> <translation id="4356973930735388585">Attackers on this site might attempt to install dangerous programs on your computer that steal or delete your information (for example, photos, passwords, messages and credit cards).</translation> <translation id="4372948949327679948">Expected <ph name="VALUE_TYPE" /> value.</translation> @@ -566,6 +599,7 @@ <translation id="5222812217790122047">Email (required)</translation> <translation id="522700295135997067">This site may have just stolen your password</translation> <translation id="5230733896359313003">Delivery Address</translation> +<translation id="5250209940322997802">'Connect to network'</translation> <translation id="5251803541071282808">Cloud</translation> <translation id="5281113152797308730"><ph name="BEGIN_PARAGRAPH" />Follow these steps to temporarily disable the software so that you can get on the web. You'll need administrator privileges.<ph name="END_PARAGRAPH" /> @@ -589,6 +623,7 @@ <translation id="5332219387342487447">Delivery Method</translation> <translation id="5355557959165512791">You cannot visit <ph name="SITE" /> right now because its certificate has been revoked. Network errors and attacks are usually temporary, so this page will probably work later.</translation> <translation id="536296301121032821">Failed to store policy settings</translation> +<translation id="5377026284221673050">'Your clock is behind' or 'Your clock is ahead' or "<span class="error-code">NET::ERR_CERT_DATE_INVALID</span>"</translation> <translation id="5386426401304769735">The certificate chain for this site contains a certificate signed using SHA-1.</translation> <translation id="5402410679244714488">Exp: <ph name="EXPIRATION_DATE_ABBR" />, last used over a year ago</translation> <translation id="540969355065856584">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not valid at this time. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation> @@ -841,6 +876,7 @@ <translation id="7542403920425041731">Once you confirm, your card details will be shared with this site.</translation> <translation id="7542995811387359312">Automatic credit card filling is disabled because this form does not use a secure connection.</translation> <translation id="7543525346216957623">Ask your parent</translation> +<translation id="7548892272833184391">Fix connection errors</translation> <translation id="7549584377607005141">This web page requires data that you entered earlier in order to be properly displayed. You can send this data again, but by doing so you will repeat any action this page previously performed.</translation> <translation id="7552846755917812628">Try the following tips:</translation> <translation id="7554791636758816595">New Tab</translation> @@ -848,6 +884,7 @@ <translation id="7567204685887185387">This server could not prove that it is <ph name="DOMAIN" />; its security certificate might have been issued fraudulently. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation> <translation id="7568593326407688803">This page is in<ph name="ORIGINAL_LANGUAGE" />Would you like to translate it?</translation> <translation id="7569952961197462199">Remove credit card from Chrome?</translation> +<translation id="7575800019233204241">'Your connection is not private' or "<span class="error-code">NET::ERR_CERT_AUTHORITY_INVALID</span>" or "<span class="error-code">ERR_CERT_COMMON_NAME_INVALID</span>" or "<span class="error-code">NET::ERR_CERT_WEAK_SIGNATURE_ALGORITHM</span>" or 'SSL certificate error'</translation> <translation id="7578104083680115302">Pay quickly on sites and apps across devices using cards that you have saved with Google.</translation> <translation id="7588950540487816470">Physical Web</translation> <translation id="7592362899630581445">Server's certificate violates name constraints.</translation> @@ -1069,6 +1106,8 @@ <translation id="973773823069644502">Add delivery address</translation> <translation id="975560348586398090">{COUNT,plural, =0{None}=1{1 item}other{# items}}</translation> <translation id="981121421437150478">Offline</translation> +<translation id="985199708454569384"><p>You'll see this error if your computer or mobile device's date and time are inaccurate.</p> + <p>To fix the error, open your device's clock. Make sure that the time and date are correct.</p></translation> <translation id="988159990683914416">Developer Build</translation> <translation id="989988560359834682">Edit Address</translation> <translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 97c28db4d..e08460e 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -874,6 +874,7 @@ VISIT(confirmation_grd_id); VISIT(locale); VISIT_ENUM(status); + VISIT(account_id); } VISIT_PROTO_FIELDS(const sync_pb::TypeHint& proto) {
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto index 5177f1e6..d000834 100644 --- a/components/sync/protocol/user_event_specifics.proto +++ b/components/sync/protocol/user_event_specifics.proto
@@ -114,6 +114,17 @@ GIVEN = 2; } optional ConsentStatus status = 5; + // The account ID of the user who gave the consent. This field is used + // by UserEventService to distinguish consents from different users, + // as UserConsent does not get deleted when a user signs out. However, + // it should be cleared before being sent over the wire, as the UserEvent + // is sent over an authenticated channel, so this information would be + // redundant. + // + // For semantics and usage of the |account_id| in the signin codebase, + // see SigninManagerBase::GetAuthenticatedAccountId() + // or AccountInfo::account_id. + optional string account_id = 6; } // User reused their GAIA password on another website.
diff --git a/components/sync/user_events/user_event_sync_bridge.cc b/components/sync/user_events/user_event_sync_bridge.cc index 5033a55..bf187a1 100644 --- a/components/sync/user_events/user_event_sync_bridge.cc +++ b/components/sync/user_events/user_event_sync_bridge.cc
@@ -152,8 +152,41 @@ std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { // Sync can only be disabled after initialization. DCHECK(deferred_user_events_while_initializing_.empty()); - // No data should be retained through sign out. - store_->DeleteAllDataAndMetadata(base::DoNothing()); + // Delete everything except user consents. With DICE the signout may happen + // frequently. It is important to report all user consents, thus, they are + // persisted for some time even after signout. + store_->ReadAllData(base::BindOnce( + &UserEventSyncBridge::OnReadAllDataToDelete, base::AsWeakPtr(this), + std::move(delete_metadata_change_list))); +} + +void UserEventSyncBridge::OnReadAllDataToDelete( + std::unique_ptr<MetadataChangeList> delete_metadata_change_list, + const base::Optional<ModelError>& error, + std::unique_ptr<RecordList> data_records) { + if (error) { + LOG(WARNING) << "OnReadAllDataToDelete received a model error: " + << error->ToString(); + return; + } + + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); + // We delete all the metadata (even for consents), because it may become + // invalid when the sync is reenabled. This may lead to the same consent + // being reported multiple times, which is allowed. + batch->TakeMetadataChangesFrom(std::move(delete_metadata_change_list)); + + UserEventSpecifics specifics; + for (const Record& r : *data_records) { + if (!specifics.ParseFromString(r.value) || + specifics.event_case() != UserEventSpecifics::EventCase::kUserConsent) { + batch->DeleteData(r.id); + } + } + + store_->CommitWriteBatch( + std::move(batch), + base::BindOnce(&UserEventSyncBridge::OnCommit, base::AsWeakPtr(this))); } void UserEventSyncBridge::RecordUserEvent( @@ -216,6 +249,10 @@ return; } + // TODO(vitaliii): Attempt to resubmit persistently stored user consents + // (probably not immediately on startup). + // TODO(vitaliii): Garbage collect old user consents if sync is disabled. + store_ = std::move(store); store_->ReadAllMetadata(base::BindOnce( &UserEventSyncBridge::OnReadAllMetadata, base::AsWeakPtr(this)));
diff --git a/components/sync/user_events/user_event_sync_bridge.h b/components/sync/user_events/user_event_sync_bridge.h index a2c340c1..2be05442 100644 --- a/components/sync/user_events/user_event_sync_bridge.h +++ b/components/sync/user_events/user_event_sync_bridge.h
@@ -63,6 +63,10 @@ void OnReadAllData(DataCallback callback, const base::Optional<ModelError>& error, std::unique_ptr<ModelTypeStore::RecordList> data_records); + void OnReadAllDataToDelete( + std::unique_ptr<MetadataChangeList> delete_metadata_change_list, + const base::Optional<ModelError>& error, + std::unique_ptr<ModelTypeStore::RecordList> data_records); void HandleGlobalIdChange(int64_t old_global_id, int64_t new_global_id);
diff --git a/components/sync/user_events/user_event_sync_bridge_unittest.cc b/components/sync/user_events/user_event_sync_bridge_unittest.cc index 04233585..068199e2 100644 --- a/components/sync/user_events/user_event_sync_bridge_unittest.cc +++ b/components/sync/user_events/user_event_sync_bridge_unittest.cc
@@ -36,6 +36,7 @@ using testing::SizeIs; using testing::UnorderedElementsAre; using testing::_; +using WriteBatch = ModelTypeStore::WriteBatch; MATCHER_P(MatchesUserEvent, expected, "") { if (!arg.has_user_event()) { @@ -101,7 +102,7 @@ mock_processor_.CreateForwardingProcessor(), &test_global_id_mapper_); ON_CALL(*processor(), IsTrackingMetadata()).WillByDefault(Return(true)); ON_CALL(*processor(), DisableSync()).WillByDefault(Invoke([this]() { - bridge_->ApplyDisableSyncChanges({}); + bridge_->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()); })); } @@ -195,10 +196,30 @@ EXPECT_CALL(*processor(), DisableSync()); bridge()->DisableSync(); + // The bridge may asynchronously query the store to choose what to delete. + base::RunLoop().RunUntilIdle(); EXPECT_THAT(GetAllData(), IsEmpty()); } +TEST_F(UserEventSyncBridgeTest, DisableSyncShouldKeepConsents) { + UserEventSpecifics user_consent_specifics(CreateSpecifics(2u, 2u, 2u)); + auto* consent = user_consent_specifics.mutable_user_consent(); + consent->set_feature(UserEventSpecifics::UserConsent::CHROME_SYNC); + bridge()->RecordUserEvent( + std::make_unique<UserEventSpecifics>(user_consent_specifics)); + ASSERT_THAT(GetAllData(), SizeIs(1)); + + EXPECT_CALL(*processor(), DisableSync()); + bridge()->DisableSync(); + // The bridge may asynchronously query the store to choose what to delete. + base::RunLoop().RunUntilIdle(); + + // User consent specific must be persisted when sync is disabled. + EXPECT_THAT(GetAllData(), + ElementsAre(Pair(_, MatchesUserEvent(user_consent_specifics)))); +} + TEST_F(UserEventSyncBridgeTest, MultipleRecords) { std::set<std::string> unique_storage_keys; EXPECT_CALL(*processor(), DoPut(_, _, _))
diff --git a/components/viz/common/gl_helper_unittest.cc b/components/viz/common/gl_helper_unittest.cc index 23214ca4..f625219 100644 --- a/components/viz/common/gl_helper_unittest.cc +++ b/components/viz/common/gl_helper_unittest.cc
@@ -8,6 +8,7 @@ #include <string.h> #include <cmath> #include <string> +#include <tuple> #include <vector> #include <GLES2/gl2.h> @@ -1504,20 +1505,20 @@ class GLHelperPixelReadbackTest : public GLHelperPixelTest, - public ::testing::WithParamInterface<std::tr1::tuple<unsigned int, - unsigned int, - unsigned int, - unsigned int, - unsigned int>> {}; + public ::testing::WithParamInterface<std::tuple<unsigned int, + unsigned int, + unsigned int, + unsigned int, + unsigned int>> {}; // Per pixel tests, all sizes are small so that we can print // out the generated bitmaps. TEST_P(GLHelperPixelReadbackTest, ScaleTest) { - unsigned int q_index = std::tr1::get<0>(GetParam()); - unsigned int x = std::tr1::get<1>(GetParam()); - unsigned int y = std::tr1::get<2>(GetParam()); - unsigned int dst_x = std::tr1::get<3>(GetParam()); - unsigned int dst_y = std::tr1::get<4>(GetParam()); + unsigned int q_index = std::get<0>(GetParam()); + unsigned int x = std::get<1>(GetParam()); + unsigned int y = std::get<2>(GetParam()); + unsigned int dst_x = std::get<3>(GetParam()); + unsigned int dst_y = std::get<4>(GetParam()); for (int flip_output = 0; flip_output <= 1; ++flip_output) { for (int pattern = 0; pattern < 3; ++pattern) { @@ -1541,11 +1542,11 @@ for (int flipped_source = 0; flipped_source <= 1; ++flipped_source) { for (int pattern = 0; pattern < 3; ++pattern) { TestScalePatching( - gfx::Vector2d(kRGBReadBackSizes[std::tr1::get<1>(GetParam())], - kRGBReadBackSizes[std::tr1::get<2>(GetParam())]), - gfx::Vector2d(kRGBReadBackSizes[std::tr1::get<3>(GetParam())], - kRGBReadBackSizes[std::tr1::get<4>(GetParam())]), - pattern, std::tr1::get<0>(GetParam()), !!flipped_source); + gfx::Vector2d(kRGBReadBackSizes[std::get<1>(GetParam())], + kRGBReadBackSizes[std::get<2>(GetParam())]), + gfx::Vector2d(kRGBReadBackSizes[std::get<3>(GetParam())], + kRGBReadBackSizes[std::get<4>(GetParam())]), + pattern, std::get<0>(GetParam()), !!flipped_source); if (HasFailure()) { return; } @@ -1556,11 +1557,11 @@ // Per pixel tests, all sizes are small so that we can print // out the generated bitmaps. TEST_P(GLHelperPixelReadbackTest, CropScaleReadbackAndCleanTextureTest) { - unsigned int q_index = std::tr1::get<0>(GetParam()); - unsigned int x = std::tr1::get<1>(GetParam()); - unsigned int y = std::tr1::get<2>(GetParam()); - unsigned int dst_x = std::tr1::get<3>(GetParam()); - unsigned int dst_y = std::tr1::get<4>(GetParam()); + unsigned int q_index = std::get<0>(GetParam()); + unsigned int x = std::get<1>(GetParam()); + unsigned int y = std::get<2>(GetParam()); + unsigned int dst_x = std::get<3>(GetParam()); + unsigned int dst_y = std::get<4>(GetParam()); const SkColorType kColorTypes[] = { kAlpha_8_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType};
diff --git a/components/viz/common/yuv_readback_unittest.cc b/components/viz/common/yuv_readback_unittest.cc index 85dd3499..d3f38fd 100644 --- a/components/viz/common/yuv_readback_unittest.cc +++ b/components/viz/common/yuv_readback_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <tuple> + #include "base/json/json_reader.h" #include "base/memory/ref_counted_memory.h" #include "base/run_loop.h" @@ -516,13 +518,13 @@ class YUVReadbackPixelTest : public YUVReadbackTest, public ::testing::WithParamInterface< - std::tr1::tuple<bool, bool, unsigned int, unsigned int>> {}; + std::tuple<bool, bool, unsigned int, unsigned int>> {}; TEST_P(YUVReadbackPixelTest, Test) { - bool flip = std::tr1::get<0>(GetParam()); - bool use_mrt = std::tr1::get<1>(GetParam()); - unsigned int x = std::tr1::get<2>(GetParam()); - unsigned int y = std::tr1::get<3>(GetParam()); + bool flip = std::get<0>(GetParam()); + bool use_mrt = std::get<1>(GetParam()); + unsigned int x = std::get<2>(GetParam()); + unsigned int y = std::get<3>(GetParam()); for (unsigned int ox = x; ox < arraysize(kYUVReadbackSizes); ox++) { for (unsigned int oy = y; oy < arraysize(kYUVReadbackSizes); oy++) {
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index babb3a72..386aa365 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -1949,18 +1949,15 @@ !quad->IsRightEdge() || texture_size.width() == tex_coord_rect.right(); bool fills_bottom_edge = !quad->IsBottomEdge() || texture_size.height() == tex_coord_rect.bottom(); - bool has_tex_clamp_rect = true; + bool has_tex_clamp_rect = + filter == GL_LINEAR && (!fills_right_edge || !fills_bottom_edge); gfx::SizeF tex_clamp_size(texture_size); // Clamp from the original tex coord rect, instead of the one that has - // been adjusted by the visible rect. Nearest neighbor should never be - // clamped. However, still specify a tex clamp rect so that we don't - // thrash shaders. - if (filter == GL_LINEAR) { - if (!fills_right_edge) - tex_clamp_size.set_width(quad->tex_coord_rect.right() - 0.5f); - if (!fills_bottom_edge) - tex_clamp_size.set_height(quad->tex_coord_rect.bottom() - 0.5f); - } + // been adjusted by the visible rect. + if (!fills_right_edge) + tex_clamp_size.set_width(quad->tex_coord_rect.right() - 0.5f); + if (!fills_bottom_edge) + tex_clamp_size.set_height(quad->tex_coord_rect.bottom() - 0.5f); // Map to normalized texture coordinates. if (sampler != SAMPLER_TYPE_2D_RECT) {
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index de23d53e..241284a 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -8,6 +8,7 @@ #include <memory> #include <set> +#include <tuple> #include <vector> #include "base/location.h" @@ -410,11 +411,11 @@ class PrecisionBlendShaderPixelTest : public GLRendererShaderPixelTest, public ::testing::WithParamInterface< - std::tr1::tuple<TexCoordPrecision, BlendMode>> {}; + std::tuple<TexCoordPrecision, BlendMode>> {}; TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) { - TestShadersWithPrecisionAndBlend(std::tr1::get<0>(GetParam()), - std::tr1::get<1>(GetParam())); + TestShadersWithPrecisionAndBlend(std::get<0>(GetParam()), + std::get<1>(GetParam())); } INSTANTIATE_TEST_CASE_P( @@ -426,11 +427,11 @@ class PrecisionSamplerShaderPixelTest : public GLRendererShaderPixelTest, public ::testing::WithParamInterface< - std::tr1::tuple<TexCoordPrecision, SamplerType>> {}; + std::tuple<TexCoordPrecision, SamplerType>> {}; TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) { - TestShadersWithPrecisionAndSampler(std::tr1::get<0>(GetParam()), - std::tr1::get<1>(GetParam())); + TestShadersWithPrecisionAndSampler(std::get<0>(GetParam()), + std::get<1>(GetParam())); } INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile, @@ -441,12 +442,11 @@ class MaskShaderPixelTest : public GLRendererShaderPixelTest, public ::testing::WithParamInterface< - std::tr1::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {}; + std::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {}; TEST_P(MaskShaderPixelTest, ShadersCompile) { - TestShadersWithMasks( - std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()), - std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam())); + TestShadersWithMasks(std::get<0>(GetParam()), std::get<1>(GetParam()), + std::get<2>(GetParam()), std::get<3>(GetParam())); } INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
diff --git a/components/viz/service/display/overlay_strategy_underlay_cast.cc b/components/viz/service/display/overlay_strategy_underlay_cast.cc index 3466447..cc7ba76 100644 --- a/components/viz/service/display/overlay_strategy_underlay_cast.cc +++ b/components/viz/service/display/overlay_strategy_underlay_cast.cc
@@ -5,11 +5,18 @@ #include "components/viz/service/display/overlay_strategy_underlay_cast.h" #include "base/containers/adapters.h" +#include "base/lazy_instance.h" #include "components/viz/common/quads/draw_quad.h" #include "components/viz/common/quads/solid_color_draw_quad.h" #include "ui/gfx/geometry/rect_conversions.h" namespace viz { +namespace { + +base::LazyInstance<OverlayStrategyUnderlayCast::OverlayCompositedCallback>:: + DestructorAtExit g_overlay_composited_callback = LAZY_INSTANCE_INITIALIZER; + +} // namespace OverlayStrategyUnderlayCast::OverlayStrategyUnderlayCast( OverlayCandidateValidator* capability_checker) @@ -23,10 +30,10 @@ RenderPass* render_pass, cc::OverlayCandidateList* candidate_list, std::vector<gfx::Rect>* content_bounds) { - const QuadList& const_quad_list = render_pass->quad_list; + QuadList& quad_list = render_pass->quad_list; bool found_underlay = false; gfx::Rect content_rect; - for (const auto* quad : base::Reversed(const_quad_list)) { + for (const auto* quad : base::Reversed(quad_list)) { if (cc::OverlayCandidate::IsInvisibleQuad(quad)) continue; @@ -55,15 +62,37 @@ } } - const bool result = OverlayStrategyUnderlay::Attempt( - output_color_matrix, resource_provider, render_pass, candidate_list, - content_bounds); + if (found_underlay) { + for (auto it = quad_list.begin(); it != quad_list.end(); ++it) { + cc::OverlayCandidate candidate; + if (!cc::OverlayCandidate::FromDrawQuad( + resource_provider, output_color_matrix, *it, &candidate)) { + continue; + } + + render_pass->quad_list.ReplaceExistingQuadWithOpaqueTransparentSolidColor( + it); + + if (!g_overlay_composited_callback.Get().is_null()) { + g_overlay_composited_callback.Get().Run(candidate.display_rect, + candidate.transform); + } + + break; + } + } + DCHECK(content_bounds && content_bounds->empty()); - DCHECK(result == found_underlay); if (found_underlay) { content_bounds->push_back(content_rect); } - return result; + return found_underlay; +} + +// static +void OverlayStrategyUnderlayCast::SetOverlayCompositedCallback( + const OverlayCompositedCallback& cb) { + g_overlay_composited_callback.Get() = cb; } } // namespace viz
diff --git a/components/viz/service/display/overlay_strategy_underlay_cast.h b/components/viz/service/display/overlay_strategy_underlay_cast.h index d8dec12..0ea20e6 100644 --- a/components/viz/service/display/overlay_strategy_underlay_cast.h +++ b/components/viz/service/display/overlay_strategy_underlay_cast.h
@@ -5,9 +5,11 @@ #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_STRATEGY_UNDERLAY_CAST_H_ #define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_STRATEGY_UNDERLAY_CAST_H_ +#include "base/callback.h" #include "base/macros.h" #include "components/viz/service/display/overlay_strategy_underlay.h" #include "components/viz/service/viz_service_export.h" +#include "ui/gfx/overlay_transform.h" namespace viz { @@ -27,6 +29,13 @@ cc::OverlayCandidateList* candidate_list, std::vector<gfx::Rect>* content_bounds) override; + // Callback that's made whenever an overlay quad is processed in the + // compositor. Used to allow hardware video plane to be positioned to match + // compositor hole. + using OverlayCompositedCallback = + base::RepeatingCallback<void(const gfx::RectF&, gfx::OverlayTransform)>; + static void SetOverlayCompositedCallback(const OverlayCompositedCallback& cb); + private: DISALLOW_COPY_AND_ASSIGN(OverlayStrategyUnderlayCast); };
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 840558a..7df2a39 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -5,6 +5,7 @@ #include <stddef.h> #include <stdint.h> #include <memory> +#include <tuple> #include "base/memory/aligned_memory.h" #include "base/message_loop/message_loop.h" @@ -3825,7 +3826,7 @@ cc::ExactPixelComparator(true))); } -using ColorSpacePair = std::tr1::tuple<gfx::ColorSpace, gfx::ColorSpace>; +using ColorSpacePair = std::tuple<gfx::ColorSpace, gfx::ColorSpace>; class ColorTransformPixelTest : public GLRendererPixelTest, @@ -3836,8 +3837,8 @@ // size of LUTs that are created. If we did not match the LUT size exactly, // then the error for LUT based transforms is much larger. device_viewport_size_ = gfx::Size(17, 4); - src_color_space_ = std::tr1::get<0>(GetParam()); - dst_color_space_ = std::tr1::get<1>(GetParam()); + src_color_space_ = std::get<0>(GetParam()); + dst_color_space_ = std::get<1>(GetParam()); if (!src_color_space_.IsValid()) { src_color_space_ = gfx::ICCProfileForTestingNoAnalyticTrFn().GetColorSpace();
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 137fffd..574a6959 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -538,11 +538,11 @@ } VideoDetector* FrameSinkManagerImpl::CreateVideoDetectorForTesting( - std::unique_ptr<base::TickClock> tick_clock, + const base::TickClock* tick_clock, scoped_refptr<base::SequencedTaskRunner> task_runner) { DCHECK(!video_detector_); - video_detector_ = std::make_unique<VideoDetector>( - surface_manager(), std::move(tick_clock), task_runner); + video_detector_ = std::make_unique<VideoDetector>(surface_manager(), + tick_clock, task_runner); return video_detector_.get(); }
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 6f4a665..e482169 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -157,7 +157,7 @@ // Instantiates |video_detector_| for tests where we simulate the passage of // time. VideoDetector* CreateVideoDetectorForTesting( - std::unique_ptr<base::TickClock> tick_clock, + const base::TickClock* tick_clock, scoped_refptr<base::SequencedTaskRunner> task_runner); // Called when |frame_token| is changed on a submitted CompositorFrame.
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc index 92370f4..3f17aca 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <tuple> + #include "base/run_loop.h" #include "components/viz/common/constants.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" @@ -557,7 +559,7 @@ class FrameSinkManagerOrderingParamTest : public FrameSinkManagerOrderingTest, public ::testing::WithParamInterface< - std::tr1::tuple<RegisterOrder, UnregisterOrder, BFSOrder>> {}; + std::tuple<RegisterOrder, UnregisterOrder, BFSOrder>> {}; TEST_P(FrameSinkManagerOrderingParamTest, Ordering) { // Test the four permutations of client/hierarchy setting/unsetting and test @@ -565,9 +567,9 @@ // client/hierarchy are less related, so BFS is tested independently instead // of every permutation of BFS setting and unsetting. // The register/unregister functions themselves test most of the state. - RegisterOrder register_order = std::tr1::get<0>(GetParam()); - UnregisterOrder unregister_order = std::tr1::get<1>(GetParam()); - BFSOrder bfs_order = std::tr1::get<2>(GetParam()); + RegisterOrder register_order = std::get<0>(GetParam()); + UnregisterOrder unregister_order = std::get<1>(GetParam()); + BFSOrder bfs_order = std::get<2>(GetParam()); // Attach everything up in the specified order. if (bfs_order == BFS_FIRST)
diff --git a/components/viz/service/frame_sinks/video_detector.cc b/components/viz/service/frame_sinks/video_detector.cc index c6762e62..42c81d0 100644 --- a/components/viz/service/frame_sinks/video_detector.cc +++ b/components/viz/service/frame_sinks/video_detector.cc
@@ -89,10 +89,10 @@ VideoDetector::VideoDetector( SurfaceManager* surface_manager, - std::unique_ptr<const base::TickClock> tick_clock, + const base::TickClock* tick_clock, scoped_refptr<base::SequencedTaskRunner> task_runner) - : tick_clock_(std::move(tick_clock)), - video_inactive_timer_(tick_clock_.get()), + : tick_clock_(tick_clock), + video_inactive_timer_(tick_clock), surface_manager_(surface_manager) { surface_manager_->AddObserver(this); for (auto it : surface_manager_->valid_frame_sink_labels())
diff --git a/components/viz/service/frame_sinks/video_detector.h b/components/viz/service/frame_sinks/video_detector.h index de32e6b..90e240e3 100644 --- a/components/viz/service/frame_sinks/video_detector.h +++ b/components/viz/service/frame_sinks/video_detector.h
@@ -28,10 +28,10 @@ // fooled by things like continuous scrolling of a page. class VIZ_SERVICE_EXPORT VideoDetector : public SurfaceObserver { public: - VideoDetector(SurfaceManager* surface_manager, - std::unique_ptr<const base::TickClock> tick_clock = - std::make_unique<base::DefaultTickClock>(), - scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr); + VideoDetector( + SurfaceManager* surface_manager, + const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance(), + scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr); virtual ~VideoDetector(); // Adds an observer. The observer can be removed by closing the mojo @@ -87,7 +87,7 @@ bool video_is_playing_ = false; // Provides the current time. - std::unique_ptr<const base::TickClock> tick_clock_; + const base::TickClock* tick_clock_; // Calls OnVideoActivityEnded() after |kVideoTimeout|. Uses |tick_clock_| to // measure time.
diff --git a/components/viz/service/frame_sinks/video_detector_unittest.cc b/components/viz/service/frame_sinks/video_detector_unittest.cc index f3cfe50..c56d8d4 100644 --- a/components/viz/service/frame_sinks/video_detector_unittest.cc +++ b/components/viz/service/frame_sinks/video_detector_unittest.cc
@@ -86,7 +86,7 @@ base::TimeTicks() + base::TimeDelta::FromSeconds(1)); detector_ = frame_sink_manager_.CreateVideoDetectorForTesting( - mock_task_runner_->DeprecatedGetMockTickClock(), mock_task_runner_); + mock_task_runner_->GetMockTickClock(), mock_task_runner_); mojom::VideoDetectorObserverPtr video_detector_observer; observer_.Bind(mojo::MakeRequest(&video_detector_observer));
diff --git a/components/zucchini/BUILD.gn b/components/zucchini/BUILD.gn index 37a548d..758ba2b 100644 --- a/components/zucchini/BUILD.gn +++ b/components/zucchini/BUILD.gn
@@ -122,6 +122,20 @@ } } +# To download the corpus for local fuzzing use: +# gsutil -m rsync \ +# gs://clusterfuzz-corpus/libfuzzer/zucchini_disassembler_win32_fuzzer \ +# components/zucchini/testdata/disassembler_win32_fuzzer +fuzzer_test("zucchini_disassembler_win32_fuzzer") { + sources = [ + "disassembler_win32_fuzzer.cc", + ] + deps = [ + ":zucchini_lib", + "//base", + ] +} + fuzzer_test("zucchini_patch_fuzzer") { sources = [ "patch_fuzzer.cc",
diff --git a/components/zucchini/disassembler_win32_fuzzer.cc b/components/zucchini/disassembler_win32_fuzzer.cc new file mode 100644 index 0000000..dbbd0e8b --- /dev/null +++ b/components/zucchini/disassembler_win32_fuzzer.cc
@@ -0,0 +1,64 @@ +// Copyright 2018 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 <stddef.h> +#include <stdint.h> + +#include "base/logging.h" +#include "components/zucchini/buffer_view.h" +#include "components/zucchini/disassembler.h" +#include "components/zucchini/disassembler_win32.h" + +struct Environment { + Environment() { + logging::SetMinLogLevel(3); // Disable console spamming. + } +}; + +Environment* env = new Environment(); + +// Entry point for LibFuzzer. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // Prep data. + zucchini::ConstBufferView image(data, size); + + // One of x86 or x64 should return a non-nullptr if the data is valid. + + // Output will be a pointer to zucchini::DisassemblerWin32X86 if successful + // or nullptr otherwise. + auto disassembler_win32x86 = + zucchini::Disassembler::Make<zucchini::DisassemblerWin32X86>(image); + if (disassembler_win32x86 != nullptr) { + // Parse the Win32 PE file and ensure nothing bad occurs. + // TODO(ckitagawa): Actually validate that the output reference is within + // the image. + auto relocx86 = disassembler_win32x86->MakeReadRelocs(0, image.size()); + while (relocx86->GetNext().has_value()) { + } + auto abs32x86 = disassembler_win32x86->MakeReadAbs32(0, image.size()); + while (abs32x86->GetNext().has_value()) { + } + auto rel32x86 = disassembler_win32x86->MakeReadRel32(0, image.size()); + while (rel32x86->GetNext().has_value()) { + } + } + + // Output will be a pointer to zucchini::DisassemblerWin32X64 if successful + // or nullptr otherwise. + auto disassembler_win32x64 = + zucchini::Disassembler::Make<zucchini::DisassemblerWin32X64>(image); + if (disassembler_win32x64 != nullptr) { + // Parse the Win32 PE file and ensure nothing bad occurs. + auto relocx64 = disassembler_win32x64->MakeReadRelocs(0, image.size()); + while (relocx64->GetNext().has_value()) { + } + auto abs32x64 = disassembler_win32x64->MakeReadAbs32(0, image.size()); + while (abs32x64->GetNext().has_value()) { + } + auto rel32x64 = disassembler_win32x64->MakeReadRel32(0, image.size()); + while (rel32x64->GetNext().has_value()) { + } + } + return 0; +}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index ed7bcab..cc3a64fe 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1168,6 +1168,10 @@ "permissions/permission_service_context.h", "permissions/permission_service_impl.cc", "permissions/permission_service_impl.h", + "picture_in_picture/overlay_surface_embedder.cc", + "picture_in_picture/overlay_surface_embedder.h", + "picture_in_picture/picture_in_picture_window_controller_impl.cc", + "picture_in_picture/picture_in_picture_window_controller_impl.h", "presentation/presentation_service_impl.cc", "presentation/presentation_service_impl.h", "push_messaging/push_messaging_context.cc",
diff --git a/content/browser/appcache/appcache_internals_ui.cc b/content/browser/appcache/appcache_internals_ui.cc index f4f1b4e..3a34269 100644 --- a/content/browser/appcache/appcache_internals_ui.cc +++ b/content/browser/appcache/appcache_internals_ui.cc
@@ -298,7 +298,7 @@ reader->ReadData(response_data.get(), amount_to_read, base::BindOnce(&Proxy::OnResponseDataReadComplete, this, response_enquiry, response_info, - base::Passed(&reader), response_data)); + std::move(reader), response_data)); } else { OnResponseDataReadComplete(response_enquiry, nullptr, nullptr, nullptr, -1); }
diff --git a/content/browser/appcache/appcache_storage_impl.cc b/content/browser/appcache/appcache_storage_impl.cc index cb64cc2f..31824f18 100644 --- a/content/browser/appcache/appcache_storage_impl.cc +++ b/content/browser/appcache/appcache_storage_impl.cc
@@ -682,7 +682,7 @@ storage_->pending_quota_queries_.insert(this); quota_manager->GetUsageAndQuota( group_record_.origin.GetURL(), blink::mojom::StorageType::kTemporary, - base::Bind(&StoreGroupAndCacheTask::OnQuotaCallback, this)); + base::BindOnce(&StoreGroupAndCacheTask::OnQuotaCallback, this)); } void AppCacheStorageImpl::StoreGroupAndCacheTask::OnQuotaCallback(
diff --git a/content/browser/background_fetch/background_fetch_test_base.cc b/content/browser/background_fetch/background_fetch_test_base.cc index 560985e..a1266fd 100644 --- a/content/browser/background_fetch/background_fetch_test_base.cc +++ b/content/browser/background_fetch/background_fetch_test_base.cc
@@ -95,8 +95,9 @@ base::RunLoop run_loop; embedded_worker_test_helper_.context()->RegisterServiceWorker( script_url, options, - base::Bind(&DidRegisterServiceWorker, &service_worker_registration_id, - run_loop.QuitClosure())); + base::BindOnce(&DidRegisterServiceWorker, + &service_worker_registration_id, + run_loop.QuitClosure())); run_loop.Run(); }
diff --git a/content/browser/background_fetch/storage/create_registration_task.cc b/content/browser/background_fetch/storage/create_registration_task.cc index b1089d0..3203b20 100644 --- a/content/browser/background_fetch/storage/create_registration_task.cc +++ b/content/browser/background_fetch/storage/create_registration_task.cc
@@ -146,8 +146,8 @@ service_worker_context()->StoreRegistrationUserData( registration_id_.service_worker_registration_id(), registration_id_.origin().GetURL(), entries, - base::BindRepeating(&CreateRegistrationTask::DidStoreMetadata, - weak_factory_.GetWeakPtr())); + base::BindOnce(&CreateRegistrationTask::DidStoreMetadata, + weak_factory_.GetWeakPtr())); } void CreateRegistrationTask::DidStoreMetadata(ServiceWorkerStatusCode status) {
diff --git a/content/browser/background_fetch/storage/delete_registration_task.cc b/content/browser/background_fetch/storage/delete_registration_task.cc index db9678a..92cb468 100644 --- a/content/browser/background_fetch/storage/delete_registration_task.cc +++ b/content/browser/background_fetch/storage/delete_registration_task.cc
@@ -88,8 +88,8 @@ service_worker_context()->ClearRegistrationUserDataByKeyPrefixes( service_worker_registration_id_, {RegistrationKey(unique_id_), RequestKeyPrefix(unique_id_)}, - base::Bind(&DeleteRegistrationTask::DidDeleteRegistration, - weak_factory_.GetWeakPtr())); + base::BindOnce(&DeleteRegistrationTask::DidDeleteRegistration, + weak_factory_.GetWeakPtr())); } void DeleteRegistrationTask::DidDeleteRegistration(
diff --git a/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc b/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc index d36f57e..365e6bf 100644 --- a/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc +++ b/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
@@ -77,8 +77,8 @@ PendingRequestKeyPrefix( metadata_proto.creation_microseconds_since_unix_epoch(), registration_id_.unique_id())}, - base::Bind(&MarkRegistrationForDeletionTask::DidDeactivate, - weak_factory_.GetWeakPtr())); + base::BindOnce(&MarkRegistrationForDeletionTask::DidDeactivate, + weak_factory_.GetWeakPtr())); } else { NOTREACHED() << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it. }
diff --git a/content/browser/background_fetch/storage/update_registration_ui_task.cc b/content/browser/background_fetch/storage/update_registration_ui_task.cc index 48b354d9..1f6b253 100644 --- a/content/browser/background_fetch/storage/update_registration_ui_task.cc +++ b/content/browser/background_fetch/storage/update_registration_ui_task.cc
@@ -73,8 +73,8 @@ service_worker_context()->StoreRegistrationUserData( service_worker_registration_id_, origin_.GetURL(), {{RegistrationKey(unique_id_), metadata_proto.SerializeAsString()}}, - base::BindRepeating(&UpdateRegistrationUITask::DidUpdateUI, - weak_factory_.GetWeakPtr())); + base::BindOnce(&UpdateRegistrationUITask::DidUpdateUI, + weak_factory_.GetWeakPtr())); } void UpdateRegistrationUITask::DidUpdateUI(ServiceWorkerStatusCode status) {
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.cc b/content/browser/bluetooth/web_bluetooth_service_impl.cc index 6e72086..3f56432 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl.cc +++ b/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -823,11 +823,12 @@ blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, RequestDeviceCallback callback, device::BluetoothAdapter* adapter) { - // requestDevice() can only be called when processing a user-gesture and any - // user gesture outside of a chooser should close the chooser. This does - // not happen on all platforms so we don't DCHECK that the old one is closed. - // We destroy the old chooser before constructing the new one to make sure - // they can't conflict. + // Calls to requestDevice() require user activation (user gestures). We + // should close any opened chooser when a duplicate requestDevice call is made + // with the same user activation or when any gesture occurs outside of the + // opened chooser. This does not happen on all platforms so we don't DCHECK + // that the old one is closed. We destroy the old chooser before constructing + // the new one to make sure they can't conflict. device_chooser_controller_.reset(); device_chooser_controller_.reset(
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index b7449a7..a8bee9c 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -546,8 +546,9 @@ quota_manager_proxy_->GetUsageAndQuota( base::ThreadTaskRunnerHandle::Get().get(), origin, StorageType::kTemporary, - base::Bind(&CacheStorageManagerTest::DidGetQuotaOriginUsage, - base::Unretained(this), base::Unretained(&usage), &loop)); + base::BindOnce(&CacheStorageManagerTest::DidGetQuotaOriginUsage, + base::Unretained(this), base::Unretained(&usage), + &loop)); loop.Run(); return usage; }
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index f422c39..cae7c56 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -369,6 +369,10 @@ // DevToolsHttpHandler ------------------------------------------------------- DevToolsHttpHandler::~DevToolsHttpHandler() { + // Disconnecting sessions might lead to the last minute messages generated + // by the targets. It is essential that this happens before we issue delete + // soon for the server wrapper. + connection_to_client_.clear(); TerminateOnUI(std::move(thread_), std::move(server_wrapper_), std::move(socket_factory_)); }
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc index cc2abc4d..8635c58e 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.cc +++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -811,8 +811,10 @@ const net::Error& net_error) { DCHECK_NE(waiting_for_user_response_, WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK); - if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) + if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) { + static_cast<InterceptedRequest*>(sub_request_.get())->FetchResponseBody(); return; + } waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK; std::unique_ptr<InterceptedRequestInfo> request_info = BuildRequestInfo(); @@ -1130,7 +1132,13 @@ // The reason we start a sub request is because we are in full control of it // and can choose to ignore it if, for example, the fetch encounters a // redirect that the user chooses to replace with a mock response. - sub_request_.reset(new SubRequest(request_details_, this, interceptor_)); + DCHECK(stage_to_intercept_ != InterceptionStage::RESPONSE); + if (stage_to_intercept_ == InterceptionStage::BOTH) { + sub_request_.reset( + new InterceptedRequest(request_details_, this, interceptor_)); + } else { + sub_request_.reset(new SubRequest(request_details_, this, interceptor_)); + } } }
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 9ec8fc85..1aa82df2 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -340,7 +340,7 @@ cookie, std::move(once_callback)); } if (!filtered_list.size()) - std::move(callback).Run(); + DeletedCookiesOnIO(std::move(callback), 0); } void DeleteCookiesOnIO(net::URLRequestContextGetter* context_getter,
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 626ed1f..a12f16c 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -89,8 +89,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); manager->GetUsageAndQuotaWithBreakdown( url, blink::mojom::StorageType::kTemporary, - base::Bind(&GotUsageAndQuotaDataCallback, - base::Passed(std::move(callback)))); + base::BindOnce(&GotUsageAndQuotaDataCallback, std::move(callback))); } } // namespace
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 57c9997..45f6b84 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -3184,14 +3184,7 @@ // Verifies that if the last slice is finished, parallel download resumption // can complete. -#if defined(OS_CHROMEOS) -// Failing on ChromeOS: https://crbug.com/822450 -#define MAYBE_ResumptionLastSliceFinished DISABLED_ResumptionLastSliceFinished -#else -#define MAYBE_ResumptionLastSliceFinished ResumptionLastSliceFinished -#endif -IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, - MAYBE_ResumptionLastSliceFinished) { +IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ResumptionLastSliceFinished) { // Create the received slices data, last slice is actually finished. std::vector<download::DownloadItem::ReceivedSlice> received_slices = { download::DownloadItem::ReceivedSlice(0, 1000), @@ -3207,16 +3200,7 @@ // Verifies that if the last slice is finished, but the database record is not // finished, which may happen in database migration. // When the server sends HTTP range not satisfied, the download can complete. -#if defined(OS_WIN) || defined(OS_ANDROID) -// Failing on Windows: https://crbug.com/814310 -// Failing on Android: https://crbug.com/817801 -#define MAYBE_ResumptionLastSliceUnfinished \ - DISABLED_ResumptionLastSliceUnfinished -#else -#define MAYBE_ResumptionLastSliceUnfinished ResumptionLastSliceUnfinished -#endif -IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, - MAYBE_ResumptionLastSliceUnfinished) { +IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ResumptionLastSliceUnfinished) { // Create the received slices data, last slice is actually finished. std::vector<download::DownloadItem::ReceivedSlice> received_slices = { download::DownloadItem::ReceivedSlice(0, 1000),
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index ffa4b9d..ccbc17a 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -11,6 +11,7 @@ #include <memory> #include <set> #include <string> +#include <tuple> #include <utility> #include "base/bind.h" @@ -60,7 +61,7 @@ ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - return ::std::tr1::get<k>(args).Run(p0); + return std::get<k>(args).Run(p0); } namespace content {
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc index eddbe5ce..de16bb4 100644 --- a/content/browser/download/mhtml_generation_manager.cc +++ b/content/browser/download/mhtml_generation_manager.cc
@@ -354,7 +354,7 @@ save_status, (save_status == MhtmlSaveStatus::SUCCESS ? mhtml_boundary_marker_ : std::string()), - base::Passed(&browser_file_), base::Passed(&extra_data_parts_)), + std::move(browser_file_), std::move(extra_data_parts_)), std::move(callback)); }
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h index 6a40d29..fb5fb99 100644 --- a/content/browser/frame_host/render_frame_host_delegate.h +++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -359,7 +359,8 @@ // Updates the Picture-in-Picture controller with the relevant viz::SurfaceId // of the video to be in Picture-in-Picture mode. - virtual void UpdatePictureInPictureSurfaceId(viz::SurfaceId surface_id) {} + virtual void UpdatePictureInPictureSurfaceId( + const viz::SurfaceId& surface_id) {} // Updates the Picture-in-Picture controller with a signal that // Picture-in-Picture mode has ended.
diff --git a/content/browser/generic_sensor/sensor_provider_proxy_impl.cc b/content/browser/generic_sensor/sensor_provider_proxy_impl.cc index 1ce1a6f..bd370f6 100644 --- a/content/browser/generic_sensor/sensor_provider_proxy_impl.cc +++ b/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
@@ -66,7 +66,8 @@ } bool SensorProviderProxyImpl::CheckPermission() const { - const GURL& requesting_origin = render_frame_host_->GetLastCommittedURL(); + const GURL& requesting_origin = + render_frame_host_->GetLastCommittedURL().GetOrigin(); blink::mojom::PermissionStatus permission_status = permission_manager_->GetPermissionStatusForFrame(
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc index b47caa4..22d03d38 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -275,7 +275,7 @@ CreateGpuMemoryBufferOnIO( new_id, request->size, request->format, request->usage, request->surface_handle, request->client_id, - base::Bind( + base::BindOnce( &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO, base::Unretained(this), base::Unretained(request))); return;
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc index ea20731..091d9fa 100644 --- a/content/browser/indexed_db/database_impl.cc +++ b/content/browser/indexed_db/database_impl.cc
@@ -913,8 +913,8 @@ indexed_db_context_->quota_manager_proxy()->GetUsageAndQuota( indexed_db_context_->TaskRunner(), origin_, blink::mojom::StorageType::kTemporary, - base::Bind(&IDBSequenceHelper::OnGotUsageAndQuotaForCommit, - weak_factory_.GetWeakPtr(), transaction_id)); + base::BindOnce(&IDBSequenceHelper::OnGotUsageAndQuotaForCommit, + weak_factory_.GetWeakPtr(), transaction_id)); } void DatabaseImpl::IDBSequenceHelper::OnGotUsageAndQuotaForCommit(
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index 5c0917bd..7b61bae 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -244,7 +244,6 @@ new_request->update_first_party_url_on_redirect = true; int load_flags = request_info->begin_params->load_flags; - load_flags |= net::LOAD_VERIFY_EV_CERT; if (request_info->is_main_frame) load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index cf892d7..42727ea 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1832,7 +1832,6 @@ } int load_flags = info.begin_params->load_flags; - load_flags |= net::LOAD_VERIFY_EV_CERT; if (info.is_main_frame) load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
diff --git a/content/browser/loader/temporary_file_stream.cc b/content/browser/loader/temporary_file_stream.cc index f1493e70..07e008d 100644 --- a/content/browser/loader/temporary_file_stream.cc +++ b/content/browser/loader/temporary_file_stream.cc
@@ -63,8 +63,8 @@ base::FileProxy* proxy = file_proxy.get(); proxy->CreateTemporary( base::File::FLAG_ASYNC, - base::Bind(&DidCreateTemporaryFile, callback, Passed(&file_proxy), - std::move(task_runner))); + base::BindOnce(&DidCreateTemporaryFile, callback, std::move(file_proxy), + std::move(task_runner))); } } // namespace content
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc index 1d3c55a..7639b8e 100644 --- a/content/browser/manifest/manifest_browsertest.cc +++ b/content/browser/manifest/manifest_browsertest.cc
@@ -73,9 +73,8 @@ } void GetManifestAndWait() { - shell()->web_contents()->GetManifest( - base::Bind(&ManifestBrowserTest::OnGetManifest, - base::Unretained(this))); + shell()->web_contents()->GetManifest(base::BindOnce( + &ManifestBrowserTest::OnGetManifest, base::Unretained(this))); message_loop_runner_ = new MessageLoopRunner(); message_loop_runner_->Run();
diff --git a/content/browser/media/cdm_file_impl.cc b/content/browser/media/cdm_file_impl.cc index 12e6e826..4c1657d 100644 --- a/content/browser/media/cdm_file_impl.cc +++ b/content/browser/media/cdm_file_impl.cc
@@ -174,8 +174,8 @@ lock_state_ = LockState::kFileLocked; pending_open_callback_ = std::move(callback); OpenFile(file_name_, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ, - base::Bind(&CdmFileImpl::OnFileOpenedForReading, - weak_factory_.GetWeakPtr())); + base::BindOnce(&CdmFileImpl::OnFileOpenedForReading, + weak_factory_.GetWeakPtr())); } void CdmFileImpl::OpenFile(const std::string& file_name, @@ -248,8 +248,8 @@ pending_open_callback_ = std::move(callback); OpenFile(temp_file_name_, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE, - base::Bind(&CdmFileImpl::OnTempFileOpenedForWriting, - weak_factory_.GetWeakPtr())); + base::BindOnce(&CdmFileImpl::OnTempFileOpenedForWriting, + weak_factory_.GetWeakPtr())); } void CdmFileImpl::OnTempFileOpenedForWriting( @@ -312,7 +312,7 @@ file_util->MoveFileLocal( std::move(operation_context), src_file_url, dest_file_url, storage::FileSystemOperation::OPTION_NONE, - base::Bind(&CdmFileImpl::OnFileRenamed, weak_factory_.GetWeakPtr())); + base::BindOnce(&CdmFileImpl::OnFileRenamed, weak_factory_.GetWeakPtr())); } void CdmFileImpl::OnFileRenamed(base::File::Error move_result) { @@ -334,8 +334,8 @@ // Reopen the original file for reading. Specifying FLAG_OPEN as the file // has to exist or something's wrong. OpenFile(file_name_, base::File::FLAG_OPEN | base::File::FLAG_READ, - base::Bind(&CdmFileImpl::OnFileOpenedForReading, - weak_factory_.GetWeakPtr())); + base::BindOnce(&CdmFileImpl::OnFileOpenedForReading, + weak_factory_.GetWeakPtr())); } storage::FileSystemURL CdmFileImpl::CreateFileSystemURL(
diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc index 46372c47..9a01d1a 100644 --- a/content/browser/media/encrypted_media_browsertest.cc +++ b/content/browser/media/encrypted_media_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <tuple> + #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -75,19 +77,15 @@ // - SrcType: The type of video src used to load media, MSE or SRC. // It is okay to run this test as a non-parameterized test, in this case, // GetParam() should not be called. -class EncryptedMediaTest : public MediaBrowserTest, - public testing::WithParamInterface< - std::tr1::tuple<const char*, SrcType>> { +class EncryptedMediaTest + : public MediaBrowserTest, + public testing::WithParamInterface<std::tuple<const char*, SrcType>> { public: // Can only be used in parameterized (*_P) tests. - const std::string CurrentKeySystem() { - return std::tr1::get<0>(GetParam()); - } + const std::string CurrentKeySystem() { return std::get<0>(GetParam()); } // Can only be used in parameterized (*_P) tests. - SrcType CurrentSourceType() { - return std::tr1::get<1>(GetParam()); - } + SrcType CurrentSourceType() { return std::get<1>(GetParam()); } void TestSimplePlayback(const std::string& encrypted_media, const std::string& media_type) {
diff --git a/content/browser/net/accept_header_browsertest.cc b/content/browser/net/accept_header_browsertest.cc index 46d76f9f..d3a6a67 100644 --- a/content/browser/net/accept_header_browsertest.cc +++ b/content/browser/net/accept_header_browsertest.cc
@@ -149,7 +149,7 @@ EXPECT_EQ("custom/type", GetFor("/xhr_with_accept_header")); shell()->web_contents()->GetManifest( - base::BindRepeating([](const GURL&, const content::Manifest&) {})); + base::BindOnce([](const GURL&, const content::Manifest&) {})); // RESOURCE_TYPE_SUB_RESOURCE EXPECT_EQ("*/*", GetFor("/manifest"));
diff --git a/content/browser/net/quota_policy_cookie_store.cc b/content/browser/net/quota_policy_cookie_store.cc index 9eaa19e..98068af 100644 --- a/content/browser/net/quota_policy_cookie_store.cc +++ b/content/browser/net/quota_policy_cookie_store.cc
@@ -33,24 +33,29 @@ } QuotaPolicyCookieStore::~QuotaPolicyCookieStore() { + using CookieOrigin = net::SQLitePersistentCookieStore::CookieOrigin; if (!special_storage_policy_.get() || !special_storage_policy_->HasSessionOnlyOrigins()) { return; } - std::list<net::SQLitePersistentCookieStore::CookieOrigin> - session_only_cookies; - for (const auto& cookie : cookies_per_origin_) { - if (cookie.second == 0) { + std::list<CookieOrigin> session_only_cookies; + auto delete_cookie_predicate = + special_storage_policy_->CreateDeleteCookieOnExitPredicate(); + DCHECK(delete_cookie_predicate); + + for (const auto& entry : cookies_per_origin_) { + if (entry.second == 0) { continue; } - const GURL url(net::cookie_util::CookieOriginToURL(cookie.first.first, - cookie.first.second)); + const CookieOrigin& cookie = entry.first; + const GURL url( + net::cookie_util::CookieOriginToURL(cookie.first, cookie.second)); if (!url.is_valid() || - !special_storage_policy_->ShouldDeleteCookieOnExit(url)) + !delete_cookie_predicate.Run(cookie.first, cookie.second)) { continue; - - session_only_cookies.push_back(cookie.first); + } + session_only_cookies.push_back(cookie); } persistent_store_->DeleteAllInList(session_only_cookies);
diff --git a/content/browser/notifications/platform_notification_context_unittest.cc b/content/browser/notifications/platform_notification_context_unittest.cc index 04b485f..99220b2 100644 --- a/content/browser/notifications/platform_notification_context_unittest.cc +++ b/content/browser/notifications/platform_notification_context_unittest.cc
@@ -334,8 +334,8 @@ options.scope = origin; embedded_worker_test_helper->context()->RegisterServiceWorker( script_url, options, - base::Bind(&PlatformNotificationContextTest::DidRegisterServiceWorker, - base::Unretained(this), &service_worker_registration_id)); + base::BindOnce(&PlatformNotificationContextTest::DidRegisterServiceWorker, + base::Unretained(this), &service_worker_registration_id)); base::RunLoop().RunUntilIdle(); ASSERT_NE(service_worker_registration_id, @@ -358,9 +358,9 @@ // Now drop the Service Worker registration which owns that notification. embedded_worker_test_helper->context()->UnregisterServiceWorker( - origin, - base::Bind(&PlatformNotificationContextTest::DidUnregisterServiceWorker, - base::Unretained(this), &unregister_status)); + origin, base::BindOnce( + &PlatformNotificationContextTest::DidUnregisterServiceWorker, + base::Unretained(this), &unregister_status)); base::RunLoop().RunUntilIdle(); ASSERT_EQ(SERVICE_WORKER_OK, unregister_status);
diff --git a/content/browser/payments/payment_app_content_unittest_base.cc b/content/browser/payments/payment_app_content_unittest_base.cc index 4e0c343..1ebc1db 100644 --- a/content/browser/payments/payment_app_content_unittest_base.cc +++ b/content/browser/payments/payment_app_content_unittest_base.cc
@@ -149,7 +149,8 @@ registration_opt.scope = scope_url; worker_helper_->context()->RegisterServiceWorker( sw_script_url, registration_opt, - base::Bind(&RegisterServiceWorkerCallback, &called, ®istration_id)); + base::BindOnce(&RegisterServiceWorkerCallback, &called, + ®istration_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(called); @@ -204,7 +205,7 @@ // Unregister service worker. bool called = false; worker_helper_->context()->UnregisterServiceWorker( - scope_url, base::Bind(&UnregisterServiceWorkerCallback, &called)); + scope_url, base::BindOnce(&UnregisterServiceWorkerCallback, &called)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(called); }
diff --git a/content/browser/payments/payment_app_database.cc b/content/browser/payments/payment_app_database.cc index 9dfa6f1..c9d49a0 100644 --- a/content/browser/payments/payment_app_database.cc +++ b/content/browser/payments/payment_app_database.cc
@@ -137,8 +137,7 @@ service_worker_context_->GetUserDataForAllRegistrationsByKeyPrefix( kPaymentAppPrefix, base::BindOnce(&PaymentAppDatabase::DidReadAllPaymentApps, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DeletePaymentInstrument( @@ -151,8 +150,7 @@ scope, base::BindOnce( &PaymentAppDatabase::DidFindRegistrationToDeletePaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), instrument_key, - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), instrument_key, std::move(callback))); } void PaymentAppDatabase::ReadPaymentInstrument( @@ -165,8 +163,7 @@ scope, base::BindOnce( &PaymentAppDatabase::DidFindRegistrationToReadPaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), instrument_key, - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), instrument_key, std::move(callback))); } void PaymentAppDatabase::KeysOfPaymentInstruments( @@ -175,9 +172,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); service_worker_context_->FindReadyRegistrationForPattern( - scope, base::BindOnce(&PaymentAppDatabase::DidFindRegistrationToGetKeys, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + scope, + base::BindOnce(&PaymentAppDatabase::DidFindRegistrationToGetKeys, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::HasPaymentInstrument( @@ -187,10 +184,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); service_worker_context_->FindReadyRegistrationForPattern( - scope, base::BindOnce( - &PaymentAppDatabase::DidFindRegistrationToHasPaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), instrument_key, - base::Passed(std::move(callback)))); + scope, + base::BindOnce( + &PaymentAppDatabase::DidFindRegistrationToHasPaymentInstrument, + weak_ptr_factory_.GetWeakPtr(), instrument_key, std::move(callback))); } void PaymentAppDatabase::WritePaymentInstrument( @@ -214,8 +211,7 @@ base::BindOnce( &PaymentAppDatabase::DidFindRegistrationToWritePaymentInstrument, weak_ptr_factory_.GetWeakPtr(), instrument_key, - base::Passed(std::move(instrument)), std::string(), - base::Passed(std::move(callback)))); + std::move(instrument), std::string(), std::move(callback))); } } @@ -236,9 +232,8 @@ scope, base::BindOnce( &PaymentAppDatabase::DidFindRegistrationToWritePaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), instrument_key, - base::Passed(std::move(instrument)), icon, - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), instrument_key, std::move(instrument), + icon, std::move(callback))); } void PaymentAppDatabase::FetchAndUpdatePaymentAppInfo( @@ -261,11 +256,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); service_worker_context_->FindReadyRegistrationForPattern( - scope, - base::BindOnce( - &PaymentAppDatabase::DidFindRegistrationToUpdatePaymentAppInfo, - weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(callback)), - base::Passed(std::move(app_info)))); + scope, base::BindOnce( + &PaymentAppDatabase::DidFindRegistrationToUpdatePaymentAppInfo, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + std::move(app_info))); } void PaymentAppDatabase::DidFindRegistrationToUpdatePaymentAppInfo( @@ -283,8 +277,8 @@ registration->id(), CreatePaymentAppKey(registration->pattern().spec()), base::BindOnce( &PaymentAppDatabase::DidGetPaymentAppInfoToUpdatePaymentAppInfo, - weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(callback)), - base::Passed(std::move(app_info)), registration)); + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + std::move(app_info), registration)); } void PaymentAppDatabase::DidGetPaymentAppInfoToUpdatePaymentAppInfo( @@ -330,10 +324,9 @@ registration->id(), registration->pattern().GetOrigin(), {{CreatePaymentAppKey(registration->pattern().spec()), serialized_payment_app}}, - base::Bind(&PaymentAppDatabase::DidUpdatePaymentApp, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)), - app_info->name.empty() | app_info->icon.empty())); + base::BindOnce(&PaymentAppDatabase::DidUpdatePaymentApp, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + app_info->name.empty() | app_info->icon.empty())); } void PaymentAppDatabase::DidUpdatePaymentApp( @@ -361,8 +354,7 @@ scope, base::BindOnce( &PaymentAppDatabase::DidFindRegistrationToClearPaymentInstruments, - weak_ptr_factory_.GetWeakPtr(), scope, - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), scope, std::move(callback))); } void PaymentAppDatabase::SetPaymentAppUserHint(const GURL& scope, @@ -415,8 +407,8 @@ service_worker_context_->StoreRegistrationUserData( registration_id, pattern.GetOrigin(), {{CreatePaymentAppKey(pattern.spec()), serialized_payment_app}}, - base::Bind(&PaymentAppDatabase::DidSetPaymentAppUserHint, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&PaymentAppDatabase::DidSetPaymentAppUserHint, + weak_ptr_factory_.GetWeakPtr())); } void PaymentAppDatabase::DidSetPaymentAppUserHint( @@ -470,9 +462,9 @@ registration->id(), registration->pattern().GetOrigin(), {{CreatePaymentAppKey(registration->pattern().spec()), serialized_payment_app}}, - base::Bind(&PaymentAppDatabase::DidWritePaymentAppForSetPaymentApp, - weak_ptr_factory_.GetWeakPtr(), instrument_key, method, - base::Passed(std::move(callback)), std::move(registration))); + base::BindOnce(&PaymentAppDatabase::DidWritePaymentAppForSetPaymentApp, + weak_ptr_factory_.GetWeakPtr(), instrument_key, method, + std::move(callback), std::move(registration))); return; } @@ -512,9 +504,9 @@ {{CreatePaymentInstrumentKey(instrument_key), serialized_instrument}, {CreatePaymentInstrumentKeyInfoKey(instrument_key), serialized_key_info}}, - base::Bind(&PaymentAppDatabase::DidWritePaymentInstrumentForSetPaymentApp, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + base::BindOnce( + &PaymentAppDatabase::DidWritePaymentInstrumentForSetPaymentApp, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidWritePaymentInstrumentForSetPaymentApp( @@ -553,9 +545,8 @@ service_worker_context_->GetUserDataForAllRegistrationsByKeyPrefix( kPaymentInstrumentPrefix, base::BindOnce(&PaymentAppDatabase::DidReadAllPaymentInstruments, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(apps)), - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), std::move(apps), + std::move(callback))); } void PaymentAppDatabase::DidReadAllPaymentInstruments( @@ -607,7 +598,7 @@ registration->id(), {CreatePaymentInstrumentKey(instrument_key)}, base::BindOnce(&PaymentAppDatabase::DidFindPaymentInstrument, weak_ptr_factory_.GetWeakPtr(), registration->id(), - instrument_key, base::Passed(std::move(callback)))); + instrument_key, std::move(callback))); } void PaymentAppDatabase::DidFindPaymentInstrument( @@ -626,9 +617,8 @@ registration_id, {CreatePaymentInstrumentKey(instrument_key), CreatePaymentInstrumentKeyInfoKey(instrument_key)}, - base::Bind(&PaymentAppDatabase::DidDeletePaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + base::BindOnce(&PaymentAppDatabase::DidDeletePaymentInstrument, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidDeletePaymentInstrument( @@ -655,8 +645,7 @@ service_worker_context_->GetRegistrationUserData( registration->id(), {CreatePaymentInstrumentKey(instrument_key)}, base::BindOnce(&PaymentAppDatabase::DidReadPaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidReadPaymentInstrument( @@ -694,8 +683,7 @@ service_worker_context_->GetRegistrationUserDataByKeyPrefix( registration->id(), {kPaymentInstrumentKeyInfoPrefix}, base::BindOnce(&PaymentAppDatabase::DidGetKeysOfPaymentInstruments, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidGetKeysOfPaymentInstruments( @@ -731,8 +719,7 @@ service_worker_context_->GetRegistrationUserData( registration->id(), {CreatePaymentInstrumentKey(instrument_key)}, base::BindOnce(&PaymentAppDatabase::DidHasPaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidHasPaymentInstrument( @@ -804,9 +791,8 @@ {{CreatePaymentInstrumentKey(instrument_key), serialized_instrument}, {CreatePaymentInstrumentKeyInfoKey(instrument_key), serialized_key_info}}, - base::Bind(&PaymentAppDatabase::DidWritePaymentInstrument, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + base::BindOnce(&PaymentAppDatabase::DidWritePaymentInstrument, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidWritePaymentInstrument( @@ -862,9 +848,8 @@ service_worker_context_->ClearRegistrationUserData( registration->id(), keys_with_prefix, - base::Bind(&PaymentAppDatabase::DidClearPaymentInstruments, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + base::BindOnce(&PaymentAppDatabase::DidClearPaymentInstruments, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void PaymentAppDatabase::DidClearPaymentInstruments(
diff --git a/content/browser/payments/payment_app_info_fetcher.cc b/content/browser/payments/payment_app_info_fetcher.cc index ba2c16ec..2d3e5e3 100644 --- a/content/browser/payments/payment_app_info_fetcher.cc +++ b/content/browser/payments/payment_app_info_fetcher.cc
@@ -107,9 +107,9 @@ std::make_unique<WebContentsHelper>(top_level_web_content); top_level_web_content->GetManifest( - base::Bind(&PaymentAppInfoFetcher::SelfDeleteFetcher:: - FetchPaymentAppManifestCallback, - base::Unretained(this))); + base::BindOnce(&PaymentAppInfoFetcher::SelfDeleteFetcher:: + FetchPaymentAppManifestCallback, + base::Unretained(this))); return; }
diff --git a/chrome/browser/overlay/OWNERS b/content/browser/picture_in_picture/OWNERS similarity index 100% rename from chrome/browser/overlay/OWNERS rename to content/browser/picture_in_picture/OWNERS
diff --git a/chrome/browser/overlay/overlay_surface_embedder.cc b/content/browser/picture_in_picture/overlay_surface_embedder.cc similarity index 91% rename from chrome/browser/overlay/overlay_surface_embedder.cc rename to content/browser/picture_in_picture/overlay_surface_embedder.cc index 8942009..6af72c47 100644 --- a/chrome/browser/overlay/overlay_surface_embedder.cc +++ b/content/browser/picture_in_picture/overlay_surface_embedder.cc
@@ -2,10 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/overlay/overlay_surface_embedder.h" +#include "content/browser/picture_in_picture/overlay_surface_embedder.h" #include "ui/compositor/layer.h" +namespace content { + OverlaySurfaceEmbedder::OverlaySurfaceEmbedder(OverlayWindow* window) : window_(window) { DCHECK(window_); @@ -34,3 +36,5 @@ cc::DeadlinePolicy::UseDefaultDeadline(), true /* stretch_content_to_fill_bounds */); } + +} // namespace content
diff --git a/chrome/browser/overlay/overlay_surface_embedder.h b/content/browser/picture_in_picture/overlay_surface_embedder.h similarity index 73% rename from chrome/browser/overlay/overlay_surface_embedder.h rename to content/browser/picture_in_picture/overlay_surface_embedder.h index f4ea8978..5b085894 100644 --- a/chrome/browser/overlay/overlay_surface_embedder.h +++ b/content/browser/picture_in_picture/overlay_surface_embedder.h
@@ -2,17 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_ -#define CHROME_BROWSER_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_ +#ifndef CONTENT_BROWSER_PICTURE_IN_PICTURE_OVERLAY_SURFACE_EMBEDDER_H_ +#define CONTENT_BROWSER_PICTURE_IN_PICTURE_OVERLAY_SURFACE_EMBEDDER_H_ #include <memory> -#include "chrome/browser/overlay/overlay_window.h" +#include "content/public/browser/overlay_window.h" namespace viz { class SurfaceId; } +namespace content { + // Embed a surface into the OverlayWindow to show content. Responsible for // setting up the surface layers that contain content to show on the // OverlayWindow. @@ -34,4 +36,6 @@ DISALLOW_COPY_AND_ASSIGN(OverlaySurfaceEmbedder); }; -#endif // CHROME_BROWSER_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_ +} // namespace content + +#endif // CONTENT_BROWSER_PICTURE_IN_PICTURE_OVERLAY_SURFACE_EMBEDDER_H_
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc new file mode 100644 index 0000000..d37188f --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -0,0 +1,78 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h" + +#include "components/viz/common/surfaces/surface_id.h" +#include "content/browser/picture_in_picture/overlay_surface_embedder.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/overlay_window.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_client.h" + +namespace content { + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(PictureInPictureWindowControllerImpl); + +// static +PictureInPictureWindowController* +PictureInPictureWindowController::GetOrCreateForWebContents( + WebContents* web_contents) { + return PictureInPictureWindowControllerImpl::GetOrCreateForWebContents( + web_contents); +} + +// static +PictureInPictureWindowControllerImpl* +PictureInPictureWindowControllerImpl::GetOrCreateForWebContents( + WebContents* web_contents) { + DCHECK(web_contents); + + // This is a no-op if the controller already exists. + CreateForWebContents(web_contents); + return FromWebContents(web_contents); +} + +PictureInPictureWindowControllerImpl::~PictureInPictureWindowControllerImpl() { + if (window_) + window_->Close(); +} + +PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl( + WebContents* initiator) { + DCHECK(initiator); + + window_ = GetContentClient()->browser()->CreateWindowForPictureInPicture(); + DCHECK(window_) << "Picture in Picture requires a valid window."; +} + +void PictureInPictureWindowControllerImpl::Show() { + DCHECK(window_); + DCHECK(surface_id_.is_valid()); + window_->Show(); +} + +void PictureInPictureWindowControllerImpl::Close() { + if (window_) + window_->Close(); + + surface_id_ = viz::SurfaceId(); +} + +void PictureInPictureWindowControllerImpl::EmbedSurface( + const viz::SurfaceId& surface_id) { + DCHECK(window_); + DCHECK(surface_id.is_valid()); + surface_id_ = surface_id; + + if (!embedder_) + embedder_.reset(new OverlaySurfaceEmbedder(window_.get())); + embedder_->SetPrimarySurfaceId(surface_id_); +} + +OverlayWindow* PictureInPictureWindowControllerImpl::GetWindowForTesting() { + return window_.get(); +} + +} // namespace content \ No newline at end of file
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h new file mode 100644 index 0000000..5ac1ad1a --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -0,0 +1,58 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_IMPL_H_ +#define CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_IMPL_H_ + +#include "base/memory/weak_ptr.h" +#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" +#include "content/public/browser/picture_in_picture_window_controller.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace content { +class OverlaySurfaceEmbedder; +class WebContents; + +// TODO(thakis,mlamouri): PictureInPictureWindowControllerImpl isn't +// CONTENT_EXPORT'd because it creates complicated build issues with +// WebContentsUserData being a non-exported template. As a result, the class +// uses CONTENT_EXPORT for methods that are being used from tests. +// CONTENT_EXPORT should be moved back to the class when the Windows build will +// work with it. https://crbug.com/589840. +class PictureInPictureWindowControllerImpl + : public PictureInPictureWindowController, + public WebContentsUserData<PictureInPictureWindowControllerImpl> { + public: + // Gets a reference to the controller associated with |initiator| and creates + // one if it does not exist. The returned pointer is guaranteed to be + // non-null. + CONTENT_EXPORT static PictureInPictureWindowControllerImpl* + GetOrCreateForWebContents(WebContents* initiator); + + ~PictureInPictureWindowControllerImpl() override; + + CONTENT_EXPORT void Show() override; + CONTENT_EXPORT void Close() override; + CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id) override; + CONTENT_EXPORT OverlayWindow* GetWindowForTesting() override; + + private: + friend class WebContentsUserData<PictureInPictureWindowControllerImpl>; + + // Use PictureInPictureWindowControllerImpl::GetOrCreateForWebContents() to + // create an instance. + CONTENT_EXPORT explicit PictureInPictureWindowControllerImpl( + WebContents* initiator); + + std::unique_ptr<OverlayWindow> window_; + std::unique_ptr<OverlaySurfaceEmbedder> embedder_; + + viz::SurfaceId surface_id_; + + DISALLOW_COPY_AND_ASSIGN(PictureInPictureWindowControllerImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_IMPL_H_
diff --git a/content/browser/plugin_private_storage_helper.cc b/content/browser/plugin_private_storage_helper.cc index 065e213..07a474e8 100644 --- a/content/browser/plugin_private_storage_helper.cc +++ b/content/browser/plugin_private_storage_helper.cc
@@ -196,9 +196,9 @@ std::move(operation_context), file_url, storage::FileSystemOperation::GET_METADATA_FIELD_SIZE | storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED, - base::Bind(&PluginPrivateDataByOriginChecker::OnFileInfo, - base::Unretained(this), - StringTypeToString(file.name.value()))); + base::BindOnce(&PluginPrivateDataByOriginChecker::OnFileInfo, + base::Unretained(this), + StringTypeToString(file.name.value()))); } }
diff --git a/content/browser/push_messaging/push_messaging_manager.cc b/content/browser/push_messaging/push_messaging_manager.cc index c8d415a..4ee4b31 100644 --- a/content/browser/push_messaging/push_messaging_manager.cc +++ b/content/browser/push_messaging/push_messaging_manager.cc
@@ -336,7 +336,7 @@ registration_id, {kPushRegistrationIdServiceWorkerKey, kPushSenderIdServiceWorkerKey}, base::BindOnce(&PushMessagingManager::DidCheckForExistingRegistration, - weak_factory_io_to_io_.GetWeakPtr(), base::Passed(&data))); + weak_factory_io_to_io_.GetWeakPtr(), std::move(data))); } void PushMessagingManager::DidCheckForExistingRegistration( @@ -385,8 +385,7 @@ service_worker_context_->GetRegistrationUserData( registration_id, {kPushSenderIdServiceWorkerKey}, base::BindOnce(&PushMessagingManager::DidGetSenderIdFromStorage, - weak_factory_io_to_io_.GetWeakPtr(), - base::Passed(&data))); + weak_factory_io_to_io_.GetWeakPtr(), std::move(data))); } } @@ -560,9 +559,9 @@ registration_id, requesting_origin, {{kPushRegistrationIdServiceWorkerKey, push_subscription_id}, {kPushSenderIdServiceWorkerKey, sender_info}}, - base::Bind(&PushMessagingManager::DidPersistRegistrationOnIO, - weak_factory_io_to_io_.GetWeakPtr(), base::Passed(&data), - push_subscription_id, p256dh, auth, status)); + base::BindOnce(&PushMessagingManager::DidPersistRegistrationOnIO, + weak_factory_io_to_io_.GetWeakPtr(), std::move(data), + push_subscription_id, p256dh, auth, status)); } void PushMessagingManager::DidPersistRegistrationOnIO( @@ -636,8 +635,8 @@ service_worker_context_->GetRegistrationUserData( service_worker_registration_id, {kPushSenderIdServiceWorkerKey}, base::BindOnce(&PushMessagingManager::UnsubscribeHavingGottenSenderId, - weak_factory_io_to_io_.GetWeakPtr(), - base::Passed(&callback), service_worker_registration_id, + weak_factory_io_to_io_.GetWeakPtr(), std::move(callback), + service_worker_registration_id, service_worker_registration->pattern().GetOrigin())); } @@ -746,8 +745,8 @@ service_worker_registration_id, {kPushRegistrationIdServiceWorkerKey, kPushSenderIdServiceWorkerKey}, base::BindOnce(&PushMessagingManager::DidGetSubscription, - weak_factory_io_to_io_.GetWeakPtr(), - base::Passed(&callback), service_worker_registration_id)); + weak_factory_io_to_io_.GetWeakPtr(), std::move(callback), + service_worker_registration_id)); } void PushMessagingManager::DidGetSubscription(
diff --git a/content/browser/quota_dispatcher_host.cc b/content/browser/quota_dispatcher_host.cc index 566848c..c327427 100644 --- a/content/browser/quota_dispatcher_host.cc +++ b/content/browser/quota_dispatcher_host.cc
@@ -94,9 +94,8 @@ QueryStorageUsageAndQuotaCallback callback) { quota_manager_->GetUsageAndQuotaForWebApps( origin.GetURL(), storage_type, - base::Bind(&QuotaDispatcherHost::DidQueryStorageUsageAndQuota, - weak_factory_.GetWeakPtr(), - base::Passed(std::move(callback)))); + base::BindOnce(&QuotaDispatcherHost::DidQueryStorageUsageAndQuota, + weak_factory_.GetWeakPtr(), std::move(callback))); } void QuotaDispatcherHost::RequestStorageQuota( @@ -126,15 +125,15 @@ if (storage_type == StorageType::kPersistent) { quota_manager_->GetUsageAndQuotaForWebApps( origin.GetURL(), storage_type, - base::Bind(&QuotaDispatcherHost::DidGetPersistentUsageAndQuota, - weak_factory_.GetWeakPtr(), origin, storage_type, - requested_size, base::Passed(std::move(callback)))); + base::BindOnce(&QuotaDispatcherHost::DidGetPersistentUsageAndQuota, + weak_factory_.GetWeakPtr(), origin, storage_type, + requested_size, std::move(callback))); } else { quota_manager_->GetUsageAndQuotaForWebApps( origin.GetURL(), storage_type, - base::Bind(&QuotaDispatcherHost::DidGetTemporaryUsageAndQuota, - weak_factory_.GetWeakPtr(), requested_size, - base::Passed(std::move(callback)))); + base::BindOnce(&QuotaDispatcherHost::DidGetTemporaryUsageAndQuota, + weak_factory_.GetWeakPtr(), requested_size, + std::move(callback))); } } @@ -209,9 +208,9 @@ // rewrite to just convert the host to a string directly. quota_manager_->SetPersistentHostQuota( net::GetHostOrSpecFromURL(origin.GetURL()), requested_quota, - base::Bind(&QuotaDispatcherHost::DidSetHostQuota, - weak_factory_.GetWeakPtr(), current_usage, - base::Passed(std::move(callback)))); + base::BindOnce(&QuotaDispatcherHost::DidSetHostQuota, + weak_factory_.GetWeakPtr(), current_usage, + std::move(callback))); } void QuotaDispatcherHost::DidSetHostQuota(int64_t current_usage,
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm index 03248f72..d6a88a6 100644 --- a/content/browser/renderer_host/browser_compositor_view_mac.mm +++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -141,8 +141,8 @@ DCHECK(ui::WindowResizeHelperMac::Get()->task_runner()); if (!g_spare_recyclable_compositors.Get().empty()) { std::unique_ptr<RecyclableCompositorMac> result; - result = std::move(g_spare_recyclable_compositors.Get().front()); - g_spare_recyclable_compositors.Get().pop_front(); + result = std::move(g_spare_recyclable_compositors.Get().back()); + g_spare_recyclable_compositors.Get().pop_back(); return result; } return std::unique_ptr<RecyclableCompositorMac>(new RecyclableCompositorMac); @@ -321,12 +321,19 @@ } void BrowserCompositorMac::UpdateState() { - if (!render_widget_host_is_hidden_) + // If the host is visible then a compositor is required. + if (!render_widget_host_is_hidden_) { TransitionToState(HasAttachedCompositor); - else if (ns_view_attached_to_window_) + return; + } + // If the host is not visible but we are attached to a window then keep around + // a compositor only if it already exists. + if (ns_view_attached_to_window_ && state_ != HasNoCompositor) { TransitionToState(HasDetachedCompositor); - else - TransitionToState(HasNoCompositor); + return; + } + // Otherwise put the compositor up for recycling. + TransitionToState(HasNoCompositor); } void BrowserCompositorMac::TransitionToState(State new_state) {
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc index 2058f2e..2a5358c 100644 --- a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
@@ -245,13 +245,8 @@ touch->event.GetType() != WebInputEvent::kTouchStart) touch->event.dispatch_type = WebInputEvent::kEventNonBlocking; - if (touch->event.GetType() == WebInputEvent::kTouchStart) { + if (touch->event.GetType() == WebInputEvent::kTouchStart) touch->event.touch_start_or_first_touch_move = true; - // Touch start events should be uncancelable during an active touchscreen - // fling. - if (client_->TouchscreenFlingInProgress()) - touch->event.dispatch_type = WebInputEvent::kEventNonBlocking; - } // For touchmove events, compare touch points position from current event // to last sent event and update touch points state.
diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc index f4f1d096..8ea8054 100644 --- a/content/browser/renderer_host/media/media_devices_manager.cc +++ b/content/browser/renderer_host/media/media_devices_manager.cc
@@ -766,34 +766,39 @@ DCHECK(IsValidMediaDeviceType(type)); for (auto& subscription : subscriptions_) { - SubscriptionRequest* request = &subscription.second; - if (request->subscribe_types[type]) { + const SubscriptionRequest& request = subscription.second; + if (request.subscribe_types[type]) { base::PostTaskAndReplyWithResult( BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE, - base::BindOnce(salt_and_origin_callback_, request->render_process_id, - request->render_frame_id), + base::BindOnce(salt_and_origin_callback_, request.render_process_id, + request.render_frame_id), base::BindOnce(&MediaDevicesManager::CheckPermissionForDeviceChange, - weak_factory_.GetWeakPtr(), request, type, snapshot)); + weak_factory_.GetWeakPtr(), subscription.first, + request.render_process_id, request.render_frame_id, + type, snapshot)); } } } void MediaDevicesManager::CheckPermissionForDeviceChange( - SubscriptionRequest* request, + uint32_t subscription_id, + int render_process_id, + int render_frame_id, MediaDeviceType type, const MediaDeviceInfoArray& device_infos, const std::pair<std::string, url::Origin>& salt_and_origin) { DCHECK_CURRENTLY_ON(BrowserThread::IO); permission_checker_->CheckPermission( - type, request->render_process_id, request->render_frame_id, + type, render_process_id, render_frame_id, base::BindOnce(&MediaDevicesManager::NotifyDeviceChange, - weak_factory_.GetWeakPtr(), request, type, device_infos, - salt_and_origin.first, salt_and_origin.second)); + weak_factory_.GetWeakPtr(), subscription_id, type, + device_infos, salt_and_origin.first, + salt_and_origin.second)); } void MediaDevicesManager::NotifyDeviceChange( - SubscriptionRequest* request, + uint32_t subscription_id, MediaDeviceType type, const MediaDeviceInfoArray& device_infos, std::string device_id_salt, @@ -801,8 +806,13 @@ bool has_permission) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(IsValidMediaDeviceType(type)); - std::string group_id_salt = request->group_id_salt_base + device_id_salt; - request->listener->OnDevicesChanged( + auto it = subscriptions_.find(subscription_id); + if (it == subscriptions_.end()) + return; + + const SubscriptionRequest& request = it->second; + std::string group_id_salt = request.group_id_salt_base + device_id_salt; + request.listener->OnDevicesChanged( type, TranslateMediaDeviceInfoArray(has_permission, device_id_salt, group_id_salt, security_origin, device_infos));
diff --git a/content/browser/renderer_host/media/media_devices_manager.h b/content/browser/renderer_host/media/media_devices_manager.h index cbc85b8..e95f873e 100644 --- a/content/browser/renderer_host/media/media_devices_manager.h +++ b/content/browser/renderer_host/media/media_devices_manager.h
@@ -233,11 +233,13 @@ void NotifyDeviceChangeSubscribers(MediaDeviceType type, const MediaDeviceInfoArray& snapshot); void CheckPermissionForDeviceChange( - SubscriptionRequest* request, + uint32_t subscription_id, + int render_process_id, + int render_frame_id, MediaDeviceType type, const MediaDeviceInfoArray& device_infos, const std::pair<std::string, url::Origin>& salt_and_origin); - void NotifyDeviceChange(SubscriptionRequest* request, + void NotifyDeviceChange(uint32_t subscription_id, MediaDeviceType type, const MediaDeviceInfoArray& device_infos, std::string device_id_salt,
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc index 5567359d3..a9a8976 100644 --- a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -315,7 +315,7 @@ BrowserThread::IO, FROM_HERE, base::BindOnce( &MediaStreamUIProxyFeaturePolicyTest::GetResultForRequestOnIOThread, - base::Unretained(this), base::Passed(&request))); + base::Unretained(this), std::move(request))); run_loop.Run(); *devices_out = devices_; *result_out = result_;
diff --git a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc index e354d976..7a5229de 100644 --- a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc +++ b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
@@ -275,7 +275,7 @@ task_runner->PostTask( FROM_HERE, base::BindOnce(&VideoCaptureGpuJpegDecoder::FinishInitialization, - weak_this, base::Passed(remote_decoder.PassInterface()))); + weak_this, remote_decoder.PassInterface())); } void VideoCaptureGpuJpegDecoder::FinishInitialization(
diff --git a/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc b/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc index eb8e27d3..cdc4ab29 100644 --- a/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc +++ b/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc
@@ -47,14 +47,10 @@ PP_Time last_modified_time) { IPC::Message reply_msg = PpapiPluginMsg_FileRef_TouchReply(); base::FileUtilProxy::Touch( - task_runner_.get(), - path_, - ppapi::PPTimeToTime(last_access_time), + task_runner_.get(), path_, ppapi::PPTimeToTime(last_access_time), ppapi::PPTimeToTime(last_modified_time), - base::Bind(&PepperExternalFileRefBackend::DidFinish, - weak_factory_.GetWeakPtr(), - reply_context, - reply_msg)); + base::BindOnce(&PepperExternalFileRefBackend::DidFinish, + weak_factory_.GetWeakPtr(), reply_context, reply_msg)); return PP_OK_COMPLETIONPENDING; } @@ -74,11 +70,9 @@ int32_t PepperExternalFileRefBackend::Query( ppapi::host::ReplyMessageContext reply_context) { bool ok = base::FileUtilProxy::GetFileInfo( - task_runner_.get(), - path_, - base::Bind(&PepperExternalFileRefBackend::GetMetadataComplete, - weak_factory_.GetWeakPtr(), - reply_context)); + task_runner_.get(), path_, + base::BindOnce(&PepperExternalFileRefBackend::GetMetadataComplete, + weak_factory_.GetWeakPtr(), reply_context)); DCHECK(ok); return PP_OK_COMPLETIONPENDING; }
diff --git a/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/content/browser/renderer_host/pepper/pepper_file_io_host.cc index c1597b7..259f110 100644 --- a/content/browser/renderer_host/pepper/pepper_file_io_host.cc +++ b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -295,8 +295,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); resolved_render_process_id_ = resolved_render_process_id; file_.CreateOrOpen(path, file_flags, - base::Bind(&PepperFileIOHost::OnLocalFileOpened, - AsWeakPtr(), reply_context, path)); + base::BindOnce(&PepperFileIOHost::OnLocalFileOpened, + AsWeakPtr(), reply_context, path)); } int32_t PepperFileIOHost::OnHostMsgTouch( @@ -309,11 +309,9 @@ return rv; if (!file_.SetTimes( - PPTimeToTime(last_access_time), - PPTimeToTime(last_modified_time), - base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, - AsWeakPtr(), - context->MakeReplyMessageContext()))) { + PPTimeToTime(last_access_time), PPTimeToTime(last_modified_time), + base::BindOnce(&PepperFileIOHost::ExecutePlatformGeneralCallback, + AsWeakPtr(), context->MakeReplyMessageContext()))) { return PP_ERROR_FAILED; } @@ -336,9 +334,8 @@ if (!file_.SetLength( length, - base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, - AsWeakPtr(), - context->MakeReplyMessageContext()))) { + base::BindOnce(&PepperFileIOHost::ExecutePlatformGeneralCallback, + AsWeakPtr(), context->MakeReplyMessageContext()))) { return PP_ERROR_FAILED; } @@ -354,9 +351,8 @@ return rv; if (!file_.Flush( - base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, - AsWeakPtr(), - context->MakeReplyMessageContext()))) { + base::BindOnce(&PepperFileIOHost::ExecutePlatformGeneralCallback, + AsWeakPtr(), context->MakeReplyMessageContext()))) { return PP_ERROR_FAILED; } @@ -373,8 +369,7 @@ } if (file_.IsValid()) { - file_.Close(base::Bind(&PepperFileIOHost::DidCloseFile, - AsWeakPtr())); + file_.Close(base::BindOnce(&PepperFileIOHost::DidCloseFile, AsWeakPtr())); } return PP_OK; }
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index c355b61..a892fe9 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -1072,24 +1072,6 @@ return {nullptr, false, base::nullopt}; } -// TODO(wjmaclean): Remove this when no longer needed. https://crbug.com/824774 -void RenderWidgetHostInputEventRouter::VerifyViewInMap( - RenderWidgetHostViewBase* view, - std::string src) const { - for (const auto& entry : owner_map_) { - if (entry.second == view) - return; - } - - static auto* ptr_key = base::debug::AllocateCrashKeyString( - "not-in-map-view-ptr", base::debug::CrashKeySize::Size64); - base::debug::ScopedCrashKeyString(ptr_key, base::StringPrintf("%p", view)); - static auto* src_key = base::debug::AllocateCrashKeyString( - "not-in-map-view-src", base::debug::CrashKeySize::Size64); - base::debug::ScopedCrashKeyString device_key_value(src_key, src); - base::debug::DumpWithoutCrashing(); -} - void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent( RenderWidgetHostViewBase* root_view, RenderWidgetHostViewBase* target, @@ -1157,7 +1139,6 @@ // created by ContentView. These will use the target found by the // RenderWidgetTargeter. These gesture events should always have a // unique_touch_event_id of 0. - VerifyViewInMap(target, "unique_touch_event_id == 0"); touchscreen_gesture_target_.target = target; base::debug::SetCrashKeyString(target_source_key, "touch_id=0"); DCHECK(target_location.has_value()); @@ -1183,13 +1164,10 @@ // Re https://crbug.com/796656): Since we are already in an error case, // don't worry about the fact we're ignoring |result.should_query_view|, as // this is the best we can do until we fix https://crbug.com/595422. - - // Since we synchronously found this target, assume it's in the map. touchscreen_gesture_target_.target = result.view; base::debug::SetCrashKeyString(target_source_key, "no_matching_id"); touchscreen_gesture_target_.delta = transformed_point - original_point; } else if (is_gesture_start) { - VerifyViewInMap(gesture_target_it->second.target, "is_gesture_start"); touchscreen_gesture_target_ = gesture_target_it->second; touchscreen_gesture_target_map_.erase(gesture_target_it);
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h index 2462113..a81e74f 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.h +++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -216,7 +216,6 @@ const ui::LatencyInfo& latency, const base::Optional<gfx::PointF>& target_location); // Assumes |gesture_event| has coordinates in root view's coordinate space. - void VerifyViewInMap(RenderWidgetHostViewBase* view, std::string src) const; void DispatchTouchscreenGestureEvent( RenderWidgetHostViewBase* root_view, RenderWidgetHostViewBase* target,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 1b5bdf1f..75770f7 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1878,7 +1878,7 @@ GetWindowTreeClientFromRenderer(), ui::mojom::kEmbedFlagEmbedderInterceptsEvents | ui::mojom::kEmbedFlagEmbedderControlsVisibility, - base::Bind(&EmbedCallback)); + base::BindOnce(&EmbedCallback)); } void RenderWidgetHostViewAura::CreateDelegatedFrameHostClient() {
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc index cf5a28a..2e37ed4 100644 --- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -737,14 +737,8 @@ DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewBrowserTestHiDPI); }; -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) -#define MAYBE_ScrollOffset DISABLED_ScrollOffset -#else -#define MAYBE_ScrollOffset ScrollOffset -#endif - IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestHiDPI, - MAYBE_ScrollOffset) { + ScrollOffset) { const int kContentHeight = 2000; const int kScrollAmount = 100; @@ -767,6 +761,10 @@ kContentHeight, kScrollAmount)); SET_UP_SURFACE_OR_PASS_TEST("\"DONE\""); + RenderFrameSubmissionObserver observer_( + GetRenderWidgetHost()->render_frame_metadata_provider()); + observer_.WaitForScrollOffsetAtTop(false); + if (!ShouldContinueAfterTestURLLoad()) return;
diff --git a/content/browser/renderer_host/web_database_host_impl.cc b/content/browser/renderer_host/web_database_host_impl.cc index 2383892..ef9189df 100644 --- a/content/browser/renderer_host/web_database_host_impl.cc +++ b/content/browser/renderer_host/web_database_host_impl.cc
@@ -186,7 +186,7 @@ db_tracker_->quota_manager_proxy()->GetUsageAndQuota( db_tracker_->task_runner(), origin, blink::mojom::StorageType::kTemporary, - base::Bind( + base::BindOnce( [](GetSpaceAvailableCallback callback, blink::mojom::QuotaStatusCode status, int64_t usage, int64_t quota) { @@ -197,7 +197,7 @@ } std::move(callback).Run(available); }, - base::Passed(std::move(callback)))); + std::move(callback))); } void WebDatabaseHostImpl::DatabaseDeleteFile(
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 48fda7a..048e6232 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -197,7 +197,8 @@ explicit WorkerActivatedObserver(ServiceWorkerContextWrapper* context) : context_(context) {} void Init() { - RunOnIOThread(base::Bind(&WorkerActivatedObserver::InitOnIOThread, this)); + RunOnIOThread( + base::BindOnce(&WorkerActivatedObserver::InitOnIOThread, this)); } // ServiceWorkerContextCoreObserver overrides. void OnVersionStateChanged(int64_t version_id, @@ -453,12 +454,13 @@ wrapper_ = static_cast<ServiceWorkerContextWrapper*>( partition->GetServiceWorkerContext()); - RunOnIOThread(base::Bind(&self::SetUpOnIOThread, base::Unretained(this))); + RunOnIOThread( + base::BindOnce(&self::SetUpOnIOThread, base::Unretained(this))); } void TearDownOnMainThread() override { RunOnIOThread( - base::Bind(&self::TearDownOnIOThread, base::Unretained(this))); + base::BindOnce(&self::TearDownOnIOThread, base::Unretained(this))); wrapper_ = nullptr; } @@ -589,8 +591,8 @@ void InstallTestHelper(const std::string& worker_url, ServiceWorkerStatusCode expected_status) { - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), worker_url)); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), worker_url)); // Dispatch install on a worker. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; @@ -739,8 +741,9 @@ store_run_loop.Run(); ASSERT_EQ(expected_status, status); - RunOnIOThread(base::Bind(&self::NotifyDoneInstallingRegistrationOnIOThread, - base::Unretained(this), status)); + RunOnIOThread( + base::BindOnce(&self::NotifyDoneInstallingRegistrationOnIOThread, + base::Unretained(this), status)); } void FindRegistrationForId(int64_t id, @@ -942,9 +945,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartAndStop) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); // Start a worker. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; @@ -970,9 +973,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, DropCountsOnBlinkUseCounter) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); // Start a worker. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; base::RunLoop start_run_loop; @@ -1001,9 +1004,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartNotFound) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/nonexistent.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/nonexistent.js")); // Start a worker for nonexistent URL. StartWorker(SERVICE_WORKER_ERROR_NETWORK); @@ -1019,9 +1022,9 @@ MAYBE_ReadResourceFailure) { StartServerAndNavigateToSetup(); // Create a registration. - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); version_->set_fetch_handler_existence( ServiceWorkerVersion::FetchHandlerExistence::EXISTS); version_->SetStatus(ServiceWorkerVersion::ACTIVATED); @@ -1041,8 +1044,8 @@ // The registration should be deleted from storage since the broken worker was // the stored one. - RunOnIOThread(base::Bind(&self::RemoveLiveRegistrationOnIOThread, - base::Unretained(this), registration_->id())); + RunOnIOThread(base::BindOnce(&self::RemoveLiveRegistrationOnIOThread, + base::Unretained(this), registration_->id())); FindRegistrationForId(registration_->id(), registration_->pattern().GetOrigin(), SERVICE_WORKER_ERROR_NOT_FOUND); @@ -1058,16 +1061,16 @@ // Give the version a controllee. RunOnIOThread( - base::Bind(&self::AddControlleeOnIOThread, base::Unretained(this))); + base::BindOnce(&self::AddControlleeOnIOThread, base::Unretained(this))); // Add a non-existent resource to the version. version_->script_cache_map()->resource_map_[version_->script_url()] = ServiceWorkerDatabase::ResourceRecord(30, version_->script_url(), 100); // Make a waiting version and store it. - RunOnIOThread(base::Bind(&self::AddWaitingWorkerOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::AddWaitingWorkerOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); std::vector<ServiceWorkerDatabase::ResourceRecord> records = { ServiceWorkerDatabase::ResourceRecord(31, version_->script_url(), 100)}; registration_->waiting_version()->script_cache_map()->SetResources(records); @@ -1082,8 +1085,8 @@ // The registration should still be in storage since the waiting worker was // the stored one. - RunOnIOThread(base::Bind(&self::RemoveLiveRegistrationOnIOThread, - base::Unretained(this), registration_->id())); + RunOnIOThread(base::BindOnce(&self::RemoveLiveRegistrationOnIOThread, + base::Unretained(this), registration_->id())); FindRegistrationForId(registration_->id(), registration_->pattern().GetOrigin(), SERVICE_WORKER_OK); @@ -1153,14 +1156,14 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithWaitUntil_RejectConsoleMessage) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/worker_install_rejected.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/worker_install_rejected.js")); ConsoleListener console_listener; - RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::AddListener, - base::Unretained(version_->embedded_worker()), - &console_listener)); + RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddListener, + base::Unretained(version_->embedded_worker()), + &console_listener)); // Dispatch install on a worker. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; @@ -1177,9 +1180,9 @@ console_listener.WaitForConsoleMessages(1); ASSERT_NE(base::string16::npos, console_listener.messages()[0].find(expected)); - RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::RemoveListener, - base::Unretained(version_->embedded_worker()), - &console_listener)); + RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::RemoveListener, + base::Unretained(version_->embedded_worker()), + &console_listener)); } class WaitForLoaded : public EmbeddedWorkerInstance::Listener { @@ -1197,26 +1200,26 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/while_true_worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/while_true_worker.js")); // Start a worker, waiting until the script is loaded. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; base::RunLoop start_run_loop; base::RunLoop load_run_loop; WaitForLoaded wait_for_load(load_run_loop.QuitClosure()); - RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::AddListener, - base::Unretained(version_->embedded_worker()), - &wait_for_load)); + RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddListener, + base::Unretained(version_->embedded_worker()), + &wait_for_load)); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::BindOnce(&self::StartOnIOThread, base::Unretained(this), start_run_loop.QuitClosure(), &status)); load_run_loop.Run(); - RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::RemoveListener, - base::Unretained(version_->embedded_worker()), - &wait_for_load)); + RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::RemoveListener, + base::Unretained(version_->embedded_worker()), + &wait_for_load)); // The script has loaded but start has not completed yet. ASSERT_EQ(SERVICE_WORKER_ERROR_FAILED, status); @@ -1225,7 +1228,7 @@ // Simulate execution timeout. Use a delay to prevent killing the worker // before it's started execution. RunOnIOThreadWithDelay( - base::Bind(&self::TimeoutWorkerOnIOThread, base::Unretained(this)), + base::BindOnce(&self::TimeoutWorkerOnIOThread, base::Unretained(this)), base::TimeDelta::FromMilliseconds(100)); start_run_loop.Run(); @@ -1234,9 +1237,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/while_true_in_install_worker.js")); + RunOnIOThread( + base::BindOnce(&self::SetUpRegistrationOnIOThread, base::Unretained(this), + "/service_worker/while_true_in_install_worker.js")); // Start a worker. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; @@ -1258,7 +1261,7 @@ // Simulate execution timeout. Use a delay to prevent killing the worker // before it's started execution. RunOnIOThreadWithDelay( - base::Bind(&self::TimeoutWorkerOnIOThread, base::Unretained(this)), + base::BindOnce(&self::TimeoutWorkerOnIOThread, base::Unretained(this)), base::TimeDelta::FromMilliseconds(100)); install_run_loop.Run(); @@ -1286,9 +1289,8 @@ EXPECT_EQ(expected_headers, response.headers); std::string body; - RunOnIOThread( - base::Bind(&ReadResponseBody, - &body, base::Owned(blob_data_handle.release()))); + RunOnIOThread(base::BindOnce(&ReadResponseBody, &body, + base::Owned(blob_data_handle.release()))); EXPECT_EQ("This resource is gone. Gone, gone, gone.", body); } @@ -1336,9 +1338,9 @@ SERVICE_WORKER_OK); ConsoleListener console_listener; - RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::AddListener, - base::Unretained(version_->embedded_worker()), - &console_listener)); + RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddListener, + base::Unretained(version_->embedded_worker()), + &console_listener)); FetchOnRegisteredWorker(&result, &response, &blob_data_handle); const base::string16 expected1 = base::ASCIIToUTF16( @@ -1349,9 +1351,9 @@ ASSERT_NE(base::string16::npos, console_listener.messages()[0].find(expected1)); ASSERT_EQ(0u, console_listener.messages()[1].find(expected2)); - RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::RemoveListener, - base::Unretained(version_->embedded_worker()), - &console_listener)); + RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::RemoveListener, + base::Unretained(version_->embedded_worker()), + &console_listener)); ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse, result); @@ -2404,10 +2406,9 @@ const base::string16 kOKTitle(base::ASCIIToUTF16("OK")); const base::string16 kFailTitle(base::ASCIIToUTF16("FAIL")); - RunOnIOThread( - base::Bind(&CreateLongLivedResourceInterceptors, - embedded_test_server()->GetURL(kScriptUrl), - embedded_test_server()->GetURL(kImportUrl))); + RunOnIOThread(base::BindOnce(&CreateLongLivedResourceInterceptors, + embedded_test_server()->GetURL(kScriptUrl), + embedded_test_server()->GetURL(kImportUrl))); TitleWatcher title_watcher(shell()->web_contents(), kOKTitle); title_watcher.AlsoWaitForTitle(kFailTitle); @@ -2418,11 +2419,9 @@ // Verify the number of resources in the implicit script cache is correct. const int kExpectedNumResources = 2; int num_resources = 0; - RunOnIOThread( - base::Bind(&CountScriptResources, - base::Unretained(wrapper()), - embedded_test_server()->GetURL(kScopeUrl), - &num_resources)); + RunOnIOThread(base::BindOnce( + &CountScriptResources, base::Unretained(wrapper()), + embedded_test_server()->GetURL(kScopeUrl), &num_resources)); EXPECT_EQ(kExpectedNumResources, num_resources); } @@ -2444,23 +2443,23 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, RendererCrash) { // Start a worker. StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); StartWorker(SERVICE_WORKER_OK); // Crash the renderer process. The version should stop. base::RunLoop run_loop; StopObserver observer(run_loop.QuitClosure()); - RunOnIOThread(base::Bind(&ServiceWorkerVersion::AddListener, - base::Unretained(version_.get()), &observer)); + RunOnIOThread(base::BindOnce(&ServiceWorkerVersion::AddListener, + base::Unretained(version_.get()), &observer)); shell()->web_contents()->GetMainFrame()->GetProcess()->Shutdown( content::RESULT_CODE_KILLED); run_loop.Run(); EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status()); - RunOnIOThread(base::Bind(&ServiceWorkerVersion::RemoveListener, - base::Unretained(version_.get()), &observer)); + RunOnIOThread(base::BindOnce(&ServiceWorkerVersion::RemoveListener, + base::Unretained(version_.get()), &observer)); } class ServiceWorkerBlackBoxBrowserTest : public ServiceWorkerBrowserTest { @@ -2666,9 +2665,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationAndListenerOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationAndListenerOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); { base::RunLoop cached_metadata_run_loop; cache_updated_closure_ = cached_metadata_run_loop.QuitClosure(); @@ -2742,9 +2741,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8FullCodeCacheTest, FullCode) { StartServerAndNavigateToSetup(); - RunOnIOThread(base::Bind(&self::SetUpRegistrationAndListenerOnIOThread, - base::Unretained(this), - "/service_worker/worker.js")); + RunOnIOThread(base::BindOnce(&self::SetUpRegistrationAndListenerOnIOThread, + base::Unretained(this), + "/service_worker/worker.js")); base::RunLoop cached_metadata_run_loop; cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index b7d836ea..7345389 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -153,7 +153,7 @@ for (const auto& registration_info : registrations) { context->UnregisterServiceWorker( registration_info.pattern, - base::Bind(&ClearAllServiceWorkersHelper::OnResult, this)); + base::BindOnce(&ClearAllServiceWorkersHelper::OnResult, this)); } } @@ -739,8 +739,7 @@ storage()->FindRegistrationForDocument( url, base::BindOnce(&ServiceWorkerContextCore:: DidFindRegistrationForCheckHasServiceWorker, - AsWeakPtr(), other_url, - base::Passed(std::move(callback)))); + AsWeakPtr(), other_url, std::move(callback))); } void ServiceWorkerContextCore::UpdateVersionFailureCount(
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc index 0a900fade..e571988 100644 --- a/content/browser/service_worker/service_worker_context_unittest.cc +++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -46,7 +46,7 @@ ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback( bool* called, int64_t* store_registration_id) { - return base::Bind(&SaveResponseCallback, called, store_registration_id); + return base::BindOnce(&SaveResponseCallback, called, store_registration_id); } void CallCompletedCallback(bool* called, ServiceWorkerStatusCode) { @@ -55,7 +55,7 @@ ServiceWorkerContextCore::UnregistrationCallback MakeUnregisteredCallback( bool* called) { - return base::Bind(&CallCompletedCallback, called); + return base::BindOnce(&CallCompletedCallback, called); } void ExpectRegisteredWorkers(
diff --git a/content/browser/service_worker/service_worker_context_watcher_unittest.cc b/content/browser/service_worker/service_worker_context_watcher_unittest.cc index c9bb895f..f5e9547 100644 --- a/content/browser/service_worker/service_worker_context_watcher_unittest.cc +++ b/content/browser/service_worker/service_worker_context_watcher_unittest.cc
@@ -146,7 +146,7 @@ int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId; context()->RegisterServiceWorker( script_url, options, - base::Bind(&DidRegisterServiceWorker, ®istration_id)); + base::BindOnce(&DidRegisterServiceWorker, ®istration_id)); base::RunLoop().RunUntilIdle(); return registration_id; } @@ -154,7 +154,7 @@ ServiceWorkerStatusCode UnregisterServiceWorker(const GURL& scope) { ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; context()->UnregisterServiceWorker( - scope, base::Bind(&DidUnregisterServiceWorker, &status)); + scope, base::BindOnce(&DidUnregisterServiceWorker, &status)); base::RunLoop().RunUntilIdle(); return status; }
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index a0072ef..6d1594d6 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -224,8 +224,8 @@ // here. return; } - context_core_->DeleteAndStartOver( - base::Bind(&ServiceWorkerContextWrapper::DidDeleteAndStartOver, this)); + context_core_->DeleteAndStartOver(base::BindOnce( + &ServiceWorkerContextWrapper::DidDeleteAndStartOver, this)); } StoragePartitionImpl* ServiceWorkerContextWrapper::storage_partition() const { @@ -281,7 +281,7 @@ net::SimplifyUrlForRequest(options.scope), options.update_via_cache); context()->RegisterServiceWorker( net::SimplifyUrlForRequest(script_url), options_to_pass, - base::Bind(&FinishRegistrationOnIO, base::Passed(std::move(callback)))); + base::BindOnce(&FinishRegistrationOnIO, std::move(callback))); } void ServiceWorkerContextWrapper::UnregisterServiceWorker( @@ -302,7 +302,7 @@ context()->UnregisterServiceWorker( net::SimplifyUrlForRequest(pattern), - base::Bind(&FinishUnregistrationOnIO, base::Passed(std::move(callback)))); + base::BindOnce(&FinishUnregistrationOnIO, std::move(callback))); } bool ServiceWorkerContextWrapper::StartingExternalRequest(
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index a7016c20..ea56985 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -350,8 +350,8 @@ context_->UpdateServiceWorker( registration.get(), true /* force_bypass_cache */, true /* skip_script_comparison */, - base::Bind(&self::DidUpdateRegistration, weak_factory_.GetWeakPtr(), - registration)); + base::BindOnce(&self::DidUpdateRegistration, weak_factory_.GetWeakPtr(), + registration)); return; }
diff --git a/content/browser/service_worker/service_worker_installed_script_reader.cc b/content/browser/service_worker/service_worker_installed_script_reader.cc index 6bad001..a70872a 100644 --- a/content/browser/service_worker/service_worker_installed_script_reader.cc +++ b/content/browser/service_worker/service_worker_installed_script_reader.cc
@@ -95,8 +95,8 @@ auto info_buf = base::MakeRefCounted<HttpResponseInfoIOBuffer>(); reader_->ReadInfo( info_buf.get(), - base::Bind(&ServiceWorkerInstalledScriptReader::OnReadInfoComplete, - AsWeakPtr(), info_buf)); + base::BindOnce(&ServiceWorkerInstalledScriptReader::OnReadInfoComplete, + AsWeakPtr(), info_buf)); } void ServiceWorkerInstalledScriptReader::OnReadInfoComplete( @@ -204,8 +204,8 @@ body_pending_write_.get()); reader_->ReadData( buffer.get(), num_bytes, - base::Bind(&ServiceWorkerInstalledScriptReader::OnResponseDataRead, - AsWeakPtr())); + base::BindOnce(&ServiceWorkerInstalledScriptReader::OnResponseDataRead, + AsWeakPtr())); } void ServiceWorkerInstalledScriptReader::OnResponseDataRead(int read_bytes) {
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index 1ab8078..6b541d0c 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -81,8 +81,8 @@ bool* called, scoped_refptr<ServiceWorkerRegistration>* registration) { *called = false; - return base::Bind( - &SaveRegistrationCallback, expected_status, called, registration); + return base::BindOnce(&SaveRegistrationCallback, expected_status, called, + registration); } ServiceWorkerStorage::FindRegistrationCallback SaveFoundRegistration( @@ -106,7 +106,7 @@ ServiceWorkerStatusCode expected_status, bool* called) { *called = false; - return base::Bind(&SaveUnregistrationCallback, expected_status, called); + return base::BindOnce(&SaveUnregistrationCallback, expected_status, called); } } // namespace
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index f0f0e4da..e05148e 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -233,33 +233,6 @@ .page_scale_factor; } -// Helper function to retrieve the bounding client rect of the element -// identified by |sel| inside |rfh|. -gfx::Rect GetBoundingClientRect(RenderFrameHostImpl* rfh, - const std::string& sel) { - std::string result; - EXPECT_TRUE(ExecuteScriptAndExtractString( - rfh, - base::StringPrintf( - "{" - " let rect = document.querySelector('%s').getBoundingClientRect();" - " let msg = `${rect.x},${rect.y},${rect.width},${rect.height}`;" - " window.domAutomationController.send(msg);" - "}", - sel.c_str()), - &result)); - std::vector<std::string> tokens = base::SplitString( - result, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - EXPECT_EQ(4U, tokens.size()); - double x = 0.0, y = 0.0, width = 0.0, height = 0.0; - EXPECT_TRUE(base::StringToDouble(tokens[0], &x)); - EXPECT_TRUE(base::StringToDouble(tokens[1], &y)); - EXPECT_TRUE(base::StringToDouble(tokens[2], &width)); - EXPECT_TRUE(base::StringToDouble(tokens[3], &height)); - return {static_cast<int>(x), static_cast<int>(y), static_cast<int>(width), - static_cast<int>(height)}; -} - class RedirectNotificationObserver : public NotificationObserver { public: // Register to listen for notifications of the given type from either a @@ -720,6 +693,102 @@ } }; +// SitePerProcessProgrammaticScrollTest. + +class SitePerProcessProgrammaticScrollTest : public SitePerProcessBrowserTest { + public: + SitePerProcessProgrammaticScrollTest() + : kInfinity(1000000U), kPositiveXYPlane(0, 0, kInfinity, kInfinity) {} + + protected: + const size_t kInfinity; + const std::string kIframeOutOfViewHTML = "/iframe_out_of_view.html"; + const std::string kIframeSelector = "iframe"; + const std::string kInputSelector = "input"; + const gfx::Rect kPositiveXYPlane; + + // Waits until the |load| handle is called inside the frame. + void WaitForOnLoad(FrameTreeNode* node) { + RunCommandAndWaitForResponse(node, "notifyWhenLoaded();", "LOADED"); + } + + void WaitForElementVisible(FrameTreeNode* node, const std::string& sel) { + RunCommandAndWaitForResponse( + node, + base::StringPrintf("notifyWhenVisible(document.querySelector('%s'));", + sel.c_str()), + "VISIBLE"); + } + + void AddFocusedInputField(FrameTreeNode* node) { + ASSERT_TRUE(ExecuteScript(node, "addFocusedInputField();")); + } + + void SetWindowScroll(FrameTreeNode* node, int x, int y) { + ASSERT_TRUE(ExecuteScript( + node, base::StringPrintf("window.scrollTo(%d, %d);", x, y))); + } + + // Helper function to retrieve the bounding client rect of the element + // identified by |sel| inside |rfh|. + gfx::Rect GetBoundingClientRect(FrameTreeNode* node, const std::string& sel) { + std::string result; + EXPECT_TRUE(ExecuteScriptAndExtractString( + node, + base::StringPrintf( + "window.domAutomationController.send(rectAsString(" + " document.querySelector('%s').getBoundingClientRect()));", + sel.c_str()), + &result)); + return GetRectFromString(result); + } + + // Returns a rect representing the current |visualViewport| in the main frame + // of |contents|. + gfx::Rect GetVisualViewport(FrameTreeNode* node) { + std::string result; + EXPECT_TRUE(ExecuteScriptAndExtractString( + node, + "window.domAutomationController.send(" + " rectAsString(visualViewportAsRect()));", + &result)); + return GetRectFromString(result); + } + + float GetVisualViewportScale(FrameTreeNode* node) { + double scale; + EXPECT_TRUE(ExecuteScriptAndExtractDouble( + node, "window.domAutomationController.send(visualViewport.scale);", + &scale)); + return static_cast<float>(scale); + } + + private: + void RunCommandAndWaitForResponse(FrameTreeNode* node, + const std::string& command, + const std::string& response) { + std::string msg_from_renderer; + ASSERT_TRUE( + ExecuteScriptAndExtractString(node, command, &msg_from_renderer)); + ASSERT_EQ(response, msg_from_renderer); + } + + gfx::Rect GetRectFromString(const std::string& str) { + std::vector<std::string> tokens = base::SplitString( + str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + EXPECT_EQ(4U, tokens.size()); + double x = 0.0, y = 0.0, width = 0.0, height = 0.0; + EXPECT_TRUE(base::StringToDouble(tokens[0], &x)); + EXPECT_TRUE(base::StringToDouble(tokens[1], &y)); + EXPECT_TRUE(base::StringToDouble(tokens[2], &width)); + EXPECT_TRUE(base::StringToDouble(tokens[3], &height)); + return {static_cast<int>(x), static_cast<int>(y), static_cast<int>(width), + static_cast<int>(height)}; + } + + DISALLOW_COPY_AND_ASSIGN(SitePerProcessProgrammaticScrollTest); +}; + IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIBrowserTest, SubframeLoadsWithCorrectDeviceScaleFactor) { GURL main_url(embedded_test_server()->GetURL( @@ -1714,50 +1783,37 @@ #define MAYBE_ScrollElementIntoView ScrollElementIntoView #endif -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_ScrollElementIntoView) { +IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest, + MAYBE_ScrollElementIntoView) { const GURL url_a( - embedded_test_server()->GetURL("a.com", "/iframe_out_of_view.html")); + embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML)); const GURL url_b( - embedded_test_server()->GetURL("b.com", "/iframe_out_of_view.html")); + embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML)); const GURL url_c( - embedded_test_server()->GetURL("c.com", "/iframe_out_of_view.html")); + embedded_test_server()->GetURL("c.com", kIframeOutOfViewHTML)); - // Script which runs and returns with a |kRendererMsgLoaded| when load handler - // is called. This is a good point to read bounding client rect values as - // basic layout has already been completed. - const std::string kWaitForFrameLoadScript = "notifyWhenLoaded();"; - const std::string kRendererMsgLoaded = "LOADED"; // Number of <iframe>'s which will not be empty. The actual frame tree has two // more nodes one for root and one for the inner-most empty <iframe>. const size_t kNonEmptyIframesCount = 5; - // Sent in 'load' handlers. - const std::string kIframeSelector = "iframe"; - const int kRectDimensionErrorTolerance = 0; - const int kInfinity = 1000000; - const gfx::Rect kPositiveXYPlane(0, 0, kInfinity, kInfinity); const std::string kScrollIntoViewScript = "document.body.scrollIntoView({'behavior' : 'instant'});"; - std::string msg_from_renderer; + const int kRectDimensionErrorTolerance = 0; // First, recursively set the |scrollTop| and |scrollLeft| of |document.body| // to its maximum and then navigate the <iframe> to |url_a|. The page will be // structured as a(a(a(a(a(a(a)))))) where the inner-most <iframe> is empty. ASSERT_TRUE(NavigateToURL(shell(), url_a)); FrameTreeNode* node = web_contents()->GetFrameTree()->root(); - ASSERT_TRUE(ExecuteScriptAndExtractString(node, kWaitForFrameLoadScript, - &msg_from_renderer)); - ASSERT_EQ(kRendererMsgLoaded, msg_from_renderer); + WaitForOnLoad(node); std::vector<gfx::Rect> reference_page_bounds_before_scroll = { - GetBoundingClientRect(node->current_frame_host(), kIframeSelector)}; + GetBoundingClientRect(node, kIframeSelector)}; node = node->child_at(0); for (size_t index = 0; index < kNonEmptyIframesCount; ++index) { NavigateFrameToURL(node, url_a); - ASSERT_TRUE(ExecuteScriptAndExtractString(node, kWaitForFrameLoadScript, - &msg_from_renderer)); - ASSERT_EQ(kRendererMsgLoaded, msg_from_renderer); + WaitForOnLoad(node); // Store |document.querySelector('iframe').getBoundingClientRect()|. reference_page_bounds_before_scroll.push_back( - GetBoundingClientRect(node->current_frame_host(), kIframeSelector)); + GetBoundingClientRect(node, kIframeSelector)); node = node->child_at(0); } // Sanity-check: If the page is setup properly then all the <iframe>s should @@ -1771,11 +1827,11 @@ // page which contains OOPIFs. node = web_contents()->GetFrameTree()->root(); std::vector<gfx::Rect> reference_page_bounds_after_scroll = { - GetBoundingClientRect(node->current_frame_host(), kIframeSelector)}; + GetBoundingClientRect(node, kIframeSelector)}; node = node->child_at(0); for (size_t index = 0; index < kNonEmptyIframesCount; ++index) { reference_page_bounds_after_scroll.push_back( - GetBoundingClientRect(node->current_frame_host(), kIframeSelector)); + GetBoundingClientRect(node, kIframeSelector)); node = node->child_at(0); } @@ -1783,20 +1839,16 @@ // structured as b(b(a(c(a(a(a)))))) where the inner-most <iframe> is empty. ASSERT_TRUE(NavigateToURL(shell(), url_b)); node = web_contents()->GetFrameTree()->root(); - ASSERT_TRUE(ExecuteScriptAndExtractString(node, kWaitForFrameLoadScript, - &msg_from_renderer)); - ASSERT_EQ(kRendererMsgLoaded, msg_from_renderer); + WaitForOnLoad(node); std::vector<gfx::Rect> test_page_bounds_before_scroll = { - GetBoundingClientRect(node->current_frame_host(), kIframeSelector)}; + GetBoundingClientRect(node, kIframeSelector)}; const GURL iframe_urls[] = {url_b, url_a, url_c, url_a, url_a}; node = node->child_at(0); for (size_t index = 0; index < kNonEmptyIframesCount; ++index) { NavigateFrameToURL(node, iframe_urls[index]); - ASSERT_TRUE(ExecuteScriptAndExtractString(node, kWaitForFrameLoadScript, - &msg_from_renderer)); - ASSERT_EQ(kRendererMsgLoaded, msg_from_renderer); + WaitForOnLoad(node); test_page_bounds_before_scroll.push_back( - GetBoundingClientRect(node->current_frame_host(), kIframeSelector)); + GetBoundingClientRect(node, kIframeSelector)); node = node->child_at(0); } // Sanity-check: The bounds should match those from non-OOPIF page. @@ -1813,7 +1865,7 @@ RenderFrameHostImpl* current_rfh = node->current_frame_host()->GetParent(); while (current_rfh) { gfx::Rect current_bounds = - GetBoundingClientRect(current_rfh, kIframeSelector); + GetBoundingClientRect(current_rfh->frame_tree_node(), kIframeSelector); gfx::Rect reference_bounds = reference_page_bounds_after_scroll[index]; if (current_bounds.ApproximatelyEqual(reference_bounds, kRectDimensionErrorTolerance)) { @@ -1828,55 +1880,98 @@ } } -// This test verifies that Scrolling a focused editable element into view works -// when the element is inside an OOPIF. -// Flaky test, see crbug.com/793616 -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DISABLED_ScrollFocusedEditableElementIntoView) { - GURL main_frame_url( - embedded_test_server()->GetURL("a.com", "/iframe_out_of_view.html")); - EXPECT_TRUE(NavigateToURL(shell(), main_frame_url)); +// This test verifies that ScrollFocusedEditableElementIntoView works correctly +// for OOPIFs. Essentially, the test verifies that in a similar setup, the +// resultant page scale factor is the same for OOPIF and non-OOPIF cases. This +// also verifies that in response to the scroll command, the root-layer scrolls +// correctly and the <input> is visible in visual viewport. +IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest, + ScrollFocusedEditableElementIntoView) { + GURL url_a(embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML)); + GURL url_b(embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML)); + +#if defined(OS_ANDROID) + // The reason for Android specific code is that + // AutoZoomFocusedNodeToLegibleScale is in blink's WebSettings and difficult + // to access from here. It so happens that the setting is on for Android. + + // A lower bound on the ratio of page scale factor after scroll. The actual + // value depends on minReadableCaretHeight / caret_bounds.Height(). The page + // is setup so caret height is quite small so the expected scale should be + // larger than 2.0. + float kLowerBoundOnScaleAfterScroll = 2.0; + float kEpsilon = 0.1; +#endif + + ASSERT_TRUE(NavigateToURL(shell(), url_a)); FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + WaitForOnLoad(root); + NavigateFrameToURL(root->child_at(0), url_a); + WaitForOnLoad(root->child_at(0)); +#if defined(OS_ANDROID) + float scale_before_scroll_nonoopif = GetVisualViewportScale(root); +#endif + AddFocusedInputField(root->child_at(0)); + // Focusing <input> causes scrollIntoView(). The following line makes sure + // that the <iframe> is out of view again. + SetWindowScroll(root, 0, 0); + ASSERT_FALSE(GetVisualViewport(root).Intersects( + GetBoundingClientRect(root, kIframeSelector))); + root->child_at(0) + ->current_frame_host() + ->GetFrameInputHandler() + ->ScrollFocusedEditableNodeIntoRect(gfx::Rect()); + WaitForElementVisible(root, kIframeSelector); +#if defined(OS_ANDROID) + float scale_after_scroll_nonoopif = GetVisualViewportScale(root); + // Increased scale means zoom triggered correctly. + EXPECT_GT(scale_after_scroll_nonoopif - scale_before_scroll_nonoopif, + kEpsilon); + EXPECT_GT(scale_after_scroll_nonoopif, kLowerBoundOnScaleAfterScroll); +#endif - GURL child_frame_url( - embedded_test_server()->GetURL("b.com", "/page_with_input_field.html")); - NavigateFrameToURL(root->child_at(0), child_frame_url); - - RenderFrameHostImpl* main_frame = root->current_frame_host(); - RenderFrameHostImpl* child_frame = root->child_at(0)->current_frame_host(); - - // Focus the input field. - std::string result; + // Retry the test on an OOPIF page. + Shell* new_shell = CreateBrowser(); + ASSERT_TRUE(NavigateToURL(new_shell, url_b)); + root = static_cast<WebContentsImpl*>(new_shell->web_contents()) + ->GetFrameTree() + ->root(); + WaitForOnLoad(root); +#if defined(OS_ANDROID) + float scale_before_scroll_oopif = GetVisualViewportScale(root); + // Sanity-check: + ASSERT_NEAR(scale_before_scroll_oopif, scale_before_scroll_nonoopif, + kEpsilon); +#endif + NavigateFrameToURL(root->child_at(0), url_a); + WaitForOnLoad(root->child_at(0)); + AddFocusedInputField(root->child_at(0)); + SetWindowScroll(root, 0, 0); + ASSERT_FALSE(GetVisualViewport(root).Intersects( + GetBoundingClientRect(root, kIframeSelector))); + root->child_at(0) + ->current_frame_host() + ->GetFrameInputHandler() + ->ScrollFocusedEditableNodeIntoRect(gfx::Rect()); + WaitForElementVisible(root, kIframeSelector); +#if defined(OS_ANDROID) + float scale_after_scroll_oopif = GetVisualViewportScale(root); + EXPECT_GT(scale_after_scroll_oopif - scale_before_scroll_oopif, kEpsilon); + EXPECT_GT(scale_after_scroll_oopif, kLowerBoundOnScaleAfterScroll); + // The scale is based on the caret height and it should be the same in both + // OOPIF and non-OOPIF pages. + EXPECT_NEAR(scale_after_scroll_oopif, scale_after_scroll_nonoopif, kEpsilon); +#endif + // Make sure the <input> is at least partly visible in the |visualViewport|. + gfx::Rect final_visual_viewport_oopif = GetVisualViewport(root); + gfx::Rect iframe_bounds_after_scroll_oopif = + GetBoundingClientRect(root, kIframeSelector); + gfx::Rect input_bounds_after_scroll_oopif = + GetBoundingClientRect(root->child_at(0), kInputSelector); + input_bounds_after_scroll_oopif += + iframe_bounds_after_scroll_oopif.OffsetFromOrigin(); ASSERT_TRUE( - ExecuteScriptAndExtractString(child_frame, "focusInputField()", &result)); - ASSERT_EQ(result, "input-focus"); - - // Wait and verify that before scrolling the child <iframe> is not visible. - while (main_frame->GetView()->GetViewBounds().Intersects( - child_frame->GetView()->GetViewBounds())) { - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); - run_loop.Run(); - } - - child_frame->GetFrameInputHandler()->ScrollFocusedEditableNodeIntoRect( - gfx::Rect()); - - // Wait until the child frame is visible. - while (!root->current_frame_host()->GetView()->GetViewBounds().Intersects( - child_frame->GetView()->GetViewBounds())) { - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); - run_loop.Run(); - } - - // Verify that the bounding box of the <input> is visible inside the main - // frame. - gfx::Rect test_rect = GetBoundingClientRect(child_frame, "input"); - test_rect += child_frame->GetView()->GetViewBounds().OffsetFromOrigin(); - EXPECT_TRUE(main_frame->GetView()->GetViewBounds().Intersects(test_rect)); + final_visual_viewport_oopif.Intersects(input_bounds_after_scroll_oopif)); } // Tests OOPIF rendering by checking that the RWH of the iframe generates
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 688f8de..ee19f0f 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -933,9 +933,10 @@ // ClearQuotaManagedOriginsOnIOThread(). quota_manager->GetOriginsModifiedSince( blink::mojom::StorageType::kPersistent, begin, - base::Bind(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread, - base::Unretained(this), base::RetainedRef(quota_manager), - special_storage_policy, origin_matcher, decrement_callback)); + base::BindOnce(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread, + base::Unretained(this), base::RetainedRef(quota_manager), + special_storage_policy, origin_matcher, + decrement_callback)); } // Do the same for temporary quota. @@ -943,9 +944,10 @@ IncrementTaskCountOnIO(); quota_manager->GetOriginsModifiedSince( blink::mojom::StorageType::kTemporary, begin, - base::Bind(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread, - base::Unretained(this), base::RetainedRef(quota_manager), - special_storage_policy, origin_matcher, decrement_callback)); + base::BindOnce(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread, + base::Unretained(this), base::RetainedRef(quota_manager), + special_storage_policy, origin_matcher, + decrement_callback)); } // Do the same for syncable quota. @@ -953,10 +955,10 @@ IncrementTaskCountOnIO(); quota_manager->GetOriginsModifiedSince( blink::mojom::StorageType::kSyncable, begin, - base::Bind(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread, - base::Unretained(this), base::RetainedRef(quota_manager), - special_storage_policy, origin_matcher, - std::move(decrement_callback))); + base::BindOnce(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread, + base::Unretained(this), base::RetainedRef(quota_manager), + special_storage_policy, origin_matcher, + std::move(decrement_callback))); } DecrementTaskCountOnIO(); @@ -997,8 +999,8 @@ quota_manager->DeleteOriginData( *origin, quota_storage_type, StoragePartitionImpl::GenerateQuotaClientMask(remove_mask_), - base::Bind(&OnQuotaManagedOriginDeleted, origin->GetOrigin(), - quota_storage_type, deletion_task_count, callback)); + base::BindOnce(&OnQuotaManagedOriginDeleted, origin->GetOrigin(), + quota_storage_type, deletion_task_count, callback)); } (*deletion_task_count)--;
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index 7bc32d4..34808a5 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc
@@ -343,8 +343,8 @@ async_file_util->CreateOrOpen( std::move(operation_context), clearkey_file_, base::File::FLAG_OPEN | base::File::FLAG_WRITE, - base::Bind(&RemovePluginPrivateDataTester::OnFileOpened, - base::Unretained(this), &file, &await_completion)); + base::BindOnce(&RemovePluginPrivateDataTester::OnFileOpened, + base::Unretained(this), &file, &await_completion)); await_completion.BlockUntilNotified(); return file; } @@ -390,8 +390,8 @@ storage::QuotaManager::kNoLimit); file_util->EnsureFileExists( std::move(operation_context), file_url, - base::Bind(&RemovePluginPrivateDataTester::OnFileCreated, - base::Unretained(this), &await_completion)); + base::BindOnce(&RemovePluginPrivateDataTester::OnFileCreated, + base::Unretained(this), &await_completion)); await_completion.BlockUntilNotified(); return file_url; } @@ -405,8 +405,8 @@ filesystem_context_); file_util->DeleteFile( std::move(operation_context), file_url, - base::Bind(&RemovePluginPrivateDataTester::OnFileDeleted, - base::Unretained(this), &await_completion)); + base::BindOnce(&RemovePluginPrivateDataTester::OnFileDeleted, + base::Unretained(this), &await_completion)); await_completion.BlockUntilNotified(); } @@ -420,10 +420,10 @@ std::unique_ptr<storage::FileSystemOperationContext> operation_context = std::make_unique<storage::FileSystemOperationContext>( filesystem_context_); - file_util->Touch(std::move(operation_context), file_url, time_stamp, - time_stamp, - base::Bind(&RemovePluginPrivateDataTester::OnFileTouched, - base::Unretained(this), &await_completion)); + file_util->Touch( + std::move(operation_context), file_url, time_stamp, time_stamp, + base::BindOnce(&RemovePluginPrivateDataTester::OnFileTouched, + base::Unretained(this), &await_completion)); await_completion.BlockUntilNotified(); }
diff --git a/content/browser/tracing/tracing_controller_impl_data_endpoint.cc b/content/browser/tracing/tracing_controller_impl_data_endpoint.cc index 5ce323d..4960ffa11 100644 --- a/content/browser/tracing/tracing_controller_impl_data_endpoint.cc +++ b/content/browser/tracing/tracing_controller_impl_data_endpoint.cc
@@ -70,7 +70,7 @@ FROM_HERE, base::BindOnce( &FileTraceDataEndpoint::ReceiveTraceChunkOnBlockingThread, this, - base::Passed(std::move(chunk)))); + std::move(chunk))); } void ReceiveTraceFinalContents(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 8b3a24b..bc1a109 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -115,6 +115,7 @@ #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/child_process_host.h" #include "content/public/common/content_constants.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/page_state.h" #include "content/public/common/page_zoom.h" @@ -4136,7 +4137,7 @@ } void WebContentsImpl::UpdatePictureInPictureSurfaceId( - viz::SurfaceId surface_id) { + const viz::SurfaceId& surface_id) { if (delegate_) delegate_->UpdatePictureInPictureSurfaceId(surface_id); } @@ -6147,8 +6148,12 @@ } void WebContentsImpl::UpdateWebContentsVisibility(Visibility visibility) { - // Occlusion can cause flakiness in browser tests. - static const bool occlusion_is_disabled = + // Occlusion is disabled when |features::kWebContentsOcclusion| is disabled + // (for power and speed impact assessment) or when + // |switches::kDisableBackgroundingOccludedWindowsForTesting| is specified on + // the command line (to avoid flakiness in browser tests). + const bool occlusion_is_disabled = + !base::FeatureList::IsEnabled(features::kWebContentsOcclusion) || base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableBackgroundingOccludedWindowsForTesting); if (occlusion_is_disabled && visibility == Visibility::OCCLUDED)
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 5af6e69..2750feb 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -576,7 +576,8 @@ net::CertStatus cert_status) override; void ResourceLoadComplete( mojom::ResourceLoadInfoPtr resource_load_information) override; - void UpdatePictureInPictureSurfaceId(viz::SurfaceId surface_id) override; + void UpdatePictureInPictureSurfaceId( + const viz::SurfaceId& surface_id) override; void ExitPictureInPicture() override; // RenderViewHostDelegate ----------------------------------------------------
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 7d7c7ca..a4e2b68 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -655,10 +655,8 @@ if (!first_network_request) EXPECT_GT(resource_load_info->request_id, 0); EXPECT_EQ(mime_type, resource_load_info->mime_type); - if (!ip_address.empty()) { - ASSERT_TRUE(resource_load_info->ip); - EXPECT_EQ(ip_address, resource_load_info->ip->ToString()); - } + ASSERT_TRUE(resource_load_info->ip); + EXPECT_EQ(ip_address, resource_load_info->ip->ToString()); EXPECT_EQ(was_cached, resource_load_info->was_cached); // Simple sanity check of the request start time. EXPECT_GT(resource_load_info->request_start, before_request); @@ -701,12 +699,9 @@ NavigateToURL(shell(), page_url); base::TimeTicks after = base::TimeTicks::Now(); ASSERT_EQ(3U, observer.resource_load_infos().size()); - // TODO(crbug.com/826082): we should test the IP address/MIME type parameters - // for frames once they are reported correctly. SCOPE_TRACED(observer.CheckResourceLoaded( page_url, /*referrer=*/GURL(), "GET", content::RESOURCE_TYPE_MAIN_FRAME, - /*mime-type*/ "", - /*ip_address=*/"", + "text/html", "127.0.0.1", /*was_cached=*/false, /*first_network_request=*/true, before, after)); SCOPE_TRACED(observer.CheckResourceLoaded( embedded_test_server()->GetURL("/image.jpg"), @@ -716,8 +711,7 @@ SCOPE_TRACED(observer.CheckResourceLoaded( embedded_test_server()->GetURL("/title1.html"), /*referrer=*/page_url, "GET", content::RESOURCE_TYPE_SUB_FRAME, - /*mime_type=*/"", - /*ip_address=*/"", + "text/html", "127.0.0.1", /*was_cached=*/false, /*first_network_request=*/false, before, after)); } @@ -750,15 +744,13 @@ NavigateToURL(shell(), page_url); base::TimeTicks after = base::TimeTicks::Now(); - // TODO(crbug.com/826082): we should test the IP address/MIME type parameters - // for frames once they are reported correctly. GURL resource_url = embedded_test_server()->GetURL("/cachetime"); ASSERT_EQ(2U, observer.resource_load_infos().size()); SCOPE_TRACED(observer.CheckResourceLoaded( page_url, /*referrer=*/GURL(), "GET", content::RESOURCE_TYPE_MAIN_FRAME, - /*mime-type*/ "", - /*ip_address=*/"", /*was_cached=*/false, /*first_network_request=*/true, - before, after)); + "text/html", "127.0.0.1", /*was_cached=*/false, + /*first_network_request=*/true, before, after)); + SCOPE_TRACED(observer.CheckResourceLoaded( resource_url, /*referrer=*/page_url, "GET", content::RESOURCE_TYPE_SCRIPT, "text/html", "127.0.0.1", @@ -774,7 +766,7 @@ ASSERT_EQ(1U, observer.resource_load_infos().size()); SCOPE_TRACED(observer.CheckResourceLoaded( page_url, /*referrer=*/GURL(), "GET", content::RESOURCE_TYPE_MAIN_FRAME, - /*mime-type*/ "", /*ip_address=*/"", + "text/html", "127.0.0.1", /*was_cached=*/false, /*first_network_request=*/false, before, after)); ASSERT_EQ(1U, observer.memory_cached_loaded_urls().size()); EXPECT_EQ(resource_url, observer.memory_cached_loaded_urls()[0]); @@ -791,7 +783,7 @@ ASSERT_EQ(2U, observer.resource_load_infos().size()); SCOPE_TRACED(observer.CheckResourceLoaded( page_url, /*referrer=*/GURL(), "GET", content::RESOURCE_TYPE_MAIN_FRAME, - /*mime-type*/ "", /*ip_address=*/"", + "text/html", "127.0.0.1", /*was_cached=*/false, /*first_network_request=*/true, before, after)); SCOPE_TRACED(observer.CheckResourceLoaded( resource_url, /*referrer=*/page_url, "GET", content::RESOURCE_TYPE_SCRIPT, @@ -808,8 +800,7 @@ NavigateToURL(shell(), GURL(embedded_test_server()->GetURL("/page_with_image.html"))); ASSERT_EQ(2U, observer.resource_load_infos().size()); - // TODO(crbug.com/826082): network_accessed should be true on the frame. - EXPECT_FALSE(observer.resource_load_infos()[0]->network_accessed); + EXPECT_TRUE(observer.resource_load_infos()[0]->network_accessed); EXPECT_TRUE(observer.resource_load_infos()[1]->network_accessed); observer.Reset(); @@ -835,9 +826,7 @@ ASSERT_EQ(2U, observer.resource_load_infos().size()); const mojom::ResourceLoadInfoPtr& page_load_info = observer.resource_load_infos()[0]; - // TODO(crbug.com/826082): turn this back on when the ResourceDispatcher - // receives redirects for the main frame. - // EXPECT_EQ(page_destination_url, page_load_info->url); + EXPECT_EQ(page_destination_url, page_load_info->url); EXPECT_EQ(page_original_url, page_load_info->original_url); GURL image_destination_url(embedded_test_server()->GetURL("/blank.jpg"));
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index d48eaca..25c88556 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "components/download/public/common/download_url_parameters.h" #include "content/browser/frame_host/interstitial_page_impl.h" @@ -42,6 +43,7 @@ #include "content/public/common/bindings_policy.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_constants.h" +#include "content/public/common/content_features.h" #include "content/public/common/url_constants.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/navigation_simulator.h" @@ -2736,6 +2738,9 @@ } TEST_F(WebContentsImplTest, UpdateWebContentsVisibility) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kWebContentsOcclusion); + TestRenderWidgetHostView* view = static_cast<TestRenderWidgetHostView*>( main_test_rfh()->GetRenderViewHost()->GetWidget()->GetView()); TestWebContentsObserver observer(contents()); @@ -2842,6 +2847,8 @@ } TEST_F(WebContentsImplTest, OccludeWithCapturer) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kWebContentsOcclusion); HideOrOccludeWithCapturerTest(contents(), Visibility::OCCLUDED); }
diff --git a/content/browser/web_contents/web_contents_view_aura_unittest.cc b/content/browser/web_contents/web_contents_view_aura_unittest.cc index 655f084e..03d3de9 100644 --- a/content/browser/web_contents/web_contents_view_aura_unittest.cc +++ b/content/browser/web_contents/web_contents_view_aura_unittest.cc
@@ -8,7 +8,9 @@ #include "base/command_line.h" #include "base/test/scoped_command_line.h" +#include "base/test/scoped_feature_list.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/common/content_features.h" #include "content/public/test/test_renderer_host.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/test/test_windows.h" @@ -58,6 +60,9 @@ } TEST_F(WebContentsViewAuraTest, OccludeView) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kWebContentsOcclusion); + // |other_window| occludes |web_contents()| when it's shown. std::unique_ptr<aura::Window> other_window( aura::test::CreateTestWindowWithDelegateAndType(
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 8bbf69b..467797e 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -167,6 +167,9 @@ IPC_STRUCT_TRAITS_MEMBER(make_visible_in_visual_viewport) IPC_STRUCT_TRAITS_MEMBER(behavior) IPC_STRUCT_TRAITS_MEMBER(is_for_scroll_sequence) + IPC_STRUCT_TRAITS_MEMBER(zoom_into_rect) + IPC_STRUCT_TRAITS_MEMBER(relative_element_bounds) + IPC_STRUCT_TRAITS_MEMBER(relative_caret_bounds) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::ContextMenuParams)
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index 5e1c2c4..019df02 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -25,6 +25,7 @@ #include "content/public/common/request_context_type.h" #include "net/url_request/redirect_info.h" #include "services/network/public/cpp/resource_request_body.h" +#include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/resource_response_info.h" #include "third_party/WebKit/public/platform/WebMixedContentContextType.h" #include "ui/base/page_transition_types.h" @@ -211,7 +212,7 @@ std::vector<GURL> redirects; // The ResourceResponseInfos received during redirects. - std::vector<network::ResourceResponseInfo> redirect_response; + std::vector<network::ResourceResponseHead> redirect_response; // PlzNavigate // The RedirectInfos received during redirects.
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc index eda2505e..61ea5e3 100644 --- a/content/common/throttling_url_loader.cc +++ b/content/common/throttling_url_loader.cc
@@ -523,7 +523,7 @@ if (original_client_request) *original_client_request = client_binding_.Unbind(); client_binding_.Bind(std::move(new_client_request)); - client_binding_.set_connection_error_handler(base::BindRepeating( + client_binding_.set_connection_error_handler(base::BindOnce( &ThrottlingURLLoader::OnClientConnectionError, base::Unretained(this))); }
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 1beeb37..92a12b29 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -183,6 +183,7 @@ "notification_service.h", "notification_source.h", "notification_types.h", + "overlay_window.h", "overscroll_configuration.h", "page_navigator.cc", "page_navigator.h", @@ -191,6 +192,7 @@ "pepper_vpn_provider_resource_host_proxy.h", "permission_manager.h", "permission_type.h", + "picture_in_picture_window_controller.h", "platform_notification_context.h", "platform_notification_service.h", "plugin_data_remover.h",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 97576b0b..27adc913 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -704,4 +704,9 @@ return true; } +std::unique_ptr<OverlayWindow> +ContentBrowserClient::CreateWindowForPictureInPicture() { + return nullptr; +} + } // namespace content
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 72d06bf..f903469 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -20,6 +20,7 @@ #include "build/build_config.h" #include "content/public/browser/certificate_request_result_type.h" #include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/overlay_window.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/content_client.h" #include "content/public/common/media_stream_request.h" @@ -1142,6 +1143,13 @@ bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture); + + // Creates an OverlayWindow to be used for Picture-in-Picture. This window + // will house the content shown when in Picture-in-Picture mode. This will + // return a new OverlayWindow. + // May return nullptr if embedder does not support this functionality. The + // default implementation provides nullptr OverlayWindow. + virtual std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture(); }; } // namespace content
diff --git a/chrome/browser/overlay/overlay_window.h b/content/public/browser/overlay_window.h similarity index 84% rename from chrome/browser/overlay/overlay_window.h rename to content/public/browser/overlay_window.h index 87bf3d7f..b58c76c 100644 --- a/chrome/browser/overlay/overlay_window.h +++ b/content/public/browser/overlay_window.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_OVERLAY_OVERLAY_WINDOW_H_ -#define CHROME_BROWSER_OVERLAY_OVERLAY_WINDOW_H_ +#ifndef CONTENT_PUBLIC_BROWSER_OVERLAY_WINDOW_H_ +#define CONTENT_PUBLIC_BROWSER_OVERLAY_WINDOW_H_ #include <memory> @@ -17,6 +17,8 @@ class Layer; } +namespace content { + // This window will always float above other windows. The intention is to show // content perpetually while the user is still interacting with the other // browser windows. @@ -42,4 +44,6 @@ DISALLOW_COPY_AND_ASSIGN(OverlayWindow); }; -#endif // CHROME_BROWSER_OVERLAY_OVERLAY_WINDOW_H_ +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_OVERLAY_WINDOW_H_
diff --git a/content/public/browser/picture_in_picture_window_controller.h b/content/public/browser/picture_in_picture_window_controller.h new file mode 100644 index 0000000..e352e4a0 --- /dev/null +++ b/content/public/browser/picture_in_picture_window_controller.h
@@ -0,0 +1,45 @@ +// 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 CONTENT_PUBLIC_BROWSER_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_ +#define CONTENT_PUBLIC_BROWSER_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_ + +#include "content/common/content_export.h" + +namespace viz { +class SurfaceId; +} // namespace viz + +namespace content { +class OverlayWindow; +class WebContents; + +// Interface for Picture in Picture window controllers. This is currently tied +// to a WebContents |initiator| and created when a Picture in Picture window is +// to be shown. This allows creation of a single window for the initiator +// WebContents. +class PictureInPictureWindowController { + public: + // Gets a reference to the controller associated with |initiator| and creates + // one if it does not exist. The returned pointer is guaranteed to be + // non-null. + CONTENT_EXPORT static PictureInPictureWindowController* + GetOrCreateForWebContents(WebContents* initiator); + + virtual ~PictureInPictureWindowController() = default; + + virtual void Show() = 0; + virtual void Close() = 0; + virtual void EmbedSurface(const viz::SurfaceId& surface_id) = 0; + virtual OverlayWindow* GetWindowForTesting() = 0; + + protected: + // Use PictureInPictureWindowController::GetOrCreateForWebContents() to + // create an instance. + PictureInPictureWindowController() = default; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
diff --git a/content/public/browser/push_messaging_service.cc b/content/public/browser/push_messaging_service.cc index afab622..72225f7 100644 --- a/content/public/browser/push_messaging_service.cc +++ b/content/public/browser/push_messaging_service.cc
@@ -56,7 +56,7 @@ service_worker_context->ClearRegistrationUserData( service_worker_registration_id, {kPushRegistrationIdServiceWorkerKey}, - base::Bind(&CallClosureFromIO, callback)); + base::BindOnce(&CallClosureFromIO, callback)); } void StorePushSubscriptionOnIOForTesting( @@ -72,7 +72,7 @@ service_worker_registration_id, origin, {{kPushRegistrationIdServiceWorkerKey, subscription_id}, {kPushSenderIdServiceWorkerKey, sender_id}}, - base::Bind(&CallClosureFromIO, callback)); + base::BindOnce(&CallClosureFromIO, callback)); } scoped_refptr<ServiceWorkerContextWrapper> GetServiceWorkerContext(
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc index d4d8d7b..f4af364c 100644 --- a/content/public/browser/web_contents_delegate.cc +++ b/content/public/browser/web_contents_delegate.cc
@@ -270,7 +270,7 @@ } void WebContentsDelegate::UpdatePictureInPictureSurfaceId( - viz::SurfaceId surface_id) {} + const viz::SurfaceId& surface_id) {} void WebContentsDelegate::ExitPictureInPicture() {}
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 28b92923..40e00a8 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -574,7 +574,8 @@ // Updates the Picture-in-Picture controller with the relevant viz::SurfaceId // of the video to be in Picture-in-Picture mode. - virtual void UpdatePictureInPictureSurfaceId(viz::SurfaceId surface_id); + virtual void UpdatePictureInPictureSurfaceId( + const viz::SurfaceId& surface_id); // Updates the Picture-in-Picture controller with a signal that // Picture-in-Picture mode has ended.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 4ca00df3..e48d9166 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -459,6 +459,17 @@ const base::Feature kWebAssemblyTrapHandler{"WebAssemblyTrapHandler", base::FEATURE_DISABLED_BY_DEFAULT}; +// Controls whether the visibility of a WebContents can be OCCLUDED. When +// disabled, an occluded WebContents behaves exactly like a VISIBLE WebContents. +const base::Feature kWebContentsOcclusion { + "WebContentsOcclusion", +#if defined(OS_MACOSX) || defined(OS_CHROMEOS) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; + // Controls whether the WebAuthentication API is enabled: // https://w3c.github.io/webauthn const base::Feature kWebAuth {
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 8c78ef47..d6f92829 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -112,6 +112,7 @@ CONTENT_EXPORT extern const base::Feature kWebAssemblyTrapHandler; CONTENT_EXPORT extern const base::Feature kWebAuth; CONTENT_EXPORT extern const base::Feature kWebAuthBle; +CONTENT_EXPORT extern const base::Feature kWebContentsOcclusion; CONTENT_EXPORT extern const base::Feature kWebGLImageChromium; CONTENT_EXPORT extern const base::Feature kWebPayments; CONTENT_EXPORT extern const base::Feature kWebRtcAecBoundedErlSetup;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 085ab671..0510493 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1893,6 +1893,14 @@ } } +void RenderFrameSubmissionObserver::WaitForScrollOffsetAtTop( + bool expected_scroll_offset_at_top) { + while (render_frame_metadata_provider_->LastRenderFrameMetadata() + .is_scroll_offset_at_top != expected_scroll_offset_at_top) { + WaitForMetadataChange(); + } +} + const cc::RenderFrameMetadata& RenderFrameSubmissionObserver::LastRenderFrameMetadata() const { return render_frame_metadata_provider_->LastRenderFrameMetadata();
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 2fe3f83..e10a2eb 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -713,6 +713,10 @@ // scroll offset matches |expected_offset|. void WaitForScrollOffset(const gfx::Vector2dF& expected_offset); + // Blocks the browser ui thread until RenderFrameMetadata arrives where its + // scroll offset at top matches |expected_scroll_offset_at_top|. + void WaitForScrollOffsetAtTop(bool expected_scroll_offset_at_top); + const cc::RenderFrameMetadata& LastRenderFrameMetadata() const; // Returns the number of frames submitted since the observer's creation.
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index af688e7..540e5073 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -352,7 +352,7 @@ std::unique_ptr<blink::WebLeakDetector> leak_detector = base::WrapUnique(blink::WebLeakDetector::Create(this)); - leak_detector->PrepareForLeakDetection(view_->GetWebView()->MainFrame()); + leak_detector->PrepareForLeakDetection(); // |view_| is ref-counted and deletes itself during the RunUntilIdle() call // below.
diff --git a/content/public/test/service_worker_test_helpers.cc b/content/public/test/service_worker_test_helpers.cc index f675c0f..7cf2116 100644 --- a/content/public/test/service_worker_test_helpers.cc +++ b/content/public/test/service_worker_test_helpers.cc
@@ -102,7 +102,7 @@ context_wrapper->FindReadyRegistrationForPattern( pattern, base::BindOnce(&FoundReadyRegistration, base::RetainedRef(context_wrapper), - base::Passed(&completion_callback_ui))); + std::move(completion_callback_ui))); } } // namespace content
diff --git a/content/public/test/test_download_http_response.cc b/content/public/test/test_download_http_response.cc index 70a7ca0..99c351c0 100644 --- a/content/public/test/test_download_http_response.cc +++ b/content/public/test/test_download_http_response.cc
@@ -59,7 +59,7 @@ const TestDownloadHttpResponse::OnResponseSentCallback& callback, std::unique_ptr<TestDownloadHttpResponse::CompletedRequest> request) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(callback, base::Passed(&request))); + base::BindOnce(callback, std::move(request))); } // The shim response object used by embedded_test_server. After this object is
diff --git a/content/public/test/url_loader_interceptor.cc b/content/public/test/url_loader_interceptor.cc index ab6766cb..4c3f127 100644 --- a/content/public/test/url_loader_interceptor.cc +++ b/content/public/test/url_loader_interceptor.cc
@@ -288,8 +288,8 @@ BrowserThread::IO, FROM_HERE, base::BindOnce( &URLLoaderInterceptor::CreateURLLoaderFactoryForSubresources, - base::Unretained(this), base::Passed(&request), process_id, - base::Passed(&original_factory))); + base::Unretained(this), std::move(request), process_id, + std::move(original_factory))); return; }
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 50252b8..2e83294d 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -234,6 +234,8 @@ "loader/child_url_loader_factory_bundle.h", "loader/ftp_directory_listing_response_delegate.cc", "loader/ftp_directory_listing_response_delegate.h", + "loader/navigation_response_override_parameters.cc", + "loader/navigation_response_override_parameters.h", "loader/request_extra_data.cc", "loader/request_extra_data.h", "loader/resource_dispatcher.cc",
diff --git a/content/renderer/image_downloader/single_image_downloader.cc b/content/renderer/image_downloader/single_image_downloader.cc index 760b2148..682e3ee 100644 --- a/content/renderer/image_downloader/single_image_downloader.cc +++ b/content/renderer/image_downloader/single_image_downloader.cc
@@ -24,8 +24,9 @@ new ImageDownloaderBase(render_frame.get())); ImageDownloaderBase* image_downloader_ptr = image_downloader.get(); image_downloader_ptr->DownloadImage( - url, false, false, base::Bind(&SingleImageDownloader::DidDownloadImage, - base::Passed(&image_downloader), cb)); + url, false, false, + base::BindOnce(&SingleImageDownloader::DidDownloadImage, + std::move(image_downloader), cb)); } // Static
diff --git a/content/renderer/loader/navigation_response_override_parameters.cc b/content/renderer/loader/navigation_response_override_parameters.cc new file mode 100644 index 0000000..69692a80 --- /dev/null +++ b/content/renderer/loader/navigation_response_override_parameters.cc
@@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/loader/navigation_response_override_parameters.h" + +#include "base/callback.h" + +namespace content { + +NavigationResponseOverrideParameters::NavigationResponseOverrideParameters() = + default; + +NavigationResponseOverrideParameters::~NavigationResponseOverrideParameters() { + if (on_delete) + std::move(on_delete).Run(stream_url); +} + +} // namespace content
diff --git a/content/renderer/loader/navigation_response_override_parameters.h b/content/renderer/loader/navigation_response_override_parameters.h new file mode 100644 index 0000000..3da030ef --- /dev/null +++ b/content/renderer/loader/navigation_response_override_parameters.h
@@ -0,0 +1,39 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_ +#define CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_ + +#include <vector> + +#include "base/callback_forward.h" +#include "content/common/content_export.h" +#include "net/url_request/redirect_info.h" +#include "services/network/public/cpp/resource_response.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "url/gurl.h" + +namespace content { + +// PlzNavigate: Used to override parameters of the navigation request. +struct CONTENT_EXPORT NavigationResponseOverrideParameters { + public: + NavigationResponseOverrideParameters(); + ~NavigationResponseOverrideParameters(); + + GURL stream_url; + network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints; + network::ResourceResponseHead response; + std::vector<GURL> redirects; + std::vector<network::ResourceResponseHead> redirect_responses; + std::vector<net::RedirectInfo> redirect_infos; + + // Called when this struct is deleted. Used to notify the browser that it can + // release its associated StreamHandle. + base::OnceCallback<void(const GURL&)> on_delete; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_ \ No newline at end of file
diff --git a/content/renderer/loader/request_extra_data.h b/content/renderer/loader/request_extra_data.h index 6c08526e..72a4adcc 100644 --- a/content/renderer/loader/request_extra_data.h +++ b/content/renderer/loader/request_extra_data.h
@@ -12,6 +12,7 @@ #include "content/common/content_export.h" #include "content/common/navigation_params.h" #include "content/public/common/url_loader_throttle.h" +#include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/web_url_loader_impl.h" #include "third_party/WebKit/public/mojom/page/page_visibility_state.mojom.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -82,15 +83,16 @@ requested_with_ = requested_with; } - // PlzNavigate: |stream_override| is used to override certain parameters of - // navigation requests. - std::unique_ptr<StreamOverrideParameters> TakeStreamOverrideOwnership() { - return std::move(stream_override_); + // PlzNavigate: |navigation_response_override| is used to override certain + // parameters of navigation requests. + std::unique_ptr<NavigationResponseOverrideParameters> + TakeNavigationResponseOverrideOwnership() { + return std::move(navigation_response_override_); } - void set_stream_override( - std::unique_ptr<StreamOverrideParameters> stream_override) { - stream_override_ = std::move(stream_override); + void set_navigation_response_override( + std::unique_ptr<NavigationResponseOverrideParameters> response_override) { + navigation_response_override_ = std::move(response_override); } // NavigationMojoResponse: |continue_navigation| is used to continue a @@ -168,9 +170,10 @@ bool originated_from_service_worker_; blink::WebString custom_user_agent_; blink::WebString requested_with_; - std::unique_ptr<StreamOverrideParameters> stream_override_; + std::unique_ptr<NavigationResponseOverrideParameters> + navigation_response_override_; // TODO(arthursonzogni): Once NavigationMojoResponse is launched, move most of - // the |stream_override_| content as parameters of this function. + // the |navigation_response_override_| content as parameters of this function. base::OnceClosure continue_navigation_function_; bool initiated_in_secure_context_; bool is_for_no_state_prefetch_;
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index de09f0e..0632e29 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -24,6 +24,7 @@ #include "content/common/inter_process_time_ticks_converter.h" #include "content/common/navigation_params.h" #include "content/common/throttling_url_loader.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/resource_load_info.mojom.h" #include "content/public/common/resource_type.h" #include "content/public/renderer/fixed_received_data.h" @@ -156,12 +157,25 @@ void ResourceDispatcher::OnReceivedResponse( int request_id, - const network::ResourceResponseHead& response_head) { + const network::ResourceResponseHead& initial_response_head) { TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedResponse"); PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); if (!request_info) return; + + network::ResourceResponseHead response_head; + std::unique_ptr<NavigationResponseOverrideParameters> response_override = + std::move(request_info->navigation_response_override); + if (response_override) { + CHECK(IsBrowserSideNavigationEnabled()); + response_head = response_override->response; + } else { + response_head = initial_response_head; + } + request_info->response_start = base::TimeTicks::Now(); + request_info->mime_type = response_head.mime_type; + request_info->network_accessed = response_head.network_accessed; if (delegate_) { std::unique_ptr<RequestPeer> new_peer = delegate_->OnReceivedResponse( @@ -249,7 +263,7 @@ request_info->response_method = redirect_info.new_method; request_info->response_referrer = GURL(redirect_info.new_referrer); request_info->has_pending_redirect = true; - if (!request_info->is_deferred) { + if (!request_info->is_deferred && request_info->should_follow_redirect) { FollowPendingRedirect(request_info); } } else { @@ -414,7 +428,9 @@ const GURL& request_url, const std::string& method, const GURL& referrer, - bool download_to_file) + bool download_to_file, + std::unique_ptr<NavigationResponseOverrideParameters> + navigation_response_override_params) : peer(std::move(peer)), resource_type(resource_type), render_frame_id(render_frame_id), @@ -423,7 +439,10 @@ response_method(method), response_referrer(referrer), download_to_file(download_to_file), - request_start(base::TimeTicks::Now()) {} + request_start(base::TimeTicks::Now()), + buffer_size(0), + navigation_response_override( + std::move(navigation_response_override_params)) {} ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() { } @@ -477,27 +496,32 @@ std::unique_ptr<RequestPeer> peer, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<NavigationResponseOverrideParameters> + response_override_params, base::OnceClosure* continue_navigation_function) { CheckSchemeForReferrerPolicy(*request); + bool override_url_loader = + !!response_override_params && + !!response_override_params->url_loader_client_endpoints; + // Compute a unique request_id for this renderer process. int request_id = MakeRequestID(); pending_requests_[request_id] = std::make_unique<PendingRequestInfo>( std::move(peer), static_cast<ResourceType>(request->resource_type), request->render_frame_id, request->url, request->method, - request->referrer, request->download_to_file); + request->referrer, request->download_to_file, + std::move(response_override_params)); - if (url_loader_client_endpoints) { + if (override_url_loader) { pending_requests_[request_id]->url_loader_client = std::make_unique<URLLoaderClientImpl>(request_id, this, loading_task_runner); DCHECK(continue_navigation_function); - *continue_navigation_function = base::BindOnce( - &ResourceDispatcher::ContinueForNavigation, weak_factory_.GetWeakPtr(), - request_id, std::move(url_loader_client_endpoints)); - + *continue_navigation_function = + base::BindOnce(&ResourceDispatcher::ContinueForNavigation, + weak_factory_.GetWeakPtr(), request_id); return request_id; } @@ -586,29 +610,42 @@ return base::TimeTicks::FromInternalValue(result); } -void ResourceDispatcher::ContinueForNavigation( - int request_id, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) { - DCHECK(url_loader_client_endpoints); +void ResourceDispatcher::ContinueForNavigation(int request_id) { PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); if (!request_info) return; - URLLoaderClientImpl* client_ptr = request_info->url_loader_client.get(); + std::unique_ptr<NavigationResponseOverrideParameters> response_override = + std::move(request_info->navigation_response_override); + DCHECK(response_override); - // Short circuiting call to OnReceivedResponse to immediately start - // the request. ResourceResponseHead can be empty here because we - // pull the StreamOverride's one in - // WebURLLoaderImpl::Context::OnReceivedResponse. - client_ptr->OnReceiveResponse(network::ResourceResponseHead(), + // Mark the request so we do not attempt to follow the redirects, they already + // happened. + request_info->should_follow_redirect = false; + + URLLoaderClientImpl* client_ptr = request_info->url_loader_client.get(); + // PlzNavigate: during navigations, the ResourceResponse has already been + // received on the browser side, and has been passed down to the renderer. + // Replay the redirects that happened during navigation. + DCHECK_EQ(response_override->redirect_responses.size(), + response_override->redirect_infos.size()); + for (size_t i = 0; i < response_override->redirect_responses.size(); ++i) { + client_ptr->OnReceiveRedirect(response_override->redirect_infos[i], + response_override->redirect_responses[i]); + // The request might have been cancelled while processing the redirect. + if (!GetPendingRequestInfo(request_id)) + return; + } + + client_ptr->OnReceiveResponse(response_override->response, network::mojom::DownloadedTempFilePtr()); - // TODO(clamy): Move the replaying of redirects from WebURLLoaderImpl here. // Abort if the request is cancelled. if (!GetPendingRequestInfo(request_id)) return; - client_ptr->Bind(std::move(url_loader_client_endpoints)); + DCHECK(response_override->url_loader_client_endpoints); + client_ptr->Bind(std::move(response_override->url_loader_client_endpoints)); } } // namespace content
diff --git a/content/renderer/loader/resource_dispatcher.h b/content/renderer/loader/resource_dispatcher.h index 5626f6c..0c4c2045 100644 --- a/content/renderer/loader/resource_dispatcher.h +++ b/content/renderer/loader/resource_dispatcher.h
@@ -52,6 +52,7 @@ } namespace content { +struct NavigationResponseOverrideParameters; class RequestPeer; class ResourceDispatcherDelegate; struct SyncLoadResponse; @@ -122,7 +123,8 @@ std::unique_ptr<RequestPeer> peer, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<NavigationResponseOverrideParameters> + response_override_params, base::OnceClosure* continue_navigation_function); network::mojom::DownloadedTempFilePtr TakeDownloadedTempFile(int request_id); @@ -179,7 +181,9 @@ const GURL& request_url, const std::string& method, const GURL& referrer, - bool download_to_file); + bool download_to_file, + std::unique_ptr<NavigationResponseOverrideParameters> + response_override_params); ~PendingRequestInfo(); @@ -205,6 +209,9 @@ bool network_accessed = false; std::string mime_type; net::RequestPriority priority = net::RequestPriority::DEFAULT_PRIORITY; + std::unique_ptr<NavigationResponseOverrideParameters> + navigation_response_override; + bool should_follow_redirect = true; // For mojo loading. std::unique_ptr<ThrottlingURLLoader> url_loader; @@ -244,9 +251,7 @@ const PendingRequestInfo& request_info, const base::TimeTicks& browser_completion_time) const; - void ContinueForNavigation( - int request_id, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints); + void ContinueForNavigation(int request_id); // All pending requests issued to the host PendingRequestMap pending_requests_;
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc index b2714c8..1c62a8d 100644 --- a/content/renderer/loader/resource_dispatcher_unittest.cc +++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -26,6 +26,7 @@ #include "content/public/renderer/fixed_received_data.h" #include "content/public/renderer/request_peer.h" #include "content/public/renderer/resource_dispatcher_delegate.h" +#include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/loader/test_request_peer.h" #include "net/base/net_errors.h" @@ -120,7 +121,7 @@ TRAFFIC_ANNOTATION_FOR_TESTS, false, false, std::move(peer), base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(this), std::vector<std::unique_ptr<URLLoaderThrottle>>(), - network::mojom::URLLoaderClientEndpointsPtr(), + nullptr /* navigation_response_override_params */, nullptr /* continue_navigation_function */); peer_context->request_id = request_id; return request_id;
diff --git a/content/renderer/loader/sync_load_context.cc b/content/renderer/loader/sync_load_context.cc index fc94a22..3c0fcb21 100644 --- a/content/renderer/loader/sync_load_context.cc +++ b/content/renderer/loader/sync_load_context.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/synchronization/waitable_event.h" #include "content/public/common/url_loader_throttle.h" +#include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/sync_load_response.h" #include "net/url_request/redirect_info.h" #include "services/network/public/cpp/resource_request.h" @@ -40,7 +41,7 @@ traffic_annotation, true /* is_sync */, download_to_blob /* pass_response_pipe_to_peer */, base::WrapUnique(context), context->url_loader_factory_, - std::move(throttles), network::mojom::URLLoaderClientEndpointsPtr(), + std::move(throttles), nullptr /* navigation_response_override_params */, nullptr /* continue_for_navigation */); }
diff --git a/content/renderer/loader/url_loader_client_impl_unittest.cc b/content/renderer/loader/url_loader_client_impl_unittest.cc index d39883ca..57d9e31 100644 --- a/content/renderer/loader/url_loader_client_impl_unittest.cc +++ b/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -9,6 +9,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "content/public/common/weak_wrapper_shared_url_loader_factory.h" +#include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/resource_dispatcher.h" #include "content/renderer/loader/test_request_peer.h" #include "mojo/public/cpp/bindings/binding.h" @@ -33,7 +34,7 @@ &request_peer_context_), base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(this), std::vector<std::unique_ptr<URLLoaderThrottle>>(), - network::mojom::URLLoaderClientEndpointsPtr(), + nullptr /* navigation_response_override_params */, nullptr /* continue_navigation_function */); request_peer_context_.request_id = request_id_;
diff --git a/content/renderer/loader/url_response_body_consumer_unittest.cc b/content/renderer/loader/url_response_body_consumer_unittest.cc index 9e27ce446..ffea578 100644 --- a/content/renderer/loader/url_response_body_consumer_unittest.cc +++ b/content/renderer/loader/url_response_body_consumer_unittest.cc
@@ -13,6 +13,7 @@ #include "base/single_thread_task_runner.h" #include "content/public/common/weak_wrapper_shared_url_loader_factory.h" #include "content/public/renderer/request_peer.h" +#include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/loader/resource_dispatcher.h" #include "net/base/request_priority.h" @@ -161,7 +162,7 @@ std::make_unique<TestRequestPeer>(context, message_loop_.task_runner()), base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(&factory_), std::vector<std::unique_ptr<URLLoaderThrottle>>(), - network::mojom::URLLoaderClientEndpointsPtr(), + nullptr /* navigation_response_override_params */, nullptr /* continue_navigation_function */); }
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 9d9ac61..fbdb133 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -364,12 +364,6 @@ } // namespace -StreamOverrideParameters::StreamOverrideParameters() {} -StreamOverrideParameters::~StreamOverrideParameters() { - if (on_delete) - std::move(on_delete).Run(stream_url); -} - WebURLLoaderFactoryImpl::WebURLLoaderFactoryImpl( base::WeakPtr<ResourceDispatcher> resource_dispatcher, scoped_refptr<network::SharedURLLoaderFactory> loader_factory) @@ -470,7 +464,6 @@ ResourceDispatcher* resource_dispatcher_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; std::unique_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; - std::unique_ptr<StreamOverrideParameters> stream_override_; std::unique_ptr<SharedMemoryDataConsumerHandle::Writer> body_stream_writer_; std::unique_ptr<KeepAliveHandleWithChildProcessReference> keep_alive_handle_; enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA}; @@ -631,10 +624,11 @@ return; } + std::unique_ptr<NavigationResponseOverrideParameters> response_override; if (request.GetExtraData()) { RequestExtraData* extra_data = static_cast<RequestExtraData*>(request.GetExtraData()); - stream_override_ = extra_data->TakeStreamOverrideOwnership(); + response_override = extra_data->TakeNavigationResponseOverrideOwnership(); } @@ -642,7 +636,7 @@ // the WebURLLoader are the ones created by CommitNavigation. Several browser // tests load HTML directly through a data url which will be handled by the // block above. - DCHECK(!IsBrowserSideNavigationEnabled() || stream_override_ || + DCHECK(response_override || request.GetFrameType() == network::mojom::RequestContextFrameType::kNone); @@ -729,18 +723,16 @@ // PlzNavigate: The network request has already been made by the browser. // The renderer should request a stream which contains the body of the // response. If the Network Service or NavigationMojoResponse is enabled, the - // URLLoaderClientEndpoints is used instead to get the body. - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints; - if (stream_override_) { + // URLLoaderClientEndpoints from |response_override| is used instead to get + // the body. + if (response_override) { CHECK(IsBrowserSideNavigationEnabled()); DCHECK(!sync_load_response); DCHECK_NE(network::mojom::RequestContextFrameType::kNone, request.GetFrameType()); - if (stream_override_->url_loader_client_endpoints) { - url_loader_client_endpoints = - std::move(stream_override_->url_loader_client_endpoints); - } else { - resource_request->resource_body_stream_url = stream_override_->stream_url; + if (!response_override->url_loader_client_endpoints) { + resource_request->resource_body_stream_url = + response_override->stream_url; } } @@ -785,8 +777,8 @@ std::move(resource_request), request.RequestorID(), task_runner_, GetTrafficAnnotationTag(request), false /* is_sync */, request.PassResponsePipeToClient(), std::move(peer), url_loader_factory_, - extra_data->TakeURLLoaderThrottles(), - std::move(url_loader_client_endpoints), &continue_navigation_function); + extra_data->TakeURLLoaderThrottles(), std::move(response_override), + &continue_navigation_function); extra_data->set_continue_navigation_function( std::move(continue_navigation_function)); @@ -824,7 +816,7 @@ } void WebURLLoaderImpl::Context::OnReceivedResponse( - const network::ResourceResponseInfo& initial_info) { + const network::ResourceResponseInfo& info) { if (!client_) return; @@ -832,25 +824,6 @@ "loading", "WebURLLoaderImpl::Context::OnReceivedResponse", this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - network::ResourceResponseInfo info = initial_info; - - // PlzNavigate: during navigations, the ResourceResponse has already been - // received on the browser side, and has been passed down to the renderer. - if (stream_override_) { - CHECK(IsBrowserSideNavigationEnabled()); - info = stream_override_->response; - - // Replay the redirects that happened during navigation. - DCHECK_EQ(stream_override_->redirect_responses.size(), - stream_override_->redirect_infos.size()); - for (size_t i = 0; i < stream_override_->redirect_responses.size(); ++i) { - bool result = OnReceivedRedirect(stream_override_->redirect_infos[i], - stream_override_->redirect_responses[i]); - if (!result) - return; - } - } - WebURLResponse response; PopulateURLResponse(url_, info, &response, report_raw_headers_);
diff --git a/content/renderer/loader/web_url_loader_impl.h b/content/renderer/loader/web_url_loader_impl.h index d635d1f..80af929 100644 --- a/content/renderer/loader/web_url_loader_impl.h +++ b/content/renderer/loader/web_url_loader_impl.h
@@ -5,22 +5,15 @@ #ifndef CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_ #define CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_ -#include <vector> - -#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "content/common/content_export.h" #include "content/common/frame.mojom.h" #include "mojo/public/cpp/system/data_pipe.h" -#include "net/url_request/redirect_info.h" -#include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/WebKit/public/platform/WebURLLoader.h" #include "third_party/WebKit/public/platform/WebURLLoaderFactory.h" -#include "url/gurl.h" namespace base { class SingleThreadTaskRunner; @@ -34,24 +27,6 @@ class ResourceDispatcher; -// PlzNavigate: Used to override parameters of the navigation request. -struct CONTENT_EXPORT StreamOverrideParameters { - public: - StreamOverrideParameters(); - ~StreamOverrideParameters(); - - GURL stream_url; - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints; - network::ResourceResponseHead response; - std::vector<GURL> redirects; - std::vector<network::ResourceResponseInfo> redirect_responses; - std::vector<net::RedirectInfo> redirect_infos; - - // Called when this struct is deleted. Used to notify the browser that it can - // release its associated StreamHandle. - base::OnceCallback<void(const GURL&)> on_delete; -}; - // Default implementation of WebURLLoaderFactory. class CONTENT_EXPORT WebURLLoaderFactoryImpl : public blink::WebURLLoaderFactory {
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc index ad45fbc3..02c293d 100644 --- a/content/renderer/loader/web_url_loader_impl_unittest.cc +++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -23,6 +23,7 @@ #include "content/public/common/weak_wrapper_shared_url_loader_factory.h" #include "content/public/renderer/fixed_received_data.h" #include "content/public/renderer/request_peer.h" +#include "content/renderer/loader/navigation_response_override_parameters.h" #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/loader/resource_dispatcher.h" #include "content/renderer/loader/sync_load_response.h" @@ -92,7 +93,8 @@ std::unique_ptr<RequestPeer> peer, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, - network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, + std::unique_ptr<NavigationResponseOverrideParameters> + navigation_response_override_params, base::OnceClosure* continue_navigation_function) override { EXPECT_FALSE(peer_); if (sync_load_response_.info.encoded_body_length != -1) @@ -100,6 +102,8 @@ peer_ = std::move(peer); url_ = request->url; stream_url_ = request->resource_body_stream_url; + navigation_response_override_params_ = + std::move(navigation_response_override_params); return 1; } @@ -126,6 +130,11 @@ sync_load_response_ = std::move(sync_load_response); } + std::unique_ptr<NavigationResponseOverrideParameters> + TakeNavigationResponseOverrideParams() { + return std::move(navigation_response_override_params_); + } + private: std::unique_ptr<RequestPeer> peer_; bool canceled_; @@ -133,6 +142,8 @@ GURL url_; GURL stream_url_; SyncLoadResponse sync_load_response_; + std::unique_ptr<NavigationResponseOverrideParameters> + navigation_response_override_params_; DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcher); }; @@ -623,8 +634,8 @@ DoFailRequest(); } -// PlzNavigate: checks that the stream override parameters provided on -// navigation commit are properly applied. +// PlzNavigate: checks that the navigation response override parameters provided +// on navigation commit are properly applied. TEST_F(WebURLLoaderImplTest, BrowserSideNavigationCommit) { // Initialize the request and the stream override. const GURL kNavigationURL = GURL(kTestURL); @@ -633,12 +644,12 @@ blink::WebURLRequest request(kNavigationURL); request.SetFrameType(network::mojom::RequestContextFrameType::kTopLevel); request.SetRequestContext(blink::WebURLRequest::kRequestContextFrame); - std::unique_ptr<StreamOverrideParameters> stream_override( - new StreamOverrideParameters()); - stream_override->stream_url = kStreamURL; - stream_override->response.mime_type = kMimeType; + std::unique_ptr<NavigationResponseOverrideParameters> response_override( + new NavigationResponseOverrideParameters()); + response_override->stream_url = kStreamURL; + response_override->response.mime_type = kMimeType; auto extra_data = std::make_unique<RequestExtraData>(); - extra_data->set_stream_override(std::move(stream_override)); + extra_data->set_navigation_response_override(std::move(response_override)); request.SetExtraData(std::move(extra_data)); client()->loader()->LoadAsynchronously(request, client()); @@ -649,7 +660,10 @@ EXPECT_EQ(kStreamURL, dispatcher()->stream_url()); EXPECT_FALSE(client()->did_receive_response()); - peer()->OnReceivedResponse(network::ResourceResponseInfo()); + + response_override = dispatcher()->TakeNavigationResponseOverrideParams(); + ASSERT_TRUE(response_override); + peer()->OnReceivedResponse(response_override->response); EXPECT_TRUE(client()->did_receive_response()); // The response info should have been overriden.
diff --git a/content/renderer/loader/web_url_request_util.cc b/content/renderer/loader/web_url_request_util.cc index 9f269d7..4eb0c811 100644 --- a/content/renderer/loader/web_url_request_util.cc +++ b/content/renderer/loader/web_url_request_util.cc
@@ -248,12 +248,6 @@ int GetLoadFlagsForWebURLRequest(const WebURLRequest& request) { int load_flags = net::LOAD_NORMAL; - // Although EV status is irrelevant to sub-frames and sub-resources, we have - // to perform EV certificate verification on all resources because an HTTP - // keep-alive connection created to load a sub-frame or a sub-resource could - // be reused to load a main frame. - load_flags |= net::LOAD_VERIFY_EV_CERT; - GURL url = request.Url(); switch (request.GetCacheMode()) { case FetchCacheMode::kNoStore:
diff --git a/content/renderer/media/stream/webmediaplayer_ms.cc b/content/renderer/media/stream/webmediaplayer_ms.cc index 42a9b92..d96c9f0 100644 --- a/content/renderer/media/stream/webmediaplayer_ms.cc +++ b/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -778,8 +778,9 @@ // back, so we can't rely on |render_frame_suspended_| being false here. if (frame_deliverer_) { io_task_runner_->PostTask( - FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, - base::Unretained(frame_deliverer_.get()), true)); + FROM_HERE, + base::BindOnce(&FrameDeliverer::SetRenderFrameSuspended, + base::Unretained(frame_deliverer_.get()), true)); } // On Android, substitute the displayed VideoFrame with a copy to avoid holding @@ -805,8 +806,9 @@ if (frame_deliverer_) { io_task_runner_->PostTask( - FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, - base::Unretained(frame_deliverer_.get()), true)); + FROM_HERE, + base::BindOnce(&FrameDeliverer::SetRenderFrameSuspended, + base::Unretained(frame_deliverer_.get()), true)); } } @@ -815,8 +817,9 @@ if (frame_deliverer_) { io_task_runner_->PostTask( - FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, - base::Unretained(frame_deliverer_.get()), false)); + FROM_HERE, + base::BindOnce(&FrameDeliverer::SetRenderFrameSuspended, + base::Unretained(frame_deliverer_.get()), false)); } // On Android, resume playback on visibility. play() clears
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc index 9f8c9de..dcf3844 100644 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
@@ -199,8 +199,8 @@ base::BindOnce( &WebRtcMediaStreamAdapterMap::OnRemoteStreamAdapterInitialized, this, - base::Passed(base::WrapUnique(new AdapterRef( - this, AdapterRef::Type::kRemote, adapter_entry))))); + base::WrapUnique(new AdapterRef(this, AdapterRef::Type::kRemote, + adapter_entry)))); } return base::WrapUnique( new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
diff --git a/content/renderer/mus/mus_embedded_frame.cc b/content/renderer/mus/mus_embedded_frame.cc index f3a08923..f6b3d1e4 100644 --- a/content/renderer/mus/mus_embedded_frame.cc +++ b/content/renderer/mus/mus_embedded_frame.cc
@@ -87,7 +87,8 @@ window_tree()->AddWindow(GetAndAdvanceNextChangeId(), renderer_window_tree_client_->root_window_id_, window_id_); - window_tree()->EmbedUsingToken(window_id_, token, 0, base::Bind(&OnEmbedAck)); + window_tree()->EmbedUsingToken(window_id_, token, 0, + base::BindOnce(&OnEmbedAck)); } void MusEmbeddedFrame::OnTreeAvailable() {
diff --git a/content/renderer/pepper/pepper_compositor_host.cc b/content/renderer/pepper/pepper_compositor_host.cc index e36454a..7bafb01 100644 --- a/content/renderer/pepper/pepper_compositor_host.cc +++ b/content/renderer/pepper/pepper_compositor_host.cc
@@ -326,8 +326,8 @@ resource, viz::SingleReleaseCallback::Create(base::BindOnce( &PepperCompositorHost::ImageReleased, weak_factory_.GetWeakPtr(), - new_layer->common.resource_id, base::Passed(&image_shm), - base::Passed(&bitmap)))); + new_layer->common.resource_id, std::move(image_shm), + std::move(bitmap)))); // TODO(penghuang): get a damage region from the application and // pass it to SetNeedsDisplayRect(). image_layer->SetNeedsDisplay();
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc index 55e6368..005c6543 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -788,7 +788,7 @@ viz::RGBA_8888); *release_callback = viz::SingleReleaseCallback::Create(base::BindOnce( &PepperGraphics2DHost::ReleaseSoftwareCallback, this->AsWeakPtr(), - base::Passed(&shared_bitmap), base::Passed(®istration))); + std::move(shared_bitmap), std::move(registration))); composited_output_modified_ = false; return true; }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 95dda00..5ebc5ee 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -422,7 +422,7 @@ WebURLRequest CreateURLRequestForNavigation( const CommonNavigationParams& common_params, const RequestNavigationParams& request_params, - std::unique_ptr<StreamOverrideParameters> stream_override, + std::unique_ptr<NavigationResponseOverrideParameters> response_override, bool is_view_source_mode_enabled, bool is_same_document_navigation) { // Use the original navigation url to construct the WebURLRequest. The @@ -462,7 +462,7 @@ static_cast<WebURLRequest::PreviewsState>(common_params.previews_state)); auto extra_data = std::make_unique<RequestExtraData>(); - extra_data->set_stream_override(std::move(stream_override)); + extra_data->set_navigation_response_override(std::move(response_override)); extra_data->set_navigation_initiated_by_renderer( request_params.nav_entry_id == 0); request.SetExtraData(std::move(extra_data)); @@ -3214,10 +3214,10 @@ // Continue the navigation. // TODO(arthursonzogni): Pass the data needed to continue the navigation to - // this function instead of storing it in the StreamOverrideParameters. - // The architecture of committing the navigation in the renderer process - // should be simplified and avoid going through the ResourceFetcher for the - // main resource. + // this function instead of storing it in the + // NavigationResponseOverrideParameters. The architecture of committing the + // navigation in the renderer process should be simplified and avoid going + // through the ResourceFetcher for the main resource. if (continue_navigation) std::move(continue_navigation).Run(); } @@ -3262,11 +3262,10 @@ has_stale_copy_in_cache ? WebURLError::HasCopyInCache::kTrue : WebURLError::HasCopyInCache::kFalse, WebURLError::IsWebSecurityViolation::kFalse, common_params.url); - WebURLRequest failed_request = - CreateURLRequestForNavigation(common_params, request_params, - std::unique_ptr<StreamOverrideParameters>(), - frame_->IsViewSourceModeEnabled(), - false); // is_same_document_navigation + WebURLRequest failed_request = CreateURLRequestForNavigation( + common_params, request_params, + /*response_override=*/nullptr, frame_->IsViewSourceModeEnabled(), + false); // is_same_document_navigation if (!ShouldDisplayErrorPageForFailedLoad(error_code, common_params.url)) { // The browser expects this frame to be loading an error page. Inform it @@ -4853,7 +4852,7 @@ // There may also be a stream url associated with the request. WebString custom_user_agent; WebString requested_with; - std::unique_ptr<StreamOverrideParameters> stream_override; + std::unique_ptr<NavigationResponseOverrideParameters> response_override; if (request.GetExtraData()) { RequestExtraData* old_extra_data = static_cast<RequestExtraData*>(request.GetExtraData()); @@ -4873,7 +4872,8 @@ else request.SetHTTPHeaderField("X-Requested-With", requested_with); } - stream_override = old_extra_data->TakeStreamOverrideOwnership(); + response_override = + old_extra_data->TakeNavigationResponseOverrideOwnership(); } // Set an empty HTTP origin header for non GET methods if none is currently @@ -4902,7 +4902,7 @@ navigation_state->common_params().allow_download); extra_data->set_transition_type(transition_type); extra_data->set_should_replace_current_entry(should_replace_current_entry); - extra_data->set_stream_override(std::move(stream_override)); + extra_data->set_navigation_response_override(std::move(response_override)); bool is_for_no_state_prefetch = GetContentClient()->renderer()->IsPrefetchOnly(this, request); extra_data->set_is_for_no_state_prefetch(is_for_no_state_prefetch); @@ -6645,20 +6645,20 @@ const GURL& body_url) { // This will override the url requested by the WebURLLoader, as well as // provide it with the response to the request. - std::unique_ptr<StreamOverrideParameters> stream_override( - new StreamOverrideParameters()); - stream_override->stream_url = body_url; - stream_override->url_loader_client_endpoints = + std::unique_ptr<NavigationResponseOverrideParameters> response_override( + new NavigationResponseOverrideParameters()); + response_override->stream_url = body_url; + response_override->url_loader_client_endpoints = std::move(url_loader_client_endpoints); - stream_override->response = head; - stream_override->redirects = request_params.redirects; - stream_override->redirect_responses = request_params.redirect_response; - stream_override->redirect_infos = request_params.redirect_infos; + response_override->response = head; + response_override->redirects = request_params.redirects; + response_override->redirect_responses = request_params.redirect_response; + response_override->redirect_infos = request_params.redirect_infos; // Used to notify the browser that it can release its |stream_handle_| when - // the |stream_override| object isn't used anymore. + // the |response_override| object isn't used anymore. // TODO(clamy): Remove this when we switch to Mojo streams. - stream_override->on_delete = base::BindOnce( + response_override->on_delete = base::BindOnce( [](base::WeakPtr<RenderFrameImpl> weak_self, const GURL& url) { if (RenderFrameImpl* self = weak_self.get()) { self->Send( @@ -6668,7 +6668,7 @@ weak_factory_.GetWeakPtr()); WebURLRequest request = CreateURLRequestForNavigation( - common_params, request_params, std::move(stream_override), + common_params, request_params, std::move(response_override), frame_->IsViewSourceModeEnabled(), false /* is_same_document */); request.SetFrameType(IsTopLevelNavigation(frame_) ? network::mojom::RequestContextFrameType::kTopLevel @@ -6822,8 +6822,11 @@ return; } - if (!render_view_->webview()->ScrollFocusedEditableElementIntoView()) + if (!frame_->LocalRoot() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView()) { return; + } rect_for_scrolled_focused_editable_node_ = rect; has_scrolled_focused_editable_node_into_rect_ = true;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index d7102e0..2ca531b 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -2021,8 +2021,14 @@ RenderWidget::OnResize(params); } - if (params.scroll_focused_node_into_view) - webview()->ScrollFocusedEditableElementIntoView(); + if (!params.scroll_focused_node_into_view) + return; + + if (WebLocalFrame* focused_frame = GetWebView()->FocusedFrame()) { + focused_frame->LocalRoot() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); + } } void RenderViewImpl::OnSetBackgroundOpaque(bool opaque) {
diff --git a/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc b/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc index fb71095..540a9912 100644 --- a/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc +++ b/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
@@ -241,7 +241,7 @@ bool is_idle = false; ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle), task_runner()->GetMockTickClock()); - int event_id = timer.StartEvent(base::BindRepeating([](int) {})); + int event_id = timer.StartEvent(base::BindOnce([](int) {})); timer.SetIdleTimerDelayToZero(); // Nothing happens since there is an inflight event. EXPECT_FALSE(is_idle); @@ -255,8 +255,8 @@ bool is_idle = false; ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle), task_runner()->GetMockTickClock()); - int event_id_1 = timer.StartEvent(base::BindRepeating([](int) {})); - int event_id_2 = timer.StartEvent(base::BindRepeating([](int) {})); + int event_id_1 = timer.StartEvent(base::BindOnce([](int) {})); + int event_id_2 = timer.StartEvent(base::BindOnce([](int) {})); timer.SetIdleTimerDelayToZero(); // Nothing happens since there are two inflight events. EXPECT_FALSE(is_idle);
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index e5b415e2..37e2bab 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -994,7 +994,7 @@ DCHECK_EQ(GURL(url::kAboutBlankURL), GURL(main_frame->ToWebLocalFrame()->GetDocument().Url())); - leak_detector_->TryLeakDetection(main_frame); + leak_detector_->TryLeakDetection(); } void BlinkTestRunner::OnReplyBluetoothManualChooserEvents(
diff --git a/content/shell/renderer/layout_test/leak_detector.cc b/content/shell/renderer/layout_test/leak_detector.cc index 8ebc1b7..9a0cdd1 100644 --- a/content/shell/renderer/layout_test/leak_detector.cc +++ b/content/shell/renderer/layout_test/leak_detector.cc
@@ -68,10 +68,10 @@ LeakDetector::~LeakDetector() { } -void LeakDetector::TryLeakDetection(blink::WebFrame* frame) { +void LeakDetector::TryLeakDetection() { blink::WebLeakDetector* web_leak_detector = blink::WebLeakDetector::Create(this); - web_leak_detector->PrepareForLeakDetection(frame); + web_leak_detector->PrepareForLeakDetection(); web_leak_detector->CollectGarbageAndReport(); }
diff --git a/content/shell/renderer/layout_test/leak_detector.h b/content/shell/renderer/layout_test/leak_detector.h index be42267..e58bf81 100644 --- a/content/shell/renderer/layout_test/leak_detector.h +++ b/content/shell/renderer/layout_test/leak_detector.h
@@ -11,10 +11,6 @@ #include "content/shell/common/leak_detection_result.h" #include "third_party/WebKit/public/web/WebLeakDetector.h" -namespace blink { -class WebFrame; -} // namespace blink - namespace content { class BlinkTestRunner; @@ -28,9 +24,9 @@ // Counts DOM objects, compare the previous status and returns the result of // leak detection. It is assumed that this method is always called when a // specific page, like about:blank is loaded to compare the previous - // circumstance of DOM objects. If the number of objects increses, there + // circumstance of DOM objects. If the number of objects increases, there // should be a leak. - void TryLeakDetection(blink::WebFrame*); + void TryLeakDetection(); // WebLeakDetectorClient: void OnLeakDetectionComplete(const Result& result) override;
diff --git a/content/shell/test_runner/test_plugin.cc b/content/shell/test_runner/test_plugin.cc index cd89b05..9f4462a 100644 --- a/content/shell/test_runner/test_plugin.cc +++ b/content/shell/test_runner/test_plugin.cc
@@ -321,8 +321,8 @@ shared_bitmap_->id(), /*sequence_number=*/0, shared_bitmap_->size(), viz::RGBA_8888); *release_callback = viz::SingleReleaseCallback::Create( - base::BindOnce(&ReleaseSharedMemory, base::Passed(&shared_bitmap_), - base::Passed(®istration))); + base::BindOnce(&ReleaseSharedMemory, std::move(shared_bitmap_), + std::move(registration))); } content_changed_ = false; return true;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index baa231b..c0606c0d 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1263,7 +1263,6 @@ "../browser/dom_storage/dom_storage_database_unittest.cc", "../browser/dom_storage/local_storage_context_mojo_unittest.cc", "../browser/dom_storage/session_storage_database_unittest.cc", - "../browser/download/download_item_impl_unittest.cc", "../browser/download/download_manager_impl_unittest.cc", "../browser/download/download_request_core_unittest.cc", "../browser/download/save_package_unittest.cc",
diff --git a/content/test/data/iframe_out_of_view.html b/content/test/data/iframe_out_of_view.html index 2e0af2ef6..fcf854c 100644 --- a/content/test/data/iframe_out_of_view.html +++ b/content/test/data/iframe_out_of_view.html
@@ -1,8 +1,5 @@ <!DOCTYPE html> <html> -<head> - <meta name='viewport' content='width=device-width, minimum-scale=1'> -</head> <body> <style> body { @@ -19,6 +16,14 @@ padding: 0; overflow: scroll; } + + input { + margin: 0; + padding: 0; + border: 0; + height: 1px; + font-size: 1px; + } </style> <p> Single <iframe> which is positioned out of view. </p> <iframe> @@ -28,8 +33,10 @@ window.loaded = false; window.notifyBrowser = false; const kInfinity = 1000000; + const kMarginOfError = 1; + const tinyTimeout = 50; - window.addEventListener('load', () => { + window.addEventListener("load", () => { document.scrollingElement.scrollTop = kInfinity; document.scrollingElement.scrollLeft = kInfinity; window.loaded = true; @@ -39,10 +46,72 @@ function notifyWhenLoaded() { if (loaded) - window.domAutomationController.send('LOADED'); + window.domAutomationController.send("LOADED"); else window.notifyBrowser = true; } + + // Waits until the |visualViewport| reaches the given size (approximately). + // Notifies the browser when this happens. + function notifyVisualViewportChanged(width, height) { + if ((Math.abs(visualViewport.width - width) < kMarginOfError) && + (Math.abs(visualViewport.height - height) < kMarginOfError)) { + return window.domAutomationController.send("SIZED"); + } + + window.setTimeout(() => { + notifyVisualViewportChanged(width, height); + }, tinyTimeout); + } + + function isEmptyRect(rect) { + return (rect.width * rect.height) === 0; + } + + function intersect(rect1, rect2) { + let minX1 = rect1.x, maxX1 = minX1 + rect1.width + minY1 = rect1.y, maxY1 = minY1 + rect1.height, + minX2 = rect2.x, maxX2 = minX2 + rect2.width, + minY2 = rect2.y, maxY2 = minY2 + rect2.height; + + return !(isEmptyRect(rect1) || + isEmptyRect(rect2) || + (minX1 > maxX2) || + (minX2 > maxX1) || + (minY1 > maxY2) || + (minY2 > maxY1)); + } + + function visualViewportAsRect() { + return { + x: visualViewport.offsetLeft, + y: visualViewport.offsetTop, + width: Math.round(visualViewport.width), + height: Math.round(visualViewport.height) + }; + } + + function rectAsString(rect) { + return `${rect.x},${rect.y},${rect.width},${rect.height}`; + } + + function addFocusedInputField() { + var input = document.createElement("input"); + input.value="some text"; + document.body.insertBefore(input, document.body.firstChild); + input.focus(); + } + + // Waits until the given element is inside the |visualViewport|. + function notifyWhenVisible(el) { + if (intersect(el.getBoundingClientRect(), visualViewportAsRect())) { + window.domAutomationController.send("VISIBLE"); + } else { + window.setTimeout(() => { + notifyWhenVisible(el); + }, tinyTimeout); + } + } </script> </body> </html>
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index 63bdd9d..3326032 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -126,19 +126,6 @@ self.Fail('Pixel_OffscreenCanvasUnaccelerated2DWorker', ['mac', 'linux', 'win', 'android', 'chromeos'], bug=817110) - # TODO(enne): temporarily suppress these tests until rebaselined. - self.Fail('Pixel_2DCanvasWebGL', ['android'], bug=972546) - self.Fail('Pixel_Canvas2DRedBox', ['android'], bug=972546) - self.Fail('Pixel_CanvasDisplayLinearRGBAccelerated2D', - ['android'], bug=972546) - self.Fail('Pixel_CanvasDisplayLinearRGBUnaccelerated2DGPUCompositing', - ['android'], bug=972546) - self.Fail('Pixel_WebGLGreenTriangle_AA_Alpha', ['android'], bug=972546) - self.Fail('Pixel_WebGLGreenTriangle_AA_NoAlpha', ['android'], bug=972546) - self.Fail('Pixel_WebGLGreenTriangle_NoAA_Alpha', ['android'], bug=972546) - self.Fail('Pixel_WebGLGreenTriangle_NoAA_NoAlpha', ['android'], bug=972546) - self.Fail('Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear', - ['android'], bug=972546) - - # TODO(hubbe): Temporary supression for rebaseline + # TODO(hubbe): Temporary supressions for rebaseline self.Fail('Pixel_Video_VP9', bug=754986) + self.Fail('Pixel_DirectComposition_Video_VP9', bug=754986)
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 6532afac..57ac72fc 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -444,42 +444,42 @@ 'pixel_offscreenCanvas_2d_commit_main.html', base_name + '_OffscreenCanvasAccelerated2D', test_rect=[0, 0, 360, 200], - revision=9, + revision=10, browser_args=browser_args), PixelTestPage( 'pixel_offscreenCanvas_2d_commit_worker.html', base_name + '_OffscreenCanvasAccelerated2DWorker', test_rect=[0, 0, 360, 200], - revision=9, + revision=10, browser_args=browser_args), PixelTestPage( 'pixel_offscreenCanvas_2d_commit_main.html', base_name + '_OffscreenCanvasUnaccelerated2D', test_rect=[0, 0, 360, 200], - revision=7, + revision=8, browser_args=browser_args + unaccelerated_args), PixelTestPage( 'pixel_offscreenCanvas_2d_commit_worker.html', base_name + '_OffscreenCanvasUnaccelerated2DWorker', test_rect=[0, 0, 360, 200], - revision=7, + revision=8, browser_args=browser_args + unaccelerated_args), PixelTestPage( 'pixel_offscreenCanvas_2d_commit_main.html', base_name + '_OffscreenCanvasUnaccelerated2DGPUCompositing', test_rect=[0, 0, 360, 200], - revision=10, + revision=11, browser_args=browser_args + ['--disable-accelerated-2d-canvas']), PixelTestPage( 'pixel_offscreenCanvas_2d_commit_worker.html', base_name + '_OffscreenCanvasUnaccelerated2DGPUCompositingWorker', test_rect=[0, 0, 360, 200], - revision=10, + revision=11, browser_args=browser_args + ['--disable-accelerated-2d-canvas']), PixelTestPage(
diff --git a/content/test/run_all_perftests.cc b/content/test/run_all_perftests.cc index 77aa196..6678243 100644 --- a/content/test/run_all_perftests.cc +++ b/content/test/run_all_perftests.cc
@@ -15,6 +15,7 @@ // perf measurements with randomness resulting from running // in parallel. return base::LaunchUnitTestsSerially( - argc, argv, base::Bind(&content::UnitTestTestSuite::Run, - base::Unretained(&test_suite))); + argc, argv, + base::BindOnce(&content::UnitTestTestSuite::Run, + base::Unretained(&test_suite))); }
diff --git a/content/test/run_all_unittests.cc b/content/test/run_all_unittests.cc index 153442c..f03294d 100644 --- a/content/test/run_all_unittests.cc +++ b/content/test/run_all_unittests.cc
@@ -17,7 +17,7 @@ catalog::Catalog::SetDefaultCatalogManifest( content::CreateContentUnittestsCatalog()); - return base::LaunchUnitTests( - argc, argv, base::Bind(&content::UnitTestTestSuite::Run, - base::Unretained(&test_suite))); + return base::LaunchUnitTests(argc, argv, + base::BindOnce(&content::UnitTestTestSuite::Run, + base::Unretained(&test_suite))); }
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc index 33ad3bd..aea3ab4 100644 --- a/device/vr/android/gvr/gvr_device.cc +++ b/device/vr/android/gvr/gvr_device.cc
@@ -35,9 +35,10 @@ // uses approximately 0.55 on a Pixel XL. static constexpr float kWebVrRecommendedResolutionScale = 0.5; -gfx::Size GetRecommendedWebVrSize(gvr::GvrApi* gvr_api) { - // Pick a reasonable default size for the WebVR transfer surface - // based on a downscaled 1:1 render resolution. This size will also +gfx::Size GetMaximumWebVrSize(gvr::GvrApi* gvr_api) { + // Get the default, unscaled size for the WebVR transfer surface + // based on the optimal 1:1 render resolution. A scalar will be applied to + // this value in the renderer to reduce the render load. This size will also // be reported to the client via CreateVRDisplayInfo as the // client-recommended renderWidth/renderHeight and for the GVR // framebuffer. If the client chooses a different size or resizes it @@ -46,9 +47,7 @@ gvr::Sizei render_target_size = gvr_api->GetMaximumEffectiveRenderTargetSize(); - gfx::Size webvr_size( - render_target_size.width * kWebVrRecommendedResolutionScale, - render_target_size.height * kWebVrRecommendedResolutionScale); + gfx::Size webvr_size(render_target_size.width, render_target_size.height); // Ensure that the width is an even number so that the eyes each // get the same size, the recommended renderWidth is per eye @@ -65,12 +64,12 @@ gvr::GvrApi* gvr_api, gvr::Eye eye, const gvr::BufferViewportList& buffers, - const gfx::Size& recommended_size) { + const gfx::Size& maximum_size) { mojom::VREyeParametersPtr eye_params = mojom::VREyeParameters::New(); eye_params->fieldOfView = mojom::VRFieldOfView::New(); eye_params->offset.resize(3); - eye_params->renderWidth = recommended_size.width() / 2; - eye_params->renderHeight = recommended_size.height(); + eye_params->renderWidth = maximum_size.width() / 2; + eye_params->renderHeight = maximum_size.height(); gvr::BufferViewport eye_viewport = gvr_api->CreateBufferViewport(); buffers.GetBufferViewport(eye, &eye_viewport); @@ -108,11 +107,17 @@ gvr_api->CreateEmptyBufferViewportList(); gvr_buffer_viewports.SetToRecommendedBufferViewports(); - gfx::Size recommended_size = GetRecommendedWebVrSize(gvr_api); + gfx::Size maximum_size = GetMaximumWebVrSize(gvr_api); device->leftEye = CreateEyeParamater(gvr_api, GVR_LEFT_EYE, - gvr_buffer_viewports, recommended_size); + gvr_buffer_viewports, maximum_size); device->rightEye = CreateEyeParamater(gvr_api, GVR_RIGHT_EYE, - gvr_buffer_viewports, recommended_size); + gvr_buffer_viewports, maximum_size); + + // This scalar will be applied in the renderer to the recommended render + // target sizes. For WebVR it will always be applied, for WebXR it can be + // overridden. + device->default_framebuffer_scale = kWebVrRecommendedResolutionScale; + return device; }
diff --git a/device/vr/oculus/oculus_device.cc b/device/vr/oculus/oculus_device.cc index 6ed77376..364daef 100644 --- a/device/vr/oculus/oculus_device.cc +++ b/device/vr/oculus/oculus_device.cc
@@ -57,6 +57,7 @@ display_info->capabilities->hasPosition = true; display_info->capabilities->hasExternalDisplay = true; display_info->capabilities->canPresent = true; + display_info->default_framebuffer_scale = 1.0; ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); display_info->leftEye = GetEyeDetails(session, hmdDesc, ovrEye_Left);
diff --git a/device/vr/oculus/oculus_render_loop.cc b/device/vr/oculus/oculus_render_loop.cc index 51e47a2..ff7a6d57 100644 --- a/device/vr/oculus/oculus_render_loop.cc +++ b/device/vr/oculus/oculus_render_loop.cc
@@ -60,6 +60,12 @@ binding_.Close(); } +void OculusRenderLoop::SubmitFrameMissing(int16_t frame_index, + const gpu::SyncToken& sync_token) { + // Nothing to do. It's OK to start the next frame even if the current + // one didn't get sent to the ovrSession. +} + void OculusRenderLoop::SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, base::TimeDelta time_waited) {
diff --git a/device/vr/oculus/oculus_render_loop.h b/device/vr/oculus/oculus_render_loop.h index 47af6a69..613f67c 100644 --- a/device/vr/oculus/oculus_render_loop.h +++ b/device/vr/oculus/oculus_render_loop.h
@@ -36,6 +36,7 @@ base::WeakPtr<OculusRenderLoop> GetWeakPtr(); // VRPresentationProvider overrides: + void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, base::TimeDelta time_waited) override;
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc index 80c1632..21e119c 100644 --- a/device/vr/openvr/openvr_device.cc +++ b/device/vr/openvr/openvr_device.cc
@@ -89,6 +89,7 @@ display_info->capabilities->hasPosition = true; display_info->capabilities->hasExternalDisplay = true; display_info->capabilities->canPresent = true; + display_info->default_framebuffer_scale = 1.0; display_info->leftEye = mojom::VREyeParameters::New(); display_info->rightEye = mojom::VREyeParameters::New();
diff --git a/device/vr/openvr/openvr_render_loop.cc b/device/vr/openvr/openvr_render_loop.cc index ffd928d..443af92 100644 --- a/device/vr/openvr/openvr_render_loop.cc +++ b/device/vr/openvr/openvr_render_loop.cc
@@ -55,6 +55,12 @@ Stop(); } +void OpenVRRenderLoop::SubmitFrameMissing(int16_t frame_index, + const gpu::SyncToken& sync_token) { + // Nothing to do. It's OK to start the next frame even if the current + // one didn't get sent to OpenVR. +} + void OpenVRRenderLoop::SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, base::TimeDelta time_waited) {
diff --git a/device/vr/openvr/openvr_render_loop.h b/device/vr/openvr/openvr_render_loop.h index a29e30f0d..fd16217c 100644 --- a/device/vr/openvr/openvr_render_loop.h +++ b/device/vr/openvr/openvr_render_loop.h
@@ -35,6 +35,7 @@ base::WeakPtr<OpenVRRenderLoop> GetWeakPtr(); // VRPresentationProvider overrides: + void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox, base::TimeDelta time_waited) override;
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index d37b449b..3e933ab1 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -113,6 +113,7 @@ // required for devices which have the canPresent capability. VREyeParameters? leftEye; VREyeParameters? rightEye; + float default_framebuffer_scale = 1.0; }; // Options supplied by the Renderer when requesting presentation. @@ -245,6 +246,16 @@ UpdateLayerBounds(int16 frame_id, gfx.mojom.RectF left_bounds, gfx.mojom.RectF right_bounds, gfx.mojom.Size source_size); + // Call this if the animation loop exited without submitting a frame to + // ensure that every GetVSync has a matching Submit call. This happens for + // WebXR if there were no drawing operations to the opaque framebuffer, and + // for WebVR 1.1 if the application didn't call SubmitFrame. Usable with any + // VRDisplayFrameTransportMethod. This path does *not* call the + // SubmitFrameClient methods such as OnSubmitFrameTransferred. This is + // intended to help separate frames while presenting, it may or may not + // be called for the last animating frame when presentation ends. + SubmitFrameMissing(int16 frame_id, gpu.mojom.SyncToken sync_token); + // VRDisplayFrameTransportMethod SUBMIT_AS_MAILBOX_HOLDER SubmitFrame(int16 frame_id, gpu.mojom.MailboxHolder mailbox_holder, mojo_base.mojom.TimeDelta time_waited);
diff --git a/docs/code_coverage.md b/docs/code_coverage.md index 5f92122..bbc7e8b8 100644 --- a/docs/code_coverage.md +++ b/docs/code_coverage.md
@@ -1,37 +1,151 @@ # Code coverage in Chromium -## Coverage script. -[Coverage script] helps to generate clang source-based code coverage report -locally and make it easy to identify under-covered areas. +Table of contents: +- [Coverage Script](#coverage-script) +- [Workflow](#workflow) + * [Step 0 Download Tooling](#step-0-download-tooling) + * [Step 1 Build](#step-1-build) + * [Step 2 Create Raw Profiles](#step-2-create-raw-profiles) + * [Step 3 Create Indexed Profile](#step-3-create-indexed-profile) + * [Step 4 Create Coverage Reports](#step-4-create-coverage-reports) -Currently, this script supports running on Linux, Mac, iOS and ChromeOS -platforms, and supports displaying code coverage results per directory, per -component and per file. +Chromium uses Clang source-based code coverage, this [documentation] explains +how to use Clang’s source-based coverage features in general. -In order to generate code coverage report, you need to first add -`use_clang_coverage=true` and `is_component_build=false` GN flags to args.gn -file in your build output directory (e.g. out/coverage). +In this doc, we first introduce a code coverage script that can be used to +generate code coverage reports for Chromium code in one command, and then dive +into details to describe the code coverage reports generation workflow. -Existing implementation requires `is_component_build=false` flag -because coverage info for dynamic libraries may be missing and -`is_component_build` is set to true by `is_debug` unless it is explicitly set -to false. +## Coverage Script +The [coverage script] automates the process described below and provides a +one-stop service to generate code coverage reports in just one command. -Example usage: +This script is currently supported on Linux, Mac, iOS and ChromeOS platforms. + +Here is an example usage: + ``` -gn gen out/coverage --args='use_clang_coverage=true is_component_build=false' -gclient runhooks -python tools/code_coverage/coverage.py crypto_unittests url_unittests - -b out/coverage -o out/report -c 'out/coverage/crypto_unittests' - -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' - -f url/ -f crypto/ +$ gn gen out/coverage \ + --args='use_clang_coverage=true is_component_build=false' +$ python tools/code_coverage/coverage.py \ + crypto_unittests url_unittests \ + -b out/coverage -o out/report \ + -c 'out/coverage/crypto_unittests' \ + -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \ + -f url/ -f crypto/ +``` +The command above builds `crypto_unittests` and `url_unittests` targets and then +runs each with the command and arguments specified by the `-c` flag. For +`url_unittests`, it only runs the test `URLParser.PathURL`. The coverage report +is filtered to include only files and sub-directories under `url/` and `crypto/` +directories. + +Aside from automating the process, this script provides additional features to +view code coverage breakdown by directories and by components, for example: + +Directory View: + +![code coverage report directory view] + +Component View: + +![code coverage report component view] + +## Workflow +This section presents the workflow of generating code coverage reports using two +unit test targets in Chromium repo as an example: `crypto_unittests` and +`url_unittests`, and the following diagram shows a step-by-step overview of the +process. + + + +### Step 0 Download Tooling +Generating code coverage reports requires llvm-profdata and llvm-cov tools. +Currently, these two tools are not part of Chromium’s Clang bundle, +[coverage script] downloads and updates them automatically, you can also +download the tools manually ([link]). + +### Step 1 Build +In Chromium, to compile code with coverage enabled, one needs to add +`use_clang_coverage=true` and `is_component_build=false` GN flags to the args.gn +file in the build output directory. Under the hood, they ensure +`-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to the +compiler. + +``` +$ gn gen out/coverage \ + --args='use_clang_coverage=true is_component_build=false' +$ gclient runhooks +$ ninja -C out/coverage crypto_unittests url_unittests ``` -For more options, please refer to the script. +### Step 2 Create Raw Profiles +The next step is to run the instrumented binaries, and when the program exits it +will write a raw profile for each process. Because Chromium runs tests in +multiple processes, and the number of processes spawned can be as many as a few +hundred, which results in the generation of a few hundred gigabytes’ raw +profiles, to limit the number of raw profiles, `%Nm` pattern in +`LLVM_PROFILE_FILE` environment variable is used to run tests in multi-process +mode, where `N` is the number of raw profiles. With `N = 4`, the total size of +the raw profiles are limited to a few gigabytes. + +``` +$ export LLVM_PROFILE_FILE=”out/report/crypto_unittests.%4m.profraw” +$ ./out/coverage/crypto_unittests +$ ls out/report/ +crypto_unittests.3657994905831792357_0.profraw +... +crypto_unittests.3657994905831792357_3.profraw +``` + +### Step 3 Create Indexed Profile +Raw profiles must be indexed before generating code coverage reports, and this +is done using the `merge` command of `llvm-profdata` tool, which merges multiple +raw profiles (.profraw) and index them to create a single profile (.profdata). + +At this point, all the raw profiles can be thrown away because their information +are already contained in the indexed profile. + +``` +$ llvm-profdata merge -o out/report/coverage.profdata \ + out/report/crypto_unittests.3657994905831792357_0.profraw +... +out/report/crypto_unittests.3657994905831792357_3.profraw +out/report/url_unittests.714228855822523802_0.profraw +... +out/report/url_unittests.714228855822523802_3.profraw +$ ls out/report/coverage.profdata +out/report/coverage.profdata +``` + +### Step 4 Create Coverage Reports +Finally, `llvm-cov` is used to render code coverage reports. There are different +report generation modes, and all of them require the indexed profile, all the +built binaries and all the exercised source files to be available. + +For example, following command can be used to generate per-file line-by-line +code coverage report: + +``` +$ llvm-cov show -output-dir=out/report -format=html \ + -instr-profile=out/report/coverage.profdata \ + -object=out/coverage/url_unittests \ + out/coverage/crypto_unittests +``` + +For more information on how to use llvm-cov, please refer to the [guide]. ## Reporting problems - For any breakage report and feature requests, please [file a bug]. -[Coverage script]: https://cs.chromium.org/chromium/src/tools/code_coverage/coverage.py -[file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage \ No newline at end of file +## Mail list +For questions and general discussions, please join [chrome-code-coverage group]. + +[documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html +[coverage script]: https://cs.chromium.org/chromium/src/tools/code_coverage/coverage.py +[code coverage report directory view]: images/code_coverage_directory_view.png +[code coverage report component view]: images/code_coverage_component_view.png +[link]: https://storage.googleapis.com/chromium-browser-clang-staging/ +[guide]: http://llvm.org/docs/CommandGuide/llvm-cov.html +[file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage +[chrome-code-coverage group]: https://groups.google.com/a/google.com/forum/#!forum/chrome-code-coverage \ No newline at end of file
diff --git a/docs/images/code_coverage_component_view.png b/docs/images/code_coverage_component_view.png new file mode 100644 index 0000000..0ee3159 --- /dev/null +++ b/docs/images/code_coverage_component_view.png Binary files differ
diff --git a/docs/images/code_coverage_directory_view.png b/docs/images/code_coverage_directory_view.png new file mode 100644 index 0000000..50ecd88 --- /dev/null +++ b/docs/images/code_coverage_directory_view.png Binary files differ
diff --git a/docs/images/code_coverage_workflow.png b/docs/images/code_coverage_workflow.png new file mode 100644 index 0000000..284be2f --- /dev/null +++ b/docs/images/code_coverage_workflow.png Binary files differ
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc b/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc index a34222f8..b507570 100644 --- a/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc +++ b/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <memory> +#include <tuple> #include <utility> #include "base/command_line.h" @@ -155,7 +156,7 @@ ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - ::std::tr1::get<k>(args).Run(); + std::get<k>(args).Run(); } IN_PROC_BROWSER_TEST_F(BluetoothPrivateApiTest, SetAdapterState) {
diff --git a/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc b/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc index 0444c6c6..c208012 100644 --- a/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc +++ b/extensions/browser/api/bluetooth_socket/bluetooth_socket_apitest.cc
@@ -4,6 +4,7 @@ #include <memory> #include <string> +#include <tuple> #include "base/memory/ref_counted.h" #include "base/run_loop.h" @@ -80,19 +81,19 @@ ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - ::std::tr1::get<k>(args).Run(); + std::get<k>(args).Run(); } ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - ::std::tr1::get<k>(args).Run(p0); + std::get<k>(args).Run(p0); } ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(p0, p1)) { - ::std::tr1::get<k>(args).Run(p0, p1); + std::get<k>(args).Run(p0, p1); } } // namespace
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc index 3b7cd1c..d393885 100644 --- a/extensions/browser/api/cast_channel/cast_channel_api.cc +++ b/extensions/browser/api/cast_channel/cast_channel_api.cc
@@ -19,7 +19,6 @@ #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "components/cast_channel/cast_channel_enum.h" -#include "components/cast_channel/cast_channel_util.h" #include "components/cast_channel/cast_message_util.h" #include "components/cast_channel/cast_socket.h" #include "components/cast_channel/cast_socket_service.h" @@ -111,11 +110,17 @@ } bool IsValidConnectInfoIpAddress(const ConnectInfo& connect_info) { - return cast_channel::IsValidCastIPAddressString(connect_info.ip_address); + // Note: this isn't technically correct since policy or feature might allow + // public IPs, but this code path is no longer used. see TODO below. + net::IPAddress ip_address; + return ip_address.AssignFromIPLiteral(connect_info.ip_address) && + ip_address.IsReserved(); } } // namespace +// TODO(https://crbug.com/752604): Remove unused cast.channel API functions now +// that in-browser Cast discovery has launched in M64. CastChannelAPI::CastChannelAPI(content::BrowserContext* context) : browser_context_(context), cast_socket_service_(cast_channel::CastSocketService::GetInstance()) {
diff --git a/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/extensions/browser/api/cast_channel/cast_channel_apitest.cc index 7bae881b..5e7e35ec 100644 --- a/extensions/browser/api/cast_channel/cast_channel_apitest.cc +++ b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <tuple> + #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" @@ -77,7 +79,7 @@ ACTION_TEMPLATE(InvokeCompletionCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(result)) { - ::std::tr1::get<k>(args).Run(result); + std::get<k>(args).Run(result); } } // namespace
diff --git a/extensions/browser/api/document_scan/document_scan_api_unittest.cc b/extensions/browser/api/document_scan/document_scan_api_unittest.cc index 9a09236..54804a1 100644 --- a/extensions/browser/api/document_scan/document_scan_api_unittest.cc +++ b/extensions/browser/api/document_scan/document_scan_api_unittest.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/document_scan/document_scan_api.h" #include <string> +#include <tuple> #include <vector> #include "extensions/browser/api/document_scan/mock_document_scan_interface.h" @@ -45,11 +46,11 @@ }; ACTION_P2(InvokeListScannersCallback, scanner_list, error) { - ::std::tr1::get<0>(args).Run(scanner_list, error); + std::get<0>(args).Run(scanner_list, error); } ACTION_P3(InvokeScanCallback, data, mime_type, error) { - ::std::tr1::get<3>(args).Run(data, mime_type, error); + std::get<3>(args).Run(data, mime_type, error); } TEST_F(DocumentScanScanFunctionTest, GestureRequired) {
diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc index 6930770..1da1097 100644 --- a/extensions/common/permissions/permissions_data.cc +++ b/extensions/common/permissions/permissions_data.cc
@@ -366,8 +366,42 @@ tab_permissions ? &tab_permissions->scriptable_hosts() : nullptr, error); } -bool PermissionsData::CanCaptureVisiblePage(int tab_id, +bool PermissionsData::CanCaptureVisiblePage(const GURL& document_url, + const Extension* extension, + int tab_id, std::string* error) const { + bool has_active_tab = false; + { + base::AutoLock auto_lock(runtime_lock_); + const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); + has_active_tab = tab_permissions && + tab_permissions->HasAPIPermission(APIPermission::kTab); + } + // We check GetPageAccess() (in addition the the <all_urls> and activeTab + // checks below) for the case of URLs that can be conditionally granted (such + // as file:// URLs or chrome:// URLs for component extensions), and to respect + // policy restrictions, if any. If an extension has <all_urls>, + // GetPageAccess() will still (correctly) return false if, for instance, the + // URL is a file:// URL and the extension does not have file access. + // See https://crbug.com/810220. + if (GetPageAccess(extension, document_url, tab_id, error) != ACCESS_ALLOWED) { + if (!document_url.SchemeIs(content::kChromeUIScheme)) + return false; + + // Most extensions will not have (and cannot get) access to chrome:// URLs + // (which are restricted). However, allowing them to capture these URLs can + // be useful, such as in the case of capturing a screenshot. Allow + // extensions that have been explicitly invoked (and have the activeTab) + // permission to capture chrome:// URLs. + if (has_active_tab) + return true; + + if (error) + *error = manifest_errors::kActiveTabPermissionNotGranted; + + return false; + } + const URLPattern all_urls(URLPattern::SCHEME_ALL, URLPattern::kAllUrlsPattern); @@ -375,15 +409,10 @@ if (active_permissions_unsafe_->explicit_hosts().ContainsPattern(all_urls)) return true; - if (tab_id >= 0) { - const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); - if (tab_permissions && - tab_permissions->HasAPIPermission(APIPermission::kTab)) { - return true; - } - if (error) - *error = manifest_errors::kActiveTabPermissionNotGranted; - return false; + const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); + if (tab_permissions && + tab_permissions->HasAPIPermission(APIPermission::kTab)) { + return true; } if (error)
diff --git a/extensions/common/permissions/permissions_data.h b/extensions/common/permissions/permissions_data.h index 2574928..3967c82 100644 --- a/extensions/common/permissions/permissions_data.h +++ b/extensions/common/permissions/permissions_data.h
@@ -212,10 +212,16 @@ std::string* error) const; // Returns true if extension is allowed to obtain the contents of a page as - // an image. Since a page may contain sensitive information, this is - // restricted to the extension's host permissions as well as the extension - // page itself. - bool CanCaptureVisiblePage(int tab_id, std::string* error) const; + // an image. Pages may contain multiple sources (e.g., example.com may embed + // google.com), so simply checking the top-frame's URL is insufficient. + // Instead: + // - If the page is a chrome:// page, require activeTab. + // - For all other pages, require host permissions to the document + // (GetPageAccess()) and one of either <all_urls> or granted activeTab. + bool CanCaptureVisiblePage(const GURL& document_url, + const Extension* extension, + int tab_id, + std::string* error) const; const TabPermissionsMap& tab_specific_permissions() const { DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread());
diff --git a/extensions/shell/browser/shell_special_storage_policy.cc b/extensions/shell/browser/shell_special_storage_policy.cc index 65cc2db..5938910d 100644 --- a/extensions/shell/browser/shell_special_storage_policy.cc +++ b/extensions/shell/browser/shell_special_storage_policy.cc
@@ -4,6 +4,9 @@ #include "extensions/shell/browser/shell_special_storage_policy.h" +#include "base/bind.h" +#include "base/callback.h" + namespace extensions { ShellSpecialStoragePolicy::ShellSpecialStoragePolicy() { @@ -30,12 +33,13 @@ return false; } -bool ShellSpecialStoragePolicy::ShouldDeleteCookieOnExit(const GURL& origin) { +bool ShellSpecialStoragePolicy::HasSessionOnlyOrigins() { return false; } -bool ShellSpecialStoragePolicy::HasSessionOnlyOrigins() { - return false; +storage::SpecialStoragePolicy::DeleteCookiePredicate +ShellSpecialStoragePolicy::CreateDeleteCookieOnExitPredicate() { + return DeleteCookiePredicate(); } bool ShellSpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) {
diff --git a/extensions/shell/browser/shell_special_storage_policy.h b/extensions/shell/browser/shell_special_storage_policy.h index 221344b..7421764 100644 --- a/extensions/shell/browser/shell_special_storage_policy.h +++ b/extensions/shell/browser/shell_special_storage_policy.h
@@ -20,9 +20,9 @@ bool IsStorageUnlimited(const GURL& origin) override; bool IsStorageDurable(const GURL& origin) override; bool IsStorageSessionOnly(const GURL& origin) override; - bool ShouldDeleteCookieOnExit(const GURL& origin) override; bool HasIsolatedStorage(const GURL& origin) override; bool HasSessionOnlyOrigins() override; + DeleteCookiePredicate CreateDeleteCookieOnExitPredicate() override; protected: ~ShellSpecialStoragePolicy() override;
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index a0fef937..5f7d075 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -603,4 +603,9 @@ ContextType GLManager::GetContextType() const { return context_type_; } + +void GLManager::Reset() { + Destroy(); + SetupBaseContext(); +} } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h index f0e2283..7ea0a3f 100644 --- a/gpu/command_buffer/tests/gl_manager.h +++ b/gpu/command_buffer/tests/gl_manager.h
@@ -163,6 +163,8 @@ size_t GetSharedMemoryBytesAllocated() const; ContextType GetContextType() const; + void Reset(); + private: void SetupBaseContext();
diff --git a/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc b/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc index 82bd266f..d1a38861 100644 --- a/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc +++ b/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc
@@ -33,6 +33,7 @@ // If the gl_real context is not initialised, switch to ES2 context type // and re-initialise if (!gl_real_.IsInitialized()) { + gl_real_.Reset(); // Must reset object before initializing again options.context_type = CONTEXT_TYPE_OPENGLES2; gl_real_.InitializeWithWorkarounds(options, workarounds); }
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index 80eb4fc..e5c6213 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -2880,6 +2880,23 @@ "GL_EXT_disjoint_timer_query", "GL_EXT_disjoint_timer_query_webgl2" ] + }, + { + "id": 266, + "cr_bugs": [828721], + "description": "Crash in gl::GLApiBase::glGetQueryObjectui64vFn with NetEase devices ", + "os": { + "type": "android" + }, + "gl_vendor": "NetEase", + "gl_renderer": "MuMu GL.*", + "features": [ + "disable_timestamp_queries" + ], + "disabled_extensions": [ + "GL_EXT_disjoint_timer_query", + "GL_EXT_disjoint_timer_query_webgl2" + ] } ] }
diff --git a/gpu/ipc/host/shader_disk_cache_unittest.cc b/gpu/ipc/host/shader_disk_cache_unittest.cc index 323a563..1e429ee1 100644 --- a/gpu/ipc/host/shader_disk_cache_unittest.cc +++ b/gpu/ipc/host/shader_disk_cache_unittest.cc
@@ -35,7 +35,14 @@ ShaderCacheFactory* factory() { return &factory_; } private: - void TearDown() override { factory_.RemoveCacheInfo(kDefaultClientId); } + void TearDown() override { + factory_.RemoveCacheInfo(kDefaultClientId); + + // Run all pending tasks before destroying ScopedTaskEnvironment. Otherwise, + // SimpleEntryImpl instances bound to pending tasks are destroyed in an + // incorrect state (see |state_| DCHECK in ~SimpleEntryImpl). + scoped_task_environment_.RunUntilIdle(); + } base::test::ScopedTaskEnvironment scoped_task_environment_; base::ScopedTempDir temp_dir_;
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index 9b009bb..bd32f269 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -805,6 +805,7 @@ Microsoft::WRL::ComPtr<IDXGIFactoryMedia> media_factory; dxgi_factory.CopyTo(media_factory.GetAddressOf()); DXGI_SWAP_CHAIN_DESC1 desc = {}; + DCHECK(!swap_chain_size_.IsEmpty()); desc.Width = swap_chain_size_.width(); desc.Height = swap_chain_size_.height(); desc.Format = DXGI_FORMAT_YUY2; @@ -1063,8 +1064,11 @@ } bool DCLayerTree::ScheduleDCLayer(const ui::DCRendererLayerParams& params) { - pending_overlays_.push_back( - std::make_unique<ui::DCRendererLayerParams>(params)); + // Skip work for zero-sized layers. + if (!params.rect.IsEmpty()) { + pending_overlays_.push_back( + std::make_unique<ui::DCRendererLayerParams>(params)); + } return true; }
diff --git a/headless/public/util/virtual_time_controller_test.cc b/headless/public/util/virtual_time_controller_test.cc index 769dbf44..6f4eac7 100644 --- a/headless/public/util/virtual_time_controller_test.cc +++ b/headless/public/util/virtual_time_controller_test.cc
@@ -5,6 +5,7 @@ #include "headless/public/util/virtual_time_controller.h" #include <memory> +#include <tuple> #include "base/bind.h" #include "base/memory/ref_counted.h" @@ -196,7 +197,7 @@ ACTION_TEMPLATE(RunClosure, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - ::std::tr1::get<k>(args).Run(); + std::get<k>(args).Run(); } ACTION_P(RunClosure, closure) {
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index 3f32624..d176720 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -13,7 +13,7 @@ } acls { role: OWNER - granted_to: "group:project-chromium-committers" + granted_to: "group:project-chromium-admins" } } @@ -35,7 +35,7 @@ } acls { role: OWNER - granted_to: "group:project-chromium-committers" + granted_to: "group:project-chromium-admins" } }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 247a543..b83aab6 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1454,6 +1454,9 @@ <message name="IDS_IOS_TAB_GRID_CLOSE_ALL_BUTTON" desc="Title of the button in the tab grid UI that closes all the tabs in the grid. [iOS only]"> Close All </message> + <message name="IDS_IOS_TAB_GRID_UNDO_CLOSE_ALL_BUTTON" desc="Title of the button in the tab grid UI that revert the close all action recently taken by the user. [iOS only]"> + Undo + </message> <message name="IDS_IOS_TAB_GRID_INCOGNITO_TABS_TITLE" desc="The accessibility label of the Incognito Tabs page in the tab grid UI. [iOS only]"> Incognito Tabs </message>
diff --git a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb index c16c9c5..d1c212dc 100644 --- a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
@@ -159,6 +159,7 @@ <translation id="3789841737615482174">Install</translation> <translation id="385051799172605136">Back</translation> <translation id="3897092660631435901">Menu</translation> +<translation id="3915450441834151894">Site Information</translation> <translation id="3928666092801078803">Combine my data</translation> <translation id="3950820424414687140">Sign in</translation> <translation id="3963231839620026525">New Incognito Tab</translation> @@ -222,6 +223,7 @@ <translation id="5197255632782567636">Internet</translation> <translation id="5228579091201413441">Enable sync</translation> <translation id="5244474230056479698">Syncing to <ph name="EMAIL" /></translation> +<translation id="527973086555161537">Open a tab to browse the web privately.</translation> <translation id="5300589172476337783">Show</translation> <translation id="5317780077021120954">Save</translation> <translation id="5327248766486351172">Name</translation> @@ -301,6 +303,7 @@ <translation id="6445981559479772097">Message sent.</translation> <translation id="6464071786529933911">Open in New Incognito Tab</translation> <translation id="6482629121755362506"><ph name="NUMBER_OF_SELECTED_BOOKMARKS" /> items deleted</translation> +<translation id="6528048372317642110">File download is available</translation> <translation id="6541915733953096570">Past Hour</translation> <translation id="6570040839871198836">Autofill Forms</translation> <translation id="6656103420185847513">Edit Folder</translation> @@ -397,6 +400,7 @@ <translation id="8532105204136943229">Year of Expiry</translation> <translation id="8534481786647257214">Google+ post completed.</translation> <translation id="8548878600947630424">Find in page...</translation> +<translation id="8563611504944539039">Download successfully finished</translation> <translation id="8605219856220328675">Close tab.</translation> <translation id="8620640915598389714">Edit</translation> <translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation>
diff --git a/ios/chrome/browser/store_kit/BUILD.gn b/ios/chrome/browser/store_kit/BUILD.gn index 7cca5ed..6aefca1 100644 --- a/ios/chrome/browser/store_kit/BUILD.gn +++ b/ios/chrome/browser/store_kit/BUILD.gn
@@ -33,6 +33,7 @@ ":store_kit", "//base", "//ios/chrome/test:test_support", + "//ios/chrome/test/fakes", "//ios/testing:ios_test_support", "//ios/web", "//ios/web/public/test",
diff --git a/ios/chrome/browser/store_kit/OWNERS b/ios/chrome/browser/store_kit/OWNERS index 241c424..2832ead6 100644 --- a/ios/chrome/browser/store_kit/OWNERS +++ b/ios/chrome/browser/store_kit/OWNERS
@@ -1,4 +1,5 @@ pkl@chromium.org +mrefaat@chromium.org # TEAM: ios-directory-owners@chromium.org # OS: iOS
diff --git a/ios/chrome/browser/store_kit/store_kit_coordinator.mm b/ios/chrome/browser/store_kit/store_kit_coordinator.mm index 3c6628e..6adf6a8 100644 --- a/ios/chrome/browser/store_kit/store_kit_coordinator.mm +++ b/ios/chrome/browser/store_kit/store_kit_coordinator.mm
@@ -26,7 +26,9 @@ - (void)start { DCHECK(self.iTunesProductParameters [SKStoreProductParameterITunesItemIdentifier]); - DCHECK(!_viewController); + // StoreKit shouldn't be launched, if there is one already presented. + if (_viewController) + return; _viewController = [[SKStoreProductViewController alloc] init]; _viewController.delegate = self; [_viewController loadProductWithParameters:self.iTunesProductParameters @@ -37,7 +39,7 @@ } - (void)stop { - [_viewController dismissViewControllerAnimated:YES completion:nil]; + [self.baseViewController dismissViewControllerAnimated:YES completion:nil]; _viewController = nil; }
diff --git a/ios/chrome/browser/store_kit/store_kit_coordinator_unittest.mm b/ios/chrome/browser/store_kit/store_kit_coordinator_unittest.mm index 42cb83e..3017ade 100644 --- a/ios/chrome/browser/store_kit/store_kit_coordinator_unittest.mm +++ b/ios/chrome/browser/store_kit/store_kit_coordinator_unittest.mm
@@ -6,8 +6,8 @@ #import <StoreKit/StoreKit.h> +#import "ios/chrome/test/fakes/fake_ui_view_controller.h" #import "ios/chrome/test/scoped_key_window.h" -#import "ios/testing/wait_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -16,20 +16,17 @@ #error "This file requires ARC support." #endif -using testing::WaitUntilConditionOrTimeout; -using testing::kWaitForUIElementTimeout; - // Test fixture for StoreKitCoordinator class. class StoreKitCoordinatorTest : public PlatformTest { protected: StoreKitCoordinatorTest() - : base_view_controller_([[UIViewController alloc] init]), + : base_view_controller_([[FakeUIViewController alloc] init]), coordinator_([[StoreKitCoordinator alloc] initWithBaseViewController:base_view_controller_]) { [scoped_key_window_.Get() setRootViewController:base_view_controller_]; } - UIViewController* base_view_controller_; + FakeUIViewController* base_view_controller_; StoreKitCoordinator* coordinator_; ScopedKeyWindow scoped_key_window_; }; @@ -44,16 +41,11 @@ [coordinator_ openAppStoreWithParameters:product_params]; EXPECT_NSEQ(product_params, coordinator_.iTunesProductParameters); - EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ - return [base_view_controller_.presentedViewController class] == - [SKStoreProductViewController class]; - })); - + EXPECT_NSEQ([SKStoreProductViewController class], + [base_view_controller_.presentedViewController class]); [coordinator_ stop]; - EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ - return base_view_controller_.presentedViewController == nil; - })); + EXPECT_FALSE(base_view_controller_.presentedViewController); } // Tests that StoreKitCoordinator presents SKStoreProductViewController when @@ -66,14 +58,42 @@ [coordinator_ openAppStore:kTestITunesItemIdentifier]; EXPECT_NSEQ(product_params, coordinator_.iTunesProductParameters); - EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ - return [base_view_controller_.presentedViewController class] == - [SKStoreProductViewController class]; - })); + EXPECT_NSEQ([SKStoreProductViewController class], + [base_view_controller_.presentedViewController class]); [coordinator_ stop]; - EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ - return base_view_controller_.presentedViewController == nil; - })); + EXPECT_FALSE(base_view_controller_.presentedViewController); +} + +// Tests that when there is a SKStoreProductViewController presented, starting +// the coordinator doesn't present new view controller. +TEST_F(StoreKitCoordinatorTest, NoOverlappingPresentedViewControllers) { + NSString* kTestITunesItemIdentifier = @"TestITunesItemIdentifier"; + coordinator_.iTunesProductParameters = @{ + SKStoreProductParameterITunesItemIdentifier : kTestITunesItemIdentifier, + }; + [coordinator_ start]; + + EXPECT_NSEQ([SKStoreProductViewController class], + [base_view_controller_.presentedViewController class]); + + UIViewController* presented_controller = + base_view_controller_.presentedViewController; + + [coordinator_ start]; + // Verify that that presented view controlled is not changed. + EXPECT_NSEQ(presented_controller, + base_view_controller_.presentedViewController); + + [coordinator_ stop]; + EXPECT_FALSE(base_view_controller_.presentedViewController); + + [coordinator_ start]; + // After reseting the view controller, a new storekit view should be + // presented. + EXPECT_NSEQ([SKStoreProductViewController class], + [base_view_controller_.presentedViewController class]); + EXPECT_NSNE(presented_controller, + base_view_controller_.presentedViewController); }
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn index 374093b..00dba3d 100644 --- a/ios/chrome/browser/ui/authentication/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -31,6 +31,7 @@ ] deps = [ ":authentication_ui", + "resources:identity_picker_view_arrow_down", "resources:signin_confirmation_more", "resources:signin_promo_close_gray", "//base",
diff --git a/ios/chrome/browser/ui/authentication/identity_picker_view.h b/ios/chrome/browser/ui/authentication/identity_picker_view.h new file mode 100644 index 0000000..e28f89b --- /dev/null +++ b/ios/chrome/browser/ui/authentication/identity_picker_view.h
@@ -0,0 +1,31 @@ +// Copyright 2018 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 IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_ +#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_ + +#import <UIKit/UIKit.h> + +// Displays the name, email and avatar of a chrome identity, as a control. +// An down arrow is also displayed on the right of the control, to invite the +// user to tap and select another chrome identity. To get the tap event, see: +// -[UIControl addTarget:action:forControlEvents:]. +@interface IdentityPickerView : UIControl + +// Initialises IdentityPickerView. +- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER; + +// See -[IdentityPickerView initWithFrame:]. +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; + +// Set the identity avatar shown. +- (void)setIdentityAvatar:(UIImage*)identityAvatar; + +// Set the name and email shown. |name| can be nil. +- (void)setIdentityName:(NSString*)name email:(NSString*)email; + +@end + +#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_
diff --git a/ios/chrome/browser/ui/authentication/identity_picker_view.mm b/ios/chrome/browser/ui/authentication/identity_picker_view.mm new file mode 100644 index 0000000..cac09827 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/identity_picker_view.mm
@@ -0,0 +1,195 @@ +// Copyright 2018 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. + +#import "ios/chrome/browser/ui/authentication/identity_picker_view.h" + +#include "base/logging.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" +#import "ios/chrome/browser/ui/util/constraints_ui_util.h" +#import "ios/third_party/material_components_ios/src/components/Ink/src/MaterialInk.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +const CGFloat kIdentityPickerViewRadius = 8.; +// Sizes. +const CGFloat kIdentityAvatarSize = 40.; +const CGFloat kTitleFontSize = 14.; +const CGFloat kSubtitleFontSize = 12.; +const CGFloat kArrowDownSize = 24.; +// Distances/margins. +const CGFloat kTitleOffset = 2; +const CGFloat kArrowDownMargin = 12.; +const CGFloat kHorizontalAvatarMargin = 16.; +const CGFloat kVerticalMargin = 12.; +// Colors +const CGFloat kTitleTextColorAlpha = .87; +const CGFloat kSubtitleTextColorAlpha = .54; + +} // namespace + +@interface IdentityPickerView () + +@property(nonatomic) UIImageView* avatarImageView; +@property(nonatomic) UILabel* title; +@property(nonatomic) UILabel* subtitle; +@property(nonatomic) MDCInkView* inkView; +@property(nonatomic) NSLayoutConstraint* titleConstraintForNameAndEmail; +@property(nonatomic) NSLayoutConstraint* titleConstraintForEmailOnly; + +@end + +@implementation IdentityPickerView + +@synthesize avatarImageView = _avatarImageView; +@synthesize title = _title; +@synthesize subtitle = _subtitle; +@synthesize inkView = _inkView; +// Constraints when email and name are available. +@synthesize titleConstraintForNameAndEmail = _titleConstraintForNameAndEmail; +// Constraints when only the email is avaiable. +@synthesize titleConstraintForEmailOnly = _titleConstraintForEmailOnly; + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.layer.cornerRadius = kIdentityPickerViewRadius; + self.backgroundColor = [UIColor colorWithRed:241. / 255. + green:243. / 255. + blue:244. / 255. + alpha:1.]; + // Adding view elements inside. + // Ink view. + _inkView = [[MDCInkView alloc] initWithFrame:CGRectZero]; + _inkView.layer.cornerRadius = kIdentityPickerViewRadius; + _inkView.inkStyle = MDCInkStyleBounded; + _inkView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:_inkView]; + + // Avatar view. + _avatarImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; + _avatarImageView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:_avatarImageView]; + + // Arrow down. + UIImageView* arrowDownImageView = + [[UIImageView alloc] initWithFrame:CGRectZero]; + arrowDownImageView.translatesAutoresizingMaskIntoConstraints = NO; + arrowDownImageView.image = + [UIImage imageNamed:@"identity_picker_view_arrow_down"]; + [self addSubview:arrowDownImageView]; + + // Title. + _title = [[UILabel alloc] initWithFrame:CGRectZero]; + _title.translatesAutoresizingMaskIntoConstraints = NO; + _title.textColor = [UIColor colorWithWhite:0 alpha:kTitleTextColorAlpha]; + _title.font = [UIFont systemFontOfSize:kTitleFontSize]; + [self addSubview:_title]; + + // Subtitle. + _subtitle = [[UILabel alloc] initWithFrame:CGRectZero]; + _subtitle.translatesAutoresizingMaskIntoConstraints = NO; + _subtitle.textColor = + [UIColor colorWithWhite:0 alpha:kSubtitleTextColorAlpha]; + _subtitle.font = [UIFont systemFontOfSize:kSubtitleFontSize]; + [self addSubview:_subtitle]; + + // Layout constraints. + NSDictionary* views = @{ + @"avatar" : _avatarImageView, + @"title" : _title, + @"subtitle" : _subtitle, + @"arrow" : arrowDownImageView, + }; + NSDictionary* metrics = @{ + @"ArMrg" : @(kArrowDownMargin), + @"ArrowSize" : @(kArrowDownSize), + @"AvatarSize" : @(kIdentityAvatarSize), + @"HAvatMrg" : @(kHorizontalAvatarMargin), + @"VMargin" : @(kVerticalMargin), + }; + NSArray* constraints = @[ + // Horizontal constraints. + @"H:|-(HAvatMrg)-[avatar]-(HAvatMrg)-[title]-(ArMrg)-[arrow]-(ArMrg)-|", + // Vertical constraints. + @"V:|-(>=VMargin)-[avatar]-(>=VMargin)-|", + @"V:|-(>=VMargin)-[title]", + @"V:[subtitle]-(>=VMargin)-|", + // Size constraints. + @"H:[avatar(AvatarSize)]", + @"V:[avatar(AvatarSize)]", + @"H:[arrow(ArrowSize)]", + @"V:[arrow(ArrowSize)]", + ]; + AddSameCenterYConstraint(self, _avatarImageView); + AddSameCenterYConstraint(self, arrowDownImageView); + ApplyVisualConstraintsWithMetrics(constraints, views, metrics); + AddSameConstraintsToSides(_title, _subtitle, + LayoutSides::kLeading | LayoutSides::kTrailing); + _titleConstraintForNameAndEmail = + [self.centerYAnchor constraintEqualToAnchor:_title.bottomAnchor + constant:kTitleOffset]; + _titleConstraintForEmailOnly = + [self.centerYAnchor constraintEqualToAnchor:_title.centerYAnchor]; + [self.centerYAnchor constraintEqualToAnchor:_subtitle.topAnchor + constant:-kTitleOffset] + .active = YES; + } + return self; +} + +#pragma mark - Setter + +- (void)setIdentityAvatar:(UIImage*)identityAvatar { + _avatarImageView.image = + CircularImageFromImage(identityAvatar, kIdentityAvatarSize); +} + +- (void)setIdentityName:(NSString*)name email:(NSString*)email { + DCHECK(email); + if (!name || name.length == 0) { + self.titleConstraintForNameAndEmail.active = NO; + self.titleConstraintForEmailOnly.active = YES; + self.subtitle.hidden = YES; + self.title.text = email; + } else { + self.titleConstraintForEmailOnly.active = NO; + self.titleConstraintForNameAndEmail.active = YES; + self.subtitle.hidden = NO; + self.title.text = name; + self.subtitle.text = email; + } +} + +#pragma mark - Private + +- (CGPoint)locationFromTouches:(NSSet*)touches { + UITouch* touch = [touches anyObject]; + return [touch locationInView:self]; +} + +#pragma mark - UIResponder + +- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { + [super touchesBegan:touches withEvent:event]; + CGPoint location = [self locationFromTouches:touches]; + [self.inkView startTouchBeganAnimationAtPoint:location completion:nil]; +} + +- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { + [super touchesEnded:touches withEvent:event]; + CGPoint location = [self locationFromTouches:touches]; + [self.inkView startTouchEndedAnimationAtPoint:location completion:nil]; +} + +- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { + [super touchesCancelled:touches withEvent:event]; + CGPoint location = [self locationFromTouches:touches]; + [self.inkView startTouchEndedAnimationAtPoint:location completion:nil]; +} + +@end
diff --git a/ios/chrome/browser/ui/authentication/resources/BUILD.gn b/ios/chrome/browser/ui/authentication/resources/BUILD.gn index 02a9899..b5c7d333 100644 --- a/ios/chrome/browser/ui/authentication/resources/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/resources/BUILD.gn
@@ -4,6 +4,14 @@ import("//build/config/ios/asset_catalog.gni") +imageset("identity_picker_view_arrow_down") { + sources = [ + "identity_picker_view_arrow_down.imageset/Contents.json", + "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png", + "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png", + "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png", + ] +} imageset("signin_confirmation_more") { sources = [ "signin_confirmation_more.imageset/Contents.json",
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/Contents.json b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/Contents.json new file mode 100644 index 0000000..50f41f9f7 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/Contents.json
@@ -0,0 +1,23 @@ +{ + "images": [ + { + "idiom": "universal", + "scale": "1x", + "filename": "identity_picker_view_arrow_down.png" + }, + { + "idiom": "universal", + "scale": "2x", + "filename": "identity_picker_view_arrow_down@2x.png" + }, + { + "idiom": "universal", + "scale": "3x", + "filename": "identity_picker_view_arrow_down@3x.png" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +}
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png new file mode 100644 index 0000000..75275c2a --- /dev/null +++ b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png Binary files differ
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png new file mode 100644 index 0000000..8246f2d --- /dev/null +++ b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png new file mode 100644 index 0000000..bd4987c --- /dev/null +++ b/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index 129d53b..a19c142 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -35,6 +35,7 @@ const CGFloat kMaxCardWidth = 416; const CGFloat kStandardSpacing = 8; const CGFloat kMostVisitedBottomMargin = 13; +const CGFloat kCardBorderRadius = 11; // Returns whether the cells should be displayed using the full width. BOOL ShouldCellsBeFullWidth(UITraitCollection* collection) { @@ -232,6 +233,8 @@ self.styler.cellStyle = MDCCollectionViewCellStyleGrouped; } else { self.styler.cellStyle = MDCCollectionViewCellStyleCard; + if (IsUIRefreshPhase1Enabled()) + self.styler.cardBorderRadius = kCardBorderRadius; } self.automaticallyAdjustsScrollViewInsets = NO; self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn index cd52815..61f6b999 100644 --- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -12,6 +12,7 @@ ] deps = [ ":recent_tabs_ui", + "resources:show_history", "//base", "//components/browser_sync", "//components/sessions",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index a5b5fb14..4176023 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -192,7 +192,7 @@ TableViewURLItem* historyItem = [[TableViewURLItem alloc] initWithType:ItemTypeShowFullHistory]; historyItem.title = l10n_util::GetNSString(IDS_HISTORY_SHOWFULLHISTORY_LINK); - historyItem.favicon = [UIImage imageNamed:@"ntp_opentabs_clock"]; + historyItem.favicon = [UIImage imageNamed:@"show_history"]; [model addItem:historyItem toSectionWithIdentifier:SectionIdentifierRecentlyClosedTabs]; }
diff --git a/ios/chrome/browser/ui/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/BUILD.gn index f1b4ce0f..a617175 100644 --- a/ios/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/BUILD.gn
@@ -115,6 +115,7 @@ deps = [ ":tab_grid_ui", + "grid:grid_ui", "//base", "//ios/chrome/app/strings", "//ios/chrome/browser/ui/tools_menu/public", @@ -134,19 +135,8 @@ ] deps = [ - ":tab_grid_ui", - "grid:grid_ui", - "//base", - "//components/strings", - "//ios/chrome/app:app_internal", - "//ios/chrome/app/strings", - "//ios/chrome/browser/ui:ui_util", - "//ios/chrome/browser/ui/util", - "//ios/chrome/test/app:test_support", + ":egtest_support", "//ios/chrome/test/earl_grey:test_support", - "//ios/testing/earl_grey:earl_grey_support", - "//ios/web:earl_grey_test_support", - "//ui/base", ] libs = [ "XCTest.framework" ] }
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h index bf72b9c..f5a37cc 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h
@@ -13,6 +13,7 @@ extern NSString* const kTabGridRemoteTabsPageButtonIdentifier; extern NSString* const kTabGridDoneButtonIdentifier; extern NSString* const kTabGridCloseAllButtonIdentifier; +extern NSString* const kTabGridUndoCloseAllButtonIdentifier; extern NSString* const kTabGridIncognitoTabsEmptyStateIdentifier; extern NSString* const kTabGridRegularTabsEmptyStateIdentifier;
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm index 4ab254c..0b24f29b 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm
@@ -18,6 +18,8 @@ NSString* const kTabGridDoneButtonIdentifier = @"TabGridDoneButtonIdentifier"; NSString* const kTabGridCloseAllButtonIdentifier = @"TabGridCloseAllButtonIdentifier"; +NSString* const kTabGridUndoCloseAllButtonIdentifier = + @"TabGridUndoCloseAllButtonIdentifier"; NSString* const kTabGridIncognitoTabsEmptyStateIdentifier = @"TabGridIncognitoTabsEmptyStateIdentifier"; NSString* const kTabGridRegularTabsEmptyStateIdentifier =
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm index 78e402cd8..2ce19d5 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm
@@ -2,11 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/tab_grid/grid/grid_constants.h" -#import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" -#import "ios/chrome/test/app/chrome_test_util.h" +#import "ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" -#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" @@ -14,48 +11,6 @@ #error "This file requires ARC support." #endif -namespace { - -// Identifer for cell at given |index|. -NSString* IdentifierForCellAtIndex(unsigned int index) { - return [NSString stringWithFormat:@"%@%u", kGridCellIdentifierPrefix, index]; -} - -// Matcher for cell at |index|. -id<GREYMatcher> CellAtIndex(unsigned int index) { - return grey_allOf(grey_accessibilityID(IdentifierForCellAtIndex(index)), - grey_sufficientlyVisible(), nil); -} - -// Matcher for close button for cell at |index|. -id<GREYMatcher> CloseButtonForCellAtIndex(unsigned int index) { - return grey_allOf( - grey_ancestor(grey_accessibilityID(IdentifierForCellAtIndex(index))), - grey_accessibilityID(kGridCellCloseButtonIdentifier), - grey_sufficientlyVisible(), nil); -} - -// Matcher for the Done button in the tab grid. -id<GREYMatcher> DoneButton() { - return grey_allOf(grey_accessibilityID(kTabGridDoneButtonIdentifier), - grey_sufficientlyVisible(), nil); -} - -// Matcher for the Close All button in the tab grid. -id<GREYMatcher> CloseAllButton() { - return grey_allOf(grey_accessibilityID(kTabGridCloseAllButtonIdentifier), - grey_sufficientlyVisible(), nil); -} - -// Matcher for the regular tabs empty state view. -id<GREYMatcher> RegularTabsEmptyStateView() { - return grey_allOf( - grey_accessibilityID(kTabGridRegularTabsEmptyStateIdentifier), - grey_sufficientlyVisible(), nil); -} - -} // namespace - @interface TabGridTestCase : ChromeTestCase @end @@ -65,14 +20,16 @@ - (void)testEnteringAndLeavingTabGrid { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:DoneButton()] performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()] + performAction:grey_tap()]; } // Tests that tapping on the first cell shows that tab. - (void)testTappingOnFirstCell { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:CellAtIndex(0)] performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] + performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] assertWithMatcher:grey_sufficientlyVisible()]; } @@ -81,23 +38,65 @@ - (void)testClosingFirstCell { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:CloseButtonForCellAtIndex(0)] + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + TabGridCloseButtonForCellAtIndex(0)] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:CellAtIndex(0)] + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] assertWithMatcher:grey_nil()]; - [[EarlGrey selectElementWithMatcher:RegularTabsEmptyStateView()] + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + TabGridRegularTabsEmptyStateView()] assertWithMatcher:grey_sufficientlyVisible()]; } -// Tests that tapping Close All shows no tabs, and displays the empty state. -- (void)testShowingEmptyStateOnCloseAll { +// Tests that tapping Close All shows no tabs, shows Undo button, and displays +// the empty state. Then tests tapping Undo shows Close All button again. +- (void)testCloseAllAndUndoCloseAll { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:CloseAllButton()] + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:CellAtIndex(0)] + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] assertWithMatcher:grey_nil()]; - [[EarlGrey selectElementWithMatcher:RegularTabsEmptyStateView()] + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + TabGridRegularTabsEmptyStateView()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()] + performAction:grey_tap()]; + // TODO(crbug.com/804567) : Implement Undo Close All and replace this alert + // check with tabs that have been previously closed. + [[EarlGrey selectElementWithMatcher:grey_text(@"OK")] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +// Tests that the Undo button is no longer available after tapping Close All, +// then creating a new tab, then coming back to the tab grid. +- (void)testUndoCloseAllNotAvailableAfterNewTabCreation { + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()] + performAction:grey_tap()]; + // Undo is available after close all action. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + // Create a new tab then come back to tab grid. + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridNewTabButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + // Undo is no longer available. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()] assertWithMatcher:grey_sufficientlyVisible()]; }
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h index fc6ddb4..ea8e249 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h
@@ -15,6 +15,17 @@ // Returns the GREYMatcher for the button that closes the tab grid. id<GREYMatcher> TabGridDoneButton(); +// Returns the GREYMatcher for the button that closes all the tabs in the tab +// grid. +id<GREYMatcher> TabGridCloseAllButton(); + +// Returns the GREYMatcher for the button that reverts the close all tabs action +// in the tab grid. +id<GREYMatcher> TabGridUndoCloseAllButton(); + +// Returns the GREYMatcher for the regular tabs empty state view. +id<GREYMatcher> TabGridRegularTabsEmptyStateView(); + // Returns the GREYMatcher for the button that creates new non incognito tabs // from within the tab grid. id<GREYMatcher> TabGridNewTabButton(); @@ -35,6 +46,13 @@ // the tab grid. id<GREYMatcher> TabGridOtherDevicesPanelButton(); +// Returns the GREYMatcher for the cell at |index| in the tab grid. +id<GREYMatcher> TabGridCellAtIndex(unsigned int index); + +// Returns the GREYMatcher for the button to close the cell at |index| in the +// tab grid. +id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index); + } // namespace chrome_test_util #endif // IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_EGTEST_UTIL_H_
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm index 66730641..d44c6a2f 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm
@@ -6,6 +6,7 @@ #import <EarlGrey/EarlGrey.h> +#import "ios/chrome/browser/ui/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_constants.h" #include "ios/chrome/grit/ios_strings.h" @@ -17,6 +18,13 @@ #error "This file requires ARC support." #endif +namespace { +// Identifer for cell at given |index| in the tab grid. +NSString* IdentifierForCellAtIndex(unsigned int index) { + return [NSString stringWithFormat:@"%@%u", kGridCellIdentifierPrefix, index]; +} +} // namespace + namespace chrome_test_util { id<GREYMatcher> TabGridOpenButton() { @@ -28,6 +36,22 @@ grey_sufficientlyVisible(), nil); } +id<GREYMatcher> TabGridCloseAllButton() { + return grey_allOf(grey_accessibilityID(kTabGridCloseAllButtonIdentifier), + grey_sufficientlyVisible(), nil); +} + +id<GREYMatcher> TabGridUndoCloseAllButton() { + return grey_allOf(grey_accessibilityID(kTabGridUndoCloseAllButtonIdentifier), + grey_sufficientlyVisible(), nil); +} + +id<GREYMatcher> TabGridRegularTabsEmptyStateView() { + return grey_allOf( + grey_accessibilityID(kTabGridRegularTabsEmptyStateIdentifier), + grey_sufficientlyVisible(), nil); +} + id<GREYMatcher> TabGridNewTabButton() { return grey_allOf( ButtonWithAccessibilityLabelId(IDS_IOS_TAB_GRID_CREATE_NEW_TAB), @@ -52,4 +76,16 @@ return grey_accessibilityID(kTabGridRemoteTabsPageButtonIdentifier); } +id<GREYMatcher> TabGridCellAtIndex(unsigned int index) { + return grey_allOf(grey_accessibilityID(IdentifierForCellAtIndex(index)), + grey_sufficientlyVisible(), nil); +} + +id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index) { + return grey_allOf( + grey_ancestor(grey_accessibilityID(IdentifierForCellAtIndex(index))), + grey_accessibilityID(kGridCellCloseButtonIdentifier), + grey_sufficientlyVisible(), nil); +} + } // namespace chrome_test_util
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index d6e3b78..0965252 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -37,6 +37,18 @@ float fractionalPage = scrollView.contentOffset.x / pageWidth; return static_cast<TabGridPage>(lround(fractionalPage)); } + +// Temporary alert used while building this feature. +UIAlertController* NotImplementedAlert() { + UIAlertController* alert = + [UIAlertController alertControllerWithTitle:@"Not implemented" + message:nil + preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleCancel + handler:nil]]; + return alert; +} } // namespace @interface TabGridViewController ()<GridViewControllerDelegate, @@ -50,8 +62,9 @@ @property(nonatomic, weak) UIView* scrollContentView; @property(nonatomic, weak) TabGridTopToolbar* topToolbar; @property(nonatomic, weak) TabGridBottomToolbar* bottomToolbar; -@property(nonatomic, weak) UIButton* closeAllButton; @property(nonatomic, weak) UIButton* doneButton; +@property(nonatomic, weak) UIButton* closeAllButton; +@property(nonatomic, assign) BOOL undoCloseAllAvailable; // Clang does not allow property getters to start with the reserved word "new", // but provides a workaround. The getter must be set before the property is // declared. @@ -81,8 +94,9 @@ @synthesize scrollContentView = _scrollContentView; @synthesize topToolbar = _topToolbar; @synthesize bottomToolbar = _bottomToolbar; -@synthesize closeAllButton = _closeAllButton; @synthesize doneButton = _doneButton; +@synthesize closeAllButton = _closeAllButton; +@synthesize undoCloseAllAvailable = _undoCloseAllAvailable; @synthesize newTabButton = _newTabButton; @synthesize floatingButton = _floatingButton; @synthesize configuration = _configuration; @@ -124,6 +138,7 @@ } - (void)viewWillDisappear:(BOOL)animated { + self.undoCloseAllAvailable = NO; if (animated && self.transitionCoordinator) { [self animateToolbarsForDisappearance]; } @@ -552,9 +567,6 @@ [self.doneButton setTitle:l10n_util::GetNSString(IDS_IOS_TAB_GRID_DONE_BUTTON) forState:UIControlStateNormal]; - [self.closeAllButton - setTitle:l10n_util::GetNSString(IDS_IOS_TAB_GRID_CLOSE_ALL_BUTTON) - forState:UIControlStateNormal]; self.doneButton.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; self.closeAllButton.titleLabel.font = @@ -562,8 +574,6 @@ self.doneButton.titleLabel.adjustsFontForContentSizeCategory = YES; self.closeAllButton.titleLabel.adjustsFontForContentSizeCategory = YES; self.doneButton.accessibilityIdentifier = kTabGridDoneButtonIdentifier; - self.closeAllButton.accessibilityIdentifier = - kTabGridCloseAllButtonIdentifier; [self.doneButton addTarget:self action:@selector(doneButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; @@ -580,28 +590,48 @@ self.newTabButton.page = self.currentPage; switch (self.originalPage) { case TabGridPageIncognitoTabs: - self.doneButton.enabled = !self.incognitoTabsViewController.isGridEmpty; + self.doneButton.enabled = !self.incognitoTabsViewController.gridEmpty; break; case TabGridPageRegularTabs: - self.doneButton.enabled = !self.regularTabsViewController.isGridEmpty; + self.doneButton.enabled = !self.regularTabsViewController.gridEmpty; break; case TabGridPageRemoteTabs: NOTREACHED() << "It is not possible to have entered tab grid directly " "into remote tabs."; break; } + [self configureCloseAllButtonForCurrentPageAndUndoAvailability]; +} + +- (void)configureCloseAllButtonForCurrentPageAndUndoAvailability { + if (self.undoCloseAllAvailable && + self.currentPage == TabGridPageRegularTabs) { + // Setup closeAllButton as undo button. + self.closeAllButton.enabled = YES; + [self.closeAllButton + setTitle:l10n_util::GetNSString(IDS_IOS_TAB_GRID_UNDO_CLOSE_ALL_BUTTON) + forState:UIControlStateNormal]; + self.closeAllButton.accessibilityIdentifier = + kTabGridUndoCloseAllButtonIdentifier; + return; + } + // Otherwise setup as a Close All button. switch (self.currentPage) { case TabGridPageIncognitoTabs: - self.closeAllButton.enabled = - !self.incognitoTabsViewController.isGridEmpty; + self.closeAllButton.enabled = !self.incognitoTabsViewController.gridEmpty; break; case TabGridPageRegularTabs: - self.closeAllButton.enabled = !self.regularTabsViewController.isGridEmpty; + self.closeAllButton.enabled = !self.regularTabsViewController.gridEmpty; break; case TabGridPageRemoteTabs: self.closeAllButton.enabled = NO; break; } + [self.closeAllButton + setTitle:l10n_util::GetNSString(IDS_IOS_TAB_GRID_CLOSE_ALL_BUTTON) + forState:UIControlStateNormal]; + self.closeAllButton.accessibilityIdentifier = + kTabGridCloseAllButtonIdentifier; } // Translates the toolbar views offscreen and then animates them back in using @@ -723,7 +753,19 @@ [self.incognitoTabsDelegate closeAllItems]; break; case TabGridPageRegularTabs: - [self.regularTabsDelegate closeAllItems]; + DCHECK_EQ(self.undoCloseAllAvailable, + self.regularTabsViewController.gridEmpty); + if (self.undoCloseAllAvailable) { + // TODO(crbug.com/804567) : Implement Undo Close All. + [self presentViewController:NotImplementedAlert() + animated:YES + completion:nil]; + } else { + [self.incognitoTabsDelegate closeAllItems]; + [self.regularTabsDelegate closeAllItems]; + } + self.undoCloseAllAvailable = !self.undoCloseAllAvailable; + [self configureCloseAllButtonForCurrentPageAndUndoAvailability]; break; case TabGridPageRemoteTabs: NOTREACHED() << "It is invalid to call close all tabs on remote tabs.";
diff --git a/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron.png b/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron.png index bdfc7b5..0e13a78b 100644 --- a/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron.png +++ b/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron.png Binary files differ
diff --git a/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@2x.png b/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@2x.png index f099ed47..761ec69 100644 --- a/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@2x.png +++ b/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@3x.png b/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@3x.png index 60fce2b..37fa8391 100644 --- a/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@3x.png +++ b/ios/chrome/browser/ui/table_view/cells/resources/table_view_cell_chevron.imageset/table_view_cell_chevron@3x.png Binary files differ
diff --git a/ios/chrome/test/fakes/BUILD.gn b/ios/chrome/test/fakes/BUILD.gn index 5b2f061c..d3fa3bd 100644 --- a/ios/chrome/test/fakes/BUILD.gn +++ b/ios/chrome/test/fakes/BUILD.gn
@@ -19,6 +19,8 @@ "fake_pass_kit_tab_helper_delegate.mm", "fake_store_kit_launcher.h", "fake_store_kit_launcher.mm", + "fake_ui_view_controller.h", + "fake_ui_view_controller.mm", ] deps = [
diff --git a/ios/chrome/test/fakes/fake_ui_view_controller.h b/ios/chrome/test/fakes/fake_ui_view_controller.h new file mode 100644 index 0000000..613de8b7 --- /dev/null +++ b/ios/chrome/test/fakes/fake_ui_view_controller.h
@@ -0,0 +1,18 @@ +// Copyright 2018 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 IOS_CHROME_TEST_FAKES_FAKE_UI_VIEW_CONTROLLER_H_ +#define IOS_CHROME_TEST_FAKES_FAKE_UI_VIEW_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +// UIViewController used for testing. +// This class updates the object state instead of actually presenting and +// waiting for animation. +@interface FakeUIViewController : UIViewController +// Updated with view controller to present when presentViewController is called. +@property(nonatomic, strong) UIViewController* presentedViewController; +@end + +#endif // IOS_CHROME_TEST_FAKES_FAKE_UI_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/test/fakes/fake_ui_view_controller.mm b/ios/chrome/test/fakes/fake_ui_view_controller.mm new file mode 100644 index 0000000..c545e21 --- /dev/null +++ b/ios/chrome/test/fakes/fake_ui_view_controller.mm
@@ -0,0 +1,27 @@ +// Copyright 2018 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. + +#import "ios/chrome/test/fakes/fake_ui_view_controller.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation FakeUIViewController +@synthesize presentedViewController = _presentedViewController; + +#pragma mark - UIViewController methods + +- (void)presentViewController:(UIViewController*)viewControllerToPresent + animated:(BOOL)flag + completion:(void (^)())completion { + self.presentedViewController = viewControllerToPresent; +} + +- (void)dismissViewControllerAnimated:(BOOL)flag + completion:(void (^)())completion { + self.presentedViewController = nil; +} + +@end
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium index 0353d28..8cadb72 100644 --- a/ios/third_party/material_components_ios/README.chromium +++ b/ios/third_party/material_components_ios/README.chromium
@@ -1,7 +1,7 @@ Name: Material Components for iOS URL: https://github.com/material-components/material-components-ios Version: 0 -Revision: dd21af4fef24ddb42d39e9610b84109273c50899 +Revision: 8c8aad6dc245a6682544952e9d47c44149bffb33 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/media/audio/audio_debug_file_writer_unittest.cc b/media/audio/audio_debug_file_writer_unittest.cc index 436b0dea..eaa026b 100644 --- a/media/audio/audio_debug_file_writer_unittest.cc +++ b/media/audio/audio_debug_file_writer_unittest.cc
@@ -44,8 +44,7 @@ } // namespace // <channel layout, sample rate, frames per buffer, number of buffer writes -typedef std::tr1::tuple<ChannelLayout, int, int, int> - AudioDebugFileWriterTestData; +typedef std::tuple<ChannelLayout, int, int, int> AudioDebugFileWriterTestData; class AudioDebugFileWriterTest : public testing::TestWithParam<AudioDebugFileWriterTestData> { @@ -56,11 +55,11 @@ base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT, execution_mode), params_(AudioParameters::Format::AUDIO_PCM_LINEAR, - std::tr1::get<0>(GetParam()), - std::tr1::get<1>(GetParam()), + std::get<0>(GetParam()), + std::get<1>(GetParam()), kBytesPerSample * 8, - std::tr1::get<2>(GetParam())), - writes_(std::tr1::get<3>(GetParam())), + std::get<2>(GetParam())), + writes_(std::get<3>(GetParam())), source_samples_(params_.frames_per_buffer() * params_.channels() * writes_), source_interleaved_(source_samples_ ? new int16_t[source_samples_] @@ -303,55 +302,53 @@ // Using 10ms frames per buffer everywhere. testing::Values( // No writes. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, - 44100, - 44100 / 100, - 0), + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, + 44100, + 44100 / 100, + 0), // 1 write of mono. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, - 44100, - 44100 / 100, - 1), + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, + 44100, + 44100 / 100, + 1), // 1 second of mono. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, - 44100, - 44100 / 100, - 100), + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, + 44100, + 44100 / 100, + 100), // 1 second of mono, higher rate. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, - 48000, - 48000 / 100, - 100), + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, + 48000, + 48000 / 100, + 100), // 1 second of stereo. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_STEREO, - 44100, - 44100 / 100, - 100), + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_STEREO, + 44100, + 44100 / 100, + 100), // 15 seconds of stereo, higher rate. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_STEREO, - 48000, - 48000 / 100, - 1500))); + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_STEREO, + 48000, + 48000 / 100, + 1500))); -INSTANTIATE_TEST_CASE_P( - AudioDebugFileWriterBehavioralTest, - AudioDebugFileWriterBehavioralTest, - // Using 10ms frames per buffer everywhere. - testing::Values( - // No writes. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, - 44100, - 44100 / 100, - 100))); +INSTANTIATE_TEST_CASE_P(AudioDebugFileWriterBehavioralTest, + AudioDebugFileWriterBehavioralTest, + // Using 10ms frames per buffer everywhere. + testing::Values( + // No writes. + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, + 44100, + 44100 / 100, + 100))); -INSTANTIATE_TEST_CASE_P( - AudioDebugFileWriterSingleThreadTest, - AudioDebugFileWriterSingleThreadTest, - // Using 10ms frames per buffer everywhere. - testing::Values( - // No writes. - std::tr1::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, - 44100, - 44100 / 100, - 100))); +INSTANTIATE_TEST_CASE_P(AudioDebugFileWriterSingleThreadTest, + AudioDebugFileWriterSingleThreadTest, + // Using 10ms frames per buffer everywhere. + testing::Values( + // No writes. + std::make_tuple(ChannelLayout::CHANNEL_LAYOUT_MONO, + 44100, + 44100 / 100, + 100))); } // namespace media
diff --git a/media/base/audio_converter_unittest.cc b/media/base/audio_converter_unittest.cc index f9abac00..dabc5ea 100644 --- a/media/base/audio_converter_unittest.cc +++ b/media/base/audio_converter_unittest.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <memory> +#include <tuple> #include "base/macros.h" #include "base/strings/string_number_conversions.h" @@ -32,19 +33,18 @@ static const int kSineCycles = 4; // Tuple of <input rate, output rate, output channel layout, epsilon>. -typedef std::tr1::tuple<int, int, ChannelLayout, double> AudioConverterTestData; +typedef std::tuple<int, int, ChannelLayout, double> AudioConverterTestData; class AudioConverterTest : public testing::TestWithParam<AudioConverterTestData> { public: - AudioConverterTest() - : epsilon_(std::tr1::get<3>(GetParam())) { + AudioConverterTest() : epsilon_(std::get<3>(GetParam())) { // Create input and output parameters based on test parameters. input_parameters_ = AudioParameters( AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, - std::tr1::get<0>(GetParam()), kBitsPerChannel, kHighLatencyBufferSize); + std::get<0>(GetParam()), kBitsPerChannel, kHighLatencyBufferSize); output_parameters_ = AudioParameters( - AudioParameters::AUDIO_PCM_LOW_LATENCY, std::tr1::get<2>(GetParam()), - std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize); + AudioParameters::AUDIO_PCM_LOW_LATENCY, std::get<2>(GetParam()), + std::get<1>(GetParam()), 16, kLowLatencyBufferSize); converter_.reset(new AudioConverter( input_parameters_, output_parameters_, false)); @@ -253,14 +253,16 @@ } INSTANTIATE_TEST_CASE_P( - AudioConverterTest, AudioConverterTest, testing::Values( + AudioConverterTest, + AudioConverterTest, + testing::Values( // No resampling. No channel mixing. - std::tr1::make_tuple(44100, 44100, CHANNEL_LAYOUT_STEREO, 0.00000048), + std::make_tuple(44100, 44100, CHANNEL_LAYOUT_STEREO, 0.00000048), // Upsampling. Channel upmixing. - std::tr1::make_tuple(44100, 48000, CHANNEL_LAYOUT_QUAD, 0.033), + std::make_tuple(44100, 48000, CHANNEL_LAYOUT_QUAD, 0.033), // Downsampling. Channel downmixing. - std::tr1::make_tuple(48000, 41000, CHANNEL_LAYOUT_MONO, 0.042))); + std::make_tuple(48000, 41000, CHANNEL_LAYOUT_MONO, 0.042))); } // namespace media
diff --git a/media/base/audio_renderer_mixer_unittest.cc b/media/base/audio_renderer_mixer_unittest.cc index 54b1b19..4ca1b9c8 100644 --- a/media/base/audio_renderer_mixer_unittest.cc +++ b/media/base/audio_renderer_mixer_unittest.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <memory> +#include <tuple> #include "base/bind.h" #include "base/bind_helpers.h" @@ -48,26 +49,26 @@ // Tuple of <input sampling rates, number of input sample rates, // output sampling rate, epsilon>. using AudioRendererMixerTestData = - std::tr1::tuple<const int* const, size_t, int, double>; + std::tuple<const int* const, size_t, int, double>; class AudioRendererMixerTest : public testing::TestWithParam<AudioRendererMixerTestData>, AudioRendererMixerPool { public: AudioRendererMixerTest() - : epsilon_(std::tr1::get<3>(GetParam())), half_fill_(false) { + : epsilon_(std::get<3>(GetParam())), half_fill_(false) { // Create input parameters based on test parameters. - const int* const sample_rates = std::tr1::get<0>(GetParam()); - size_t sample_rates_count = std::tr1::get<1>(GetParam()); + const int* const sample_rates = std::get<0>(GetParam()); + size_t sample_rates_count = std::get<1>(GetParam()); for (size_t i = 0; i < sample_rates_count; ++i) input_parameters_.push_back(AudioParameters( AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, sample_rates[i], kBitsPerChannel, kHighLatencyBufferSize)); // Create output parameters based on test parameters. - output_parameters_ = AudioParameters( - AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout, - std::tr1::get<2>(GetParam()), 16, kLowLatencyBufferSize); + output_parameters_ = + AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout, + std::get<2>(GetParam()), 16, kLowLatencyBufferSize); sink_ = new MockAudioRendererSink(); EXPECT_CALL(*sink_.get(), Start()); @@ -520,31 +521,31 @@ AudioRendererMixerTest, testing::Values( // No resampling, 1 input sample rate. - std::tr1::make_tuple(&kTestInputLower, 1, kTestInputLower, 0.00000048), + std::make_tuple(&kTestInputLower, 1, kTestInputLower, 0.00000048), // Upsampling, 1 input sample rate. - std::tr1::make_tuple(&kTestInputLower, 1, kTestInputHigher, 0.01), + std::make_tuple(&kTestInputLower, 1, kTestInputHigher, 0.01), // Downsampling, 1 input sample rate. - std::tr1::make_tuple(&kTestInputHigher, 1, kTestInputLower, 0.01), + std::make_tuple(&kTestInputHigher, 1, kTestInputLower, 0.01), // Downsampling, multuple input sample rates. - std::tr1::make_tuple(static_cast<const int* const>(kTestInput3Rates), - arraysize(kTestInput3Rates), - kTestInput3Rates[0], - 0.01), + std::make_tuple(static_cast<const int* const>(kTestInput3Rates), + arraysize(kTestInput3Rates), + kTestInput3Rates[0], + 0.01), // Upsampling, multiple sinput sample rates. - std::tr1::make_tuple(static_cast<const int* const>(kTestInput3Rates), - arraysize(kTestInput3Rates), - kTestInput3Rates[2], - 0.01), + std::make_tuple(static_cast<const int* const>(kTestInput3Rates), + arraysize(kTestInput3Rates), + kTestInput3Rates[2], + 0.01), // Both downsampling and upsampling, multiple input sample rates - std::tr1::make_tuple(static_cast<const int* const>(kTestInput3Rates), - arraysize(kTestInput3Rates), - kTestInput3Rates[1], - 0.01))); + std::make_tuple(static_cast<const int* const>(kTestInput3Rates), + arraysize(kTestInput3Rates), + kTestInput3Rates[1], + 0.01))); // Test cases for behavior which is independent of parameters. Values() doesn't // support single item lists and we don't want these test cases to run for every @@ -554,8 +555,5 @@ AudioRendererMixerBehavioralTest, testing::ValuesIn(std::vector<AudioRendererMixerTestData>( 1, - std::tr1::make_tuple(&kTestInputLower, - 1, - kTestInputLower, - 0.00000048)))); + std::make_tuple(&kTestInputLower, 1, kTestInputLower, 0.00000048)))); } // namespace media
diff --git a/media/base/gmock_callback_support.h b/media/base/gmock_callback_support.h index 93af410..5227875b 100644 --- a/media/base/gmock_callback_support.h +++ b/media/base/gmock_callback_support.h
@@ -5,6 +5,8 @@ #ifndef MEDIA_BASE_GMOCK_CALLBACK_SUPPORT_H_ #define MEDIA_BASE_GMOCK_CALLBACK_SUPPORT_H_ +#include <tuple> + #include "testing/gmock/include/gmock/gmock.h" namespace media { @@ -25,7 +27,7 @@ ACTION_TEMPLATE(RunClosure, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - ::std::tr1::get<k>(args).Run(); + std::get<k>(args).Run(); } ACTION_P(RunClosure, closure) { @@ -61,49 +63,49 @@ ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - return ::std::tr1::get<k>(args).Run(); + return std::get<k>(args).Run(); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - return ::std::tr1::get<k>(args).Run(p0); + return std::get<k>(args).Run(p0); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(p0, p1)) { - return ::std::tr1::get<k>(args).Run(p0, p1); + return std::get<k>(args).Run(p0, p1); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_3_VALUE_PARAMS(p0, p1, p2)) { - return ::std::tr1::get<k>(args).Run(p0, p1, p2); + return std::get<k>(args).Run(p0, p1, p2); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - return ::std::tr1::get<k>(args).Run(p0, p1, p2, p3); + return std::get<k>(args).Run(p0, p1, p2, p3); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - return ::std::tr1::get<k>(args).Run(p0, p1, p2, p3, p4); + return std::get<k>(args).Run(p0, p1, p2, p3, p4); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - return ::std::tr1::get<k>(args).Run(p0, p1, p2, p3, p4, p5); + return std::get<k>(args).Run(p0, p1, p2, p3, p4, p5); } ACTION_TEMPLATE(RunCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - return ::std::tr1::get<k>(args).Run(p0, p1, p2, p3, p4, p5, p6); + return std::get<k>(args).Run(p0, p1, p2, p3, p4, p5, p6); } // Various overloads for RunOnceClosure and RunOnceCallback<N>(). These are @@ -113,7 +115,7 @@ ACTION_TEMPLATE(RunOnceClosure, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - std::move(::std::tr1::get<k>(args)).Run(); + std::move(std::get<k>(args)).Run(); } ACTION_P(RunOnceClosure, closure) { @@ -123,43 +125,43 @@ ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - return std::move(::std::tr1::get<k>(args)).Run(p0); + return std::move(std::get<k>(args)).Run(p0); } ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(p0, p1)) { - return std::move(::std::tr1::get<k>(args)).Run(p0, p1); + return std::move(std::get<k>(args)).Run(p0, p1); } ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_3_VALUE_PARAMS(p0, p1, p2)) { - return std::move(::std::tr1::get<k>(args)).Run(p0, p1, p2); + return std::move(std::get<k>(args)).Run(p0, p1, p2); } ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - return std::move(::std::tr1::get<k>(args)).Run(p0, p1, p2, p3); + return std::move(std::get<k>(args)).Run(p0, p1, p2, p3); } ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - return std::move(::std::tr1::get<k>(args)).Run(p0, p1, p2, p3, p4); + return std::move(std::get<k>(args)).Run(p0, p1, p2, p3, p4); } ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - return std::move(::std::tr1::get<k>(args)).Run(p0, p1, p2, p3, p4, p5); + return std::move(std::get<k>(args)).Run(p0, p1, p2, p3, p4, p5); } ACTION_TEMPLATE(RunOnceCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - return std::move(::std::tr1::get<k>(args)).Run(p0, p1, p2, p3, p4, p5, p6); + return std::move(std::get<k>(args)).Run(p0, p1, p2, p3, p4, p5, p6); } } // namespace media
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index aa7e685..9d1f0fe4 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc
@@ -73,7 +73,7 @@ HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(::std::tr1::get<k>(args), p0)); + FROM_HERE, base::Bind(std::get<k>(args), p0)); } // TODO(scherkus): even though some filters are initialized on separate
diff --git a/media/base/sinc_resampler_unittest.cc b/media/base/sinc_resampler_unittest.cc index 93bdce6..8f1a1f2 100644 --- a/media/base/sinc_resampler_unittest.cc +++ b/media/base/sinc_resampler_unittest.cc
@@ -248,16 +248,15 @@ DISALLOW_COPY_AND_ASSIGN(SinusoidalLinearChirpSource); }; -typedef std::tr1::tuple<int, int, double, double> SincResamplerTestData; +typedef std::tuple<int, int, double, double> SincResamplerTestData; class SincResamplerTest : public testing::TestWithParam<SincResamplerTestData> { public: SincResamplerTest() - : input_rate_(std::tr1::get<0>(GetParam())), - output_rate_(std::tr1::get<1>(GetParam())), - rms_error_(std::tr1::get<2>(GetParam())), - low_freq_error_(std::tr1::get<3>(GetParam())) { - } + : input_rate_(std::get<0>(GetParam())), + output_rate_(std::get<1>(GetParam())), + rms_error_(std::get<2>(GetParam())), + low_freq_error_(std::get<3>(GetParam())) {} virtual ~SincResamplerTest() = default; @@ -362,49 +361,51 @@ // Thresholds chosen arbitrarily based on what each resampling reported during // testing. All thresholds are in dbFS, http://en.wikipedia.org/wiki/DBFS. INSTANTIATE_TEST_CASE_P( - SincResamplerTest, SincResamplerTest, testing::Values( + SincResamplerTest, + SincResamplerTest, + testing::Values( // To 44.1kHz - std::tr1::make_tuple(8000, 44100, kResamplingRMSError, -62.73), - std::tr1::make_tuple(11025, 44100, kResamplingRMSError, -72.19), - std::tr1::make_tuple(16000, 44100, kResamplingRMSError, -62.54), - std::tr1::make_tuple(22050, 44100, kResamplingRMSError, -73.53), - std::tr1::make_tuple(32000, 44100, kResamplingRMSError, -63.32), - std::tr1::make_tuple(44100, 44100, kResamplingRMSError, -73.53), - std::tr1::make_tuple(48000, 44100, -15.01, -64.04), - std::tr1::make_tuple(96000, 44100, -18.49, -25.51), - std::tr1::make_tuple(192000, 44100, -20.50, -13.31), + std::make_tuple(8000, 44100, kResamplingRMSError, -62.73), + std::make_tuple(11025, 44100, kResamplingRMSError, -72.19), + std::make_tuple(16000, 44100, kResamplingRMSError, -62.54), + std::make_tuple(22050, 44100, kResamplingRMSError, -73.53), + std::make_tuple(32000, 44100, kResamplingRMSError, -63.32), + std::make_tuple(44100, 44100, kResamplingRMSError, -73.53), + std::make_tuple(48000, 44100, -15.01, -64.04), + std::make_tuple(96000, 44100, -18.49, -25.51), + std::make_tuple(192000, 44100, -20.50, -13.31), // To 48kHz - std::tr1::make_tuple(8000, 48000, kResamplingRMSError, -63.43), - std::tr1::make_tuple(11025, 48000, kResamplingRMSError, -62.61), - std::tr1::make_tuple(16000, 48000, kResamplingRMSError, -63.96), - std::tr1::make_tuple(22050, 48000, kResamplingRMSError, -62.42), - std::tr1::make_tuple(32000, 48000, kResamplingRMSError, -64.04), - std::tr1::make_tuple(44100, 48000, kResamplingRMSError, -62.63), - std::tr1::make_tuple(48000, 48000, kResamplingRMSError, -73.52), - std::tr1::make_tuple(96000, 48000, -18.40, -28.44), - std::tr1::make_tuple(192000, 48000, -20.43, -14.11), + std::make_tuple(8000, 48000, kResamplingRMSError, -63.43), + std::make_tuple(11025, 48000, kResamplingRMSError, -62.61), + std::make_tuple(16000, 48000, kResamplingRMSError, -63.96), + std::make_tuple(22050, 48000, kResamplingRMSError, -62.42), + std::make_tuple(32000, 48000, kResamplingRMSError, -64.04), + std::make_tuple(44100, 48000, kResamplingRMSError, -62.63), + std::make_tuple(48000, 48000, kResamplingRMSError, -73.52), + std::make_tuple(96000, 48000, -18.40, -28.44), + std::make_tuple(192000, 48000, -20.43, -14.11), // To 96kHz - std::tr1::make_tuple(8000, 96000, kResamplingRMSError, -63.19), - std::tr1::make_tuple(11025, 96000, kResamplingRMSError, -62.61), - std::tr1::make_tuple(16000, 96000, kResamplingRMSError, -63.39), - std::tr1::make_tuple(22050, 96000, kResamplingRMSError, -62.42), - std::tr1::make_tuple(32000, 96000, kResamplingRMSError, -63.95), - std::tr1::make_tuple(44100, 96000, kResamplingRMSError, -62.63), - std::tr1::make_tuple(48000, 96000, kResamplingRMSError, -73.52), - std::tr1::make_tuple(96000, 96000, kResamplingRMSError, -73.52), - std::tr1::make_tuple(192000, 96000, kResamplingRMSError, -28.41), + std::make_tuple(8000, 96000, kResamplingRMSError, -63.19), + std::make_tuple(11025, 96000, kResamplingRMSError, -62.61), + std::make_tuple(16000, 96000, kResamplingRMSError, -63.39), + std::make_tuple(22050, 96000, kResamplingRMSError, -62.42), + std::make_tuple(32000, 96000, kResamplingRMSError, -63.95), + std::make_tuple(44100, 96000, kResamplingRMSError, -62.63), + std::make_tuple(48000, 96000, kResamplingRMSError, -73.52), + std::make_tuple(96000, 96000, kResamplingRMSError, -73.52), + std::make_tuple(192000, 96000, kResamplingRMSError, -28.41), // To 192kHz - std::tr1::make_tuple(8000, 192000, kResamplingRMSError, -63.10), - std::tr1::make_tuple(11025, 192000, kResamplingRMSError, -62.61), - std::tr1::make_tuple(16000, 192000, kResamplingRMSError, -63.14), - std::tr1::make_tuple(22050, 192000, kResamplingRMSError, -62.42), - std::tr1::make_tuple(32000, 192000, kResamplingRMSError, -63.38), - std::tr1::make_tuple(44100, 192000, kResamplingRMSError, -62.63), - std::tr1::make_tuple(48000, 192000, kResamplingRMSError, -73.44), - std::tr1::make_tuple(96000, 192000, kResamplingRMSError, -73.52), - std::tr1::make_tuple(192000, 192000, kResamplingRMSError, -73.52))); + std::make_tuple(8000, 192000, kResamplingRMSError, -63.10), + std::make_tuple(11025, 192000, kResamplingRMSError, -62.61), + std::make_tuple(16000, 192000, kResamplingRMSError, -63.14), + std::make_tuple(22050, 192000, kResamplingRMSError, -62.42), + std::make_tuple(32000, 192000, kResamplingRMSError, -63.38), + std::make_tuple(44100, 192000, kResamplingRMSError, -62.63), + std::make_tuple(48000, 192000, kResamplingRMSError, -73.44), + std::make_tuple(96000, 192000, kResamplingRMSError, -73.52), + std::make_tuple(192000, 192000, kResamplingRMSError, -73.52))); } // namespace media
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 309b9e2..58846de 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -791,7 +791,6 @@ } void WebMediaPlayerImpl::ExitPictureInPicture() { - LOG(ERROR) << "WebMediaPlayerImpl::ExitPictureInPicture"; // TODO(apacible): Handle ending PiP from a user gesture. This currently // handles ending Picture-in-Picture mode from the source. // https://crbug.com/823172.
diff --git a/media/filters/video_renderer_algorithm_unittest.cc b/media/filters/video_renderer_algorithm_unittest.cc index 28bd807b..ec93d0e 100644 --- a/media/filters/video_renderer_algorithm_unittest.cc +++ b/media/filters/video_renderer_algorithm_unittest.cc
@@ -6,6 +6,7 @@ #include <stdint.h> #include <cmath> +#include <tuple> #include "base/bind.h" #include "base/bind_helpers.h" @@ -1360,8 +1361,8 @@ public ::testing::WithParamInterface<::testing::tuple<double, double>> {}; TEST_P(VideoRendererAlgorithmCadenceTest, CadenceTest) { - double display_rate = std::tr1::get<0>(GetParam()); - double frame_rate = std::tr1::get<1>(GetParam()); + double display_rate = std::get<0>(GetParam()); + double frame_rate = std::get<1>(GetParam()); TickGenerator frame_tg(base::TimeTicks(), frame_rate); TickGenerator display_tg(tick_clock_->NowTicks(), display_rate);
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc index e717c21..f5c802b6 100644 --- a/media/gpu/v4l2/v4l2_image_processor.cc +++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -47,10 +47,15 @@ V4L2ImageProcessor::InputRecord::InputRecord() : at_device(false) {} +V4L2ImageProcessor::InputRecord::InputRecord( + const V4L2ImageProcessor::InputRecord&) = default; + V4L2ImageProcessor::InputRecord::~InputRecord() {} V4L2ImageProcessor::OutputRecord::OutputRecord() : at_device(false) {} +V4L2ImageProcessor::OutputRecord::OutputRecord(OutputRecord&&) = default; + V4L2ImageProcessor::OutputRecord::~OutputRecord() {} V4L2ImageProcessor::JobRecord::JobRecord() : output_buffer_index(-1) {}
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h index d43a8c8..272ad15 100644 --- a/media/gpu/v4l2/v4l2_image_processor.h +++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -109,6 +109,7 @@ // Record for input buffers. struct InputRecord { InputRecord(); + InputRecord(const V4L2ImageProcessor::InputRecord&); ~InputRecord(); scoped_refptr<VideoFrame> frame; bool at_device; @@ -117,7 +118,7 @@ // Record for output buffers. struct OutputRecord { OutputRecord(); - OutputRecord(OutputRecord&&) = default; + OutputRecord(OutputRecord&&); ~OutputRecord(); bool at_device; // The processed frame will be stored in these buffers if
diff --git a/media/gpu/v4l2/v4l2_jpeg_decode_accelerator.h b/media/gpu/v4l2/v4l2_jpeg_decode_accelerator.h index bae48f9..05afb04c 100644 --- a/media/gpu/v4l2/v4l2_jpeg_decode_accelerator.h +++ b/media/gpu/v4l2/v4l2_jpeg_decode_accelerator.h
@@ -180,11 +180,11 @@ // ordering. std::vector<int> free_output_buffers_; - // Weak factory for producing weak pointers on the child thread. - base::WeakPtrFactory<V4L2JpegDecodeAccelerator> weak_factory_; // Point to |this| for use in posting tasks from the decoder thread back to // the ChildThread. base::WeakPtr<V4L2JpegDecodeAccelerator> weak_ptr_; + // Weak factory for producing weak pointers on the child thread. + base::WeakPtrFactory<V4L2JpegDecodeAccelerator> weak_factory_; DISALLOW_COPY_AND_ASSIGN(V4L2JpegDecodeAccelerator); };
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc index 45cad1c..060fea19 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -196,6 +196,11 @@ egl_sync(EGL_NO_SYNC_KHR), cleared(false) {} +V4L2SliceVideoDecodeAccelerator::OutputRecord::OutputRecord(OutputRecord&&) = + default; + +V4L2SliceVideoDecodeAccelerator::OutputRecord::~OutputRecord() = default; + struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef { BitstreamBufferRef( base::WeakPtr<VideoDecodeAccelerator::Client>& client,
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h index 967513d..5838beb 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h +++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h
@@ -83,7 +83,8 @@ // Record for output buffers. struct OutputRecord { OutputRecord(); - OutputRecord(OutputRecord&&) = default; + OutputRecord(OutputRecord&&); + ~OutputRecord(); bool at_device; bool at_client; int32_t picture_id;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index 209efbe4..ed193740 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -133,6 +133,9 @@ texture_id(0), cleared(false) {} +V4L2VideoDecodeAccelerator::OutputRecord::OutputRecord(OutputRecord&&) = + default; + V4L2VideoDecodeAccelerator::OutputRecord::~OutputRecord() {} V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord(bool cleared, @@ -2333,10 +2336,10 @@ static const uint32_t kPreferredFormats[] = {V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_NV12}; auto preferred_formats_first = [](uint32_t a, uint32_t b) -> bool { - auto iter_a = std::find(std::begin(kPreferredFormats), - std::end(kPreferredFormats), a); - auto iter_b = std::find(std::begin(kPreferredFormats), - std::end(kPreferredFormats), b); + auto* iter_a = std::find(std::begin(kPreferredFormats), + std::end(kPreferredFormats), a); + auto* iter_b = std::find(std::begin(kPreferredFormats), + std::end(kPreferredFormats), b); return iter_a < iter_b; };
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h index e991e3c..8e150ba 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -188,7 +188,7 @@ // Record for output buffers. struct OutputRecord { OutputRecord(); - OutputRecord(OutputRecord&&) = default; + OutputRecord(OutputRecord&&); ~OutputRecord(); OutputRecordState state; EGLImageKHR egl_image; // EGLImageKHR for the output buffer.
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index 3742899..3aa0ea1 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -95,6 +95,9 @@ V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) {} +V4L2VideoEncodeAccelerator::InputRecord::InputRecord(const InputRecord&) = + default; + V4L2VideoEncodeAccelerator::InputRecord::~InputRecord() {} V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord() @@ -110,6 +113,9 @@ bool force_keyframe) : frame(frame), force_keyframe(force_keyframe) {} +V4L2VideoEncodeAccelerator::InputFrameInfo::InputFrameInfo( + const InputFrameInfo&) = default; + V4L2VideoEncodeAccelerator::InputFrameInfo::~InputFrameInfo() {} V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator(
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h index 5a64e65b..4b89ddb7 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -68,6 +68,7 @@ // Record for codec input buffers. struct InputRecord { InputRecord(); + InputRecord(const InputRecord&); ~InputRecord(); bool at_device; scoped_refptr<VideoFrame> frame; @@ -87,6 +88,7 @@ struct InputFrameInfo { InputFrameInfo(); InputFrameInfo(scoped_refptr<VideoFrame> frame, bool force_keyframe); + InputFrameInfo(const InputFrameInfo&); ~InputFrameInfo(); scoped_refptr<VideoFrame> frame; bool force_keyframe;
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index fa27da4..1792a3f 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -836,8 +836,12 @@ DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); base::AutoLock auto_lock(lock_); - if (available_va_surfaces_.empty()) + if (available_va_surfaces_.empty()) { + VLOGF(4) + << "There is not available VASurface. The number of total surfaces is " + << picture_map_.size(); return nullptr; + } DCHECK(!awaiting_va_surfaces_recycle_); scoped_refptr<VASurface> va_surface(new VASurface(
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc index 2cd08a8..765878bb 100644 --- a/media/gpu/video_encode_accelerator_unittest.cc +++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -134,7 +134,7 @@ // Bitrate is only forced for tests that test bitrate. const char* g_default_in_filename = "bear_320x192_40frames.yuv"; -#if defined(OS_CHROMEOS) +#if defined(OS_CHROMEOS) || defined(OS_LINUX) const base::FilePath::CharType* g_default_in_parameters = FILE_PATH_LITERAL(":320:192:1:out.h264:200000"); #elif defined(OS_MACOSX) || defined(OS_WIN) @@ -2529,7 +2529,7 @@ SimpleTestFunc<VEACacheLineUnalignedInputClient>(); } -#if defined(OS_CHROMEOS) +#if defined(OS_CHROMEOS) || defined(OS_LINUX) // TODO(kcwu): add back test of verify_output=true after // https://crbug.com/694131 fixed. INSTANTIATE_TEST_CASE_P( @@ -2636,7 +2636,7 @@ std::make_tuple(1, false, 0, true, false, false, false, false, false))); #endif // defined(OS_WIN) -#endif // defined(OS_CHROMEOS) +#endif // defined(OS_CHROMEOS) || defined(OS_LINUX) // TODO(posciak): more tests: // - async FeedEncoderWithOutput
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index a22f996..d3a04c9 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -361,6 +361,10 @@ // the decoded samples. These buffers are then reused when the client tells // us that it is done with the buffer. kNumPictureBuffers = 5, + // When GetTextureTarget() returns GL_TEXTURE_EXTERNAL_OES, allocated + // PictureBuffers do not consume significant resources, so we can optimize for + // latency more aggressively. + kNumPictureBuffersForZeroCopy = 10, // The keyed mutex should always be released before the other thread // attempts to acquire it, so AcquireSync should always return immediately. kAcquireSyncWaitMs = 0, @@ -714,6 +718,9 @@ support_share_nv12_textures_( gpu_preferences.enable_zero_copy_dxgi_video && !workarounds.disable_dxgi_zero_copy_video), + num_picture_buffers_requested_(support_share_nv12_textures_ + ? kNumPictureBuffersForZeroCopy + : kNumPictureBuffers), support_copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video && !workarounds.disable_nv12_dxgi_video), support_delayed_copy_nv12_textures_( @@ -763,7 +770,7 @@ if (!config.supported_output_formats.empty() && !base::ContainsValue(config.supported_output_formats, PIXEL_FORMAT_NV12)) { - support_share_nv12_textures_ = false; + DisableSharedTextureSupport(); support_copy_nv12_textures_ = false; } @@ -1188,9 +1195,10 @@ RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized), "Invalid state: " << state, ILLEGAL_STATE, ); RETURN_AND_NOTIFY_ON_FAILURE( - (kNumPictureBuffers <= buffers.size()), + (num_picture_buffers_requested_ <= static_cast<int>(buffers.size())), "Failed to provide requested picture buffers. (Got " - << buffers.size() << ", requested " << kNumPictureBuffers << ")", + << buffers.size() << ", requested " << num_picture_buffers_requested_ + << ")", INVALID_ARGUMENT, ); RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), @@ -1697,7 +1705,7 @@ if (use_fp16_) { // TODO(hubbe): Share/copy P010/P016 textures. - support_share_nv12_textures_ = false; + DisableSharedTextureSupport(); support_copy_nv12_textures_ = false; } @@ -1731,7 +1739,7 @@ // pending_output_samples_. The decoder adds this number to the number of // reference pictures it expects to need and uses that to determine the // array size of the output texture. - const int kMaxOutputSamples = kNumPictureBuffers + 1; + const int kMaxOutputSamples = num_picture_buffers_requested_ + 1; attributes->SetUINT32(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE, kMaxOutputSamples); attributes->SetUINT32(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT, kMaxOutputSamples); @@ -1759,7 +1767,7 @@ !gl::g_driver_egl.ext.b_EGL_KHR_stream || !gl::g_driver_egl.ext.b_EGL_KHR_stream_consumer_gltexture || !gl::g_driver_egl.ext.b_EGL_NV_stream_consumer_gltexture_yuv) { - support_share_nv12_textures_ = false; + DisableSharedTextureSupport(); support_copy_nv12_textures_ = false; } @@ -2221,7 +2229,7 @@ bool provide_nv12_textures = GetPictureBufferMechanism() != PictureBufferMechanism::COPY_TO_RGB; client_->ProvidePictureBuffers( - kNumPictureBuffers, + num_picture_buffers_requested_, provide_nv12_textures ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_UNKNOWN, provide_nv12_textures ? 2 : 1, gfx::Size(width, height), GetTextureTarget()); @@ -3157,6 +3165,11 @@ return 0; } +void DXVAVideoDecodeAccelerator::DisableSharedTextureSupport() { + support_share_nv12_textures_ = false; + num_picture_buffers_requested_ = kNumPictureBuffers; +} + DXVAVideoDecodeAccelerator::PictureBufferMechanism DXVAVideoDecodeAccelerator::GetPictureBufferMechanism() const { if (use_fp16_)
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.h b/media/gpu/windows/dxva_video_decode_accelerator_win.h index f930624..2ac80a4 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.h +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.h
@@ -351,6 +351,10 @@ // decoder here. void ConfigChanged(const Config& config); + // Sets |support_share_nv12_textures_| to false and updates + // |num_picture_buffers_requested_|. + void DisableSharedTextureSupport(); + uint32_t GetTextureTarget() const; PictureBufferMechanism GetPictureBufferMechanism() const; @@ -500,6 +504,10 @@ // Supports sharing the decoded NV12 textures with ANGLE bool support_share_nv12_textures_; + // Number of requested picture buffers from the client which are used to hold + // the decoded samples. + int num_picture_buffers_requested_; + // Supports copying the NV12 texture to another NV12 texture to use in // ANGLE. bool support_copy_nv12_textures_;
diff --git a/net/BUILD.gn b/net/BUILD.gn index 52320b9..b084ee9 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -240,10 +240,6 @@ "cert/signed_certificate_timestamp_and_status.h", "cert/signed_tree_head.cc", "cert/signed_tree_head.h", - "cert/sth_distributor.cc", - "cert/sth_distributor.h", - "cert/sth_observer.h", - "cert/sth_reporter.h", "cert/symantec_certs.cc", "cert/symantec_certs.h", "cert/x509_cert_types.cc", @@ -4794,7 +4790,6 @@ "cert/nss_profile_filter_chromeos_unittest.cc", "cert/pem_tokenizer_unittest.cc", "cert/signed_certificate_timestamp_unittest.cc", - "cert/sth_distributor_unittest.cc", "cert/symantec_certs_unittest.cc", "cert/test_root_certs_unittest.cc", "cert/x509_cert_types_unittest.cc",
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h index 9abb9b9..a342d761 100644 --- a/net/base/load_flags_list.h +++ b/net/base/load_flags_list.h
@@ -49,18 +49,15 @@ // to avoid having a circular dependency. LOAD_FLAG(BYPASS_PROXY, 1 << 7) -// Requires EV certificate verification. -LOAD_FLAG(VERIFY_EV_CERT, 1 << 8) - // This load will not send any cookies. -LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 9) +LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 8) // This load will not send authentication data (user name/password) // to the server (as opposed to the proxy). -LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 10) +LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 9) // This should only be used for testing (set by HttpNetworkTransaction). -LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 11) +LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 10) // DO NOT USE THIS FLAG // The network stack should not have frame level knowledge. Any pre-connect @@ -69,29 +66,29 @@ // Indicate that this is a top level frame, so that we don't assume it is a // subresource and speculatively pre-connect or pre-resolve when a referring // page is loaded. -LOAD_FLAG(MAIN_FRAME_DEPRECATED, 1 << 12) +LOAD_FLAG(MAIN_FRAME_DEPRECATED, 1 << 11) // Indicates that this load was motivated by the rel=prefetch feature, // and is (in theory) not intended for the current frame. -LOAD_FLAG(PREFETCH, 1 << 13) +LOAD_FLAG(PREFETCH, 1 << 12) // Indicates that this load could cause deadlock if it has to wait for another // request. Overrides socket limits. Must always be used with MAXIMUM_PRIORITY. -LOAD_FLAG(IGNORE_LIMITS, 1 << 14) +LOAD_FLAG(IGNORE_LIMITS, 1 << 13) // Indicates that the operation is somewhat likely to be due to an // explicit user action. This can be used as a hint to treat the // request with higher priority. -LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 15) +LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 14) // Indicates that the username:password portion of the URL should not // be honored, but that other forms of authority may be used. -LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 16) +LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 15) // Indicates that this request is not to be migrated to a new network when QUIC // connection migration is enabled. -LOAD_FLAG(DISABLE_CONNECTION_MIGRATION, 1 << 17) +LOAD_FLAG(DISABLE_CONNECTION_MIGRATION, 1 << 16) // Indicates that the cache should not check that the request matches the // response's vary header. -LOAD_FLAG(SKIP_VARY_CHECK, 1 << 18) +LOAD_FLAG(SKIP_VARY_CHECK, 1 << 17)
diff --git a/net/cert/cert_verifier.h b/net/cert/cert_verifier.h index c083c86..8c0ac02 100644 --- a/net/cert/cert_verifier.h +++ b/net/cert/cert_verifier.h
@@ -43,27 +43,9 @@ // certificate chain. VERIFY_REV_CHECKING_ENABLED = 1 << 0, - // If set, and the certificate being verified may be an EV certificate, - // attempt to verify the certificate according to the EV processing - // guidelines. In order to successfully verify a certificate as EV, - // either an online or offline revocation check must be successfully - // completed. To ensure it's possible to complete a revocation check, - // callers should also specify either VERIFY_REV_CHECKING_ENABLED or - // VERIFY_REV_CHECKING_ENABLED_EV_ONLY (to enable online checks), and - // VERIFY_CERT_IO_ENABLED (to enable network fetches for online checks). - VERIFY_EV_CERT = 1 << 1, - - // If set, permits NSS to use the network when verifying certificates, - // such as to fetch missing intermediates or to check OCSP or CRLs. - // TODO(rsleevi): http://crbug.com/143300 - Define this flag for all - // verification engines with well-defined semantics, rather than being - // NSS only. - VERIFY_CERT_IO_ENABLED = 1 << 2, - - // If set, enables online revocation checking via CRLs or OCSP when the - // chain is not covered by a fresh CRLSet, but only for certificates which - // may be EV, and only when VERIFY_EV_CERT is also set. - VERIFY_REV_CHECKING_ENABLED_EV_ONLY = 1 << 3, + // 1 << 1 is reserved (used to be VERIFY_EV_CERT). + // 1 << 2 is reserved (used to be VERIY_CERT_IO_ENABLED). + // 1 << 3 is reserved (used to be VERIFY_REV_CHECKING_ENABLED_EV_ONLY). // If set, this is equivalent to VERIFY_REV_CHECKING_ENABLED, in that it // enables online revocation checking via CRLs or OCSP, but only @@ -80,7 +62,8 @@ // they are issued by non-public trust anchors. VERIFY_ENABLE_SHA1_LOCAL_ANCHORS = 1 << 5, - // 1 << 6 is reserved. + // 1 << 6 is reserved (used to be + // VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS). // If set, disables the policy enforcement described at // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
diff --git a/net/cert/cert_verifier_unittest.cc b/net/cert/cert_verifier_unittest.cc index b54f00fa..fa76bed 100644 --- a/net/cert/cert_verifier_unittest.cc +++ b/net/cert/cert_verifier_unittest.cc
@@ -87,7 +87,7 @@ // The same certificate, chain, and host, but with different flags // are different validation keys. CertVerifier::RequestParams(ok_cert, "www.example.test", - CertVerifier::VERIFY_EV_CERT, + CertVerifier::VERIFY_REV_CHECKING_ENABLED, std::string(), empty_list), CertVerifier::RequestParams(ok_cert, "www.example.test", 0, std::string(), empty_list),
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc index ba51d3a..7e65301 100644 --- a/net/cert/cert_verify_proc.cc +++ b/net/cert/cert_verify_proc.cc
@@ -508,13 +508,6 @@ return ERR_CERT_REVOKED; } - // We do online revocation checking for EV certificates that aren't covered - // by a fresh CRLSet. - // TODO(rsleevi): http://crbug.com/142974 - Allow preferences to fully - // disable revocation checking. - if (flags & CertVerifier::VERIFY_EV_CERT) - flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY; - int rv = VerifyInternal(cert, hostname, ocsp_response, flags, crl_set, additional_trust_anchors, verify_result);
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc index 50dcda9..95cf8ffb 100644 --- a/net/cert/cert_verify_proc_builtin.cc +++ b/net/cert/cert_verify_proc_builtin.cc
@@ -185,8 +185,7 @@ !certs.empty() && !ssl_trust_store_->IsKnownRoot(certs.back().get())) { RevocationPolicy policy; policy.check_revocation = true; - policy.networking_allowed = - (flags_ & CertVerifier::VERIFY_CERT_IO_ENABLED); + policy.networking_allowed = true; policy.allow_missing_info = true; policy.allow_network_failure = false; @@ -206,12 +205,7 @@ RevocationPolicy policy; policy.check_revocation = true; - // TODO(eroman): This definition for |networking_allowed| is redundant. - // Perhaps VERIFY_EV_CERT should imply revocation checking. - policy.networking_allowed = - (flags_ & CertVerifier::VERIFY_CERT_IO_ENABLED) && - ((flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED) || - (flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY)); + policy.networking_allowed = true; policy.allow_missing_info = false; policy.allow_network_failure = false; return policy; @@ -221,7 +215,7 @@ if (flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED) { RevocationPolicy policy; policy.check_revocation = true; - policy.networking_allowed = flags_ & CertVerifier::VERIFY_CERT_IO_ENABLED; + policy.networking_allowed = true; policy.allow_missing_info = true; policy.allow_network_failure = true; return policy; @@ -449,14 +443,11 @@ // Allow the path builder to discover intermediates through AIA fetching. std::unique_ptr<CertIssuerSourceAia> aia_cert_issuer_source; - if (flags & CertVerifier::VERIFY_CERT_IO_ENABLED) { - if (net_fetcher) { - aia_cert_issuer_source = - std::make_unique<CertIssuerSourceAia>(net_fetcher); - path_builder.AddCertIssuerSource(aia_cert_issuer_source.get()); - } else { - LOG(ERROR) << "VERIFY_CERT_IO_ENABLED specified but no net_fetcher"; - } + if (net_fetcher) { + aia_cert_issuer_source = std::make_unique<CertIssuerSourceAia>(net_fetcher); + path_builder.AddCertIssuerSource(aia_cert_issuer_source.get()); + } else { + LOG(ERROR) << "No net_fetcher for performing AIA chasing."; } path_builder.Run(); @@ -585,10 +576,9 @@ // setting output flag CERT_STATUS_REV_CHECKING_ENABLED). bool checked_revocation_for_some_path = false; - // Only attempt to build EV paths if it was requested by the caller AND the - // target could possibly be an EV certificate. - const bool should_try_ev = (flags & CertVerifier::VERIFY_EV_CERT) && - IsEVCandidate(ev_metadata, target.get()); + // Only attempt to build EV paths if the target could possibly be an EV + // certificate. + const bool should_try_ev = IsEVCandidate(ev_metadata, target.get()); // Run path building with the different parameters (attempts) until a valid // path is found. Earlier successful attempts have priority over later
diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc index 6e482e1e..7484f58 100644 --- a/net/cert/cert_verify_proc_mac.cc +++ b/net/cert/cert_verify_proc_mac.cc
@@ -1003,10 +1003,9 @@ // verification with different flags. const CertVerifyResult input_verify_result(*verify_result); - // If EV verification is enabled, check for EV policy in leaf cert. + // Check for EV policy in leaf cert. std::string candidate_ev_policy_oid; - if (flags & CertVerifier::VERIFY_EV_CERT) - GetCandidateEVPolicy(cert, &candidate_ev_policy_oid); + GetCandidateEVPolicy(cert, &candidate_ev_policy_oid); CRLSetResult completed_chain_crl_result; int rv = VerifyWithGivenFlags(cert, hostname, flags, crl_set, verify_result, @@ -1020,7 +1019,6 @@ // EV policies check out and the verification succeeded. See if revocation // checking still needs to be done before it can be marked as EV. if (completed_chain_crl_result == kCRLSetUnknown && - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) && !(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)) { // If this is an EV cert and it wasn't covered by CRLSets and revocation // checking wasn't already on, try again with revocation forced on.
diff --git a/net/cert/cert_verify_proc_mac_unittest.cc b/net/cert/cert_verify_proc_mac_unittest.cc index 79a0a08d..d813438 100644 --- a/net/cert/cert_verify_proc_mac_unittest.cc +++ b/net/cert/cert_verify_proc_mac_unittest.cc
@@ -170,7 +170,6 @@ CertificateList(), &verify_result); ASSERT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); EXPECT_FALSE(verify_result.has_sha1); ASSERT_TRUE(verify_result.verified_cert.get());
diff --git a/net/cert/cert_verify_proc_nss.cc b/net/cert/cert_verify_proc_nss.cc index c5e83c5..195a901 100644 --- a/net/cert/cert_verify_proc_nss.cc +++ b/net/cert/cert_verify_proc_nss.cc
@@ -384,10 +384,10 @@ } // Forward declarations. -SECStatus RetryPKIXVerifyCertWithWorkarounds( - CERTCertificate* cert_handle, int num_policy_oids, - bool cert_io_enabled, std::vector<CERTValInParam>* cvin, - CERTValOutParam* cvout); +SECStatus RetryPKIXVerifyCertWithWorkarounds(CERTCertificate* cert_handle, + int num_policy_oids, + std::vector<CERTValInParam>* cvin, + CERTValOutParam* cvout); SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle); // Call CERT_PKIXVerifyCert for the cert_handle. @@ -406,7 +406,6 @@ SECStatus PKIXVerifyCert(CERTCertificate* cert_handle, bool check_revocation, bool hard_fail, - bool cert_io_enabled, const SECOidTag* policy_oids, int num_policy_oids, CERTCertList* additional_trust_anchors, @@ -511,8 +510,8 @@ SECStatus rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, &cvin[0], cvout, NULL); if (rv != SECSuccess) { - rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, - cert_io_enabled, &cvin, cvout); + rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, &cvin, + cvout); } return rv; } @@ -520,10 +519,10 @@ // PKIXVerifyCert calls this function to work around some bugs in // CERT_PKIXVerifyCert. All the arguments of this function are either the // arguments or local variables of PKIXVerifyCert. -SECStatus RetryPKIXVerifyCertWithWorkarounds( - CERTCertificate* cert_handle, int num_policy_oids, - bool cert_io_enabled, std::vector<CERTValInParam>* cvin, - CERTValOutParam* cvout) { +SECStatus RetryPKIXVerifyCertWithWorkarounds(CERTCertificate* cert_handle, + int num_policy_oids, + std::vector<CERTValInParam>* cvin, + CERTValOutParam* cvout) { // We call this function when the first CERT_PKIXVerifyCert call in // PKIXVerifyCert failed, so we initialize |rv| to SECFailure. SECStatus rv = SECFailure; @@ -539,8 +538,7 @@ // missing intermediate CA certificate, and fail with the // SEC_ERROR_BAD_SIGNATURE error (NSS bug 524013), so we also retry with // cert_pi_useAIACertFetch on SEC_ERROR_BAD_SIGNATURE. - if (cert_io_enabled && - (nss_error == SEC_ERROR_UNKNOWN_ISSUER || + if ((nss_error == SEC_ERROR_UNKNOWN_ISSUER || nss_error == SEC_ERROR_BAD_SIGNATURE)) { DCHECK_EQ(cvin->back().type, cert_pi_end); cvin->pop_back(); @@ -756,7 +754,6 @@ cert_handle, rev_checking_enabled, true, /* hard fail is implied in EV. */ - flags & CertVerifier::VERIFY_CERT_IO_ENABLED, &ev_policy_oid, 1, additional_trust_anchors, @@ -830,8 +827,7 @@ CERTChainVerifyCallback* chain_verify_callback, CertVerifyResult* verify_result) { crypto::EnsureNSSInit(); - if (flags & CertVerifier::VERIFY_CERT_IO_ENABLED) - EnsureNSSHttpIOInit(); + EnsureNSSHttpIOInit(); // Convert the whole input chain into NSS certificates. Even though only the // target cert is explicitly referred to in this function, creating NSS @@ -898,11 +894,8 @@ EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); SECOidTag ev_policy_oid = SEC_OID_UNKNOWN; bool is_ev_candidate = - (flags & CertVerifier::VERIFY_EV_CERT) && IsEVCandidate(metadata, cert_handle, &ev_policy_oid); - bool cert_io_enabled = flags & CertVerifier::VERIFY_CERT_IO_ENABLED; bool check_revocation = - cert_io_enabled && (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED); if (check_revocation) verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; @@ -914,8 +907,8 @@ } SECStatus status = - PKIXVerifyCert(cert_handle, check_revocation, false, cert_io_enabled, - NULL, 0, trust_anchors.get(), &crlset_callback, cvout); + PKIXVerifyCert(cert_handle, check_revocation, false, NULL, 0, + trust_anchors.get(), &crlset_callback, cvout); bool known_root = false; HashValueVector hashes; @@ -934,7 +927,7 @@ // NSS tests for that feature. scoped_cvout.Clear(); verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - status = PKIXVerifyCert(cert_handle, true, true, cert_io_enabled, NULL, 0, + status = PKIXVerifyCert(cert_handle, true, true, NULL, 0, trust_anchors.get(), &crlset_callback, cvout); if (status == SECSuccess) { AppendPublicKeyHashesAndTestKnownRoot( @@ -1003,11 +996,8 @@ if (IsCertStatusError(verify_result->cert_status)) return MapCertStatusToNetError(verify_result->cert_status); - if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate) { - check_revocation |= - crl_set_result != kCRLSetOk && - cert_io_enabled && - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY); + if (is_ev_candidate) { + check_revocation |= crl_set_result != kCRLSetOk; if (check_revocation) verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 09352c3..5dddddac 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -348,7 +348,7 @@ CRLSet::ForTesting(false, &spki_sha256, "", "", {})); CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_EV_CERT; + int flags = 0; int error = Verify(chain.get(), "trustcenter.websecurity.symantec.com", flags, crl_set.get(), CertificateList(), &verify_result); EXPECT_THAT(error, IsOk()); @@ -370,7 +370,7 @@ ScopedTestRoot scoped_test_root(cert.get()); CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_EV_CERT; + int flags = 0; int error = Verify(cert.get(), "policy_test.example", flags, nullptr /*crl_set*/, CertificateList(), &verify_result); if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) { @@ -407,7 +407,7 @@ ScopedTestRoot scoped_test_root(cert.get()); CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_EV_CERT; + int flags = 0; int error = Verify(cert.get(), "policy_test.example", flags, nullptr /*crl_set*/, CertificateList(), &verify_result); if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
diff --git a/net/cert/cert_verify_proc_win.cc b/net/cert/cert_verify_proc_win.cc index 1768627..505122bf 100644 --- a/net/cert/cert_verify_proc_win.cc +++ b/net/cert/cert_verify_proc_win.cc
@@ -891,24 +891,22 @@ // Get the certificatePolicies extension of the certificate. std::unique_ptr<CERT_POLICIES_INFO, base::FreeDeleter> policies_info; LPSTR ev_policy_oid = NULL; - if (flags & CertVerifier::VERIFY_EV_CERT) { - GetCertPoliciesInfo(cert_list.get(), &policies_info); - if (policies_info.get()) { - EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); - for (DWORD i = 0; i < policies_info->cPolicyInfo; ++i) { - LPSTR policy_oid = policies_info->rgPolicyInfo[i].pszPolicyIdentifier; - if (metadata->IsEVPolicyOID(policy_oid)) { - ev_policy_oid = policy_oid; - chain_para.RequestedIssuancePolicy.dwType = USAGE_MATCH_TYPE_AND; - chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 1; - chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = - &ev_policy_oid; + GetCertPoliciesInfo(cert_list.get(), &policies_info); + if (policies_info) { + EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); + for (DWORD i = 0; i < policies_info->cPolicyInfo; ++i) { + LPSTR policy_oid = policies_info->rgPolicyInfo[i].pszPolicyIdentifier; + if (metadata->IsEVPolicyOID(policy_oid)) { + ev_policy_oid = policy_oid; + chain_para.RequestedIssuancePolicy.dwType = USAGE_MATCH_TYPE_AND; + chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 1; + chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = + &ev_policy_oid; - // De-prioritize the CA/Browser forum Extended Validation policy - // (2.23.140.1.1). See crbug.com/705285. - if (!EVRootCAMetadata::IsCaBrowserForumEvOid(ev_policy_oid)) - break; - } + // De-prioritize the CA/Browser forum Extended Validation policy + // (2.23.140.1.1). See https://crbug.com/705285. + if (!EVRootCAMetadata::IsCaBrowserForumEvOid(ev_policy_oid)) + break; } } } @@ -1031,10 +1029,8 @@ if (crl_set_result == kCRLSetRevoked) { verify_result->cert_status |= CERT_STATUS_REVOKED; - } else if (crl_set_result == kCRLSetUnknown && - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) && - !rev_checking_enabled && - ev_policy_oid != NULL) { + } else if (crl_set_result == kCRLSetUnknown && !rev_checking_enabled && + ev_policy_oid) { // We don't have fresh information about this chain from the CRLSet and // it's probably an EV certificate. Retry with online revocation checking. rev_checking_enabled = true;
diff --git a/net/cert/sth_observer.h b/net/cert/sth_observer.h deleted file mode 100644 index ad65a6b..0000000 --- a/net/cert/sth_observer.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_CERT_STH_OBSERVER_H_ -#define NET_CERT_STH_OBSERVER_H_ - -#include <set> - -#include "net/base/net_export.h" - -namespace net { - -namespace ct { - -struct SignedTreeHead; - -// Interface for receiving notifications of new STHs observed. -class NET_EXPORT STHObserver { - public: - virtual ~STHObserver() {} - - // Called with a new |sth| when one is observed. - virtual void NewSTHObserved(const SignedTreeHead& sth) = 0; -}; - -} // namespace ct - -} // namespace net - -#endif // NET_CERT_STH_OBSERVER_H_
diff --git a/net/cert/sth_reporter.h b/net/cert/sth_reporter.h deleted file mode 100644 index a62ad65..0000000 --- a/net/cert/sth_reporter.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_CERT_STH_REPORTER_H_ -#define NET_CERT_STH_REPORTER_H_ - -#include <set> - -#include "net/base/net_export.h" - -namespace net { - -namespace ct { - -class STHObserver; - -// Interface for registering/unregistering observers. -class NET_EXPORT STHReporter { - public: - virtual ~STHReporter() {} - - virtual void RegisterObserver(STHObserver* observer) = 0; - virtual void UnregisterObserver(STHObserver* observer) = 0; -}; - -} // namespace ct - -} // namespace net - -#endif // NET_CERT_STH_REPORTER_H_
diff --git a/net/cert_net/nss_ocsp_unittest.cc b/net/cert_net/nss_ocsp_unittest.cc index 09659f2..b4c5947a 100644 --- a/net/cert_net/nss_ocsp_unittest.cc +++ b/net/cert_net/nss_ocsp_unittest.cc
@@ -129,9 +129,8 @@ std::unique_ptr<CertVerifier> verifier_; }; -// Tests that when using NSS to verify certificates, and IO is enabled, -// that a request to fetch missing intermediate certificates is -// made successfully. +// Tests that when using NSS to verify certificates that a request to fetch +// missing intermediate certificates is made successfully. TEST_F(NssHttpTest, TestAia) { scoped_refptr<X509Certificate> test_cert( ImportCertFromFile(GetTestCertsDirectory(), "aia-cert.pem")); @@ -147,7 +146,7 @@ TestCompletionCallback test_callback; std::unique_ptr<CertVerifier::Request> request; - int flags = CertVerifier::VERIFY_CERT_IO_ENABLED; + int flags = 0; int error = verifier()->Verify( CertVerifier::RequestParams(test_cert, "aia-host.invalid", flags, std::string(), CertificateList()),
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 0939cdd..ffd247ea 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -346,36 +346,7 @@ } bool CanonicalCookie::IsDomainMatch(const std::string& host) const { - // Can domain match in two ways; as a domain cookie (where the cookie - // domain begins with ".") or as a host cookie (where it doesn't). - - // Some consumers of the CookieMonster expect to set cookies on - // URLs like http://.strange.url. To retrieve cookies in this instance, - // we allow matching as a host cookie even when the domain_ starts with - // a period. - if (host == domain_) - return true; - - // Domain cookie must have an initial ".". To match, it must be - // equal to url's host with initial period removed, or a suffix of - // it. - - // Arguably this should only apply to "http" or "https" cookies, but - // extension cookie tests currently use the funtionality, and if we - // ever decide to implement that it should be done by preventing - // such cookies from being set. - if (domain_.empty() || domain_[0] != '.') - return false; - - // The host with a "." prefixed. - if (domain_.compare(1, std::string::npos, host) == 0) - return true; - - // A pure suffix of the host (ok since we know the domain already - // starts with a ".") - return (host.length() > domain_.length() && - host.compare(host.length() - domain_.length(), - domain_.length(), domain_) == 0); + return cookie_util::IsDomainMatch(domain_, host); } bool CanonicalCookie::IncludeForRequestURL(const GURL& url,
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc index cf133b6..0a1ecac 100644 --- a/net/cookies/cookie_util.cc +++ b/net/cookies/cookie_util.cc
@@ -273,6 +273,39 @@ return GURL(scheme + "://" + host); } +bool IsDomainMatch(const std::string& domain, const std::string& host) { + // Can domain match in two ways; as a domain cookie (where the cookie + // domain begins with ".") or as a host cookie (where it doesn't). + + // Some consumers of the CookieMonster expect to set cookies on + // URLs like http://.strange.url. To retrieve cookies in this instance, + // we allow matching as a host cookie even when the domain_ starts with + // a period. + if (host == domain) + return true; + + // Domain cookie must have an initial ".". To match, it must be + // equal to url's host with initial period removed, or a suffix of + // it. + + // Arguably this should only apply to "http" or "https" cookies, but + // extension cookie tests currently use the funtionality, and if we + // ever decide to implement that it should be done by preventing + // such cookies from being set. + if (domain.empty() || domain[0] != '.') + return false; + + // The host with a "." prefixed. + if (domain.compare(1, std::string::npos, host) == 0) + return true; + + // A pure suffix of the host (ok since we know the domain already + // starts with a ".") + return (host.length() > domain.length() && + host.compare(host.length() - domain.length(), domain.length(), + domain) == 0); +} + void ParseRequestCookieLine(const std::string& header_value, ParsedRequestCookies* parsed_cookies) { std::string::const_iterator i = header_value.begin();
diff --git a/net/cookies/cookie_util.h b/net/cookies/cookie_util.h index 60e5f66..18a3bfb 100644 --- a/net/cookies/cookie_util.h +++ b/net/cookies/cookie_util.h
@@ -48,6 +48,11 @@ // Convenience for converting a cookie origin (domain and https pair) to a URL. NET_EXPORT GURL CookieOriginToURL(const std::string& domain, bool is_https); +// Returns true if the cookie |domain| matches the given |host| as described +// in section 5.1.3 of RFC 6265. +NET_EXPORT bool IsDomainMatch(const std::string& domain, + const std::string& host); + // A ParsedRequestCookie consists of the key and value of the cookie. typedef std::pair<base::StringPiece, base::StringPiece> ParsedRequestCookie; typedef std::vector<ParsedRequestCookie> ParsedRequestCookies;
diff --git a/net/cookies/cookie_util_unittest.cc b/net/cookies/cookie_util_unittest.cc index 7d55dd9..79c952bd 100644 --- a/net/cookies/cookie_util_unittest.cc +++ b/net/cookies/cookie_util_unittest.cc
@@ -250,6 +250,19 @@ cookie_util::GetEffectiveDomain("ftp", "www.example.com")); } +TEST(CookieUtilTest, TestIsDomainMatch) { + EXPECT_TRUE(cookie_util::IsDomainMatch("example.com", "example.com")); + EXPECT_FALSE(cookie_util::IsDomainMatch("www.example.com", "example.com")); + + EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "example.com")); + EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "www.example.com")); + EXPECT_FALSE(cookie_util::IsDomainMatch(".www.example.com", "example.com")); + + EXPECT_FALSE(cookie_util::IsDomainMatch("example.com", "example.de")); + EXPECT_FALSE(cookie_util::IsDomainMatch(".example.com", "example.de")); + EXPECT_FALSE(cookie_util::IsDomainMatch(".example.de", "example.de.vu")); +} + } // namespace } // namespace net
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index f2ba2ff..a2306c1 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h
@@ -127,6 +127,8 @@ private: FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart); + FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, + CreateWebSocketHandshakeStream); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow);
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index f86255e..50e2a8a 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -16303,342 +16303,6 @@ EXPECT_EQ("bar", foo); } -namespace { - -// Fake HttpStream that simply records calls to SetPriority(). -class FakeStream : public HttpStream, - public base::SupportsWeakPtr<FakeStream> { - public: - explicit FakeStream(RequestPriority priority) : priority_(priority) {} - ~FakeStream() override = default; - - RequestPriority priority() const { return priority_; } - - int InitializeStream(const HttpRequestInfo* request_info, - bool can_send_early, - RequestPriority priority, - const NetLogWithSource& net_log, - CompletionOnceCallback callback) override { - return ERR_IO_PENDING; - } - - int SendRequest(const HttpRequestHeaders& request_headers, - HttpResponseInfo* response, - CompletionOnceCallback callback) override { - ADD_FAILURE(); - return ERR_UNEXPECTED; - } - - int ReadResponseHeaders(CompletionOnceCallback callback) override { - ADD_FAILURE(); - return ERR_UNEXPECTED; - } - - int ReadResponseBody(IOBuffer* buf, - int buf_len, - CompletionOnceCallback callback) override { - ADD_FAILURE(); - return ERR_UNEXPECTED; - } - - void Close(bool not_reusable) override {} - - bool IsResponseBodyComplete() const override { - ADD_FAILURE(); - return false; - } - - bool IsConnectionReused() const override { - ADD_FAILURE(); - return false; - } - - void SetConnectionReused() override { ADD_FAILURE(); } - - bool CanReuseConnection() const override { return false; } - - int64_t GetTotalReceivedBytes() const override { - ADD_FAILURE(); - return 0; - } - - int64_t GetTotalSentBytes() const override { - ADD_FAILURE(); - return 0; - } - - bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override { - ADD_FAILURE(); - return false; - } - - bool GetAlternativeService( - AlternativeService* alternative_service) const override { - ADD_FAILURE(); - return false; - } - - void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); } - - void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override { - ADD_FAILURE(); - } - - bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; } - - Error GetTokenBindingSignature(crypto::ECPrivateKey* key, - TokenBindingType tb_type, - std::vector<uint8_t>* out) override { - ADD_FAILURE(); - return ERR_NOT_IMPLEMENTED; - } - - void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); } - - void PopulateNetErrorDetails(NetErrorDetails* details) override { return; } - - void SetPriority(RequestPriority priority) override { priority_ = priority; } - - HttpStream* RenewStreamForAuth() override { return NULL; } - - void SetRequestHeadersCallback(RequestHeadersCallback callback) override {} - - private: - RequestPriority priority_; - - DISALLOW_COPY_AND_ASSIGN(FakeStream); -}; - -// Fake HttpStreamRequest that simply records calls to SetPriority() -// and vends FakeStreams with its current priority. -class FakeStreamRequest : public HttpStreamRequest, - public base::SupportsWeakPtr<FakeStreamRequest> { - public: - FakeStreamRequest(RequestPriority priority, - HttpStreamRequest::Delegate* delegate) - : priority_(priority), - delegate_(delegate), - websocket_stream_create_helper_(NULL) {} - - FakeStreamRequest(RequestPriority priority, - HttpStreamRequest::Delegate* delegate, - WebSocketHandshakeStreamBase::CreateHelper* create_helper) - : priority_(priority), - delegate_(delegate), - websocket_stream_create_helper_(create_helper) {} - - ~FakeStreamRequest() override = default; - - RequestPriority priority() const { return priority_; } - - const WebSocketHandshakeStreamBase::CreateHelper* - websocket_stream_create_helper() const { - return websocket_stream_create_helper_; - } - - // Create a new FakeStream and pass it to the request's - // delegate. Returns a weak pointer to the FakeStream. - base::WeakPtr<FakeStream> FinishStreamRequest() { - auto fake_stream = std::make_unique<FakeStream>(priority_); - // Do this before calling OnStreamReady() as OnStreamReady() may - // immediately delete |fake_stream|. - base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr(); - delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream)); - return weak_stream; - } - - int RestartTunnelWithProxyAuth() override { - ADD_FAILURE(); - return ERR_UNEXPECTED; - } - - LoadState GetLoadState() const override { - ADD_FAILURE(); - return LoadState(); - } - - void SetPriority(RequestPriority priority) override { priority_ = priority; } - - bool was_alpn_negotiated() const override { return false; } - - NextProto negotiated_protocol() const override { return kProtoUnknown; } - - bool using_spdy() const override { return false; } - - const ConnectionAttempts& connection_attempts() const override { - static ConnectionAttempts no_attempts; - return no_attempts; - } - - private: - RequestPriority priority_; - HttpStreamRequest::Delegate* const delegate_; - WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_; - - DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest); -}; - -// Fake HttpStreamFactory that vends FakeStreamRequests. -class FakeStreamFactory : public HttpStreamFactory { - public: - FakeStreamFactory() = default; - ~FakeStreamFactory() override = default; - - // Returns a WeakPtr<> to the last HttpStreamRequest returned by - // RequestStream() (which may be NULL if it was destroyed already). - base::WeakPtr<FakeStreamRequest> last_stream_request() { - return last_stream_request_; - } - - std::unique_ptr<HttpStreamRequest> RequestStream( - const HttpRequestInfo& info, - RequestPriority priority, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - HttpStreamRequest::Delegate* delegate, - bool enable_ip_based_pooling, - bool enable_alternative_services, - const NetLogWithSource& net_log) override { - auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate); - last_stream_request_ = fake_request->AsWeakPtr(); - return std::move(fake_request); - } - - std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl( - const HttpRequestInfo& info, - RequestPriority priority, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - HttpStreamRequest::Delegate* delegate, - bool enable_ip_based_pooling, - bool enable_alternative_services, - const NetLogWithSource& net_log) override { - NOTREACHED(); - return nullptr; - } - - std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream( - const HttpRequestInfo& info, - RequestPriority priority, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - HttpStreamRequest::Delegate* delegate, - WebSocketHandshakeStreamBase::CreateHelper* create_helper, - bool enable_ip_based_pooling, - bool enable_alternative_services, - const NetLogWithSource& net_log) override { - auto fake_request = - std::make_unique<FakeStreamRequest>(priority, delegate, create_helper); - last_stream_request_ = fake_request->AsWeakPtr(); - return std::move(fake_request); - } - - void PreconnectStreams(int num_streams, - const HttpRequestInfo& info) override { - ADD_FAILURE(); - } - - const HostMappingRules* GetHostMappingRules() const override { - ADD_FAILURE(); - return NULL; - } - - void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, - const std::string& parent_absolute_name) const override { - ADD_FAILURE(); - } - - private: - base::WeakPtr<FakeStreamRequest> last_stream_request_; - - DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory); -}; - -} // namespace - -// Make sure that HttpNetworkTransaction passes on its priority to its -// stream request on start. -TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) { - std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - HttpNetworkSessionPeer peer(session.get()); - FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory)); - - HttpRequestInfo request; - HttpNetworkTransaction trans(LOW, session.get()); - - request.traffic_annotation = - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - - ASSERT_FALSE(fake_factory->last_stream_request()); - - TestCompletionCallback callback; - EXPECT_EQ(ERR_IO_PENDING, - trans.Start(&request, callback.callback(), NetLogWithSource())); - - base::WeakPtr<FakeStreamRequest> fake_request = - fake_factory->last_stream_request(); - ASSERT_TRUE(fake_request); - EXPECT_EQ(LOW, fake_request->priority()); -} - -// Make sure that HttpNetworkTransaction passes on its priority -// updates to its stream request. -TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) { - std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - HttpNetworkSessionPeer peer(session.get()); - FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory)); - - HttpRequestInfo request; - HttpNetworkTransaction trans(LOW, session.get()); - - request.traffic_annotation = - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - - TestCompletionCallback callback; - EXPECT_EQ(ERR_IO_PENDING, - trans.Start(&request, callback.callback(), NetLogWithSource())); - - base::WeakPtr<FakeStreamRequest> fake_request = - fake_factory->last_stream_request(); - ASSERT_TRUE(fake_request); - EXPECT_EQ(LOW, fake_request->priority()); - - trans.SetPriority(LOWEST); - ASSERT_TRUE(fake_request); - EXPECT_EQ(LOWEST, fake_request->priority()); -} - -// Make sure that HttpNetworkTransaction passes on its priority -// updates to its stream. -TEST_F(HttpNetworkTransactionTest, SetStreamPriority) { - std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - HttpNetworkSessionPeer peer(session.get()); - FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory)); - - HttpRequestInfo request; - HttpNetworkTransaction trans(LOW, session.get()); - - request.traffic_annotation = - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - - TestCompletionCallback callback; - EXPECT_EQ(ERR_IO_PENDING, - trans.Start(&request, callback.callback(), NetLogWithSource())); - - base::WeakPtr<FakeStreamRequest> fake_request = - fake_factory->last_stream_request(); - ASSERT_TRUE(fake_request); - base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest(); - ASSERT_TRUE(fake_stream); - EXPECT_EQ(LOW, fake_stream->priority()); - - trans.SetPriority(LOWEST); - EXPECT_EQ(LOWEST, fake_stream->priority()); -} - // Tests that when a used socket is returned to the SSL socket pool, it's closed // if the transport socket pool is stalled on the global socket limit. TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) { @@ -17302,35 +16966,61 @@ } // namespace TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) { - std::string test_cases[] = {"ws://www.example.org/", - "wss://www.example.org/"}; - for (size_t i = 0; i < arraysize(test_cases); ++i) { - std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - HttpNetworkSessionPeer peer(session.get()); - FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory)); + for (bool secure : {true, false}) { + MockWrite data_writes[] = { + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Origin: http://www.example.org\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Extensions: permessage-deflate; " + "client_max_window_bits\r\n\r\n")}; + + MockRead data_reads[] = { + MockRead("HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")}; + + StaticSocketDataProvider data(data_reads, arraysize(data_reads), + data_writes, arraysize(data_writes)); + session_deps_.socket_factory->AddSocketDataProvider(&data); + SSLSocketDataProvider ssl(ASYNC, OK); + if (secure) + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); HttpRequestInfo request; request.method = "GET"; - request.url = GURL(test_cases[i]); + request.url = + GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/"); + AddWebSocketHeaders(&request.extra_headers); request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper; + TestWebSocketHandshakeStreamCreateHelper + websocket_handshake_stream_create_helper; + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(LOW, session.get()); trans.SetWebSocketHandshakeStreamCreateHelper( - &websocket_stream_create_helper); + &websocket_handshake_stream_create_helper); TestCompletionCallback callback; - EXPECT_EQ(ERR_IO_PENDING, - trans.Start(&request, callback.callback(), NetLogWithSource())); + int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - base::WeakPtr<FakeStreamRequest> fake_request = - fake_factory->last_stream_request(); - ASSERT_TRUE(fake_request); - EXPECT_EQ(&websocket_stream_create_helper, - fake_request->websocket_stream_create_helper()); + const HttpStreamRequest* stream_request = trans.stream_request_.get(); + ASSERT_TRUE(stream_request); + EXPECT_EQ(&websocket_handshake_stream_create_helper, + stream_request->websocket_handshake_stream_create_helper()); + + rv = callback.WaitForResult(); + EXPECT_THAT(rv, IsOk()); + + EXPECT_TRUE(data.AllReadDataConsumed()); + EXPECT_TRUE(data.AllWriteDataConsumed()); } }
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index fe5d77a..7b0795027 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h
@@ -188,6 +188,11 @@ // Returns socket-layer connection attempts made for this stream request. virtual const ConnectionAttempts& connection_attempts() const = 0; + + // Returns the WebSocketHandshakeStreamBase::CreateHelper for this stream + // request. + virtual WebSocketHandshakeStreamBase::CreateHelper* + websocket_handshake_stream_create_helper() const = 0; }; // The HttpStreamFactory defines an interface for creating usable HttpStreams.
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 1374a69..05dc57b 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -120,9 +120,6 @@ SSLConfig server_ssl_config; SSLConfig proxy_ssl_config; session_->GetSSLConfig(request_info, &server_ssl_config, &proxy_ssl_config); - // All preconnects should perform EV certificate verification. - server_ssl_config.verify_ev_cert = true; - proxy_ssl_config.verify_ev_cert = true; auto job_controller = std::make_unique<JobController>( this, nullptr, session_, job_factory_.get(), request_info,
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 87a81db5..3b419e9 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -1377,9 +1377,6 @@ ssl_config->false_start_enabled = false; } - if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) - ssl_config->verify_ev_cert = true; - // Disable Channel ID if privacy mode is enabled. if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) ssl_config->channel_id_enabled = false;
diff --git a/net/http/http_stream_factory_impl_request.cc b/net/http/http_stream_factory_impl_request.cc index 3579aea..35d8767 100644 --- a/net/http/http_stream_factory_impl_request.cc +++ b/net/http/http_stream_factory_impl_request.cc
@@ -110,4 +110,10 @@ connection_attempts_.push_back(attempt); } +WebSocketHandshakeStreamBase::CreateHelper* +HttpStreamFactoryImpl::Request::websocket_handshake_stream_create_helper() + const { + return websocket_handshake_stream_create_helper_; +} + } // namespace net
diff --git a/net/http/http_stream_factory_impl_request.h b/net/http/http_stream_factory_impl_request.h index 2418dfb..f5e7363 100644 --- a/net/http/http_stream_factory_impl_request.h +++ b/net/http/http_stream_factory_impl_request.h
@@ -98,9 +98,7 @@ void AddConnectionAttempts(const ConnectionAttempts& attempts); WebSocketHandshakeStreamBase::CreateHelper* - websocket_handshake_stream_create_helper() { - return websocket_handshake_stream_create_helper_; - } + websocket_handshake_stream_create_helper() const override; void OnStreamReadyOnPooledConnection(const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info,
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h index 53e9fc6..8773215 100644 --- a/net/quic/core/quic_flags_list.h +++ b/net/quic/core/quic_flags_list.h
@@ -182,7 +182,7 @@ QUIC_FLAG( bool, FLAGS_quic_reloadable_flag_quic_clear_queued_packets_before_sending_connectivity_probing, - true) + false) // When true, this flag has QuicConnection call // QuicConnectionVisitorInterface::OnSuccessfulVersionNegotiation earlier when
diff --git a/net/quic/core/quic_packet_creator.cc b/net/quic/core/quic_packet_creator.cc index 759f5c0..a137c06 100644 --- a/net/quic/core/quic_packet_creator.cc +++ b/net/quic/core/quic_packet_creator.cc
@@ -645,8 +645,9 @@ void QuicPacketCreator::SetTransmissionType(TransmissionType type) { DCHECK(can_set_transmission_type_); - QUIC_DVLOG(1) << "Setting Transmission type to " - << QuicUtils::TransmissionTypeToString(type); + QUIC_DVLOG_IF(1, type != packet_.transmission_type) + << "Setting Transmission type to " + << QuicUtils::TransmissionTypeToString(type); packet_.transmission_type = type; }
diff --git a/net/quic/platform/api/quic_logging.h b/net/quic/platform/api/quic_logging.h index 14b1bff..798bfbf8 100644 --- a/net/quic/platform/api/quic_logging.h +++ b/net/quic/platform/api/quic_logging.h
@@ -13,6 +13,8 @@ // they would simply be translated to LOG. #define QUIC_DVLOG(verbose_level) QUIC_DVLOG_IMPL(verbose_level) +#define QUIC_DVLOG_IF(verbose_level, condition) \ + QUIC_DVLOG_IF_IMPL(verbose_level, condition) #define QUIC_DLOG(severity) QUIC_DLOG_IMPL(severity) #define QUIC_DLOG_IF(severity, condition) QUIC_DLOG_IF_IMPL(severity, condition) #define QUIC_VLOG(verbose_level) QUIC_VLOG_IMPL(verbose_level)
diff --git a/net/quic/platform/impl/quic_logging_impl.h b/net/quic/platform/impl/quic_logging_impl.h index 37aa990b..fb9add3 100644 --- a/net/quic/platform/impl/quic_logging_impl.h +++ b/net/quic/platform/impl/quic_logging_impl.h
@@ -42,6 +42,8 @@ #define QUIC_CHROMIUM_DLOG_IF_DFATAL(condition) DLOG_IF(DFATAL, condition) #define QUIC_DVLOG_IMPL(verbose_level) DVLOG(verbose_level) +#define QUIC_DVLOG_IF_IMPL(verbose_level, condition) \ + DVLOG_IF(verbose_level, condition) #if defined(OS_WIN) // wingdi.h defines ERROR to be 0. When we call QUIC_DLOG(ERROR), it gets
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc index 5f7e415..f9b728b3 100644 --- a/net/reporting/reporting_delivery_agent.cc +++ b/net/reporting/reporting_delivery_agent.cc
@@ -71,8 +71,10 @@ // ReportingObserver implementation: void OnCacheUpdated() override { - if (CacheHasReports()) + if (CacheHasReports() && !timer_->IsRunning()) { + SendReports(); StartTimer(); + } } private:
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index afd1f89..c1e8b2c 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -57,9 +57,7 @@ const std::string kType_ = "type"; }; -TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) { - static const int kAgeMillis = 12345; - +TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) { base::DictionaryValue body; body.SetString("key", "value"); @@ -67,7 +65,49 @@ cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); - tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis)); + // Upload is automatically started when cache is modified. + + ASSERT_EQ(1u, pending_uploads().size()); + EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url()); + { + auto value = pending_uploads()[0]->GetValue(); + + base::ListValue* list; + ASSERT_TRUE(value->GetAsList(&list)); + EXPECT_EQ(1u, list->GetSize()); + + base::DictionaryValue* report; + ASSERT_TRUE(list->GetDictionary(0, &report)); + EXPECT_EQ(4u, report->size()); + + ExpectDictIntegerValue(0, *report, "age"); + ExpectDictStringValue(kType_, *report, "type"); + ExpectDictStringValue(kUrl_.spec(), *report, "url"); + ExpectDictDictionaryValue(body, *report, "report"); + } + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + + // Successful upload should remove delivered reports. + std::vector<const ReportingReport*> reports; + cache()->GetReports(&reports); + EXPECT_TRUE(reports.empty()); + + // TODO(juliatuttle): Check that BackoffEntry was informed of success. +} + +TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) { + base::DictionaryValue body; + body.SetString("key", "value"); + + // Trigger and complete an upload to start the delivery timer. + SetClient(kOrigin_, kEndpoint_, kGroup_); + cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0, + tick_clock()->NowTicks(), 0); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + + SetClient(kOrigin_, kEndpoint_, kGroup_); + cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0, + tick_clock()->NowTicks(), 0); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -85,7 +125,7 @@ ASSERT_TRUE(list->GetDictionary(0, &report)); EXPECT_EQ(4u, report->size()); - ExpectDictIntegerValue(kAgeMillis, *report, "age"); + ExpectDictIntegerValue(0, *report, "age"); ExpectDictStringValue(kType_, *report, "type"); ExpectDictStringValue(kUrl_.spec(), *report, "url"); ExpectDictDictionaryValue(body, *report, "report"); @@ -236,8 +276,6 @@ std::make_unique<base::DictionaryValue>(), 0, tick_clock()->NowTicks(), 0); - EXPECT_TRUE(delivery_timer()->IsRunning()); - delivery_timer()->Fire(); ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused()); // Remove the report while the upload is running.
diff --git a/net/socket/tcp_socket_unittest.cc b/net/socket/tcp_socket_unittest.cc index c9d4c716..eadda3f 100644 --- a/net/socket/tcp_socket_unittest.cc +++ b/net/socket/tcp_socket_unittest.cc
@@ -38,6 +38,24 @@ namespace { +// IOBuffer with the ability to invoke a callback when destroyed. Useful for +// checking for leaks. +class IOBufferWithDestructionCallback : public IOBufferWithSize { + public: + explicit IOBufferWithDestructionCallback(base::OnceClosure on_destroy_closure) + : IOBufferWithSize(1024), + on_destroy_closure_(std::move(on_destroy_closure)) { + DCHECK(on_destroy_closure_); + } + + protected: + ~IOBufferWithDestructionCallback() override { + std::move(on_destroy_closure_).Run(); + } + + base::OnceClosure on_destroy_closure_; +}; + class TestSocketPerformanceWatcher : public SocketPerformanceWatcher { public: explicit TestSocketPerformanceWatcher(bool should_notify_updated_rtt) @@ -419,6 +437,96 @@ ASSERT_EQ(message, received_message); } +// Destroy a TCPSocket while there's a pending read, and make sure the read +// IOBuffer that the socket was holding on to is destroyed. +// See https://crbug.com/804868. +TEST_F(TCPSocketTest, DestroyWithPendingRead) { + ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); + + // Create a connected socket. + + TestCompletionCallback connect_callback; + std::unique_ptr<TCPSocket> connecting_socket = + std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource()); + int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4); + ASSERT_THAT(result, IsOk()); + int connect_result = + connecting_socket->Connect(local_address_, connect_callback.callback()); + + TestCompletionCallback accept_callback; + std::unique_ptr<TCPSocket> accepted_socket; + IPEndPoint accepted_address; + result = socket_.Accept(&accepted_socket, &accepted_address, + accept_callback.callback()); + ASSERT_THAT(accept_callback.GetResult(result), IsOk()); + ASSERT_TRUE(accepted_socket.get()); + ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk()); + + // Try to read from the socket, but never write anything to the other end. + base::RunLoop run_loop; + scoped_refptr<IOBufferWithDestructionCallback> read_buffer( + base::MakeRefCounted<IOBufferWithDestructionCallback>( + run_loop.QuitClosure())); + TestCompletionCallback read_callback; + EXPECT_EQ(ERR_IO_PENDING, + connecting_socket->Read(read_buffer.get(), read_buffer->size(), + read_callback.callback())); + + // Release the handle to the read buffer and destroy the socket. Make sure the + // read buffer is destroyed. + read_buffer = nullptr; + connecting_socket.reset(); + run_loop.Run(); +} + +// Destroy a TCPSocket while there's a pending write, and make sure the write +// IOBuffer that the socket was holding on to is destroyed. +TEST_F(TCPSocketTest, DestroyWithPendingWrite) { + ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); + + // Create a connected socket. + + TestCompletionCallback connect_callback; + std::unique_ptr<TCPSocket> connecting_socket = + std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource()); + int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4); + ASSERT_THAT(result, IsOk()); + int connect_result = + connecting_socket->Connect(local_address_, connect_callback.callback()); + + TestCompletionCallback accept_callback; + std::unique_ptr<TCPSocket> accepted_socket; + IPEndPoint accepted_address; + result = socket_.Accept(&accepted_socket, &accepted_address, + accept_callback.callback()); + ASSERT_THAT(accept_callback.GetResult(result), IsOk()); + ASSERT_TRUE(accepted_socket.get()); + ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk()); + + // Repeatedly write to the socket until an operation does not complete + // synchronously. + base::RunLoop run_loop; + scoped_refptr<IOBufferWithDestructionCallback> write_buffer( + base::MakeRefCounted<IOBufferWithDestructionCallback>( + run_loop.QuitClosure())); + memset(write_buffer->data(), '1', write_buffer->size()); + TestCompletionCallback write_callback; + while (true) { + int result = connecting_socket->Write( + write_buffer.get(), write_buffer->size(), write_callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS); + if (result == ERR_IO_PENDING) + break; + ASSERT_LT(0, result); + } + + // Release the handle to the read buffer and destroy the socket. Make sure the + // write buffer is destroyed. + write_buffer = nullptr; + connecting_socket.reset(); + run_loop.Run(); +} + // These tests require kernel support for tcp_info struct, and so they are // enabled only on certain platforms. #if defined(TCP_INFO) || defined(OS_LINUX)
diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc index 4ecab0b60..f7448fd5 100644 --- a/net/socket/tcp_socket_win.cc +++ b/net/socket/tcp_socket_win.cc
@@ -114,10 +114,13 @@ // The TCPSocketWin is going away. void Detach() { socket_ = NULL; } - // The separate OVERLAPPED variables for asynchronous operation. - // |read_overlapped_| is used for both Connect() and Read(). - // |write_overlapped_| is only used for Write(); - OVERLAPPED read_overlapped_; + // Event handle for monitoring connect and read events through WSAEventSelect. + HANDLE read_event_; + + // OVERLAPPED variable for overlapped writes. + // TODO(mmenke): Can writes be switched to WSAEventSelect as well? That would + // allow removing this class. The only concern is whether that would have a + // negative perf impact. OVERLAPPED write_overlapped_; // The buffers used in Read() and Write(). @@ -174,16 +177,14 @@ }; TCPSocketWin::Core::Core(TCPSocketWin* socket) - : read_buffer_length_(0), + : read_event_(WSACreateEvent()), + read_buffer_length_(0), write_buffer_length_(0), non_blocking_reads_initialized_(false), socket_(socket), reader_(this), writer_(this) { - memset(&read_overlapped_, 0, sizeof(read_overlapped_)); memset(&write_overlapped_, 0, sizeof(write_overlapped_)); - - read_overlapped_.hEvent = WSACreateEvent(); write_overlapped_.hEvent = WSACreateEvent(); } @@ -192,17 +193,15 @@ read_watcher_.StopWatching(); write_watcher_.StopWatching(); - WSACloseEvent(read_overlapped_.hEvent); - memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); + WSACloseEvent(read_event_); WSACloseEvent(write_overlapped_.hEvent); memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_)); } void TCPSocketWin::Core::WatchForRead() { - // We grab an extra reference because there is an IO operation in progress. - // Balanced in ReadDelegate::OnObjectSignaled(). - AddRef(); - read_watcher_.StartWatchingOnce(read_overlapped_.hEvent, &reader_); + // Reads use WSAEventSelect, which closesocket() cancels so unlike writes, + // there's no need to increment the reference count here. + read_watcher_.StartWatchingOnce(read_event_, &reader_); } void TCPSocketWin::Core::WatchForWrite() { @@ -213,15 +212,12 @@ } void TCPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) { - DCHECK_EQ(object, core_->read_overlapped_.hEvent); - if (core_->socket_) { - if (core_->socket_->waiting_connect_) - core_->socket_->DidCompleteConnect(); - else - core_->socket_->DidSignalRead(); - } - - core_->Release(); + DCHECK_EQ(object, core_->read_event_); + DCHECK(core_->socket_); + if (core_->socket_->waiting_connect_) + core_->socket_->DidCompleteConnect(); + else + core_->socket_->DidSignalRead(); } void TCPSocketWin::Core::WriteDelegate::OnObjectSignaled( @@ -230,6 +226,7 @@ if (core_->socket_) core_->socket_->DidCompleteWrite(); + // Matches the AddRef() in WatchForWrite(). core_->Release(); } @@ -493,7 +490,7 @@ DCHECK(read_if_ready_callback_.is_null()); if (!core_->non_blocking_reads_initialized_) { - WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_READ | FD_CLOSE); + WSAEventSelect(socket_, core_->read_event_, FD_READ | FD_CLOSE); core_->non_blocking_reads_initialized_ = true; } int rv = recv(socket_, buf->data(), buf_len, 0); @@ -672,8 +669,8 @@ if (!accept_callback_.is_null()) { accept_watcher_.StopWatching(); - accept_socket_ = NULL; - accept_address_ = NULL; + accept_socket_ = nullptr; + accept_address_ = nullptr; accept_callback_.Reset(); } @@ -683,16 +680,12 @@ } if (core_.get()) { - if (waiting_connect_) { - // We closed the socket, so this notification will never come. - // From MSDN' WSAEventSelect documentation: - // "Closing a socket with closesocket also cancels the association and - // selection of network events specified in WSAEventSelect for the - // socket". - core_->Release(); - } core_->Detach(); - core_ = NULL; + core_ = nullptr; + + // |core_| may still exist and own a reference to itself, if there's a + // pending write. It has to stay alive until the operation completes, even + // when the socket is closed. This is not the case for reads. } waiting_connect_ = false; @@ -808,7 +801,7 @@ // WSAEventSelect sets the socket to non-blocking mode as a side effect. // Our connect() and recv() calls require that the socket be non-blocking. - WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); + WSAEventSelect(socket_, core_->read_event_, FD_CONNECT); SockaddrStorage storage; if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) @@ -827,7 +820,7 @@ // and we don't know if it's correct. NOTREACHED(); - if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) + if (ResetEventIfSignaled(core_->read_event_)) return OK; } else { int os_error = WSAGetLastError(); @@ -912,8 +905,7 @@ int result; WSANETWORKEVENTS events; - int rv = - WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); + int rv = WSAEnumNetworkEvents(socket_, core_->read_event_, &events); int os_error = WSAGetLastError(); if (rv == SOCKET_ERROR) { NOTREACHED(); @@ -977,8 +969,7 @@ int os_error = 0; WSANETWORKEVENTS network_events; - int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, - &network_events); + int rv = WSAEnumNetworkEvents(socket_, core_->read_event_, &network_events); os_error = WSAGetLastError(); if (rv == SOCKET_ERROR) {
diff --git a/net/spdy/chromium/spdy_network_transaction_unittest.cc b/net/spdy/chromium/spdy_network_transaction_unittest.cc index b427ee87..9d3202ac 100644 --- a/net/spdy/chromium/spdy_network_transaction_unittest.cc +++ b/net/spdy/chromium/spdy_network_transaction_unittest.cc
@@ -593,6 +593,43 @@ EXPECT_EQ("hello!", out.response_data); } +TEST_F(SpdyNetworkTransactionTest, SetPriority) { + for (bool set_priority_before_starting_transaction : {true, false}) { + SpdyTestUtil spdy_test_util; + SpdySerializedFrame req( + spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); + MockWrite writes[] = {CreateMockWrite(req, 0)}; + + SpdySerializedFrame resp( + spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1)); + SpdySerializedFrame body(spdy_test_util.ConstructSpdyDataFrame(1, true)); + MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2), + MockRead(ASYNC, 0, 3)}; + + SequencedSocketData data(reads, arraysize(reads), writes, + arraysize(writes)); + NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr); + helper.RunPreTestSetup(); + helper.AddData(&data); + + if (set_priority_before_starting_transaction) { + helper.trans()->SetPriority(LOWEST); + EXPECT_TRUE(helper.StartDefaultTest()); + } else { + EXPECT_TRUE(helper.StartDefaultTest()); + helper.trans()->SetPriority(LOWEST); + } + + helper.FinishDefaultTest(); + helper.VerifyDataConsumed(); + + TransactionHelperResult out = helper.output(); + EXPECT_THAT(out.rv, IsOk()); + EXPECT_EQ("HTTP/1.1 200", out.status_line); + EXPECT_EQ("hello!", out.response_data); + } +} + TEST_F(SpdyNetworkTransactionTest, GetAtEachPriority) { for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY; p = RequestPriority(p + 1)) {
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc index 50538a0..92f7308b 100644 --- a/net/ssl/ssl_config.cc +++ b/net/ssl/ssl_config.cc
@@ -34,8 +34,6 @@ false_start_enabled(true), require_ecdhe(false), send_client_cert(false), - verify_ev_cert(false), - cert_io_enabled(true), renego_allowed_default(false) {} SSLConfig::SSLConfig(const SSLConfig& other) = default; @@ -58,10 +56,6 @@ int flags = 0; if (rev_checking_enabled) flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; - if (verify_ev_cert) - flags |= CertVerifier::VERIFY_EV_CERT; - if (cert_io_enabled) - flags |= CertVerifier::VERIFY_CERT_IO_ENABLED; if (rev_checking_required_local_anchors) flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; if (sha1_local_anchors_enabled)
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h index bbfe459..122e2105 100644 --- a/net/ssl/ssl_config.h +++ b/net/ssl/ssl_config.h
@@ -150,15 +150,6 @@ // True if we should send client_cert to the server. bool send_client_cert; - bool verify_ev_cert; // True if we should verify the certificate for EV. - - // If cert_io_enabled is false, then certificate verification will not - // result in additional HTTP requests. (For example: to fetch missing - // intermediates or to perform OCSP/CRL fetches.) It also implies that online - // revocation checking is disabled. - // NOTE: Only used by NSS. - bool cert_io_enabled; - // The list of application level protocols supported with ALPN (Application // Layer Protocol Negotation), in decreasing order of preference. Protocols // will be advertised in this order during TLS handshake.
diff --git a/net/ssl/ssl_config_unittest.cc b/net/ssl/ssl_config_unittest.cc index e3fca97..11001b4 100644 --- a/net/ssl/ssl_config_unittest.cc +++ b/net/ssl/ssl_config_unittest.cc
@@ -13,13 +13,9 @@ void CheckCertVerifyFlags(SSLConfig* ssl_config, bool rev_checking_enabled, - bool verify_ev_cert, - bool cert_io_enabled, bool rev_checking_required_local_anchors, bool symantec_enforcement_disabled) { ssl_config->rev_checking_enabled = rev_checking_enabled; - ssl_config->verify_ev_cert = verify_ev_cert; - ssl_config->cert_io_enabled = cert_io_enabled; ssl_config->rev_checking_required_local_anchors = rev_checking_required_local_anchors; ssl_config->symantec_enforcement_disabled = symantec_enforcement_disabled; @@ -27,8 +23,6 @@ int flags = ssl_config->GetCertVerifyFlags(); EXPECT_EQ(rev_checking_enabled, !!(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)); - EXPECT_EQ(verify_ev_cert, !!(flags & CertVerifier::VERIFY_EV_CERT)); - EXPECT_EQ(cert_io_enabled, !!(flags & CertVerifier::VERIFY_CERT_IO_ENABLED)); EXPECT_EQ( rev_checking_required_local_anchors, !!(flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS)); @@ -42,52 +36,28 @@ SSLConfig ssl_config; CheckCertVerifyFlags(&ssl_config, /*rev_checking_enabled=*/true, - /*verify_ev_cert=*/true, - /*cert_io_enabled=*/true, /*rev_checking_required_local_anchors=*/true, /*symantec_enforcement_disabled=*/true); CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/false, - /*verify_ev_cert=*/false, - /*cert_io_enabled=*/false, - /*rev_checking_required_local_anchors=*/false, - /*symantec_enforcement_disabled=*/false); - - CheckCertVerifyFlags(&ssl_config, /*rev_checking_enabled=*/true, - /*verify_ev_cert=*/false, - /*cert_io_enabled=*/false, /*rev_checking_required_local_anchors=*/false, /*symantec_enforcement_disabled=*/false); CheckCertVerifyFlags(&ssl_config, /*rev_checking_enabled=*/false, - /*verify_ev_cert=*/true, - /*cert_io_enabled=*/false, - /*rev_checking_required_local_anchors=*/false, - /*symantec_enforcement_disabled=*/false); - - CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/false, - /*verify_ev_cert=*/false, - /*cert_io_enabled=*/true, - /*rev_checking_required_local_anchors=*/false, - /*symantec_enforcement_disabled=*/false); - - CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/false, - /*verify_ev_cert=*/false, - /*cert_io_enabled=*/false, /*rev_checking_required_local_anchors=*/true, /*symantec_enforcement_disabled=*/false); CheckCertVerifyFlags(&ssl_config, /*rev_checking_enabled=*/false, - /*verify_ev_cert=*/false, - /*cert_io_enabled=*/true, /*rev_checking_required_local_anchors=*/false, /*symantec_enforcement_disabled=*/true); + + CheckCertVerifyFlags(&ssl_config, + /*rev_checking_enabled=*/false, + /*rev_checking_required_local_anchors=*/false, + /*symantec_enforcement_disabled=*/false); } } // namespace net
diff --git a/net/test/embedded_test_server/embedded_test_server_unittest.cc b/net/test/embedded_test_server/embedded_test_server_unittest.cc index e9fdec8a..d6f74a11 100644 --- a/net/test/embedded_test_server/embedded_test_server_unittest.cc +++ b/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -4,6 +4,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" +#include <tuple> #include <utility> #include "base/macros.h" @@ -495,8 +496,7 @@ // where there is no MessageLoop available on the thread at EmbeddedTestServer // initialization and/or destruction. -typedef std::tr1::tuple<bool, bool, EmbeddedTestServer::Type> - ThreadingTestParams; +typedef std::tuple<bool, bool, EmbeddedTestServer::Type> ThreadingTestParams; class EmbeddedTestServerThreadingTest : public testing::TestWithParam<ThreadingTestParams> {}; @@ -570,9 +570,9 @@ // of a MessageLoop - the test suite already sets up a MessageLoop for the // main test thread. base::PlatformThreadHandle thread_handle; - EmbeddedTestServerThreadingTestDelegate delegate( - std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()), - std::tr1::get<2>(GetParam())); + EmbeddedTestServerThreadingTestDelegate delegate(std::get<0>(GetParam()), + std::get<1>(GetParam()), + std::get<2>(GetParam())); ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle)); base::PlatformThread::Join(thread_handle); }
diff --git a/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc b/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc index 9e74531..a858091 100644 --- a/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc +++ b/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
@@ -150,8 +150,7 @@ } // TODO(mattm): add command line flags to configure VerifyFlags. - int flags = net::CertVerifier::VERIFY_EV_CERT | - net::CertVerifier::VERIFY_CERT_IO_ENABLED; + int flags = 0; if (!x509_additional_trust_anchors.empty() && !cert_verify_proc->SupportsAdditionalTrustAnchors()) {
diff --git a/net/tools/cert_verify_tool/verify_using_path_builder.cc b/net/tools/cert_verify_tool/verify_using_path_builder.cc index 7a936025..8621c76 100644 --- a/net/tools/cert_verify_tool/verify_using_path_builder.cc +++ b/net/tools/cert_verify_tool/verify_using_path_builder.cc
@@ -174,7 +174,6 @@ // TODO(mattm): add command line flags to configure using // CertIssuerSourceAia - // (similar to VERIFY_CERT_IO_ENABLED flag for CertVerifyProc). DCHECK(net::GetGlobalCertNetFetcher()); net::CertIssuerSourceAia aia_cert_issuer_source( net::GetGlobalCertNetFetcher());
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py index 8d2369b..345c4cd 100755 --- a/net/tools/testserver/testserver.py +++ b/net/tools/testserver/testserver.py
@@ -124,6 +124,13 @@ pass +class ThreadingHTTPServer(SocketServer.ThreadingMixIn, + HTTPServer): + """This variant of HTTPServer creates a new thread for every connection. It + should only be used with handlers that are known to be threadsafe.""" + + pass + class OCSPServer(testserver_base.ClientRestrictingServerMixIn, testserver_base.BrokenPipeHandlerMixIn, BaseHTTPServer.HTTPServer): @@ -2119,7 +2126,7 @@ elif self.options.server_type == SERVER_BASIC_AUTH_PROXY: BasicAuthProxyRequestHandler.redirect_connect_to_localhost = \ self.options.redirect_connect_to_localhost - server = HTTPServer((host, port), BasicAuthProxyRequestHandler) + server = ThreadingHTTPServer((host, port), BasicAuthProxyRequestHandler) print 'BasicAuthProxy server started on port %d...' % server.server_port server_data['port'] = server.server_port elif self.options.server_type == SERVER_FTP:
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 8001e35..4756d558 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -3731,12 +3731,10 @@ class TestSSLConfigService : public SSLConfigService { public: - TestSSLConfigService(bool ev_enabled, - bool online_rev_checking, + TestSSLConfigService(bool online_rev_checking, bool rev_checking_required_local_anchors, bool token_binding_enabled) - : ev_enabled_(ev_enabled), - online_rev_checking_(online_rev_checking), + : online_rev_checking_(online_rev_checking), rev_checking_required_local_anchors_( rev_checking_required_local_anchors), token_binding_enabled_(token_binding_enabled), @@ -3750,7 +3748,6 @@ void GetSSLConfig(SSLConfig* config) override { *config = SSLConfig(); config->rev_checking_enabled = online_rev_checking_; - config->verify_ev_cert = ev_enabled_; config->rev_checking_required_local_anchors = rev_checking_required_local_anchors_; config->version_min = min_version_; @@ -3764,7 +3761,6 @@ ~TestSSLConfigService() override = default; private: - const bool ev_enabled_; const bool online_rev_checking_; const bool rev_checking_required_local_anchors_; const bool token_binding_enabled_; @@ -3780,7 +3776,7 @@ void SetUp() override { default_context_.set_ssl_config_service( - new TestSSLConfigService(false, false, false, true)); + new TestSSLConfigService(false, false, true)); channel_id_service_.reset( new ChannelIDService(new DefaultChannelIDStore(NULL))); default_context_.set_channel_id_service(channel_id_service_.get()); @@ -10216,7 +10212,7 @@ public: HTTPSFallbackTest() : context_(true) { ssl_config_service_ = new TestSSLConfigService( - true /* check for EV */, false /* online revocation checking */, + false /* online revocation checking */, false /* require rev. checking for local anchors */, false /* token binding enabled */); context_.set_ssl_config_service(ssl_config_service_.get()); @@ -10507,11 +10503,11 @@ // connetions to testserver. This can be overridden in test subclasses for // different behaviour. virtual void SetupContext() { - context_.set_ssl_config_service(new TestSSLConfigService( - true /* check for EV */, true /* online revocation checking */, - false /* require rev. checking for local + context_.set_ssl_config_service( + new TestSSLConfigService(true /* online revocation checking */, + false /* require rev. checking for local anchors */, - false /* token binding enabled */)); + false /* token binding enabled */)); } std::unique_ptr<ScopedTestRoot> test_root_; @@ -11231,7 +11227,7 @@ public: void SetupContext() override { context_.set_ssl_config_service(new TestSSLConfigService( - false /* check for EV */, false /* online revocation checking */, + false /* online revocation checking */, false /* require rev. checking for local anchors */, false /* token binding enabled */)); } @@ -11245,6 +11241,10 @@ base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); ASSERT_TRUE(test_server.Start()); + // Unmark the certificate's OID as EV, which will disable revocation + // checking. + ev_test_policy_.reset(); + TestDelegate d; d.set_allow_certificate_errors(true); std::unique_ptr<URLRequest> r(context_.CreateRequest( @@ -11271,9 +11271,8 @@ protected: void SetupContext() override { context_.set_ssl_config_service(new TestSSLConfigService( - false /* check for EV */, false /* online revocation checking */, - true /* require rev. checking for local - anchors */, + false /* online revocation checking */, + true /* require rev. checking for local anchors */, false /* token binding enabled */)); } }; @@ -11315,11 +11314,11 @@ class HTTPSEVCRLSetTest : public HTTPSOCSPTest { protected: void SetupContext() override { - context_.set_ssl_config_service(new TestSSLConfigService( - true /* check for EV */, false /* online revocation checking */, - false /* require rev. checking for local + context_.set_ssl_config_service( + new TestSSLConfigService(false /* online revocation checking */, + false /* require rev. checking for local anchors */, - false /* token binding enabled */)); + false /* token binding enabled */)); } }; @@ -11487,41 +11486,22 @@ static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); } -TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSetAndRevokedNonEVCert) { - // Test that when EV verification is requested, but online revocation - // checking is disabled, and the leaf certificate is not in fact EV, that - // no revocation checking actually happens. - if (!SystemSupportsOCSP()) { - LOG(WARNING) << "Skipping test because system doesn't support OCSP"; - return; - } - - // Unmark the certificate's OID as EV, which should disable revocation - // checking (as per the user preference) - ev_test_policy_.reset(); - - SpawnedTestServer::SSLOptions ssl_options( - SpawnedTestServer::SSLOptions::CERT_AUTO); - ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; - ScopedSetCRLSet set_crlset(CRLSet::ExpiredCRLSetForTesting()); - - CertStatus cert_status; - DoConnection(ssl_options, &cert_status); - - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); -} - class HTTPSCRLSetTest : public HTTPSOCSPTest { protected: void SetupContext() override { - context_.set_ssl_config_service(new TestSSLConfigService( - false /* check for EV */, false /* online revocation checking */, - false /* require rev. checking for local + context_.set_ssl_config_service( + new TestSSLConfigService(false /* online revocation checking */, + false /* require rev. checking for local anchors */, - false /* token binding enabled */)); + false /* token binding enabled */)); + } + + void SetUp() override { + HTTPSOCSPTest::SetUp(); + + // Unmark the certificate's OID as EV, which should disable revocation + // checking (as per the user preference). + ev_test_policy_.reset(); } }; @@ -11542,6 +11522,28 @@ EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } +TEST_F(HTTPSCRLSetTest, ExpiredCRLSetAndRevoked) { + // Test that when online revocation checking is disabled, and the leaf + // certificate is not EV, that no revocation checking actually happens. + if (!SystemSupportsOCSP()) { + LOG(WARNING) << "Skipping test because system doesn't support OCSP"; + return; + } + + SpawnedTestServer::SSLOptions ssl_options( + SpawnedTestServer::SSLOptions::CERT_AUTO); + ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; + ScopedSetCRLSet set_crlset(CRLSet::ExpiredCRLSetForTesting()); + + CertStatus cert_status; + DoConnection(ssl_options, &cert_status); + + EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + + EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); + EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); +} + TEST_F(HTTPSCRLSetTest, CRLSetRevoked) { #if defined(OS_ANDROID) LOG(WARNING) << "Skipping test because system doesn't support CRLSets"; @@ -11562,8 +11564,7 @@ // reflected without online revocation checking. EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_FALSE( - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } TEST_F(HTTPSCRLSetTest, CRLSetRevokedBySubject) { @@ -11589,8 +11590,7 @@ // reflected without online revocation checking. EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_FALSE( - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } const uint8_t kTestServerSPKISHA256[32] = {
diff --git a/notification_helper/notification_helper.cc b/notification_helper/notification_helper.cc index 313f00e2..00f2be4c 100644 --- a/notification_helper/notification_helper.cc +++ b/notification_helper/notification_helper.cc
@@ -29,7 +29,7 @@ // chrome/browser/metrics/chrome_metrics_service_client.cc. base::PersistentHistogramStorage persistent_histogram_storage( "NotificationHelperMetrics", - base::PersistentHistogramStorage::StorageDirCreation::kEnable); + base::PersistentHistogramStorage::StorageDirManagement::kCreate); // Initialize the CommandLine singleton from the environment. base::CommandLine::Init(0, nullptr); @@ -39,6 +39,9 @@ // process should exit immediately. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683844.aspx if (!base::CommandLine::ForCurrentProcess()->HasSwitch("embedding")) { + // Histogram storage is enabled at the very top of this wWinMain. Disable it + // in this case as there is no directory in which to write them nor a + // browser to subsequently upload them. persistent_histogram_storage.Disable(); return 0; }
diff --git a/remoting/client/gesture_interpreter.cc b/remoting/client/gesture_interpreter.cc index b3d6dfa..2d5498ae 100644 --- a/remoting/client/gesture_interpreter.cc +++ b/remoting/client/gesture_interpreter.cc
@@ -19,26 +19,31 @@ } // namespace namespace remoting { -GestureInterpreter::GestureInterpreter(RendererProxy* renderer, - ChromotingSession* input_stub) - : renderer_(renderer), - input_stub_(input_stub), - pan_animation_(kOneFingerFlingTimeConstant, +GestureInterpreter::GestureInterpreter() + // TODO(yuweih): These animations are better to take GetWeakPtr(). + : pan_animation_(kOneFingerFlingTimeConstant, base::Bind(&GestureInterpreter::PanWithoutAbortAnimations, base::Unretained(this))), scroll_animation_( kScrollFlingTimeConstant, base::Bind(&GestureInterpreter::ScrollWithoutAbortAnimations, base::Unretained(this))), - weak_factory_(this) { - viewport_.RegisterOnTransformationChangedCallback( - base::Bind(&RendererProxy::SetTransformation, - base::Unretained(renderer_)), - true); -} + weak_factory_(this) {} GestureInterpreter::~GestureInterpreter() = default; +void GestureInterpreter::SetContext(RendererProxy* renderer, + ChromotingSession* input_stub) { + renderer_ = renderer; + input_stub_ = input_stub; + auto transformation_callback = + renderer_ ? base::BindRepeating(&RendererProxy::SetTransformation, + base::Unretained(renderer_)) + : DesktopViewport::TransformationCallback(); + viewport_.RegisterOnTransformationChangedCallback(transformation_callback, + true); +} + void GestureInterpreter::SetInputMode(InputMode mode) { switch (mode) { case DIRECT_INPUT_MODE: @@ -51,6 +56,9 @@ NOTREACHED(); } input_mode_ = mode; + if (!renderer_) { + return; + } renderer_->SetCursorVisibility(input_strategy_->IsCursorVisible()); ViewMatrix::Point cursor_position = input_strategy_->GetCursorPosition(); renderer_->SetCursorPosition(cursor_position.x, cursor_position.y); @@ -100,7 +108,7 @@ bool is_dragging_mode = state != GESTURE_ENDED; SetGestureInProgress(TouchInputStrategy::DRAG, is_dragging_mode); - if (!viewport_.IsViewportReady() || + if (!input_stub_ || !viewport_.IsViewportReady() || !input_strategy_->TrackTouchInput({x, y}, viewport_)) { return; } @@ -191,17 +199,22 @@ // Drag() will inject the position so don't need to do that in that case. InjectCursorPosition(cursor_position.x, cursor_position.y); } - renderer_->SetCursorPosition(cursor_position.x, cursor_position.y); + if (renderer_) { + renderer_->SetCursorPosition(cursor_position.x, cursor_position.y); + } } } void GestureInterpreter::InjectCursorPosition(float x, float y) { + if (!input_stub_) { + return; + } input_stub_->SendMouseEvent( x, y, protocol::MouseEvent_MouseButton_BUTTON_UNDEFINED, false); } void GestureInterpreter::ScrollWithoutAbortAnimations(float dx, float dy) { - if (!viewport_.IsViewportReady()) { + if (!input_stub_ || !viewport_.IsViewportReady()) { return; } ViewMatrix::Point desktopDelta = @@ -218,7 +231,7 @@ float touch_x, float touch_y, protocol::MouseEvent_MouseButton button) { - if (!viewport_.IsViewportReady() || + if (!input_stub_ || !viewport_.IsViewportReady() || !input_strategy_->TrackTouchInput({touch_x, touch_y}, viewport_)) { return; } @@ -254,7 +267,9 @@ // the *2 logic inside the renderer. float diameter_on_desktop = 2.f * feedback_radius / viewport_.GetTransformation().GetScale(); - renderer_->StartInputFeedback(cursor_x, cursor_y, diameter_on_desktop); + if (renderer_) { + renderer_->StartInputFeedback(cursor_x, cursor_y, diameter_on_desktop); + } } }
diff --git a/remoting/client/gesture_interpreter.h b/remoting/client/gesture_interpreter.h index d281b18..fdbc57e3e 100644 --- a/remoting/client/gesture_interpreter.h +++ b/remoting/client/gesture_interpreter.h
@@ -31,9 +31,13 @@ TRACKPAD_INPUT_MODE }; - GestureInterpreter(RendererProxy* renderer, ChromotingSession* input_stub); + GestureInterpreter(); ~GestureInterpreter(); + // Sets the context for the interpreter. Both arguments are nullable. If both + // are nullptr then methods below will have no effect. + void SetContext(RendererProxy* renderer, ChromotingSession* input_stub); + // Must be called right after the renderer is ready. void SetInputMode(InputMode mode); @@ -107,8 +111,8 @@ InputMode input_mode_ = UNDEFINED_INPUT_MODE; std::unique_ptr<TouchInputStrategy> input_strategy_; DesktopViewport viewport_; - RendererProxy* renderer_; - ChromotingSession* input_stub_; + RendererProxy* renderer_ = nullptr; + ChromotingSession* input_stub_ = nullptr; TouchInputStrategy::Gesture gesture_in_progress_; FlingAnimation pan_animation_;
diff --git a/remoting/client/input/keyboard_interpreter.cc b/remoting/client/input/keyboard_interpreter.cc index 1a9194ca..30abfe6 100644 --- a/remoting/client/input/keyboard_interpreter.cc +++ b/remoting/client/input/keyboard_interpreter.cc
@@ -10,19 +10,34 @@ namespace remoting { -KeyboardInterpreter::KeyboardInterpreter(ClientInputInjector* input_injector) { - // TODO(nicholss): This should be configurable. - input_strategy_.reset(new TextKeyboardInputStrategy(input_injector)); -} +KeyboardInterpreter::KeyboardInterpreter() = default; KeyboardInterpreter::~KeyboardInterpreter() = default; +void KeyboardInterpreter::SetContext(ClientInputInjector* input_injector) { + // TODO(nicholss): This should be configurable. + if (input_injector) { + input_strategy_ = + std::make_unique<TextKeyboardInputStrategy>(input_injector); + } else { + input_strategy_.reset(); + } +} + void KeyboardInterpreter::HandleTextEvent(const std::string& text, uint8_t modifiers) { + if (!input_strategy_) { + return; + } + input_strategy_->HandleTextEvent(text, modifiers); } void KeyboardInterpreter::HandleDeleteEvent(uint8_t modifiers) { + if (!input_strategy_) { + return; + } + base::queue<KeyEvent> keys; // TODO(nicholss): Handle modifers. // Key press. @@ -35,6 +50,10 @@ } void KeyboardInterpreter::HandleCtrlAltDeleteEvent() { + if (!input_strategy_) { + return; + } + base::queue<KeyEvent> keys; // Key press. @@ -51,6 +70,10 @@ } void KeyboardInterpreter::HandlePrintScreenEvent() { + if (!input_strategy_) { + return; + } + base::queue<KeyEvent> keys; // Key press.
diff --git a/remoting/client/input/keyboard_interpreter.h b/remoting/client/input/keyboard_interpreter.h index 300b43ad..6f6d7e3 100644 --- a/remoting/client/input/keyboard_interpreter.h +++ b/remoting/client/input/keyboard_interpreter.h
@@ -19,9 +19,12 @@ // handling of text events to the selected keyboard input strategy. class KeyboardInterpreter { public: - explicit KeyboardInterpreter(ClientInputInjector* input_injector); + explicit KeyboardInterpreter(); ~KeyboardInterpreter(); + // If |input_injector| is nullptr, all methods below will have no effect. + void SetContext(ClientInputInjector* input_injector); + // Delegates to |KeyboardInputStrategy| to covert and send the input. void HandleTextEvent(const std::string& text, uint8_t modifiers); // Delegates to |KeyboardInputStrategy| to covert and send the delete.
diff --git a/remoting/client/ui/desktop_viewport.cc b/remoting/client/ui/desktop_viewport.cc index 6abbfb8a..7f6de72 100644 --- a/remoting/client/ui/desktop_viewport.cc +++ b/remoting/client/ui/desktop_viewport.cc
@@ -117,8 +117,8 @@ const TransformationCallback& callback, bool run_immediately) { on_transformation_changed_ = callback; - if (IsViewportReady() && run_immediately) { - callback.Run(desktop_to_surface_transform_); + if (on_transformation_changed_ && IsViewportReady() && run_immediately) { + on_transformation_changed_.Run(desktop_to_surface_transform_); } }
diff --git a/remoting/host/installer/mac/Scripts/remoting_postflight.sh b/remoting/host/installer/mac/Scripts/remoting_postflight.sh index 69ad5f9..fc62ee5 100755 --- a/remoting/host/installer/mac/Scripts/remoting_postflight.sh +++ b/remoting/host/installer/mac/Scripts/remoting_postflight.sh
@@ -103,12 +103,11 @@ for uid in $(sort "$USERS_TMP_FILE" | uniq); do logger Starting service for user "$uid". - sudo_user="sudo -u #$uid" load="launchctl load -w -S Aqua $PLIST" start="launchctl start $SERVICE_NAME" if is_el_capitan_or_newer; then - boostrap_user="launchctl asuser $uid" + bootstrap_user="launchctl asuser $uid" else # Load the launchd agent in the bootstrap context of user $uid's # graphical session, so that screen-capture and input-injection can @@ -119,6 +118,7 @@ if [[ ! -n "$pid" ]]; then exit 1 fi + sudo_user="sudo -u #$uid" bootstrap_user="launchctl bsexec $pid" fi
diff --git a/remoting/host/installer/mac/Scripts/remoting_preflight.sh b/remoting/host/installer/mac/Scripts/remoting_preflight.sh index 372e0541..1511735 100755 --- a/remoting/host/installer/mac/Scripts/remoting_preflight.sh +++ b/remoting/host/installer/mac/Scripts/remoting_preflight.sh
@@ -78,12 +78,11 @@ context="Aqua" fi - sudo_user="sudo -u #$uid" stop="launchctl stop $SERVICE_NAME" unload="launchctl unload -w -S $context $PLIST" if is_el_capitan_or_newer; then - boostrap_user="launchctl asuser $uid" + bootstrap_user="launchctl asuser $uid" else # Load the launchd agent in the bootstrap context of user $uid's # graphical session, so that screen-capture and input-injection can @@ -94,6 +93,7 @@ if [[ ! -n "$pid" ]]; then exit 1 fi + sudo_user="sudo -u #$uid" bootstrap_user="launchctl bsexec $pid" fi
diff --git a/remoting/ios/BUILD.gn b/remoting/ios/BUILD.gn index bd2b63c8..d99e335e 100644 --- a/remoting/ios/BUILD.gn +++ b/remoting/ios/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//remoting/build/config/remoting_build.gni") +import("//remoting/remoting_locales.gni") group("all") { testonly = true @@ -71,10 +72,31 @@ data = [] } +# test + test("ios_remoting_unittests") { deps = [ "//base/test:run_all_unittests", "//base/test:test_support", + "//remoting//ios/facade:unit_tests", "//remoting/ios/persistence:unit_tests", ] + + foreach(locale, remoting_locales_with_underscores) { + deps += [ ":unittests_locale_${locale}_bundle_data" ] + } +} + +foreach(locale, remoting_locales_with_underscores) { + bundle_data("unittests_locale_${locale}_bundle_data") { + sources = [ + "$root_out_dir/remoting/resources/$locale.lproj/locale.pak", + ] + outputs = [ + "{{bundle_resources_dir}}/$locale.lproj/{{source_file_part}}", + ] + public_deps = [ + "//remoting/resources:copy_locales", + ] + } }
diff --git a/remoting/ios/DEPS b/remoting/ios/DEPS index fc71873..a513cf89 100644 --- a/remoting/ios/DEPS +++ b/remoting/ios/DEPS
@@ -12,5 +12,6 @@ "+remoting/signaling", "+third_party/libjingle_xmpp", "+third_party/webrtc", + "+third_party/ocmock", "+third_party/protobuf/src", ]
diff --git a/remoting/ios/app/host_view_controller.mm b/remoting/ios/app/host_view_controller.mm index 905e662f..7f0e59c 100644 --- a/remoting/ios/app/host_view_controller.mm +++ b/remoting/ios/app/host_view_controller.mm
@@ -466,6 +466,8 @@ } } +// TODO(yuweih): This method is badly named. Should be changed to +// "didTapShowMenu". - (void)didTap:(id)sender { // TODO(nicholss): The FAB is being used to launch an alert window with // more options. This is not ideal but it gets us an easy way to make a
diff --git a/remoting/ios/app/remoting_view_controller.mm b/remoting/ios/app/remoting_view_controller.mm index 03db9962..20f85fc 100644 --- a/remoting/ios/app/remoting_view_controller.mm +++ b/remoting/ios/app/remoting_view_controller.mm
@@ -36,6 +36,7 @@ #include "remoting/base/oauth_token_getter.h" #include "remoting/base/string_resources.h" #include "remoting/client/connect_to_host_info.h" +#include "remoting/ios/facade/host_list_service.h" #include "ui/base/l10n/l10n_util.h" static CGFloat kHostInset = 5.f; @@ -81,6 +82,8 @@ #pragma mark - RemotingViewController +using remoting::HostListService; + @interface RemotingViewController ()<HostCollectionViewControllerDelegate, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate> { @@ -90,7 +93,11 @@ HostFetchingViewController* _fetchingViewController; HostFetchingErrorViewController* _fetchingErrorViewController; HostSetupViewController* _setupViewController; - RemotingService* _remotingService; + HostListService* _hostListService; + std::unique_ptr<HostListService::CallbackSubscription> + _hostListStateSubscription; + std::unique_ptr<HostListService::CallbackSubscription> + _hostListFetchFailureSubscription; NSArray<id<RemotingRefreshControl>>* _refreshControls; } @@ -107,7 +114,7 @@ sectionInset, sectionInset)]; self = [super init]; if (self) { - _remotingService = RemotingService.instance; + _hostListService = HostListService::GetInstance(); __weak RemotingViewController* weakSelf = self; RemotingRefreshAction refreshAction = ^{ @@ -197,17 +204,15 @@ [_appBar addSubviewsToParent]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(hostListStateDidChangeNotification:) - name:kHostListStateDidChange - object:nil]; - - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(hostListFetchDidFailNotification:) - name:kHostListFetchDidFail - object:nil]; + __weak __typeof(self) weakSelf = self; + _hostListStateSubscription = + _hostListService->RegisterHostListStateCallback(base::BindBlockArc(^{ + [weakSelf hostListStateDidChange]; + })); + _hostListFetchFailureSubscription = + _hostListService->RegisterFetchFailureCallback(base::BindBlockArc(^{ + [weakSelf hostListFetchDidFail]; + })); } - (void)viewWillAppear:(BOOL)animated { @@ -222,16 +227,14 @@ return UIStatusBarStyleLightContent; } -#pragma mark - Remoting Service Notifications +#pragma mark - HostListService Callbacks -- (void)hostListStateDidChangeNotification:(NSNotification*)notification { +- (void)hostListStateDidChange { [self refreshContent]; } -- (void)hostListFetchDidFailNotification:(NSNotification*)notification { - HostListFetchFailureReason reason = (HostListFetchFailureReason) - [notification.userInfo[kHostListFetchFailureReasonKey] integerValue]; - [self handleHostListFetchFailure:reason]; +- (void)hostListFetchDidFail { + [self handleHostListFetchFailure]; } #pragma mark - HostCollectionViewControllerDelegate @@ -288,11 +291,12 @@ } - (NSInteger)getHostCount { - return _remotingService.hosts.count; + return _hostListService->hosts().size(); } - (HostInfo*)getHostAtIndexPath:(NSIndexPath*)path { - return _remotingService.hosts[path.row]; + return [[HostInfo alloc] + initWithRemotingHostInfo:_hostListService->hosts()[path.row]]; } #pragma mark - UIViewControllerTransitioningDelegate @@ -316,9 +320,7 @@ #pragma mark - Private - (void)didSelectRefresh { - // TODO(nicholss): Might want to rate limit this. Maybe remoting service - // controls that. - [_remotingService requestHostListFetch]; + _hostListService->RequestFetch(); } - (void)didSelectMenu { @@ -326,31 +328,30 @@ } - (void)refreshContent { - if (_remotingService.hostListState == HostListStateFetching) { + if (_hostListService->state() == HostListService::State::FETCHING) { if (![self isAnyRefreshControlRefreshing]) { self.contentViewController = _fetchingViewController; } return; } - if (_remotingService.hostListState == HostListStateNotFetched) { - if (_remotingService.lastFetchFailureReason == - HostListFetchFailureReasonNoFailure) { + if (_hostListService->state() == HostListService::State::NOT_FETCHED) { + if (!_hostListService->last_fetch_failure()) { self.contentViewController = nil; } else { // hostListFetchDidFailNotification might miss the first failure happened // before the notification is registered. This logic covers that. - [self handleHostListFetchFailure:_remotingService.lastFetchFailureReason]; + [self handleHostListFetchFailure]; } return; } - DCHECK(_remotingService.hostListState == HostListStateFetched); + DCHECK(_hostListService->state() == HostListService::State::FETCHED); [self stopAllRefreshControls]; UICollectionViewController* contentViewController; - if (_remotingService.hosts.count > 0) { + if (_hostListService->hosts().size() > 0) { [_collectionViewController.collectionView reloadData]; contentViewController = _collectionViewController; } else { @@ -362,20 +363,12 @@ self.contentViewController.view.frame = self.view.bounds; } -- (void)handleHostListFetchFailure:(HostListFetchFailureReason)reason { - int messageId; - switch (reason) { - case HostListFetchFailureReasonNetworkError: - messageId = IDS_ERROR_NETWORK_ERROR; - break; - case HostListFetchFailureReasonAuthError: - messageId = IDS_ERROR_OAUTH_TOKEN_INVALID; - break; - default: - NOTREACHED(); - return; +- (void)handleHostListFetchFailure { + const auto* failure = _hostListService->last_fetch_failure(); + if (!failure) { + return; } - NSString* errorText = l10n_util::GetNSString(messageId); + NSString* errorText = base::SysUTF8ToNSString(failure->localized_description); if ([self isAnyRefreshControlRefreshing]) { // User could just try pull-to-refresh again to refresh. We just need to // show the error as a toast.
diff --git a/remoting/ios/domain/host_info.h b/remoting/ios/domain/host_info.h index 0af707a..b4abefc 100644 --- a/remoting/ios/domain/host_info.h +++ b/remoting/ios/domain/host_info.h
@@ -7,6 +7,10 @@ #import <Foundation/Foundation.h> +namespace remoting { +struct HostInfo; +} // namespace remoting + // A detail record for a Remoting Host. @interface HostInfo : NSObject @@ -26,6 +30,8 @@ // True when |status| is @"ONLINE", anything else is False. @property(nonatomic, readonly) bool isOnline; +- (instancetype)initWithRemotingHostInfo:(const remoting::HostInfo&)hostInfo; + // First consider if |isOnline| is greater than anything else, then consider by // case insensitive locale of |hostName|. - (NSComparisonResult)compare:(HostInfo*)host;
diff --git a/remoting/ios/domain/host_info.mm b/remoting/ios/domain/host_info.mm index 1321730..5ef41ad 100644 --- a/remoting/ios/domain/host_info.mm +++ b/remoting/ios/domain/host_info.mm
@@ -8,6 +8,10 @@ #import "remoting/ios/domain/host_info.h" +#include "base/i18n/time_formatting.h" +#include "base/strings/sys_string_conversions.h" +#include "remoting/ios/facade/host_info.h" + @implementation HostInfo @synthesize createdTime = _createdTime; @@ -23,6 +27,34 @@ @synthesize updatedTime = _updatedTime; @synthesize offlineReason = _offlineReason; +- (instancetype)initWithRemotingHostInfo:(const remoting::HostInfo&)hostInfo { + if (self = [super init]) { + NSString* status; + switch (hostInfo.status) { + case remoting::kHostStatusOnline: + status = @"ONLINE"; + break; + case remoting::kHostStatusOffline: + status = @"OFFLINE"; + break; + default: + NOTREACHED(); + } + _hostId = base::SysUTF8ToNSString(hostInfo.host_id); + _hostName = base::SysUTF8ToNSString(hostInfo.host_name); + _hostOs = base::SysUTF8ToNSString(hostInfo.host_os); + _hostOsVersion = base::SysUTF8ToNSString(hostInfo.host_os_version); + _hostVersion = base::SysUTF8ToNSString(hostInfo.host_version); + _jabberId = base::SysUTF8ToNSString(hostInfo.host_jid); + _publicKey = base::SysUTF8ToNSString(hostInfo.public_key); + _status = status; + _updatedTime = base::SysUTF16ToNSString( + base::TimeFormatShortDateAndTime(hostInfo.updated_time)); + _offlineReason = base::SysUTF8ToNSString(hostInfo.offline_reason); + } + return self; +} + - (bool)isOnline { return (self.status && [self.status isEqualToString:@"ONLINE"]); } @@ -31,7 +63,7 @@ if (self.isOnline != host.isOnline) { return self.isOnline ? NSOrderedAscending : NSOrderedDescending; } else { - return [self.hostName localizedCaseInsensitiveCompare:host.hostName]; + return [self.hostName localizedCaseInsensitiveCompare:_hostName]; } }
diff --git a/remoting/ios/facade/BUILD.gn b/remoting/ios/facade/BUILD.gn index c0b83150..4ea43147 100644 --- a/remoting/ios/facade/BUILD.gn +++ b/remoting/ios/facade/BUILD.gn
@@ -12,6 +12,8 @@ "host_info.h", "host_list_fetcher.cc", "host_list_fetcher.h", + "host_list_service.h", + "host_list_service.mm", "ios_client_runtime_delegate.h", "ios_client_runtime_delegate.mm", "ios_oauth_token_getter.h", @@ -25,9 +27,39 @@ deps = [ "//base", + "//ios/third_party/material_components_ios", "//remoting/base:authorization", + "//remoting/client", "//remoting/ios/domain", "//remoting/ios/persistence", + "//remoting/resources", + "//ui/base", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("test_support") { + testonly = true + sources = [ + "fake_host_list_fetcher.cc", + "fake_host_list_fetcher.h", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "host_list_service_unittest.mm", + ] + deps = [ + ":facade", + ":test_support", + "//testing/gmock", + "//testing/gtest", + "//third_party/ocmock", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/remoting/ios/facade/fake_host_list_fetcher.cc b/remoting/ios/facade/fake_host_list_fetcher.cc new file mode 100644 index 0000000..e79eeaf5 --- /dev/null +++ b/remoting/ios/facade/fake_host_list_fetcher.cc
@@ -0,0 +1,39 @@ +// Copyright 2018 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 "remoting/ios/facade/fake_host_list_fetcher.h" + +namespace remoting { + +FakeHostListFetcher::FakeHostListFetcher() : HostListFetcher(nullptr){}; + +FakeHostListFetcher::~FakeHostListFetcher(){}; + +void FakeHostListFetcher::RetrieveHostlist(const std::string& access_token, + HostlistCallback callback) { + DCHECK(!callback_); + callback_ = std::move(callback); +} + +void FakeHostListFetcher::ResolveCallback( + int response_code, + const std::vector<HostInfo>& host_list) { + DCHECK(callback_); + std::move(callback_).Run(response_code, host_list); +} + +void FakeHostListFetcher::CancelFetch() { + DCHECK(cancel_fetch_expected_); + cancel_fetch_expected_ = false; + if (callback_) { + std::move(callback_).Run(RESPONSE_CODE_CANCELLED, {}); + } +} + +void FakeHostListFetcher::ExpectCancelFetch() { + DCHECK(!cancel_fetch_expected_); + cancel_fetch_expected_ = true; +} + +} // namespace remoting
diff --git a/remoting/ios/facade/fake_host_list_fetcher.h b/remoting/ios/facade/fake_host_list_fetcher.h new file mode 100644 index 0000000..d9cb979 --- /dev/null +++ b/remoting/ios/facade/fake_host_list_fetcher.h
@@ -0,0 +1,39 @@ +// Copyright 2018 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 REMOTING_IOS_FACADE_FAKE_HOST_LIST_FETCHER_H_ +#define REMOTING_IOS_FACADE_FAKE_HOST_LIST_FETCHER_H_ + +#include "base/macros.h" +#include "remoting/ios/facade/host_list_fetcher.h" + +namespace remoting { + +// Used to fake retrieving the host list without making any actual calls to the +// directory service for information. +class FakeHostListFetcher : public HostListFetcher { + public: + FakeHostListFetcher(); + ~FakeHostListFetcher() override; + + // HostListFetcher interface. + void RetrieveHostlist(const std::string& access_token, + HostlistCallback callback) override; + + void ResolveCallback(int response_code, + const std::vector<HostInfo>& host_list); + + void CancelFetch() override; + void ExpectCancelFetch(); + + private: + HostlistCallback callback_; + bool cancel_fetch_expected_ = false; + + DISALLOW_COPY_AND_ASSIGN(FakeHostListFetcher); +}; + +} // namespace remoting + +#endif // REMOTING_IOS_FACADE_FAKE_HOST_LIST_FETCHER_H_
diff --git a/remoting/ios/facade/host_list_fetcher.cc b/remoting/ios/facade/host_list_fetcher.cc index 43e6b28..33e874ed 100644 --- a/remoting/ios/facade/host_list_fetcher.cc +++ b/remoting/ios/facade/host_list_fetcher.cc
@@ -21,6 +21,13 @@ namespace { +// Used by the HostlistFetcher to make HTTP requests and also by the +// unittests for this class to set fake response data for these URLs. +// TODO(nicholss): Consider moving this to an extern and conditionally include +// prod or test environment urls based on config. A test env app would be nice. +const char kHostListProdRequestUrl[] = + "https://www.googleapis.com/chromoting/v1/@me/hosts"; + // Returns true if |h1| should sort before |h2|. bool compareHost(const HostInfo& h1, const HostInfo& h2) { // Online hosts always sort before offline hosts. @@ -50,14 +57,14 @@ // TODO(nicholss): This was written assuming only one request at a time. Fix // that. For the moment it will work to make progress in the app. void HostListFetcher::RetrieveHostlist(const std::string& access_token, - const HostlistCallback& callback) { + HostlistCallback callback) { // TODO(nicholss): There is a bug here if two host list fetches are happening // at the same time there will be a dcheck thrown. Fix this for release. DCHECK(!access_token.empty()); DCHECK(callback); DCHECK(!hostlist_callback_); - hostlist_callback_ = callback; + hostlist_callback_ = std::move(callback); request_ = net::URLFetcher::Create(GURL(kHostListProdRequestUrl), net::URLFetcher::GET, this); @@ -71,7 +78,7 @@ void HostListFetcher::CancelFetch() { request_.reset(); if (hostlist_callback_) { - base::ResetAndReturn(&hostlist_callback_).Run(RESPONSE_CODE_CANCELLED, {}); + std::move(hostlist_callback_).Run(RESPONSE_CODE_CANCELLED, {}); } } @@ -134,8 +141,7 @@ hostlist.clear(); } std::sort(hostlist.begin(), hostlist.end(), &compareHost); - base::ResetAndReturn(&hostlist_callback_) - .Run(request_->GetResponseCode(), hostlist); + std::move(hostlist_callback_).Run(request_->GetResponseCode(), hostlist); } } // namespace remoting
diff --git a/remoting/ios/facade/host_list_fetcher.h b/remoting/ios/facade/host_list_fetcher.h index 6a8d8e7..9f0a528 100644 --- a/remoting/ios/facade/host_list_fetcher.h +++ b/remoting/ios/facade/host_list_fetcher.h
@@ -18,13 +18,6 @@ namespace remoting { -// Used by the HostlistFetcher to make HTTP requests and also by the -// unittests for this class to set fake response data for these URLs. -// TODO(nicholss): Consider moving this to an extern and conditionally include -// prod or test environment urls based on config. A test env app would be nice. -const char kHostListProdRequestUrl[] = - "https://www.googleapis.com/chromoting/v1/@me/hosts"; - // Requests a host list from the directory service for an access token. // Destroying the RemoteHostInfoFetcher while a request is outstanding // will cancel the request. It is safe to delete the fetcher from within a @@ -46,14 +39,14 @@ // Supplied by the client for each hostlist request and returns a valid, // initialized Hostlist object on success. - typedef base::Callback<void(int response_code, - const std::vector<remoting::HostInfo>& hostlist)> + typedef base::OnceCallback< + void(int response_code, const std::vector<remoting::HostInfo>& hostlist)> HostlistCallback; // Makes a service call to retrieve a hostlist. The // callback will be called once the HTTP request has completed. virtual void RetrieveHostlist(const std::string& access_token, - const HostlistCallback& callback); + HostlistCallback callback); // Cancels the current fetch request and runs the host list callback with // RESPONSE_CODE_CANCELLED. Nothing will happen if there is no ongoing fetch
diff --git a/remoting/ios/facade/host_list_service.h b/remoting/ios/facade/host_list_service.h new file mode 100644 index 0000000..2f22cad --- /dev/null +++ b/remoting/ios/facade/host_list_service.h
@@ -0,0 +1,120 @@ +// Copyright 2018 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 REMOTING_IOS_FACADE_HOST_LIST_SERVICE_H_ +#define REMOTING_IOS_FACADE_HOST_LIST_SERVICE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/callback_list.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/no_destructor.h" +#include "net/http/http_status_code.h" +#include "remoting/ios/facade/host_info.h" + +namespace remoting { + +class HostListFetcher; + +// |HostListService| is the centralized place to retrieve the current signed in +// user's host list. +class HostListService { + public: + enum class State { + // Nobody has requested a host list fetch since login or last failure. + NOT_FETCHED, + // The host list is currently being fetched. + FETCHING, + // The host list has been fetched. + FETCHED, + }; + + enum class FetchFailureReason { + NETWORK_ERROR, + AUTH_ERROR, + REQUEST_ERROR, + }; + + struct FetchFailureInfo { + FetchFailureReason reason; + // error_code is only used if the reason is |REQUEST_ERROR|. + int error_code; + std::string localized_description; + }; + + using CallbackSubscription = base::CallbackList<void()>::Subscription; + + // Returns the singleton instance. + static HostListService* GetInstance(); + + ~HostListService(); + + // Registers callback to be called when the host list state is changed. + std::unique_ptr<CallbackSubscription> RegisterHostListStateCallback( + const base::RepeatingClosure& callback); + + // Registers callback to be called when the host list has failed to fetch. + std::unique_ptr<CallbackSubscription> RegisterFetchFailureCallback( + const base::RepeatingClosure& callback); + + // Start a request to fetch the host list. Calls either the host list state + // callbacks or fetch failure callbacks during the process. + void RequestFetch(); + + // Returns the host list. Returns an empty vector if the host list state is + // not |FETCHED|. + const std::vector<remoting::HostInfo>& hosts() const { return hosts_; } + + State state() const { return state_; } + + // Returns the last host list fetch failure. Returns nullptr if the host list + // has never been fetched or the last fetch has succeeded. + const FetchFailureInfo* last_fetch_failure() const { + return last_fetch_failure_.get(); + } + + // Allow creating instace for each test so that states don't get carried over. + static std::unique_ptr<HostListService> CreateInstanceForTesting(); + + void SetHostListFetcherForTesting(std::unique_ptr<HostListFetcher> fetcher); + + private: + friend class base::NoDestructor<HostListService>; + friend std::unique_ptr<HostListService> std::make_unique<HostListService>(); + + HostListService(); + + // Changes the host list state and notifies callbacks. + void SetState(State state); + + void StartHostListFetch(const std::string& access_token); + + void HandleHostListResult(int responseCode, + const std::vector<remoting::HostInfo>& hostlist); + + void HandleFetchFailure(FetchFailureReason reason, int error_code); + + void OnUserUpdated(bool is_user_signed_in); + + id user_update_observer_; + + base::CallbackList<void()> host_list_state_callbacks_; + base::CallbackList<void()> fetch_failure_callbacks_; + + std::unique_ptr<HostListFetcher> host_list_fetcher_; + + std::vector<remoting::HostInfo> hosts_; + State state_; + std::unique_ptr<FetchFailureInfo> last_fetch_failure_; + + base::WeakPtrFactory<HostListService> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(HostListService); +}; + +} // namespace remoting + +#endif // REMOTING_IOS_FACADE_HOST_LIST_SERVICE_H_
diff --git a/remoting/ios/facade/host_list_service.mm b/remoting/ios/facade/host_list_service.mm new file mode 100644 index 0000000..9fa8be9 --- /dev/null +++ b/remoting/ios/facade/host_list_service.mm
@@ -0,0 +1,190 @@ +// Copyright 2018 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. + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#import "remoting/ios/facade/host_list_service.h" + +#import <CoreFoundation/CoreFoundation.h> + +#import "base/mac/bind_objc_block.h" +#import "remoting/ios/domain/host_info.h" +#import "remoting/ios/domain/user_info.h" +#import "remoting/ios/facade/host_info.h" +#import "remoting/ios/facade/host_list_fetcher.h" +#import "remoting/ios/facade/remoting_authentication.h" +#import "remoting/ios/facade/remoting_service.h" + +#include "base/i18n/time_formatting.h" +#include "base/logging.h" +#include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "remoting/base/string_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace remoting { + +HostListService* HostListService::GetInstance() { + static base::NoDestructor<HostListService> instance; + return instance.get(); +} + +HostListService::HostListService() : weak_factory_(this) { + auto weak_this = weak_factory_.GetWeakPtr(); + user_update_observer_ = [NSNotificationCenter.defaultCenter + addObserverForName:kUserDidUpdate + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + UserInfo* user = notification.userInfo[kUserInfo]; + if (weak_this) { + weak_this->OnUserUpdated(user != nil); + } + }]; +} + +HostListService::~HostListService() { + [NSNotificationCenter.defaultCenter removeObserver:user_update_observer_]; +} + +std::unique_ptr<HostListService::CallbackSubscription> +HostListService::RegisterHostListStateCallback( + const base::RepeatingClosure& callback) { + return host_list_state_callbacks_.Add(callback); +} + +std::unique_ptr<HostListService::CallbackSubscription> +HostListService::RegisterFetchFailureCallback( + const base::RepeatingClosure& callback) { + return fetch_failure_callbacks_.Add(callback); +} + +void HostListService::RequestFetch() { + auto weak_this = weak_factory_.GetWeakPtr(); + [RemotingService.instance.authentication + callbackWithAccessToken:^(RemotingAuthenticationStatus status, + NSString* userEmail, NSString* accessToken) { + if (status == RemotingAuthenticationStatusSuccess) { + if (weak_this) { + weak_this->StartHostListFetch(base::SysNSStringToUTF8(accessToken)); + } + return; + } + + FetchFailureReason failureReason; + switch (status) { + case RemotingAuthenticationStatusNetworkError: + failureReason = FetchFailureReason::NETWORK_ERROR; + break; + case RemotingAuthenticationStatusAuthError: + failureReason = FetchFailureReason::AUTH_ERROR; + break; + default: + NOTREACHED(); + failureReason = FetchFailureReason::NETWORK_ERROR; + } + if (weak_this) { + weak_this->HandleFetchFailure(failureReason, 0); + } + }]; +} + +void HostListService::SetHostListFetcherForTesting( + std::unique_ptr<HostListFetcher> fetcher) { + host_list_fetcher_ = std::move(fetcher); +} + +// static +std::unique_ptr<HostListService> HostListService::CreateInstanceForTesting() { + return std::make_unique<HostListService>(); +} + +void HostListService::SetState(State state) { + if (state == state_) { + return; + } + if (state == State::NOT_FETCHED) { + hosts_ = {}; + } else if (state == State::FETCHING || state == State::FETCHED) { + last_fetch_failure_.reset(); + } + state_ = state; + host_list_state_callbacks_.Notify(); +} + +void HostListService::StartHostListFetch(const std::string& access_token) { + if (state_ == State::FETCHING) { + return; + } + SetState(State::FETCHING); + if (!host_list_fetcher_) { + host_list_fetcher_.reset(new HostListFetcher( + ChromotingClientRuntime::GetInstance()->url_requester())); + } + host_list_fetcher_->RetrieveHostlist( + access_token, base::BindOnce(&HostListService::HandleHostListResult, + weak_factory_.GetWeakPtr())); +} + +void HostListService::HandleHostListResult( + int responseCode, + const std::vector<remoting::HostInfo>& hostlist) { + if (responseCode == net::HTTP_OK) { + hosts_ = hostlist; + SetState(State::FETCHED); + return; + } + + if (responseCode != HostListFetcher::RESPONSE_CODE_CANCELLED) { + if (responseCode == net::HTTP_UNAUTHORIZED) { + [RemotingService.instance.authentication logout]; + } else { + HandleFetchFailure(FetchFailureReason::REQUEST_ERROR, responseCode); + } + } + SetState(State::NOT_FETCHED); +} + +void HostListService::HandleFetchFailure(FetchFailureReason reason, + int error_code) { + last_fetch_failure_ = std::make_unique<FetchFailureInfo>(); + last_fetch_failure_->reason = reason; + last_fetch_failure_->error_code = error_code; + + switch (reason) { + case FetchFailureReason::NETWORK_ERROR: + last_fetch_failure_->localized_description = + l10n_util::GetStringUTF8(IDS_ERROR_NETWORK_ERROR); + break; + case FetchFailureReason::AUTH_ERROR: + last_fetch_failure_->localized_description = + l10n_util::GetStringUTF8(IDS_ERROR_OAUTH_TOKEN_INVALID); + break; + case FetchFailureReason::REQUEST_ERROR: + last_fetch_failure_->localized_description = l10n_util::GetStringFUTF8( + IDS_SERVER_COMMUNICATION_ERROR, + base::UTF8ToUTF16(net::GetHttpReasonPhrase( + static_cast<net::HttpStatusCode>(error_code)))); + break; + default: + NOTREACHED(); + } + LOG(WARNING) << "Failed to fetch host list: " + << last_fetch_failure_->localized_description; + fetch_failure_callbacks_.Notify(); +} + +void HostListService::OnUserUpdated(bool is_user_signed_in) { + if (host_list_fetcher_) { + host_list_fetcher_->CancelFetch(); + } + SetState(State::NOT_FETCHED); + if (is_user_signed_in) { + RequestFetch(); + } +} + +} // namespace remoting
diff --git a/remoting/ios/facade/host_list_service_unittest.mm b/remoting/ios/facade/host_list_service_unittest.mm new file mode 100644 index 0000000..3a5dfbe --- /dev/null +++ b/remoting/ios/facade/host_list_service_unittest.mm
@@ -0,0 +1,255 @@ +// Copyright 2018 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. + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#include "remoting/ios/facade/host_list_service.h" + +#import <Foundation/Foundation.h> + +#import "remoting/ios/facade/remoting_authentication.h" +#import "remoting/ios/facade/remoting_service.h" +#import "third_party/ocmock/OCMock/OCMock.h" + +#include "base/bind.h" +#include "net/http/http_status_code.h" +#include "remoting/ios/facade/fake_host_list_fetcher.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gtest_mac.h" +#include "testing/platform_test.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +#define EXPECT_HOST_LIST_STATE(expected) \ + EXPECT_EQ(expected, host_list_service_->state()) + +#define EXPECT_NO_FETCH_FAILURE() \ + EXPECT_TRUE(host_list_service_->last_fetch_failure() == nullptr) + +namespace remoting { + +class HostListServiceTest : public PlatformTest { + public: + void SetUp() override; + void TearDown() override; + + protected: + void ExpectAuthResult(RemotingAuthenticationStatus status); + void NotifyUserUpdate(bool is_signed_in); + + std::unique_ptr<HostListService> host_list_service_; + FakeHostListFetcher* host_list_fetcher_; + + HostInfo fake_host_; + + int on_fetch_failed_call_count_ = 0; + int on_host_list_state_changed_call_count_ = 0; + + id remoting_authentication_mock_; + id remoting_service_mock_; + + private: + std::unique_ptr<HostListService::CallbackSubscription> + host_list_state_subscription_; + std::unique_ptr<HostListService::CallbackSubscription> + fetch_failure_subscription_; +}; + +void HostListServiceTest::SetUp() { + static const char use_cocoa_locale[] = ""; + + l10n_util::OverrideLocaleWithCocoaLocale(); + ui::ResourceBundle::InitSharedInstanceWithLocale( + use_cocoa_locale, NULL, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES); + + on_fetch_failed_call_count_ = 0; + on_host_list_state_changed_call_count_ = 0; + + remoting_authentication_mock_ = + OCMProtocolMock(@protocol(RemotingAuthentication)); + + remoting_service_mock_ = OCMClassMock([RemotingService class]); + OCMStub([remoting_service_mock_ instance]).andReturn(remoting_service_mock_); + OCMStub([remoting_service_mock_ authentication]) + .andReturn(remoting_authentication_mock_); + + host_list_service_ = HostListService::CreateInstanceForTesting(); + auto host_list_fetcher = std::make_unique<FakeHostListFetcher>(); + host_list_fetcher_ = host_list_fetcher.get(); + host_list_service_->SetHostListFetcherForTesting( + std::move(host_list_fetcher)); + + host_list_state_subscription_ = + host_list_service_->RegisterHostListStateCallback(base::BindRepeating( + [](HostListServiceTest* that) { + that->on_host_list_state_changed_call_count_++; + }, + base::Unretained(this))); + fetch_failure_subscription_ = + host_list_service_->RegisterFetchFailureCallback(base::BindRepeating( + [](HostListServiceTest* that) { + that->on_fetch_failed_call_count_++; + }, + base::Unretained(this))); + + fake_host_.host_id = "fake_host_id"; +} + +void HostListServiceTest::TearDown() { + ui::ResourceBundle::CleanupSharedInstance(); +} + +void HostListServiceTest::ExpectAuthResult( + RemotingAuthenticationStatus status) { + NSString* user_email = + status == RemotingAuthenticationStatusSuccess ? @"fake@gmail.com" : nil; + NSString* access_token = + status == RemotingAuthenticationStatusSuccess ? @"fake_token" : nil; + OCMStub([remoting_authentication_mock_ callbackWithAccessToken:[OCMArg any]]) + .andDo(^(NSInvocation* invocation) { + AccessTokenCallback callback; + [invocation getArgument:&callback atIndex:2]; + DCHECK(callback); + callback(status, user_email, access_token); + }); +} + +void HostListServiceTest::NotifyUserUpdate(bool is_signed_in) { + NSDictionary* user_info = + is_signed_in ? @{kUserInfo : [[UserInfo alloc] init]} : @{}; + [NSNotificationCenter.defaultCenter postNotificationName:kUserDidUpdate + object:nil + userInfo:user_info]; +} + +TEST_F(HostListServiceTest, SuccessfullyFetchHostList) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + EXPECT_NO_FETCH_FAILURE(); + + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + EXPECT_NO_FETCH_FAILURE(); + + host_list_fetcher_->ResolveCallback(net::HTTP_OK, {fake_host_}); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHED); + EXPECT_NO_FETCH_FAILURE(); + + EXPECT_EQ(1u, host_list_service_->hosts().size()); + EXPECT_EQ(fake_host_.host_id, host_list_service_->hosts()[0].host_id); + + EXPECT_EQ(2, on_host_list_state_changed_call_count_); + EXPECT_EQ(0, on_fetch_failed_call_count_); +} + +TEST_F(HostListServiceTest, FetchHostListAuthFailed) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + EXPECT_NO_FETCH_FAILURE(); + + ExpectAuthResult(RemotingAuthenticationStatusAuthError); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + EXPECT_EQ(HostListService::FetchFailureReason::AUTH_ERROR, + host_list_service_->last_fetch_failure()->reason); + EXPECT_TRUE(host_list_service_->hosts().empty()); + + EXPECT_EQ(0, on_host_list_state_changed_call_count_); + EXPECT_EQ(1, on_fetch_failed_call_count_); +} + +TEST_F(HostListServiceTest, FetchHostListRequestFailed) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + EXPECT_NO_FETCH_FAILURE(); + + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + EXPECT_NO_FETCH_FAILURE(); + + host_list_fetcher_->ResolveCallback(net::HTTP_INTERNAL_SERVER_ERROR, {}); + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + EXPECT_EQ(HostListService::FetchFailureReason::REQUEST_ERROR, + host_list_service_->last_fetch_failure()->reason); + EXPECT_EQ(net::HTTP_INTERNAL_SERVER_ERROR, + host_list_service_->last_fetch_failure()->error_code); + EXPECT_TRUE(host_list_service_->hosts().empty()); + + EXPECT_EQ(2, on_host_list_state_changed_call_count_); + EXPECT_EQ(1, on_fetch_failed_call_count_); +} + +TEST_F(HostListServiceTest, FetchHostListRequestUnauthenticated_signOut) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + EXPECT_NO_FETCH_FAILURE(); + + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + EXPECT_NO_FETCH_FAILURE(); + + OCMExpect([remoting_authentication_mock_ logout]); + host_list_fetcher_->ResolveCallback(net::HTTP_UNAUTHORIZED, {}); + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + [remoting_authentication_mock_ verifyAtLocation:nil]; + + EXPECT_EQ(2, on_host_list_state_changed_call_count_); + EXPECT_EQ(0, on_fetch_failed_call_count_); +} + +TEST_F(HostListServiceTest, RequestFetchWhileFetching_ignoreSecondRequest) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + + EXPECT_EQ(1, on_host_list_state_changed_call_count_); + EXPECT_EQ(0, on_fetch_failed_call_count_); +} + +TEST_F(HostListServiceTest, UserLogOut_cancelFetch) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + + host_list_fetcher_->ExpectCancelFetch(); + NotifyUserUpdate(false); + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + + EXPECT_EQ(2, on_host_list_state_changed_call_count_); + EXPECT_EQ(0, on_fetch_failed_call_count_); +} + +TEST_F(HostListServiceTest, UserSwitchAccount_cancelThenRequestNewFetch) { + EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED); + + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + host_list_service_->RequestFetch(); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + + host_list_fetcher_->ExpectCancelFetch(); + ExpectAuthResult(RemotingAuthenticationStatusSuccess); + NotifyUserUpdate(true); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING); + + host_list_fetcher_->ResolveCallback(net::HTTP_OK, {fake_host_}); + EXPECT_HOST_LIST_STATE(HostListService::State::FETCHED); + + EXPECT_EQ(1u, host_list_service_->hosts().size()); + EXPECT_EQ(fake_host_.host_id, host_list_service_->hosts()[0].host_id); + + // Note that there is an extra FETCHING->NOT_FETCH change during + // NotifyUserUpdate(true). + EXPECT_EQ(4, on_host_list_state_changed_call_count_); + EXPECT_EQ(0, on_fetch_failed_call_count_); +} + +} // namespace remoting
diff --git a/remoting/ios/facade/remoting_service.h b/remoting/ios/facade/remoting_service.h index f59088b..a1d071d 100644 --- a/remoting/ios/facade/remoting_service.h +++ b/remoting/ios/facade/remoting_service.h
@@ -7,37 +7,12 @@ #import "remoting/client/chromoting_client_runtime.h" -@class HostInfo; @class UserInfo; @protocol RemotingAuthentication; -typedef NS_ENUM(NSInteger, HostListState) { - // Nobody has requested a host list fetch since login or last failure. - HostListStateNotFetched, - - // The host list is currently being fetched. - HostListStateFetching, - - // The host list has been fetched. - HostListStateFetched, -}; - -typedef NS_ENUM(NSInteger, HostListFetchFailureReason) { - HostListFetchFailureReasonNoFailure, - HostListFetchFailureReasonNetworkError, - HostListFetchFailureReasonAuthError, - HostListFetchFailureReasonUnknown, -}; - // Eventing related keys: -// Host list fetch failed event. -extern NSString* const kHostListFetchDidFail; -// Map key for the host list fetch failure reason. -extern NSString* const kHostListFetchFailureReasonKey; -// Hosts did update event. -extern NSString* const kHostListStateDidChange; // User did update event name. extern NSString* const kUserDidUpdate; // Map key for UserInfo object. @@ -46,31 +21,17 @@ // |RemotingService| is the centralized place to ask for information about // authentication or query the remote services. It also helps deal with the // runtime and threading used in the application. |RemotingService| is a -// singleton and should only be accessed via the |SharedInstance| method. +// singleton and should only be accessed via the instance property. @interface RemotingService : NSObject -// Start a request to fetch the host list. This will produce an notification on -// |kHostsDidUpdate| when a new host is ready. -- (void)requestHostListFetch; - // Access to the singleton shared instance from this property. @property(nonatomic, readonly, class) RemotingService* instance; -// Returns the current host list. -@property(nonatomic, readonly) NSArray<HostInfo*>* hosts; - -@property(nonatomic, readonly) HostListState hostListState; - // The Chromoting Client Runtime, this holds the threads and other shared // resources used by the Chromoting clients @property(nonatomic, readonly) remoting::ChromotingClientRuntime* runtime; -// Returns the last failure reason when fetching the host list. Returns -// HostListFetchFailureReasonNoFailure when the host list has never been fetched -// or the last fetch has succeeded. -@property(nonatomic, readonly) - HostListFetchFailureReason lastFetchFailureReason; - +// TODO(yuweih): Make |authentication| its own singleton. // This must be set immediately after the authentication object is created. It // can only be set once. @property(nonatomic) id<RemotingAuthentication> authentication;
diff --git a/remoting/ios/facade/remoting_service.mm b/remoting/ios/facade/remoting_service.mm index 43004d9..bee0dd4f 100644 --- a/remoting/ios/facade/remoting_service.mm +++ b/remoting/ios/facade/remoting_service.mm
@@ -12,36 +12,18 @@ #import <Security/Security.h> #import "base/mac/bind_objc_block.h" -#import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" -#import "remoting/ios/domain/host_info.h" #import "remoting/ios/domain/user_info.h" -#import "remoting/ios/facade/host_info.h" -#import "remoting/ios/facade/host_list_fetcher.h" #import "remoting/ios/facade/ios_client_runtime_delegate.h" #import "remoting/ios/facade/remoting_authentication.h" -#include "base/i18n/time_formatting.h" #include "base/logging.h" #include "base/strings/sys_string_conversions.h" -#include "net/http/http_status_code.h" -#include "net/url_request/url_request_context_getter.h" -#include "remoting/base/oauth_token_getter.h" -#include "remoting/base/oauth_token_getter_impl.h" - -static NSString* const kCRDAuthenticatedUserEmailKey = - @"kCRDAuthenticatedUserEmailKey"; - -NSString* const kHostListFetchDidFail = @"kHostListFetchDidFail"; -NSString* const kHostListFetchFailureReasonKey = @"kHostListFetchFailureReason"; - -NSString* const kHostListStateDidChange = @"kHostListStateDidChange"; NSString* const kUserDidUpdate = @"kUserDidUpdate"; NSString* const kUserInfo = @"kUserInfo"; @interface RemotingService ()<RemotingAuthenticationDelegate> { id<RemotingAuthentication> _authentication; - std::unique_ptr<remoting::HostListFetcher> _hostListFetcher; // TODO(yuweih): It's suspicious to use a raw C++ pointer here. Investigate // its lifetime in ChromotingRuntime and change to unique_ptr if possible. @@ -51,10 +33,6 @@ @implementation RemotingService -@synthesize hosts = _hosts; -@synthesize hostListState = _hostListState; -@synthesize lastFetchFailureReason = _lastFetchFailureReason; - // RemotingService is a singleton. + (RemotingService*)instance { static RemotingService* sharedInstance = nil; @@ -68,10 +46,6 @@ - (instancetype)init { self = [super init]; if (self) { - _hosts = nil; - // TODO(yuweih): Maybe better to just cancel the previous request. - _hostListState = HostListStateNotFetched; - _lastFetchFailureReason = HostListFetchFailureReasonNoFailure; _clientRuntimeDelegate = new remoting::IosClientRuntimeDelegate(); [self runtime]->Init(_clientRuntimeDelegate); @@ -79,105 +53,11 @@ return self; } -#pragma mark - RemotingService Implementation - -- (void)startHostListFetchWith:(NSString*)accessToken { - if (_hostListState == HostListStateFetching) { - return; - } - [self setHostListState:HostListStateFetching]; - if (!_hostListFetcher) { - _hostListFetcher.reset(new remoting::HostListFetcher( - remoting::ChromotingClientRuntime::GetInstance()->url_requester())); - } - _hostListFetcher->RetrieveHostlist( - base::SysNSStringToUTF8(accessToken), - base::BindBlockArc(^(int responseCode, - const std::vector<remoting::HostInfo>& hostlist) { - if (responseCode != net::HTTP_OK) { - if (responseCode != - remoting::HostListFetcher::RESPONSE_CODE_CANCELLED) { - LOG(WARNING) << "Failed to fetch host list. Response code: " - << responseCode; - } - - if (responseCode == net::HTTP_UNAUTHORIZED) { - [[RemotingService instance].authentication logout]; - } - // TODO(nicholss): There are more |responseCode|s that we might want - // to trigger on, look into that later. - - [self setHostListState:HostListStateNotFetched]; - _hosts = nil; - return; - } - - NSMutableArray<HostInfo*>* hosts = - [NSMutableArray arrayWithCapacity:hostlist.size()]; - std::string status; - for (const remoting::HostInfo& host_info : hostlist) { - remoting::HostStatus host_status = host_info.status; - switch (host_status) { - case remoting::kHostStatusOnline: - status = "ONLINE"; - break; - case remoting::kHostStatusOffline: - status = "OFFLINE"; - break; - default: - NOTREACHED(); - } - // TODO(nicholss): Not yet integrated: createdTime, kind, - // offlineReason. Add them as the app will need this info. - HostInfo* host = [[HostInfo alloc] init]; - host.hostId = base::SysUTF8ToNSString(host_info.host_id); - host.hostName = base::SysUTF8ToNSString(host_info.host_name); - host.hostOs = base::SysUTF8ToNSString(host_info.host_os); - host.hostOsVersion = - base::SysUTF8ToNSString(host_info.host_os_version); - host.hostVersion = base::SysUTF8ToNSString(host_info.host_version); - host.jabberId = base::SysUTF8ToNSString(host_info.host_jid); - host.publicKey = base::SysUTF8ToNSString(host_info.public_key); - host.status = base::SysUTF8ToNSString(status); - host.updatedTime = base::SysUTF16ToNSString( - base::TimeFormatShortDateAndTime(host_info.updated_time)); - host.offlineReason = - base::SysUTF8ToNSString(host_info.offline_reason); - [hosts addObject:host]; - } - _hosts = hosts; - [self setHostListState:HostListStateFetched]; - })); -} - -- (void)setHostListState:(HostListState)state { - if (state == _hostListState) { - return; - } - if (state == HostListStateFetching || state == HostListStateFetched) { - _lastFetchFailureReason = HostListFetchFailureReasonNoFailure; - } - _hostListState = state; - [[NSNotificationCenter defaultCenter] - postNotificationName:kHostListStateDidChange - object:self - userInfo:nil]; -} - #pragma mark - RemotingAuthenticationDelegate - (void)userDidUpdate:(UserInfo*)user { - NSDictionary* userInfo = nil; - if (_hostListFetcher) { - _hostListFetcher->CancelFetch(); - } - [self setHostListState:HostListStateNotFetched]; - if (user) { - userInfo = [NSDictionary dictionaryWithObject:user forKey:kUserInfo]; - [self requestHostListFetch]; - } else { - _hosts = nil; - } + NSDictionary* userInfo = + user ? [NSDictionary dictionaryWithObject:user forKey:kUserInfo] : nil; [[NSNotificationCenter defaultCenter] postNotificationName:kUserDidUpdate object:self userInfo:userInfo]; @@ -185,48 +65,12 @@ #pragma mark - Properties -- (NSArray<HostInfo*>*)hosts { - if ([_authentication.user isAuthenticated]) { - return _hosts; - } - return nil; -} - - (remoting::ChromotingClientRuntime*)runtime { return remoting::ChromotingClientRuntime::GetInstance(); } #pragma mark - Implementation -- (void)requestHostListFetch { - [_authentication - callbackWithAccessToken:^(RemotingAuthenticationStatus status, - NSString* userEmail, NSString* accessToken) { - if (status == RemotingAuthenticationStatusSuccess) { - [self startHostListFetchWith:accessToken]; - return; - } - - switch (status) { - case RemotingAuthenticationStatusNetworkError: - _lastFetchFailureReason = HostListFetchFailureReasonNetworkError; - break; - case RemotingAuthenticationStatusAuthError: - _lastFetchFailureReason = HostListFetchFailureReasonAuthError; - break; - default: - _lastFetchFailureReason = HostListFetchFailureReasonUnknown; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kHostListFetchDidFail - object:self - userInfo:@{ - kHostListFetchFailureReasonKey : - @(_lastFetchFailureReason) - }]; - }]; -} - - (void)setAuthentication:(id<RemotingAuthentication>)authentication { DCHECK(_authentication == nil); authentication.delegate = self;
diff --git a/remoting/ios/session/remoting_client.h b/remoting/ios/session/remoting_client.h index 3c8d182..85e7329 100644 --- a/remoting/ios/session/remoting_client.h +++ b/remoting/ios/session/remoting_client.h
@@ -95,12 +95,11 @@ @property(nonatomic, strong) GlDisplayHandler* displayHandler; // The host info used to make the remoting client connection. @property(nonatomic, readonly) HostInfo* hostInfo; -// The gesture interpreter used to handle gestures. -// This is valid only after the client has connected to the host. Always use -// RemotingClient.gestureInterpreter instead of storing the pointer separately. +// The gesture interpreter used to handle gestures. It has no effect if the +// session is not connected. @property(nonatomic, readonly) remoting::GestureInterpreter* gestureInterpreter; // The keyboard interpreter used to convert key events and send them to the -// host. +// host. It has no effect if the session is not connected. @property(nonatomic, readonly) remoting::KeyboardInterpreter* keyboardInterpreter;
diff --git a/remoting/ios/session/remoting_client.mm b/remoting/ios/session/remoting_client.mm index 41ba4dc..a8c7453 100644 --- a/remoting/ios/session/remoting_client.mm +++ b/remoting/ios/session/remoting_client.mm
@@ -65,9 +65,9 @@ std::unique_ptr<remoting::RemotingClientSessonDelegate> _sessonDelegate; ClientSessionDetails* _sessionDetails; remoting::protocol::SecretFetchedCallback _secretFetchedCallback; + remoting::GestureInterpreter _gestureInterpreter; + remoting::KeyboardInterpreter _keyboardInterpreter; std::unique_ptr<remoting::RendererProxy> _renderer; - std::unique_ptr<remoting::GestureInterpreter> _gestureInterpreter; - std::unique_ptr<remoting::KeyboardInterpreter> _keyboardInterpreter; std::unique_ptr<remoting::AudioPlayerIos> _audioPlayer; std::unique_ptr<remoting::ChromotingSession> _session; } @@ -141,9 +141,8 @@ [_displayHandler CreateVideoRenderer], _audioPlayer->GetAudioStreamConsumer(), info)); _renderer = [_displayHandler CreateRendererProxy]; - _gestureInterpreter.reset( - new remoting::GestureInterpreter(_renderer.get(), _session.get())); - _keyboardInterpreter.reset(new remoting::KeyboardInterpreter(_session.get())); + _gestureInterpreter.SetContext(_renderer.get(), _session.get()); + _keyboardInterpreter.SetContext(_session.get()); _session->Connect(); _audioPlayer->Start(); @@ -167,8 +166,8 @@ _runtime->display_task_runner()->DeleteSoon(FROM_HERE, _renderer.release()); } - _gestureInterpreter.reset(); - _keyboardInterpreter.reset(); + _gestureInterpreter.SetContext(nullptr, nullptr); + _keyboardInterpreter.SetContext(nullptr); } #pragma mark - Eventing @@ -195,11 +194,11 @@ } - (remoting::GestureInterpreter*)gestureInterpreter { - return _gestureInterpreter.get(); + return &_gestureInterpreter; } - (remoting::KeyboardInterpreter*)keyboardInterpreter { - return _keyboardInterpreter.get(); + return &_keyboardInterpreter; } #pragma mark - ChromotingSession::Delegate @@ -370,15 +369,11 @@ #pragma mark - GlDisplayHandlerDelegate - (void)canvasSizeChanged:(CGSize)size { - if (_gestureInterpreter) { - _gestureInterpreter->OnDesktopSizeChanged(size.width, size.height); - } + _gestureInterpreter.OnDesktopSizeChanged(size.width, size.height); } - (void)rendererTicked { - if (_gestureInterpreter) { - _gestureInterpreter->ProcessAnimations(); - } + _gestureInterpreter.ProcessAnimations(); } @end
diff --git a/remoting/protocol/ssl_hmac_channel_authenticator.cc b/remoting/protocol/ssl_hmac_channel_authenticator.cc index 542a0c3..353bb1f2 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator.cc +++ b/remoting/protocol/ssl_hmac_channel_authenticator.cc
@@ -303,7 +303,6 @@ // because we use self-signed certs. Disable it so that the SSL // layer doesn't try to initialize OCSP (OCSP works only on the IO // thread). - ssl_config.cert_io_enabled = false; ssl_config.rev_checking_enabled = false; ssl_config.require_ecdhe = true;
diff --git a/remoting/protocol/validating_authenticator_unittest.cc b/remoting/protocol/validating_authenticator_unittest.cc index 6baddf23..75631e1 100644 --- a/remoting/protocol/validating_authenticator_unittest.cc +++ b/remoting/protocol/validating_authenticator_unittest.cc
@@ -4,6 +4,7 @@ #include <memory> #include <string> +#include <tuple> #include <utility> #include "base/bind.h" @@ -37,7 +38,7 @@ ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - ::std::tr1::get<k>(args).Run(); + std::get<k>(args).Run(); } } // namespace
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd index 104e1dc..0fe27d9 100644 --- a/remoting/resources/remoting_strings.grd +++ b/remoting/resources/remoting_strings.grd
@@ -650,6 +650,9 @@ <message name="IDS_IOS_CAMERA_USAGE_DESCRIPTION" desc="Message shown when the app requests permission to use the camera of the device."> To choose a profile picture, allow Chrome Remote Desktop to access your camera </message> + <message name="IDS_SERVER_COMMUNICATION_ERROR" desc="Message shown when the client fails to communicate with the back end server."> + Failed to communicate with the server: <ph name="ERROR">$1<ex>Server Unavailable</ex></ph> + </message> <!-- Play Store listings text. These Android-specific strings are not marked with formatter_data="android_java" since they are used only for the Play @@ -707,9 +710,7 @@ • On your iOS device, open the app and tap on any of your online computers to connect. </message> <message name="IDS_APP_STORE_CHANGES" desc="List of what's changed in this release of Chrome Remote Desktop for iOS. [CHAR-LIMIT=4000] [NAME=app_store_changes]"> -• New look and feel. -• Improved performance, responsiveness and reliability. -• Support for playing audio from Windows or Linux computers. +General fixes and stability improvements. </message> </if> <!-- is_android or is_ios -->
diff --git a/remoting/resources/remoting_strings_en-GB.xtb b/remoting/resources/remoting_strings_en-GB.xtb index f440e7cf..b1cd15e 100644 --- a/remoting/resources/remoting_strings_en-GB.xtb +++ b/remoting/resources/remoting_strings_en-GB.xtb
@@ -143,6 +143,7 @@ <translation id="4145029455188493639">Signed in as <ph name="EMAIL_ADDRESS" />.</translation> <translation id="4155497795971509630">Some required components are missing. Please make sure that you have installed the latest version of the software and try again.</translation> <translation id="4156740505453712750">To protect access to this computer, please choose a PIN of <ph name="BOLD_START" />at least six digits<ph name="BOLD_END" />. This PIN will be required when connecting from another location.</translation> +<translation id="4169432154993690151">To choose a profile picture, allow Chrome Remote Desktop to access your camera</translation> <translation id="4176825807642096119">Access code</translation> <translation id="4207623512727273241">Please run the installer before continuing.</translation> <translation id="4227991223508142681">Host Provisioning Utility</translation> @@ -260,6 +261,7 @@ <translation id="6748108480210050150">From</translation> <translation id="677755392401385740">Host started for user: <ph name="HOST_USERNAME" />.</translation> <translation id="6865175692670882333">View/edit</translation> +<translation id="6913710942997637770">To choose a profile picture, allow Chrome Remote Desktop to access your photos</translation> <translation id="6930242544192836755">Duration</translation> <translation id="6939719207673461467">Show/hide keyboard.</translation> <translation id="6944854424004126054">Restore window</translation>
diff --git a/services/device/public/cpp/device_features.cc b/services/device/public/cpp/device_features.cc index 14feade..dcbbb00 100644 --- a/services/device/public/cpp/device_features.cc +++ b/services/device/public/cpp/device_features.cc
@@ -9,7 +9,7 @@ // Enables sensors based on Generic Sensor API: // https://w3c.github.io/sensors/ const base::Feature kGenericSensor{"GenericSensor", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables an extra set of concrete sensors classes based on Generic Sensor API, // which expose previously unexposed platform features, e.g. ALS or Magnetometer const base::Feature kGenericSensorExtraClasses{
diff --git a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc index 6216ec6..4c1694c 100644 --- a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc +++ b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.cc
@@ -39,11 +39,10 @@ } bool PowerMonitorBroadcastSource::IsOnBatteryPowerImpl() { - return client_->last_reported_battery_power_state(); + return client_->last_reported_on_battery_power_state(); } -PowerMonitorBroadcastSource::Client::Client() - : last_reported_battery_power_state_(false), binding_(this) {} +PowerMonitorBroadcastSource::Client::Client() : binding_(this) {} PowerMonitorBroadcastSource::Client::~Client() {} @@ -58,14 +57,9 @@ power_monitor->AddClient(std::move(client)); } -bool PowerMonitorBroadcastSource::Client::last_reported_battery_power_state() { - return base::subtle::NoBarrier_Load(&last_reported_battery_power_state_) != 0; -} - void PowerMonitorBroadcastSource::Client::PowerStateChange( bool on_battery_power) { - base::subtle::NoBarrier_Store(&last_reported_battery_power_state_, - on_battery_power); + last_reported_on_battery_power_state_ = on_battery_power; ProcessPowerEvent(PowerMonitorSource::POWER_STATE_EVENT); }
diff --git a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h index 73feb64..46e686dd 100644 --- a/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h +++ b/services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/atomicops.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/power_monitor/power_monitor_source.h" @@ -47,17 +46,22 @@ ~Client() override; void Init(std::unique_ptr<service_manager::Connector> connector); - bool last_reported_battery_power_state(); + bool last_reported_on_battery_power_state() const { + return last_reported_on_battery_power_state_; + } + + // device::mojom::PowerMonitorClient implementation void PowerStateChange(bool on_battery_power) override; void Suspend() override; void Resume() override; private: - volatile base::subtle::AtomicWord last_reported_battery_power_state_; std::unique_ptr<service_manager::Connector> connector_; mojo::Binding<device::mojom::PowerMonitorClient> binding_; + bool last_reported_on_battery_power_state_ = false; + DISALLOW_COPY_AND_ASSIGN(Client); }; @@ -70,6 +74,7 @@ Client* client_for_testing() const { return client_.get(); } bool IsOnBatteryPowerImpl() override; + std::unique_ptr<Client> client_; scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/storage/browser/blob/blob_memory_controller.cc b/storage/browser/blob/blob_memory_controller.cc index 028108a..17d5d7d68 100644 --- a/storage/browser/blob/blob_memory_controller.cc +++ b/storage/browser/blob/blob_memory_controller.cc
@@ -50,6 +50,16 @@ using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask; using DiskSpaceFuncPtr = BlobMemoryController::DiskSpaceFuncPtr; +File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) { + File::Error error = File::FILE_OK; + base::CreateDirectoryAndGetError(blob_storage_dir, &error); + UMA_HISTOGRAM_ENUMERATION("Storage.Blob.CreateDirectoryResult", -error, + -File::FILE_ERROR_MAX); + DLOG_IF(ERROR, error != File::FILE_OK) + << "Error creating blob storage directory: " << error; + return error; +} + // CrOS: // * Ram - 20% // * Disk - 50% @@ -63,9 +73,10 @@ // * Disk - 10% BlobStorageLimits CalculateBlobStorageLimitsImpl(const FilePath& storage_dir, bool disk_enabled) { - int64_t disk_size = - disk_enabled ? base::SysInfo::AmountOfTotalDiskSpace(storage_dir) : 0ull; + int64_t disk_size = 0ull; int64_t memory_size = base::SysInfo::AmountOfPhysicalMemory(); + if (disk_enabled && CreateBlobDirectory(storage_dir) == base::File::FILE_OK) + disk_size = base::SysInfo::AmountOfTotalDiskSpace(storage_dir); BlobStorageLimits limits; @@ -100,16 +111,6 @@ return limits; } -File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) { - File::Error error = File::FILE_OK; - base::CreateDirectoryAndGetError(blob_storage_dir, &error); - UMA_HISTOGRAM_ENUMERATION("Storage.Blob.CreateDirectoryResult", -error, - -File::FILE_ERROR_MAX); - DLOG_IF(ERROR, error != File::FILE_OK) - << "Error creating blob storage directory: " << error; - return error; -} - void DestructFile(File infos_without_references) {} void DeleteFiles(std::vector<FileCreationInfo> files) { @@ -280,7 +281,7 @@ if (file.IsValid()) { DCHECK(file_deletion_runner); file_deletion_runner->PostTask( - FROM_HERE, base::BindOnce(&DestructFile, base::Passed(&file))); + FROM_HERE, base::BindOnce(&DestructFile, std::move(file))); } } FileCreationInfo::FileCreationInfo(FileCreationInfo&&) = default; @@ -473,7 +474,7 @@ controller_->disk_used_ -= allocation_size_; controller_->AdjustDiskUsage(static_cast<uint64_t>(avail_disk_space)); controller_->file_runner_->PostTask( - FROM_HERE, base::BindOnce(&DeleteFiles, base::Passed(&result.files))); + FROM_HERE, base::BindOnce(&DeleteFiles, std::move(result.files))); std::unique_ptr<FileQuotaAllocationTask> this_object = std::move(*my_list_position_); controller_->pending_file_quota_tasks_.erase(my_list_position_); @@ -686,8 +687,8 @@ DCHECK_GE(disk_used_, old_length - new_length); disk_used_ -= old_length - new_length; file_reference->AddFinalReleaseCallback( - base::BindRepeating(&BlobMemoryController::OnShrunkenBlobFileDelete, - weak_factory_.GetWeakPtr(), old_length - new_length)); + base::BindOnce(&BlobMemoryController::OnShrunkenBlobFileDelete, + weak_factory_.GetWeakPtr(), old_length - new_length)); } void BlobMemoryController::GrowFileAllocation( @@ -696,8 +697,8 @@ DCHECK_LE(delta, GetAvailableFileSpaceForBlobs()); disk_used_ += delta; file_reference->AddFinalReleaseCallback( - base::BindRepeating(&BlobMemoryController::OnBlobFileDelete, - weak_factory_.GetWeakPtr(), delta)); + base::BindOnce(&BlobMemoryController::OnBlobFileDelete, + weak_factory_.GetWeakPtr(), delta)); } void BlobMemoryController::NotifyMemoryItemsUsed( @@ -887,15 +888,12 @@ // We try to page items to disk until our current system size + requested // memory is below our size limit. // Size limit is a lower |memory_limit_before_paging()| if we have disk space. - while (total_memory_usage > limits_.effective_max_disk_space || - (disk_used_ < limits_.effective_max_disk_space && - total_memory_usage > in_memory_limit)) { + while (disk_used_ < limits_.effective_max_disk_space && + total_memory_usage > in_memory_limit) { const char* reason = nullptr; if (memory_pressure_level != base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { reason = "OnMemoryPressure"; - } else if (total_memory_usage > limits_.effective_max_disk_space) { - reason = "SizeExceededMaxDiskSpace"; } else { reason = "SizeExceededInMemoryLimit"; }
diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc index 3264dd07..469b01ab 100644 --- a/storage/browser/blob/blob_storage_context.cc +++ b/storage/browser/blob/blob_storage_context.cc
@@ -323,7 +323,7 @@ content->ReleasePendingTransportItems(), base::BindOnce(&BlobStorageContext::OnEnoughSpaceForTransport, ptr_factory_.GetWeakPtr(), content->uuid_, - base::Passed(&empty_files))); + std::move(empty_files))); break; } case TransportQuotaType::FILE:
diff --git a/storage/browser/fileapi/async_file_util_adapter.cc b/storage/browser/fileapi/async_file_util_adapter.cc index f2c0c3f..4c46da8 100644 --- a/storage/browser/fileapi/async_file_util_adapter.cc +++ b/storage/browser/fileapi/async_file_util_adapter.cc
@@ -142,7 +142,7 @@ // If |callback| been cancelled, free |file| on the correct task runner. context->task_runner()->PostTask( FROM_HERE, - BindOnce([](base::File file) { file.Close(); }, Passed(&file))); + BindOnce([](base::File file) { file.Close(); }, std::move(file))); return; }
diff --git a/storage/browser/fileapi/file_system_operation_impl.cc b/storage/browser/fileapi/file_system_operation_impl.cc index 93a975f1..fb7c6d7 100644 --- a/storage/browser/fileapi/file_system_operation_impl.cc +++ b/storage/browser/fileapi/file_system_operation_impl.cc
@@ -47,7 +47,7 @@ base::OnceClosure on_close_callback) { if (!operation) { context->default_file_task_runner()->PostTask( - FROM_HERE, base::BindOnce(&Destruct, base::Passed(&file))); + FROM_HERE, base::BindOnce(&Destruct, std::move(file))); return; } callback.Run(std::move(file), std::move(on_close_callback)); @@ -136,8 +136,8 @@ DCHECK(SetPendingOperationType(kOperationDirectoryExists)); async_file_util_->GetFileInfo( std::move(operation_context_), url, GET_METADATA_FIELD_IS_DIRECTORY, - base::Bind(&FileSystemOperationImpl::DidDirectoryExists, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidDirectoryExists, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::FileExists(const FileSystemURL& url, @@ -145,8 +145,8 @@ DCHECK(SetPendingOperationType(kOperationFileExists)); async_file_util_->GetFileInfo( std::move(operation_context_), url, GET_METADATA_FIELD_IS_DIRECTORY, - base::Bind(&FileSystemOperationImpl::DidFileExists, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFileExists, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::GetMetadata(const FileSystemURL& url, @@ -175,8 +175,8 @@ // in DidDeleteRecursively. async_file_util_->DeleteRecursively( std::move(operation_context_), url, - base::Bind(&FileSystemOperationImpl::DidDeleteRecursively, - weak_factory_.GetWeakPtr(), url, callback)); + base::BindOnce(&FileSystemOperationImpl::DidDeleteRecursively, + weak_factory_.GetWeakPtr(), url, callback)); return; } @@ -227,8 +227,8 @@ async_file_util_->Touch( std::move(operation_context_), url, last_access_time, last_modified_time, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::OpenFile(const FileSystemURL& url, @@ -306,8 +306,8 @@ DCHECK(SetPendingOperationType(kOperationRemove)); async_file_util_->DeleteFile( std::move(operation_context_), url, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::RemoveDirectory( @@ -316,8 +316,8 @@ DCHECK(SetPendingOperationType(kOperationRemove)); async_file_util_->DeleteDirectory( std::move(operation_context_), url, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::CopyFileLocal( @@ -405,10 +405,9 @@ DCHECK(quota_manager_proxy); DCHECK(quota_manager_proxy->quota_manager()); quota_manager_proxy->quota_manager()->GetUsageAndQuota( - url.origin(), - FileSystemTypeToQuotaStorageType(url.type()), - base::Bind(&FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask, - weak_factory_.GetWeakPtr(), task, error_callback)); + url.origin(), FileSystemTypeToQuotaStorageType(url.type()), + base::BindOnce(&FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask, + weak_factory_.GetWeakPtr(), task, error_callback)); } void FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask( @@ -433,7 +432,7 @@ bool exclusive) { async_file_util_->EnsureFileExists( std::move(operation_context_), url, - base::Bind( + base::BindOnce( exclusive ? &FileSystemOperationImpl::DidEnsureFileExistsExclusive : &FileSystemOperationImpl::DidEnsureFileExistsNonExclusive, weak_factory_.GetWeakPtr(), callback)); @@ -445,8 +444,8 @@ bool exclusive, bool recursive) { async_file_util_->CreateDirectory( std::move(operation_context_), url, exclusive, recursive, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::DoCopyFileLocal( @@ -458,8 +457,8 @@ async_file_util_->CopyFileLocal( std::move(operation_context_), src_url, dest_url, option, progress_callback, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::DoMoveFileLocal( @@ -469,8 +468,8 @@ const StatusCallback& callback) { async_file_util_->MoveFileLocal( std::move(operation_context_), src_url, dest_url, option, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::DoCopyInForeignFile( @@ -479,8 +478,8 @@ const StatusCallback& callback) { async_file_util_->CopyInForeignFile( std::move(operation_context_), src_local_disk_file_path, dest_url, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::DoTruncate(const FileSystemURL& url, @@ -488,8 +487,8 @@ int64_t length) { async_file_util_->Truncate( std::move(operation_context_), url, length, - base::Bind(&FileSystemOperationImpl::DidFinishOperation, - weak_factory_.GetWeakPtr(), callback)); + base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::DoOpenFile(const FileSystemURL& url, @@ -497,8 +496,8 @@ int file_flags) { async_file_util_->CreateOrOpen( std::move(operation_context_), url, file_flags, - base::Bind(&DidOpenFile, file_system_context_, weak_factory_.GetWeakPtr(), - callback)); + base::BindOnce(&DidOpenFile, file_system_context_, + weak_factory_.GetWeakPtr(), callback)); } void FileSystemOperationImpl::DidEnsureFileExistsExclusive(
diff --git a/storage/browser/fileapi/file_system_operation_runner.cc b/storage/browser/fileapi/file_system_operation_runner.cc index 368603c..3519a3d 100644 --- a/storage/browser/fileapi/file_system_operation_runner.cc +++ b/storage/browser/fileapi/file_system_operation_runner.cc
@@ -630,9 +630,10 @@ if (handle.scope) { finished_operations_.insert(handle.id); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&FileSystemOperationRunner::DidOpenFile, - AsWeakPtr(), handle, callback, Passed(&file), - std::move(on_close_callback))); + FROM_HERE, + base::BindOnce(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(), + handle, callback, std::move(file), + std::move(on_close_callback))); return; } callback.Run(std::move(file), std::move(on_close_callback));
diff --git a/storage/browser/fileapi/file_system_quota_client_unittest.cc b/storage/browser/fileapi/file_system_quota_client_unittest.cc index e8b4c830..4cb11e1 100644 --- a/storage/browser/fileapi/file_system_quota_client_unittest.cc +++ b/storage/browser/fileapi/file_system_quota_client_unittest.cc
@@ -73,8 +73,8 @@ StorageType type) { quota_client->GetOriginUsage( url::Origin::Create(GURL(origin_url)), type, - base::Bind(&FileSystemQuotaClientTest::OnGetUsage, - weak_factory_.GetWeakPtr())); + base::BindOnce(&FileSystemQuotaClientTest::OnGetUsage, + weak_factory_.GetWeakPtr())); } int64_t GetOriginUsage(FileSystemQuotaClient* quota_client, @@ -90,9 +90,8 @@ StorageType type) { origins_.clear(); quota_client->GetOriginsForType( - type, - base::Bind(&FileSystemQuotaClientTest::OnGetOrigins, - weak_factory_.GetWeakPtr())); + type, base::BindOnce(&FileSystemQuotaClientTest::OnGetOrigins, + weak_factory_.GetWeakPtr())); base::RunLoop().RunUntilIdle(); return origins_; } @@ -104,8 +103,8 @@ origins_.clear(); quota_client->GetOriginsForHost( type, host, - base::Bind(&FileSystemQuotaClientTest::OnGetOrigins, - weak_factory_.GetWeakPtr())); + base::BindOnce(&FileSystemQuotaClientTest::OnGetOrigins, + weak_factory_.GetWeakPtr())); base::RunLoop().RunUntilIdle(); return origins_; } @@ -115,8 +114,8 @@ StorageType type) { quota_client->GetOriginUsage( url::Origin::Create(GURL(origin_url)), type, - base::Bind(&FileSystemQuotaClientTest::OnGetAdditionalUsage, - weak_factory_.GetWeakPtr())); + base::BindOnce(&FileSystemQuotaClientTest::OnGetAdditionalUsage, + weak_factory_.GetWeakPtr())); } bool CreateFileSystemDirectory(const base::FilePath& file_path, @@ -206,8 +205,8 @@ deletion_status_ = blink::mojom::QuotaStatusCode::kUnknown; quota_client->DeleteOriginData( url::Origin::Create(GURL(origin)), type, - base::Bind(&FileSystemQuotaClientTest::OnDeleteOrigin, - weak_factory_.GetWeakPtr())); + base::BindOnce(&FileSystemQuotaClientTest::OnDeleteOrigin, + weak_factory_.GetWeakPtr())); } int64_t usage() const { return usage_; }
diff --git a/storage/browser/fileapi/local_file_stream_reader.cc b/storage/browser/fileapi/local_file_stream_reader.cc index 187d13d..88ffb1eb 100644 --- a/storage/browser/fileapi/local_file_stream_reader.cc +++ b/storage/browser/fileapi/local_file_stream_reader.cc
@@ -49,11 +49,9 @@ int64_t LocalFileStreamReader::GetLength( const net::Int64CompletionCallback& callback) { const bool posted = base::FileUtilProxy::GetFileInfo( - task_runner_.get(), - file_path_, - base::Bind(&LocalFileStreamReader::DidGetFileInfoForGetLength, - weak_factory_.GetWeakPtr(), - callback)); + task_runner_.get(), file_path_, + base::BindOnce(&LocalFileStreamReader::DidGetFileInfoForGetLength, + weak_factory_.GetWeakPtr(), callback)); DCHECK(posted); return net::ERR_IO_PENDING; }
diff --git a/storage/browser/fileapi/quota/quota_backend_impl.cc b/storage/browser/fileapi/quota/quota_backend_impl.cc index e77a125..f0689b61 100644 --- a/storage/browser/fileapi/quota/quota_backend_impl.cc +++ b/storage/browser/fileapi/quota/quota_backend_impl.cc
@@ -49,9 +49,9 @@ quota_manager_proxy_->GetUsageAndQuota( file_task_runner_.get(), url::Origin::Create(origin), FileSystemTypeToQuotaStorageType(type), - base::Bind(&QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota, - weak_ptr_factory_.GetWeakPtr(), - QuotaReservationInfo(origin, type, delta), callback)); + base::BindOnce(&QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota, + weak_ptr_factory_.GetWeakPtr(), + QuotaReservationInfo(origin, type, delta), callback)); } void QuotaBackendImpl::ReleaseReservedQuota(const GURL& origin,
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.cc b/storage/browser/fileapi/sandbox_file_stream_writer.cc index 73c6c09..fb4d9fb1 100644 --- a/storage/browser/fileapi/sandbox_file_stream_writer.cc +++ b/storage/browser/fileapi/sandbox_file_stream_writer.cc
@@ -161,10 +161,9 @@ DCHECK(quota_manager_proxy->quota_manager()); quota_manager_proxy->quota_manager()->GetUsageAndQuota( - url_.origin(), - FileSystemTypeToQuotaStorageType(url_.type()), - base::Bind(&SandboxFileStreamWriter::DidGetUsageAndQuota, - weak_factory_.GetWeakPtr(), callback)); + url_.origin(), FileSystemTypeToQuotaStorageType(url_.type()), + base::BindOnce(&SandboxFileStreamWriter::DidGetUsageAndQuota, + weak_factory_.GetWeakPtr(), callback)); } void SandboxFileStreamWriter::DidGetUsageAndQuota(
diff --git a/storage/browser/fileapi/timed_task_helper.cc b/storage/browser/fileapi/timed_task_helper.cc index 6a2e2c30..bac6358c 100644 --- a/storage/browser/fileapi/timed_task_helper.cc +++ b/storage/browser/fileapi/timed_task_helper.cc
@@ -86,8 +86,8 @@ void TimedTaskHelper::PostDelayedTask(std::unique_ptr<Tracker> tracker, base::TimeDelta delay) { task_runner_->PostDelayedTask( - posted_from_, - base::BindOnce(&TimedTaskHelper::Fired, base::Passed(&tracker)), delay); + posted_from_, base::BindOnce(&TimedTaskHelper::Fired, std::move(tracker)), + delay); } } // namespace storage
diff --git a/storage/browser/quota/special_storage_policy.h b/storage/browser/quota/special_storage_policy.h index a76d983d..f8a1253 100644 --- a/storage/browser/quota/special_storage_policy.h +++ b/storage/browser/quota/special_storage_policy.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" #include "storage/browser/storage_browser_export.h" @@ -40,6 +41,11 @@ virtual ~Observer(); }; + // Returns true if the cookie associated with the domain and is_https status + // should be deleted. + using DeleteCookiePredicate = + base::RepeatingCallback<bool(const std::string&, bool)>; + SpecialStoragePolicy(); // Protected storage is not subject to removal by the browsing data remover. @@ -58,16 +64,18 @@ // when the session ends. virtual bool IsStorageSessionOnly(const GURL& origin) = 0; - // Cookies should be deleted if the origin is session only or blocked because - // it is possible to e.g. create an .example.com cookie from www.example.com. - // If www.example.com is SESSION_ONLY and example.com is BLOCKED, this cookie - // could be created but not deleted. If http://example.com is BLOCKED, but - // https://example.com is ALLOWED, the cookie will be kept. - virtual bool ShouldDeleteCookieOnExit(const GURL& origin) = 0; - // Returns true if some origins are only allowed session-only storage. virtual bool HasSessionOnlyOrigins() = 0; + // Returns a predicate that takes the domain of a cookie and a bool whether + // the cookie is secure and returns true if the cookie should be deleted on + // exit. + // If |HasSessionOnlyOrigins()| is true a non-null callback is returned. + // It uses domain matching as described in section 5.1.3 of RFC 6265 to + // identify content setting rules that could have influenced the cookie + // when it was created. + virtual DeleteCookiePredicate CreateDeleteCookieOnExitPredicate() = 0; + // Adds/removes an observer, the policy does not take // ownership of the observer. Should only be called on the IO thread. void AddObserver(Observer* observer);
diff --git a/storage/browser/test/async_file_test_helper.cc b/storage/browser/test/async_file_test_helper.cc index b395425e..a741d833 100644 --- a/storage/browser/test/async_file_test_helper.cc +++ b/storage/browser/test/async_file_test_helper.cc
@@ -267,8 +267,8 @@ base::RunLoop run_loop; quota_manager->GetUsageAndQuota( origin, FileSystemTypeToQuotaStorageType(type), - base::Bind(&DidGetUsageAndQuota, &status, usage, quota, - run_loop.QuitWhenIdleClosure())); + base::BindOnce(&DidGetUsageAndQuota, &status, usage, quota, + run_loop.QuitWhenIdleClosure())); run_loop.Run(); return status; }
diff --git a/storage/browser/test/mock_quota_manager_unittest.cc b/storage/browser/test/mock_quota_manager_unittest.cc index 33f7bcf..9fc112d 100644 --- a/storage/browser/test/mock_quota_manager_unittest.cc +++ b/storage/browser/test/mock_quota_manager_unittest.cc
@@ -60,8 +60,8 @@ void GetModifiedOrigins(StorageType type, base::Time since) { manager_->GetOriginsModifiedSince( type, since, - base::Bind(&MockQuotaManagerTest::GotModifiedOrigins, - weak_factory_.GetWeakPtr())); + base::BindOnce(&MockQuotaManagerTest::GotModifiedOrigins, + weak_factory_.GetWeakPtr())); } void GotModifiedOrigins(const std::set<GURL>& origins, StorageType type) { @@ -73,8 +73,8 @@ int quota_client_mask) { manager_->DeleteOriginData( origin, type, quota_client_mask, - base::Bind(&MockQuotaManagerTest::DeletedOriginData, - weak_factory_.GetWeakPtr())); + base::BindOnce(&MockQuotaManagerTest::DeletedOriginData, + weak_factory_.GetWeakPtr())); } void DeletedOriginData(blink::mojom::QuotaStatusCode status) {
diff --git a/storage/browser/test/mock_special_storage_policy.cc b/storage/browser/test/mock_special_storage_policy.cc index 5a711dd..42af186 100644 --- a/storage/browser/test/mock_special_storage_policy.cc +++ b/storage/browser/test/mock_special_storage_policy.cc
@@ -4,7 +4,10 @@ #include "storage/browser/test/mock_special_storage_policy.h" +#include "base/bind.h" +#include "base/callback.h" #include "base/stl_util.h" +#include "net/cookies/cookie_util.h" namespace content { @@ -24,8 +27,18 @@ return base::ContainsKey(session_only_, origin); } -bool MockSpecialStoragePolicy::ShouldDeleteCookieOnExit(const GURL& origin) { - return base::ContainsKey(session_only_, origin); +storage::SpecialStoragePolicy::DeleteCookiePredicate +MockSpecialStoragePolicy::CreateDeleteCookieOnExitPredicate() { + return base::BindRepeating( + &MockSpecialStoragePolicy::ShouldDeleteCookieOnExit, + base::Unretained(this)); +} + +bool MockSpecialStoragePolicy::ShouldDeleteCookieOnExit( + const std::string& domain, + bool is_https) { + GURL origin = net::cookie_util::CookieOriginToURL(domain, is_https); + return IsStorageSessionOnly(origin); } bool MockSpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) {
diff --git a/storage/browser/test/mock_special_storage_policy.h b/storage/browser/test/mock_special_storage_policy.h index f210e15e..b6a26ae 100644 --- a/storage/browser/test/mock_special_storage_policy.h +++ b/storage/browser/test/mock_special_storage_policy.h
@@ -22,10 +22,10 @@ bool IsStorageProtected(const GURL& origin) override; bool IsStorageUnlimited(const GURL& origin) override; bool IsStorageSessionOnly(const GURL& origin) override; - bool ShouldDeleteCookieOnExit(const GURL& origin) override; bool HasIsolatedStorage(const GURL& origin) override; bool HasSessionOnlyOrigins() override; bool IsStorageDurable(const GURL& origin) override; + DeleteCookiePredicate CreateDeleteCookieOnExitPredicate() override; void AddProtected(const GURL& origin) { protected_.insert(origin); } @@ -66,6 +66,8 @@ ~MockSpecialStoragePolicy() override; private: + bool ShouldDeleteCookieOnExit(const std::string& domain, bool is_https); + std::set<GURL> protected_; std::set<GURL> unlimited_; std::set<GURL> session_only_;
diff --git a/storage/common/run_all_unittests.cc b/storage/common/run_all_unittests.cc index e1eb33c0..75ad05f 100644 --- a/storage/common/run_all_unittests.cc +++ b/storage/common/run_all_unittests.cc
@@ -15,7 +15,7 @@ mojo::edk::Init(); result = base::LaunchUnitTests( argc, argv, - base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); + base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); } return result; }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 6c0bf79..5dfef214 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -2274,7 +2274,7 @@ "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, - "shards": 10 + "shards": 12 } }, { @@ -5679,7 +5679,7 @@ "os": "Ubuntu-16.04" } ], - "shards": 10 + "shards": 12 } }, { @@ -6200,7 +6200,7 @@ "os": "Ubuntu-14.04" } ], - "shards": 6 + "shards": 12 } } ] @@ -9025,7 +9025,7 @@ "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, - "shards": 6 + "shards": 12 } } ] @@ -9190,7 +9190,7 @@ "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, - "shards": 6 + "shards": 12 } } ]
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 52818eb..208548c 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -467,7 +467,7 @@ "os": "Mac-10.10.5" } ], - "shards": 10 + "shards": 12 } }, { @@ -928,7 +928,7 @@ "os": "Mac-10.11.6" } ], - "shards": 10 + "shards": 12 } }, { @@ -1850,6 +1850,28 @@ } }, { + "isolate_name": "webkit_layout_tests_exparchive", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/WebKit/Tools/Scripts/merge-layout-test-results" + }, + "name": "webkit_layout_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "hidpi": "0", + "os": "Mac-10.12.6" + } + ], + "shards": 12 + } + }, + { "isolate_name": "webkit_python_tests", "name": "webkit_python_tests", "swarming": {
diff --git a/testing/buildbot/chromium.webkit.json b/testing/buildbot/chromium.webkit.json index 6f309ff..f6b4ee2 100644 --- a/testing/buildbot/chromium.webkit.json +++ b/testing/buildbot/chromium.webkit.json
@@ -20,7 +20,7 @@ "os": "Ubuntu-14.04" } ], - "shards": 6 + "shards": 12 } } ] @@ -168,7 +168,7 @@ "os": "Mac-10.10.5" } ], - "shards": 6 + "shards": 12 } } ] @@ -193,7 +193,7 @@ "os": "Mac-10.11.6" } ], - "shards": 6 + "shards": 12 } } ] @@ -221,37 +221,12 @@ "os": "Mac-10.11.6" } ], - "shards": 6 + "shards": 12 } } ] }, - "WebKit Mac10.12": { - "isolated_scripts": [ - { - "isolate_name": "webkit_layout_tests_exparchive", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/WebKit/Tools/Scripts/merge-layout-test-results" - }, - "name": "webkit_layout_tests", - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "hidpi": "0", - "os": "Mac-10.12.6" - } - ], - "shards": 6 - } - } - ] - }, + "WebKit Mac10.12": {}, "WebKit Mac10.12 (retina)": { "isolated_scripts": [ { @@ -274,7 +249,7 @@ "pool": "Chrome-GPU" } ], - "shards": 6 + "shards": 12 } } ] @@ -308,7 +283,7 @@ "os": "Windows-10-15063" } ], - "shards": 6 + "shards": 12 } } ] @@ -332,7 +307,7 @@ "os": "Windows-7-SP1" } ], - "shards": 6 + "shards": 12 } } ]
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 179fe183..9c6d9f3 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -1764,7 +1764,7 @@ "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, - "shards": 10 + "shards": 12 } }, { @@ -2993,7 +2993,7 @@ "os": "Windows-7-SP1" } ], - "shards": 10 + "shards": 12 } }, {
diff --git a/testing/buildbot/filters/fuchsia.content_unittests.filter b/testing/buildbot/filters/fuchsia.content_unittests.filter index 67db632..33ec215 100644 --- a/testing/buildbot/filters/fuchsia.content_unittests.filter +++ b/testing/buildbot/filters/fuchsia.content_unittests.filter
@@ -55,6 +55,7 @@ -WebContentsAudioInputStreamTest.MirroringOneStreamAfterTargetChange* # Flaky, https://crbug.com/802375 and https://crbug.com/776424. +-RenderWidgetHostViewAuraOverscrollTest.GestureScrollDebounceOverscrolls -RenderWidgetHostViewAuraOverscrollTest.GestureScrollDebounceTimerOverscroll -RenderWidgetHostViewAuraOverscrollTest.TouchGestureEndDispatchedAfterOverscrollComplete -RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest.TimerBasedWheelEventPhaseInfo
diff --git a/testing/buildbot/filters/mash.ash_unittests.filter b/testing/buildbot/filters/mash.ash_unittests.filter index 606e0d76..a1da907a 100644 --- a/testing/buildbot/filters/mash.ash_unittests.filter +++ b/testing/buildbot/filters/mash.ash_unittests.filter
@@ -42,9 +42,15 @@ # TODO: Docked magnifier needs reflector to work in mash. # https://crbug.com/814481. +-AccessibilityControllerSigninTest.EnableOnLoginScreenAndLogin/0 +-AccessibilityControllerSigninTest.EnableOnLoginScreenAndLogin/1 +-AccessibilityControllerSigninTest.EnableOnLoginScreenAndLogin/2 -DockedMagnifierTest.AddRemoveDisplays -DockedMagnifierTest.DisplaysWorkAreas -DockedMagnifierTest.HighContrastMode +-DockedMagnifierTest.MutuallyExclusiveMagnifiers +-DockedMagnifierTest.TestEnableAndDisable +-DockedMagnifierTest.TestOutsidePrefsUpdates -DockedMagnifierTest.TextInputFieldEvents -DockedMagnifierTest.TransformSimple
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 94394e2..9c952f52a 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -3522,7 +3522,6 @@ 'Linux Tests (dbg)(1)', 'Linux Tests (dbg)(1)(32)', # chromium.mac - 'Mac10.13 Tests', 'Mac10.13 Tests (dbg)', # chromium.win 'Win 7 Tests x64 (1)', @@ -3622,6 +3621,23 @@ 'shards': 12, }, }, + 'Mac10.13 Tests': { + # TODO(jbudorick,dpranke): Switch this to 10.13. + + # TODO(kbr): if the Swarming dimensions were explicitly specified for + # all jobs then this wouldn't be needed. However, note that this bot + # implicitly specifies gpu:none rather than gpu:8086:0a2e. + 'swarming': { + 'dimension_sets': [ + { + 'gpu': '8086:0a2e', + 'hidpi': '0', + 'os': 'Mac-10.12.6', + }, + ], + 'shards': 12, + }, + }, # TODO(dpranke): Clean up all of the unneeded exceptions on # chromium.webkit.
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 1b6f3a5e..6bf8306 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -545,7 +545,7 @@ }, 'results_handler': 'layout tests', 'swarming': { - 'shards': 6, + 'shards': 12, } }, }, @@ -820,7 +820,7 @@ }, 'results_handler': 'layout tests', 'swarming': { - 'shards': 10, + 'shards': 12, } }, 'webkit_python_tests': {}, @@ -1102,7 +1102,7 @@ 'os': 'Ubuntu-14.04', } ], - 'shards': 6, + 'shards': 12, }, }, },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 454d88f..d7da8f3 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1865,18 +1865,8 @@ }, }, 'WebKit Mac10.12': { - 'test_suites': { - 'isolated_scripts': 'chromium_webkit_isolated_scripts', - }, - 'swarming': { - 'dimension_sets': [ - { - 'gpu': '8086:0a2e', - 'hidpi': '0', - 'os': 'Mac-10.12.6', - }, - ], - }, + # TODO(dpranke): Remove this builder, it is now redundant + # w/ Mac10.13 Tests on chromium.mac }, 'WebKit Win x64 Builder': { # TODO(dpranke): Remove this builder, it is now redundant
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8038d6d3..59aa01af 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1954,6 +1954,25 @@ ] } ], + "NTPArticleSuggestionsNowStream": [ + { + "platforms": [ + "android", + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "content_suggestions_backend": "https://chromefeedcontentsuggestions-pa.googleapis.com/v2/suggestions/fetch" + }, + "enable_features": [ + "NTPArticleSuggestions" + ] + } + ] + } + ], "NTPBreakingNewsPush": [ { "platforms": [ @@ -4135,7 +4154,7 @@ { "name": "VariationsHttpDisabled", "disable_features": [ - "VariationsHTTPRetry" + "VariationsHttpRetry" ] } ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 915bd060a..652cacff 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -509,9 +509,6 @@ crbug.com/714962 external/wpt/css/css-transforms/transform-origin-006.html [ Failure ] crbug.com/591099 external/wpt/css/css-transforms/transform-transformed-tr-percent-height-child.html [ Failure ] crbug.com/591099 external/wpt/css/css-transforms/transform3d-perspective-008.html [ Pass ] -crbug.com/591099 external/wpt/css/css-ui/box-sizing-007.html [ Failure ] -crbug.com/591099 external/wpt/css/css-ui/box-sizing-008.html [ Failure ] -crbug.com/591099 external/wpt/css/css-ui/box-sizing-009.html [ Failure ] crbug.com/591099 external/wpt/css/css-ui/text-overflow-010.html [ Pass ] crbug.com/591099 external/wpt/css/css-ui/text-overflow-012.html [ Failure ] crbug.com/591099 external/wpt/css/css-ui/text-overflow-013.html [ Failure ] @@ -1685,9 +1682,6 @@ crbug.com/591099 fast/writing-mode/vertical-baseline-alignment.html [ Failure ] crbug.com/591099 fast/writing-mode/vertical-font-fallback.html [ Failure ] crbug.com/591099 fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ] -crbug.com/591099 fonts/monospace.html [ Failure ] -crbug.com/591099 fonts/sans-serif.html [ Failure ] -crbug.com/591099 fonts/serif.html [ Failure ] crbug.com/591099 fullscreen/enter-exit-full-screen-hover.html [ Crash ] crbug.com/591099 fullscreen/full-screen-css.html [ Crash ] crbug.com/591099 fullscreen/full-screen-element-stack.html [ Crash ] @@ -1717,7 +1711,6 @@ crbug.com/591099 html/dialog/multiple-centered-dialogs.html [ Failure ] crbug.com/591099 html/marquee/marquee-scroll.html [ Failure ] crbug.com/591099 html/marquee/marquee-scrollamount.html [ Failure ] -crbug.com/591099 html/tabular_data/td_colspan_rendering.html [ Failure ] crbug.com/591099 http/tests/css/css-image-valued-shape.html [ Failure ] crbug.com/591099 http/tests/css/shape-image-file.html [ Failure ] crbug.com/591099 http/tests/csspaint/invalidation-background-image.html [ Timeout ] @@ -1758,10 +1751,7 @@ crbug.com/591099 http/tests/loading/preload-picture-sizes.html [ Failure ] crbug.com/591099 http/tests/local/fileapi/select-dragged-file-input.html [ Skip ] crbug.com/591099 http/tests/misc/acid3.html [ Crash ] -crbug.com/591099 http/tests/misc/iframe404.html [ Failure ] crbug.com/591099 http/tests/misc/object-embedding-svg-delayed-size-negotiation.xhtml [ Failure ] -crbug.com/591099 http/tests/misc/slow-loading-image-in-pattern.html [ Failure ] -crbug.com/591099 http/tests/misc/slow-loading-mask.html [ Failure ] crbug.com/591099 http/tests/origin_trials/sample-api-workers.html [ Pass ] crbug.com/591099 http/tests/permissions/test-api-surface.html [ Pass ] crbug.com/591099 http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Failure ] @@ -1777,19 +1767,13 @@ crbug.com/591099 http/tests/shapes/shape-outside-svg-image-shape-margin.html [ Failure ] crbug.com/591099 http/tests/text-autosizing/narrow-iframe.html [ Failure ] crbug.com/591099 http/tests/text-autosizing/wide-iframe.html [ Failure ] -crbug.com/591099 http/tests/uri/css-href.php [ Failure ] crbug.com/591099 http/tests/websocket/invalid-subprotocol-characters.html [ Timeout ] crbug.com/591099 ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling.htm [ Failure ] crbug.com/591099 ietestcenter/css3/bordersbackgrounds/background-color-applied-to-rounded-inline-element.htm [ Failure ] crbug.com/591099 ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-001.htm [ Failure ] -crbug.com/591099 ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003.htm [ Failure ] -crbug.com/591099 ietestcenter/css3/bordersbackgrounds/border-radius-clip-001.htm [ Failure ] crbug.com/824918 ietestcenter/css3/multicolumn/column-width-applies-to-010.htm [ Failure ] -crbug.com/591099 ietestcenter/css3/text/textshadow-002.htm [ Failure ] crbug.com/714962 images/color-profile-background-clip-text.html [ Failure ] crbug.com/591099 images/color-profile-image-shape.html [ Failure ] -crbug.com/591099 images/exif-orientation-image-document.html [ Failure ] -crbug.com/591099 images/exif-orientation.html [ Failure ] crbug.com/591099 images/percent-height-image.html [ Failure ] crbug.com/591099 inspector-protocol/accessibility/accessibility-ignoredNodes.js [ Crash ] crbug.com/714962 inspector-protocol/accessibility/accessibility-ignoredNodesModal.js [ Failure ] @@ -1824,9 +1808,6 @@ crbug.com/591099 inspector-protocol/timeline/page-frames.js [ Pass ] crbug.com/714962 intersection-observer/text-target.html [ Failure ] crbug.com/591099 media/autoplay/document-user-activation.html [ Failure ] -crbug.com/591099 media/video-aspect-ratio.html [ Failure ] -crbug.com/591099 media/video-colorspace-yuv420.html [ Failure ] -crbug.com/591099 media/video-colorspace-yuv422.html [ Failure ] crbug.com/591099 media/video-persistence.html [ Crash ] crbug.com/591099 netinfo/estimate-multiple-frames.html [ Failure Pass ] crbug.com/591099 overflow/overflow-basic-002.html [ Pass ] @@ -1857,8 +1838,6 @@ crbug.com/714962 paint/invalidation/compositing/composited-inline-change-text-data-keep-geometry.html [ Crash ] crbug.com/591099 paint/invalidation/compositing/fixed-pos-with-abs-pos-child-scroll.html [ Failure ] crbug.com/591099 paint/invalidation/compositing/iframe-inside-squashed-layer.html [ Failure ] -crbug.com/591099 paint/invalidation/compositing/layer-repaint-rects.html [ Failure ] -crbug.com/591099 paint/invalidation/compositing/layer-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/compositing/remove-squashed-layer-plus-move.html [ Failure ] crbug.com/714962 paint/invalidation/compositing/repaint-via-layout-offset.html [ Failure ] crbug.com/591099 paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ Failure ] @@ -1904,16 +1883,6 @@ crbug.com/591099 paint/invalidation/inline-reflow.html [ Failure ] crbug.com/591099 paint/invalidation/insert-frame.html [ Failure ] crbug.com/591099 paint/invalidation/invisible-objects.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-1.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-10.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-2.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-3.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-4.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-5.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-6.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-7.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-8.html [ Failure ] -crbug.com/591099 paint/invalidation/line-flow-with-floats-9.html [ Failure ] crbug.com/591099 paint/invalidation/lines-with-layout-delta.html [ Failure ] crbug.com/591099 paint/invalidation/list-marker-2.html [ Failure ] crbug.com/591099 paint/invalidation/list-marker.html [ Failure ] @@ -1932,7 +1901,6 @@ crbug.com/591099 paint/invalidation/outline/focus-ring-on-inline-continuation-move.html [ Failure ] crbug.com/591099 paint/invalidation/outline/inline-focus.html [ Failure ] crbug.com/591099 paint/invalidation/outline/inline-outline-repaint-2.html [ Failure ] -crbug.com/591099 paint/invalidation/outline/inline-outline-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/outline/outline-change-continuations.html [ Failure ] crbug.com/591099 paint/invalidation/outline/outline-change-invalidation.html [ Failure ] crbug.com/591099 paint/invalidation/outline/outline-change-vertical-rl.html [ Failure ] @@ -1952,7 +1920,6 @@ crbug.com/591099 paint/invalidation/overflow/justify-self-overflow-change.html [ Failure ] crbug.com/591099 paint/invalidation/overflow/line-overflow.html [ Failure ] crbug.com/591099 paint/invalidation/overflow/negative-text-indent-with-overflow-hidden.html [ Failure ] -crbug.com/591099 paint/invalidation/overflow/paged-with-overflowing-block-rl.html [ Failure ] crbug.com/591099 paint/invalidation/overflow/repaint-resized-overflow.html [ Failure ] crbug.com/591099 paint/invalidation/overflow/vertical-overflow-parent.html [ Failure ] crbug.com/591099 paint/invalidation/overflow/vertical-overflow-same.html [ Failure ] @@ -1988,7 +1955,6 @@ crbug.com/591099 paint/invalidation/remove-block-after-layout.html [ Failure ] crbug.com/591099 paint/invalidation/remove-inline-after-layout.html [ Failure ] crbug.com/591099 paint/invalidation/remove-inline-layer-after-layout.html [ Crash ] -crbug.com/591099 paint/invalidation/repaint-across-writing-mode-boundary.html [ Failure ] crbug.com/591099 paint/invalidation/repaint-descandant-on-ancestor-layer-move.html [ Failure ] crbug.com/591099 paint/invalidation/scroll/fixed-under-composited-absolute-scrolled.html [ Crash ] crbug.com/591099 paint/invalidation/scroll/fixed-with-border-under-composited-absolute-scrolled.html [ Crash ] @@ -2013,7 +1979,6 @@ crbug.com/591099 paint/invalidation/svg/add-background-property-on-root.html [ Failure ] crbug.com/591099 paint/invalidation/svg/add-outline-property-on-root.html [ Failure ] crbug.com/591099 paint/invalidation/svg/animated-path-inside-transformed-html.xhtml [ Failure ] -crbug.com/591099 paint/invalidation/svg/hit-test-with-br.xhtml [ Failure ] crbug.com/591099 paint/invalidation/svg/overflow-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/svg/remove-background-property-on-root.html [ Failure ] crbug.com/591099 paint/invalidation/svg/remove-outline-property-on-root.html [ Failure ] @@ -2038,7 +2003,6 @@ crbug.com/591099 paint/invalidation/table/resize-table-repaint-percent-size-cell.html [ Failure ] crbug.com/591099 paint/invalidation/table/resize-table-repaint-vertical-align-cell.html [ Failure ] crbug.com/591099 paint/invalidation/table/resize-table-row-repaint.html [ Failure ] -crbug.com/591099 paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only.html [ Failure ] crbug.com/591099 paint/invalidation/table/table-cell-collapsed-border.html [ Failure ] crbug.com/591099 paint/invalidation/table/table-cell-move.html [ Failure ] crbug.com/591099 paint/invalidation/table/table-collapsed-border.html [ Failure ] @@ -2062,8 +2026,6 @@ crbug.com/591099 paint/invalidation/vertical-align1.html [ Failure ] crbug.com/591099 paint/invalidation/vertical-align2.html [ Failure ] crbug.com/591099 paint/invalidation/vertical-rl-as-paint-container.html [ Failure ] -crbug.com/591099 paint/invalidation/video-mute-repaint.html [ Failure ] -crbug.com/591099 paint/invalidation/video-unmute-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/window-resize/window-resize-centered-inline-under-fixed-pos.html [ Failure ] crbug.com/591099 paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Failure ] crbug.com/591099 paint/markers/active-suggestion-marker-basic.html [ Failure ] @@ -2077,9 +2039,6 @@ crbug.com/591099 paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers.html [ Failure ] crbug.com/591099 paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers.html [ Failure ] crbug.com/591099 paint/markers/first-letter.html [ Failure ] -crbug.com/591099 paint/markers/inline-spelling-markers-hidpi-composited.html [ Failure ] -crbug.com/591099 paint/markers/inline-spelling-markers-hidpi.html [ Failure ] -crbug.com/591099 paint/markers/inline_spelling_markers.html [ Failure ] crbug.com/591099 paint/markers/marker-early-break-bug.html [ Failure ] crbug.com/591099 paint/overflow/background-mask-should-be-recorded-full.html [ Failure ] crbug.com/591099 paint/overflow/composited-scroll-vertical-rl.html [ Failure ] @@ -2131,31 +2090,19 @@ crbug.com/714962 svg/as-background-image/svg-as-background-body.html [ Failure ] crbug.com/591099 svg/as-border-image/svg-as-border-image-2.html [ Failure ] crbug.com/591099 svg/as-border-image/svg-as-border-image.html [ Failure ] -crbug.com/591099 svg/custom/absolute-sized-svg-in-xhtml.xhtml [ Failure ] -crbug.com/591099 svg/custom/clone-element-with-animated-svg-properties.html [ Failure ] crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Failure ] crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area.xhtml [ Failure ] -crbug.com/591099 svg/custom/getsvgdocument.html [ Failure ] -crbug.com/591099 svg/custom/inline-svg-in-xhtml.xml [ Failure ] crbug.com/591099 svg/custom/inline-svg-use-available-width-in-stf.html [ Failure ] crbug.com/591099 svg/custom/junk-data.svg [ Failure ] crbug.com/591099 svg/custom/load-non-wellformed.svg [ Failure ] crbug.com/591099 svg/custom/missing-xlink.svg [ Failure ] -crbug.com/591099 svg/custom/no-inherited-dashed-stroke.xhtml [ Failure ] crbug.com/591099 svg/custom/object-sizing-no-width-height.xhtml [ Failure ] -crbug.com/591099 svg/custom/object-sizing.xhtml [ Failure ] crbug.com/591099 svg/custom/path-bad-data.svg [ Failure ] -crbug.com/591099 svg/custom/rootmost-svg-xy-attrs.xhtml [ Failure ] -crbug.com/591099 svg/custom/svg-float-border-padding.xml [ Failure ] -crbug.com/591099 svg/custom/svg-fonts-in-html.html [ Failure ] crbug.com/591099 svg/custom/text-match-highlight.html [ Failure ] -crbug.com/591099 svg/custom/transformed-text-pattern.html [ Failure ] crbug.com/591099 svg/custom/use-event-retargeting.html [ Failure ] crbug.com/591099 svg/custom/use-font-face-crash.svg [ Failure ] -crbug.com/591099 svg/dom/SVGStringList-basics.xhtml [ Failure ] crbug.com/591099 svg/dom/svgangle-units.html [ Pass Timeout ] crbug.com/591099 svg/filters/feTurbulence-bad-seeds.html [ Failure ] -crbug.com/591099 svg/foreignObject/svg-document-in-html-document.svg [ Failure ] crbug.com/591099 svg/hixie/error/012.xml [ Failure ] crbug.com/591099 svg/hixie/error/dumpAsText/004.xml [ Failure ] crbug.com/591099 svg/hixie/error/dumpAsText/005.xml [ Failure ] @@ -2166,187 +2113,50 @@ crbug.com/591099 svg/parser/whitespace-length-invalid-4.html [ Pass Timeout ] crbug.com/591099 svg/parser/whitespace-number.html [ Timeout ] crbug.com/591099 svg/text/foreignObject-text-clipping-bug.xml [ Failure ] -crbug.com/591099 svg/text/text-repaint-rects.xhtml [ Failure ] crbug.com/714962 svg/text/tspan-multiple-outline.svg [ Failure ] crbug.com/591099 svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ Failure ] crbug.com/591099 svg/wicd/test-scalable-background-image1.xhtml [ Failure ] crbug.com/591099 svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ Failure ] -crbug.com/591099 svg/zoom/page/zoom-svg-float-border-padding.xml [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-percentage-size.xhtml [ Failure ] -crbug.com/591099 svg/zoom/text/zoom-svg-float-border-padding.xml [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug101674.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug106158-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug106158-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug109043.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug110566.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug11384q.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug11384s.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug12008.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug1271.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug1302.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug131020-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug131020.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug131020_iframe.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug13118.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug13196.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug133948.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug137388-1.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug137388-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug137388-3.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug139524-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug14159-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug1430.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug149275-1.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug149275-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug16252.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug17130-1.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug18440.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug18955.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug219693-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2267.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug23235.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2479-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2479-3.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2479-4.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug27038-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2757.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug2886-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2962.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug2973.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2981-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug2997.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug30692.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug3191.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug32205-3.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug38916.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug3977.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug43039.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug43854-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug4427.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug44523.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug4501.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug4576.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46268-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46268-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46268-5.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46268.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46368-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46368-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46480-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46480-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46623-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug46924.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug4803.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug4849-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug48827.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug50695-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug53690-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug5538.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug55527.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug55694.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug57828-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug57828.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug5798.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug58402-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug59354.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug6304.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug641-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug69382-2.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug727.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug7342.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug78162.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug82946-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug82946-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug88035-1.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug88035-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug88524.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug9123-1.html [ Failure ] -crbug.com/591099 tables/mozilla/bugs/bug93363.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug98196.html [ Failure ] -crbug.com/591099 tables/mozilla/core/bloomberg.html [ Failure ] crbug.com/591099 tables/mozilla/core/table_heights.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/col_span.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_align_center.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_align_justify.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_align_left.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_align_right.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_span.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_valign_baseline.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_valign_bottom.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_valign_middle.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_valign_top.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_width_pct.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/colgroup_width_px.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tables_td_align_center.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tables_td_align_left.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tables_td_align_right.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tables_th_align_center.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tables_th_align_left.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tables_th_align_right.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_align_center.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_align_char.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_align_justify.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_align_left.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_align_right.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_char.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_valign_baseline.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_valign_bottom.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_valign_middle.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tbody_valign_top.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tfoot_align_char.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/tfoot_align_justify.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/thead_align_char.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/thead_align_justify.html [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_valign_baseline.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_valign_bottom.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_valign_middle.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_valign_top.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_width_pct.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_width_px.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_col_width_rel.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_colgroup_valign_baseline.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_colgroup_valign_bottom.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_colgroup_valign_middle.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_colgroup_valign_top.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_colgroup_width_pct.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_colgroup_width_rel.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_table.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_align_center.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_align_char.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_align_justify.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_align_left.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_align_right.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_valign_baseline.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_valign_bottom.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_valign_middle.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tbody_valign_top.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_td_align_justify.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_th_align_justify.xml [ Failure ] -crbug.com/591099 tables/mozilla/marvin/x_tr_align_justify.xml [ Failure ] -crbug.com/591099 tables/mozilla/other/cellspacing.html [ Failure ] -crbug.com/591099 tables/mozilla/other/test3.html [ Failure ] -crbug.com/591099 tables/mozilla/other/test6.html [ Failure ] -crbug.com/591099 tables/mozilla/other/wa_table_thtd_rowspan.html [ Failure ] -crbug.com/591099 tables/mozilla/other/wa_table_tr_align.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug1010.html [ Failure ] -crbug.com/714962 tables/mozilla_expected_failures/bugs/bug1055-2.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug1128.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug21518.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug22122.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug32205-4.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug4294.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug51000.html [ Failure ] crbug.com/591099 tables/mozilla_expected_failures/bugs/bug7113.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug72393.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug80762-2.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug85016.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug89315.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/bugs/bug91057.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/core/standards1.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html [ Failure ] crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption.html [ Failure ] crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_bottom.html [ Failure ] crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_hidden.html [ Failure ] @@ -2354,19 +2164,14 @@ crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_left.html [ Failure ] crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_right.html [ Failure ] crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_top.html [ Failure ] -crbug.com/591099 tables/mozilla_expected_failures/marvin/x_colgroup_width_px.xml [ Failure ] crbug.com/591099 transforms/2d/compound-transforms-vs-containers.html [ Failure ] crbug.com/591099 transforms/2d/hindi-rotated.html [ Failure ] crbug.com/591099 transforms/2d/transform-2d.html [ Timeout ] -crbug.com/591099 transforms/2d/transform-fixed-container.html [ Failure ] crbug.com/591099 transforms/3d/general/perspective-non-layer.html [ Failure ] -crbug.com/591099 transforms/3d/general/perspective-units.html [ Failure ] crbug.com/591099 transforms/3d/hit-testing/backface-hit-test.html [ Failure ] crbug.com/591099 transforms/3d/hit-testing/backface-no-transform-hit-test.html [ Failure ] crbug.com/714962 transforms/selection-bounds-in-transformed-view.html [ Failure ] crbug.com/591099 transforms/shadows.html [ Failure ] -crbug.com/591099 transforms/transform-on-inline.html [ Failure ] -crbug.com/591099 transforms/transforms-with-zoom.html [ Failure ] crbug.com/591099 virtual/android/ [ Skip ] crbug.com/591099 virtual/disable-rls/compositing/squashing/add-remove-squashed-layers.html [ Failure ] crbug.com/591099 virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps.html [ Failure ] @@ -2381,15 +2186,11 @@ crbug.com/591099 virtual/gpu-rasterization/images/color-profile-layer.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-reflection.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/cross-fade-overflow-position.html [ Pass Timeout ] -crbug.com/591099 virtual/gpu-rasterization/images/exif-orientation-image-document.html [ Failure ] -crbug.com/591099 virtual/gpu-rasterization/images/exif-orientation.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/percent-height-image.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-video-imageSmoothingEnabled.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-imageSmoothingQuality.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/fillrect_gradient.html [ Pass Timeout ] -crbug.com/591099 virtual/gpu/fast/canvas/image-object-in-canvas.html [ Failure ] -crbug.com/591099 virtual/gpu/fast/canvas/patternfill-repeat.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/shadow-huge-blur.html [ Pass Timeout ] crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html [ Failure ] crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/scrollbar.html [ Crash ] @@ -2413,7 +2214,6 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseevent-getModifierState.html [ Timeout ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/overflow-scroll-fake-mouse-move.html [ Timeout ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointer-events-2.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-capture-transition-events.html [ Timeout ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-capture.html [ Timeout ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-preventdefault.html [ Timeout ] @@ -2437,9 +2237,7 @@ crbug.com/591099 virtual/prefer_compositing_to_lcd_text/ [ Skip ] crbug.com/591099 virtual/reporting-api/external/wpt/content-security-policy/reporting-api/reporting-api-doesnt-send-reports-without-violation.https.sub.html [ Pass ] crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] -crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance.html [ Failure ] crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] -crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance.html [ Failure ] crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] crbug.com/591099 virtual/scroll_customization/ [ Skip ] crbug.com/591099 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 843adb96..8d0386d 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -732,8 +732,6 @@ Bug(none) paint/invalidation/svg/deep-nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ] Bug(none) paint/invalidation/svg/deep-nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ] Bug(none) paint/invalidation/svg/animated-svg-as-image-transformed-offscreen.html [ Failure ] -Bug(none) paint/invalidation/video-mute-repaint.html [ Failure ] -Bug(none) paint/invalidation/video-unmute-repaint.html [ Failure ] Bug(none) paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Failure ] # Wrong invalidation/painting/rasterization for multicol. Different layer tree.
diff --git a/third_party/WebKit/LayoutTests/SmokeTests b/third_party/WebKit/LayoutTests/SmokeTests index 5e1676f..56e2caae 100644 --- a/third_party/WebKit/LayoutTests/SmokeTests +++ b/third_party/WebKit/LayoutTests/SmokeTests
@@ -318,6 +318,7 @@ external/wpt/web-animations/timing-model/animations/finishing-an-animation.html external/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html external/wpt/web-animations/timing-model/time-transformations/transformed-progress.html +external/wpt/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html external/wpt/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html external/wpt/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html @@ -998,7 +999,6 @@ wake_lock/wakelock-in-nested-frame.html webaudio/AudioBufferSource/audiobuffersource-ended.html webaudio/AudioBufferSource/audiobuffersource-playbackrate-zero.html -webaudio/AudioNode/channel-mode-interp-basic.html webaudio/AudioParam/audioparam-setValueCurve-duration.html webaudio/codec-tests/flac/flac-decode.html webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index c7c1a81..c42c754c 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -956,7 +956,7 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/caret-range-anonymous-block-rtl.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/caret-range-anonymous-block.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/caret-range-outside-columns-rtl.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/caret-range-outside-columns.html [ Failure ] +crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/caret-range-outside-columns.html [ Timeout Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/client-rect-after-spanner.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/client-rects-crossing-boundaries-nested.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/vertical-lr/column-break-with-balancing.html [ Failure ] @@ -3806,9 +3806,6 @@ crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-on-play-button.html [ Skip ] crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ] -# Test failing on WebKit Trusty -crbug.com/829228 [ Win7 Linux ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Failure ] - crbug.com/802915 css3/blending/isolation-should-include-non-local-background.html [ Failure ] crbug.com/807838 external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html [ Crash Pass ] @@ -4015,14 +4012,6 @@ # Utility for manual testing, not intended to be run as part of layout tests. crbug.com/785955 http/tests/credentialmanager/tools/virtual-authenticator-environment-manual.html [ Skip ] -# Disabled after r548309. TODO(thomasanderson): Reenable these tests -crbug.com/787020 virtual/gpu/fast/canvas/canvas-zero-length-lineCap.html [ Pass Failure ] -crbug.com/787020 virtual/threaded/http/tests/devtools/tracing/timeline-js/compile-script.js [ Pass Failure ] -crbug.com/787020 external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html [ Pass Failure ] -crbug.com/787020 external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html [ Pass Failure ] -crbug.com/787020 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html [ Pass Failure ] -crbug.com/787020 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html [ Pass Failure ] - # These Web Authentication API would require either real hardware, or # virtual simulation thereof (work in progress, see: https://crbug.com/785955). crbug.com/826936 external/wpt/webauthn/createcredential-badargs-authnrselection.https.html [ Pass Timeout ] @@ -4038,5 +4027,5 @@ crbug.com/826936 external/wpt/webauthn/getcredential-passing.https.html [ Pass Timeout ] crbug.com/826936 external/wpt/webauthn/getcredential-timeout.https.html [ Pass Timeout ] -# Flaky on all platforms -crbug.com/829761 external/wpt/cookie-store/cookieStore_special_names.tentative.https.html [ Pass Failure ] +# Sheriff 2018-04-06 +crbug.com/829921 external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-some.https.sub.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 94ed045..a3b7f49 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -99234,6 +99234,16 @@ {} ] ], + "budget-api/interfaces.any-expected.txt": [ + [ + {} + ] + ], + "budget-api/interfaces.any.worker-expected.txt": [ + [ + {} + ] + ], "clear-site-data/OWNERS": [ [ {} @@ -99524,6 +99534,11 @@ {} ] ], + "compat/interfaces.any.worker-expected.txt": [ + [ + {} + ] + ], "compat/webkit-text-fill-color-property-001-ref.html": [ [ {} @@ -100744,21 +100759,16 @@ {} ] ], + "cookie-store/cookieStore_set_expires_option.tentative.window-expected.txt": [ + [ + {} + ] + ], "cookie-store/idlharness_serviceworker.js": [ [ {} ] ], - "cookie-store/no_name_equals_in_value.tentative-expected.txt": [ - [ - {} - ] - ], - "cookie-store/no_name_equals_in_value.tentative.https-expected.txt": [ - [ - {} - ] - ], "cookie-store/resources/cookie-test-helpers.js": [ [ {} @@ -100779,11 +100789,6 @@ {} ] ], - "cookie-store/resources/expiration.js": [ - [ - {} - ] - ], "cookie-store/resources/get_set_get_all.js": [ [ {} @@ -100809,21 +100814,11 @@ {} ] ], - "cookie-store/resources/one_simple_origin_cookie.js": [ - [ - {} - ] - ], "cookie-store/resources/ordering.js": [ [ {} ] ], - "cookie-store/resources/secure_cookies.js": [ - [ - {} - ] - ], "cookie-store/serviceworker_cookieStore_arguments.js": [ [ {} @@ -125504,6 +125499,21 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/background-position-expected.txt": [ + [ + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/background-repeat-expected.txt": [ + [ + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/border-radius-expected.txt": [ + [ + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/break-expected.txt": [ [ {} @@ -151584,6 +151594,11 @@ {} ] ], + "interfaces/BackgroundSync.idl": [ + [ + {} + ] + ], "interfaces/FileAPI.idl": [ [ {} @@ -151619,11 +151634,21 @@ {} ] ], + "interfaces/budget-api.idl": [ + [ + {} + ] + ], "interfaces/clipboard-apis.idl": [ [ {} ] ], + "interfaces/compat.idl": [ + [ + {} + ] + ], "interfaces/console.idl": [ [ {} @@ -160169,31 +160194,11 @@ {} ] ], - "streams/readable-streams/bad-underlying-sources-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt": [ - [ - {} - ] - ], "streams/readable-streams/bad-underlying-sources.js": [ [ {} ] ], - "streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/bad-underlying-sources.sharedworker-expected.txt": [ - [ - {} - ] - ], "streams/readable-streams/brand-checks.js": [ [ {} @@ -160209,82 +160214,27 @@ {} ] ], - "streams/readable-streams/default-reader-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/default-reader.dedicatedworker-expected.txt": [ - [ - {} - ] - ], "streams/readable-streams/default-reader.js": [ [ {} ] ], - "streams/readable-streams/default-reader.serviceworker.https-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/default-reader.sharedworker-expected.txt": [ - [ - {} - ] - ], "streams/readable-streams/floating-point-total-queue-size.js": [ [ {} ] ], - "streams/readable-streams/garbage-collection-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/garbage-collection.dedicatedworker-expected.txt": [ - [ - {} - ] - ], "streams/readable-streams/garbage-collection.js": [ [ {} ] ], - "streams/readable-streams/garbage-collection.serviceworker.https-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/garbage-collection.sharedworker-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/general-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/general.dedicatedworker-expected.txt": [ - [ - {} - ] - ], "streams/readable-streams/general.js": [ [ {} ] ], - "streams/readable-streams/general.serviceworker.https-expected.txt": [ - [ - {} - ] - ], - "streams/readable-streams/general.sharedworker-expected.txt": [ + "streams/readable-streams/patched-global.js": [ [ {} ] @@ -161999,6 +161949,11 @@ {} ] ], + "webaudio/resources/mixing-rules.js": [ + [ + {} + ] + ], "webaudio/resources/panner-formulas.js": [ [ {} @@ -171451,6 +171406,16 @@ {} ] ], + "BackgroundSync/interfaces.any.js": [ + [ + "/BackgroundSync/interfaces.any.html", + {} + ], + [ + "/BackgroundSync/interfaces.any.worker.html", + {} + ] + ], "FileAPI/FileReader/Progress_event_bubbles_cancelable.html": [ [ "/FileAPI/FileReader/Progress_event_bubbles_cancelable.html", @@ -175435,14 +175400,6 @@ } ] ], - "bluetooth/requestDevice/consumes-user-gesture.https.html": [ - [ - "/bluetooth/requestDevice/consumes-user-gesture.https.html", - { - "testdriver": true - } - ] - ], "bluetooth/requestDevice/cross-origin-iframe.sub.https.html": [ [ "/bluetooth/requestDevice/cross-origin-iframe.sub.https.html", @@ -175459,6 +175416,14 @@ } ] ], + "bluetooth/requestDevice/doesnt-consume-user-gesture.https.html": [ + [ + "/bluetooth/requestDevice/doesnt-consume-user-gesture.https.html", + { + "testdriver": true + } + ] + ], "bluetooth/requestDevice/filter-matches.https.html": [ [ "/bluetooth/requestDevice/filter-matches.https.html", @@ -176195,6 +176160,16 @@ } ] ], + "budget-api/interfaces.any.js": [ + [ + "/budget-api/interfaces.any.html", + {} + ], + [ + "/budget-api/interfaces.any.worker.html", + {} + ] + ], "clear-site-data/navigation-insecure.html": [ [ "/clear-site-data/navigation-insecure.html", @@ -176255,6 +176230,16 @@ {} ] ], + "compat/interfaces.any.js": [ + [ + "/compat/interfaces.any.html", + {} + ], + [ + "/compat/interfaces.any.worker.html", + {} + ] + ], "compat/webkit-appearance.tentative.html": [ [ "/compat/webkit-appearance.tentative.html", @@ -178747,12 +178732,24 @@ {} ] ], + "cookie-store/cookieStore_set_expires_option.tentative.window.js": [ + [ + "/cookie-store/cookieStore_set_expires_option.tentative.window.html", + {} + ] + ], "cookie-store/cookieStore_special_names.tentative.html": [ [ "/cookie-store/cookieStore_special_names.tentative.html", {} ] ], + "cookie-store/cookieStore_special_names.tentative.https.html": [ + [ + "/cookie-store/cookieStore_special_names.tentative.https.html", + {} + ] + ], "cookie-store/delete_cookies.tentative.html": [ [ "/cookie-store/delete_cookies.tentative.html", @@ -178783,18 +178780,6 @@ {} ] ], - "cookie-store/expiration.tentative.html": [ - [ - "/cookie-store/expiration.tentative.html", - {} - ] - ], - "cookie-store/expiration.tentative.https.html": [ - [ - "/cookie-store/expiration.tentative.https.html", - {} - ] - ], "cookie-store/get_set_get_all.tentative.html": [ [ "/cookie-store/get_set_get_all.tentative.html", @@ -178867,36 +178852,12 @@ {} ] ], - "cookie-store/one_simple_origin_cookie.tentative.html": [ - [ - "/cookie-store/one_simple_origin_cookie.tentative.html", - {} - ] - ], - "cookie-store/one_simple_origin_cookie.tentative.https.html": [ - [ - "/cookie-store/one_simple_origin_cookie.tentative.https.html", - {} - ] - ], "cookie-store/ordering.tentative.https.html": [ [ "/cookie-store/ordering.tentative.https.html", {} ] ], - "cookie-store/secure_cookies.tentative.html": [ - [ - "/cookie-store/secure_cookies.tentative.html", - {} - ] - ], - "cookie-store/secure_cookies.tentative.https.html": [ - [ - "/cookie-store/secure_cookies.tentative.https.html", - {} - ] - ], "cookie-store/serviceworker_cookieStore_arguments.tentative.https.html": [ [ "/cookie-store/serviceworker_cookieStore_arguments.tentative.https.html", @@ -185125,6 +185086,24 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/background-attachment.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-attachment.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/background-blend-mode.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-blend-mode.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/background-clip.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-clip.html", + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/background-color.html": [ [ "/css/css-typed-om/the-stylepropertymap/properties/background-color.html", @@ -185137,6 +185116,30 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/background-origin.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-origin.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/background-position.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-position.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/background-repeat.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-repeat.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/background-size.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/background-size.html", + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/background.html": [ [ "/css/css-typed-om/the-stylepropertymap/properties/background.html", @@ -185161,12 +185164,42 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-outset.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/border-image-outset.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-repeat.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/border-image-repeat.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-slice.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/border-image-slice.html", + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/border-image-source.html": [ [ "/css/css-typed-om/the-stylepropertymap/properties/border-image-source.html", {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-width.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/border-image-width.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/border-radius.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/border-radius.html", + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/border-style.html": [ [ "/css/css-typed-om/the-stylepropertymap/properties/border-style.html", @@ -230067,6 +230100,30 @@ {} ] ], + "streams/readable-streams/patched-global.dedicatedworker.html": [ + [ + "/streams/readable-streams/patched-global.dedicatedworker.html", + {} + ] + ], + "streams/readable-streams/patched-global.html": [ + [ + "/streams/readable-streams/patched-global.html", + {} + ] + ], + "streams/readable-streams/patched-global.serviceworker.https.html": [ + [ + "/streams/readable-streams/patched-global.serviceworker.https.html", + {} + ] + ], + "streams/readable-streams/patched-global.sharedworker.html": [ + [ + "/streams/readable-streams/patched-global.sharedworker.html", + {} + ] + ], "streams/readable-streams/reentrant-strategies.dedicatedworker.html": [ [ "/streams/readable-streams/reentrant-strategies.dedicatedworker.html", @@ -232371,12 +232428,54 @@ {} ] ], + "webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html", + {} + ] + ], + "webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html", + {} + ] + ], + "webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html", + {} + ] + ], "webaudio/the-audio-api/the-audionode-interface/audionode-connect-return-value.html": [ [ "/webaudio/the-audio-api/the-audionode-interface/audionode-connect-return-value.html", {} ] ], + "webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html", + {} + ] + ], + "webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html", + {} + ] + ], + "webaudio/the-audio-api/the-audionode-interface/audionode.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/audionode.html", + {} + ] + ], + "webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html": [ + [ + "/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html", + {} + ] + ], "webaudio/the-audio-api/the-audioparam-interface/idl-test.html": [ [ "/webaudio/the-audio-api/the-audioparam-interface/idl-test.html", @@ -245105,7 +245204,7 @@ "support" ], "./lint.whitelist": [ - "7b2da77b77cbedbb707b49df4bc1aa9ad8f0da49", + "58434d31fc8973e9f587328ae6aec0c79313a8a6", "support" ], "./update-built-tests.sh": [ @@ -249316,6 +249415,10 @@ "73f0071c06f429c3d47eac8d0863e11f1d6e8c25", "support" ], + "BackgroundSync/interfaces.any.js": [ + "2a158ca33b93b78a581341d885150d252a0e4555", + "testharness" + ], "FileAPI/BlobURL/support/file_test2.txt": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" @@ -249549,7 +249652,7 @@ "support" ], "FileAPI/url/sandboxed-iframe-expected.txt": [ - "cbdc3181c15700b3b9657237a761b15e2bb77e9c", + "da682b918c8f44b187cf9cafa419a5634e92b3ff", "support" ], "FileAPI/url/sandboxed-iframe.html": [ @@ -252617,11 +252720,11 @@ "testharness" ], "background-fetch/interfaces.worker-expected.txt": [ - "db5baa6abbe13cb1d79f2624265fe6d09f215f81", + "5453d79743c43a705d2276fb4ea7ea1967056e5a", "support" ], "background-fetch/interfaces.worker.js": [ - "c1f72ff423ec67b8400ce233a6ede945b8d262eb", + "f1013d140f361226c81c24926548860d975ec3b2", "testharness" ], "background-fetch/mixed-content-and-allowed-schemes.https.window.js": [ @@ -253088,10 +253191,6 @@ "084ec334261ed7c584a0888ff3dfdec0f3538bad", "testharness" ], - "bluetooth/requestDevice/consumes-user-gesture.https.html": [ - "c76d7e37417a7db3043b761989eebbfded6e6804", - "testharness" - ], "bluetooth/requestDevice/cross-origin-iframe.sub.https.html": [ "e5e22c1b7811699bb8bfd2b6593edf78a270a658", "testharness" @@ -253100,6 +253199,10 @@ "0b75576a4742cc7496a890b273f2bb1c1f56017c", "testharness" ], + "bluetooth/requestDevice/doesnt-consume-user-gesture.https.html": [ + "f7dfed31210d9e498648a3063313cb804a9a6879", + "testharness" + ], "bluetooth/requestDevice/filter-matches.https.html": [ "22ea4176f1f5cdd67a730cce43e3fbf08d1fcfdb", "testharness" @@ -253137,7 +253240,7 @@ "testharness" ], "bluetooth/resources/bluetooth-helpers.js": [ - "c86347e3b26f369907ec7f0c3adaee20b630ade8", + "337417e818d3e722bf16643fc779850bc44c1e92", "support" ], "bluetooth/resources/health-thermometer-iframe.html": [ @@ -253588,6 +253691,18 @@ "417d39a317f55a95180c806d28047c85dd959d65", "testharness" ], + "budget-api/interfaces.any-expected.txt": [ + "25d68d63509ea934c3c278eb8e049fd1a8514a17", + "support" + ], + "budget-api/interfaces.any.js": [ + "7532e03a56725728052d4b5a973630e2b86686da", + "testharness" + ], + "budget-api/interfaces.any.worker-expected.txt": [ + "25d68d63509ea934c3c278eb8e049fd1a8514a17", + "support" + ], "clear-site-data/OWNERS": [ "8c90c19ce29952d868460d36f7b20120b155992c", "support" @@ -253888,6 +254003,14 @@ "2d71e7532fc32af61d2410927b6405a9e79279a4", "testharness" ], + "compat/interfaces.any.js": [ + "b96341f909d00d6d1f3ee244f174dbe576bc0780", + "testharness" + ], + "compat/interfaces.any.worker-expected.txt": [ + "dd136edd0999c6e04a80fb0c80d673c9704a0d35", + "support" + ], "compat/webkit-appearance.tentative.html": [ "19f5d49ab9383759357d9b7cd73f15fe7fff2939", "testharness" @@ -256560,8 +256683,20 @@ "27019d0e79b6754715a292f40e064de53daaf5e8", "testharness" ], + "cookie-store/cookieStore_set_expires_option.tentative.window-expected.txt": [ + "65271f7b7ac58380a21ecb24a47238e6088ab1a2", + "support" + ], + "cookie-store/cookieStore_set_expires_option.tentative.window.js": [ + "1eb72c6868686177a34fdb69158d184f096887b5", + "testharness" + ], "cookie-store/cookieStore_special_names.tentative.html": [ - "d1cfe7619cc915b17dbf4d358363b16ec8ba9666", + "f839e2825dd18a6f54639fc2b7d4a18ce9906b25", + "testharness" + ], + "cookie-store/cookieStore_special_names.tentative.https.html": [ + "4d53aaecbf9fea2865ca6492bc69b2ec3a47af79", "testharness" ], "cookie-store/delete_cookies.tentative.html": [ @@ -256584,14 +256719,6 @@ "179f3ffe69715f9767ec2d2ef661c429fef52bc6", "testharness" ], - "cookie-store/expiration.tentative.html": [ - "a4e8764c12e39068a4008ad0f12c982540565dbf", - "testharness" - ], - "cookie-store/expiration.tentative.https.html": [ - "fff43dd4b66455e493c06d2a1e98333e8e9b2437", - "testharness" - ], "cookie-store/get_set_get_all.tentative.html": [ "89c72f73d511ab3510653baebb7c77aab6441f35", "testharness" @@ -256628,18 +256755,10 @@ "61cfa6f1e5ee1e9165dcc16e32486660a1da9c42", "testharness" ], - "cookie-store/no_name_equals_in_value.tentative-expected.txt": [ - "65c12018b266720697dc9bd4df6c6dd20781f391", - "support" - ], "cookie-store/no_name_equals_in_value.tentative.html": [ "07d5e9462c4395002f23aa4aaf25ae795f9f2452", "testharness" ], - "cookie-store/no_name_equals_in_value.tentative.https-expected.txt": [ - "65c12018b266720697dc9bd4df6c6dd20781f391", - "support" - ], "cookie-store/no_name_equals_in_value.tentative.https.html": [ "61e7a3cc1f5b197d924c76098b66979d00444012", "testharness" @@ -256652,14 +256771,6 @@ "aa3ed15714a1ed2b7cac4ba2fc7998d9792b7339", "testharness" ], - "cookie-store/one_simple_origin_cookie.tentative.html": [ - "1ba5278aa3725c8e27bb486388b5456045f735a0", - "testharness" - ], - "cookie-store/one_simple_origin_cookie.tentative.https.html": [ - "e86d324bf8a771b7f7deb6c4e2e64da088baef69", - "testharness" - ], "cookie-store/ordering.tentative.https.html": [ "e40eb0cdca00826731e9242682105b76baea9a03", "testharness" @@ -256680,10 +256791,6 @@ "b34ad56a2afd7f52c52dd0777b15eac2d77c4856", "support" ], - "cookie-store/resources/expiration.js": [ - "483b923b03a0a0787b73118fd3f3b9f5d269f5ae", - "support" - ], "cookie-store/resources/get_set_get_all.js": [ "235f22721a73a617d0b14068c8e639e93232526a", "support" @@ -256697,33 +256804,17 @@ "support" ], "cookie-store/resources/no_name_equals_in_value.js": [ - "37b510261b203717fccaf6917c38ea3d0f24151f", + "8a5b87568d36dde7093b1bc6aae02ffe556887ca", "support" ], "cookie-store/resources/no_name_multiple_values.js": [ "028a1c2e9b82299eef5f383886f2a1cb008c65ee", "support" ], - "cookie-store/resources/one_simple_origin_cookie.js": [ - "c5a3cc58200f8c160e50a0ca03a5d763dd96c635", - "support" - ], "cookie-store/resources/ordering.js": [ "822567b7eb113c809379dff5b62a2e24c9e9e171", "support" ], - "cookie-store/resources/secure_cookies.js": [ - "c4ddb9a024d0fc0d370891e587ed8aba54c5709e", - "support" - ], - "cookie-store/secure_cookies.tentative.html": [ - "0d0b2324cbf5439491ea9f8fddd4ef7ca4b8eed6", - "testharness" - ], - "cookie-store/secure_cookies.tentative.https.html": [ - "bcfbbd7ae2e9ae85deefbf284f6cf76901975a93", - "testharness" - ], "cookie-store/serviceworker_cookieStore_arguments.js": [ "a90956237d63fd51556f2d9e50967522870816d4", "support" @@ -306920,6 +307011,18 @@ "d880e41674d468fe364c74941a8ae0921b9bdfac", "testharness" ], + "css/css-typed-om/the-stylepropertymap/properties/background-attachment.html": [ + "024166d038e4982b56fd7d7221e82e9458f7e84e", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-blend-mode.html": [ + "701b6878c4fc175ee06ad2c626396c81d89e4f50", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-clip.html": [ + "4e21edae338e7b5bb4c037b8f33300cd2f95fc06", + "testharness" + ], "css/css-typed-om/the-stylepropertymap/properties/background-color.html": [ "f52a2182afc7107a9f411a27aab81c4c4c90ef1e", "testharness" @@ -306932,6 +307035,30 @@ "08055b88eca1f841f3b8a9867d8ffeb93d214d1f", "testharness" ], + "css/css-typed-om/the-stylepropertymap/properties/background-origin.html": [ + "93730d54f961f28a88fde1c00d44e2a9be64b742", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-position-expected.txt": [ + "fdec7c3db80adc27845c5a11863ef446bb1d018b", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-position.html": [ + "8b409700195cf670b29333f719f073044474c5c6", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-repeat-expected.txt": [ + "563d795eb640e418ea04b8936726d1de7680dfda", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-repeat.html": [ + "49c91e1a014ea784ef0417865e0cd2c37255bc59", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/background-size.html": [ + "0867d73b9e4beb8c0152a214cef87aa636287575", + "testharness" + ], "css/css-typed-om/the-stylepropertymap/properties/background.html": [ "32d684e452a4bafd7b58a0b33d42d32aa51ac091", "testharness" @@ -306948,10 +307075,34 @@ "5b8adde602ac79d8b1ea92bd29f25d8756d72f8a", "testharness" ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-outset.html": [ + "d884ef177bd0966ffa3935aabb2494e305738bd9", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-repeat.html": [ + "c8fcdad32a801fde33554fb49ad5b3f66d73d953", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-slice.html": [ + "26fa7f01d3fb41e8e20e09c3be2ee669c4b136bc", + "testharness" + ], "css/css-typed-om/the-stylepropertymap/properties/border-image-source.html": [ "08934e205f88aecda9809ff98d63f2d8784080c3", "testharness" ], + "css/css-typed-om/the-stylepropertymap/properties/border-image-width.html": [ + "16ae049c907d5a139c09423d1e08017c3a4ec838", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/border-radius-expected.txt": [ + "0830d82968daf58a6d4b6eba3ba775bd31f76059", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/border-radius.html": [ + "dfb1ac911d906b9700076657fc0ff354e1d3683d", + "testharness" + ], "css/css-typed-om/the-stylepropertymap/properties/border-style.html": [ "5d258827fb6a26d07efbdf5b47a440300f0aa307", "testharness" @@ -307365,7 +307516,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/resources/testsuite.js": [ - "9e7a4bb8fa2d8ad491353117b409a2a7ff314d7f", + "2a2cf021b0bb67e028a4a83c49d914112cf6d18e", "support" ], "css/css-typed-om/the-stylepropertymap/properties/right.html": [ @@ -350060,8 +350211,12 @@ "f585014db144083ee2f70f6fd65f78bf2e289093", "manual" ], + "interfaces/BackgroundSync.idl": [ + "f4812cb04b153d5f39e12e373b184c04d29b00fd", + "support" + ], "interfaces/FileAPI.idl": [ - "2a12d457a38d00109c0f6423bf3e3f16fcc700c9", + "3fb06078e603a6010c2eb0fb45715c8cbda35678", "support" ], "interfaces/IndexedDB.idl": [ @@ -350088,10 +350243,18 @@ "f2c8fc84af7bf785ba42f1398181e2ab08c3826a", "support" ], + "interfaces/budget-api.idl": [ + "99f4eacad964a3ca3bcc034b48a2f4c4a2bd6f72", + "support" + ], "interfaces/clipboard-apis.idl": [ "66b014c6a2ba5cd8e0fbc83081d4c16ac4d46d39", "support" ], + "interfaces/compat.idl": [ + "5169148beaeb622da36a824a892421e86bf36c15", + "support" + ], "interfaces/console.idl": [ "43ced34008dc73d05c79140d8dc33c60e2d9df3a", "support" @@ -350113,7 +350276,7 @@ "support" ], "interfaces/cssom.idl": [ - "fbd624297dbfaa5e0fc2144b701c38eda41537ac", + "65a8a0ef05cce0b09bf685dedab3540a7593f5a4", "support" ], "interfaces/dedicated-workers.idl": [ @@ -353037,7 +353200,7 @@ "testharness" ], "navigation-timing/nav2_test_redirect_server.html": [ - "fab304c2f896c156d3374073c8f870219f3e0246", + "788929e77d0f3979aeb5e05892ec069aeed6fb02", "testharness" ], "navigation-timing/nav2_test_redirect_xserver.html": [ @@ -373400,14 +373563,6 @@ "a4692c839ca53134bc5036b2f813e2311db3f2d0", "testharness" ], - "streams/readable-streams/bad-underlying-sources-expected.txt": [ - "b082b3b2884e8e5c681980f4c77ec512cebbc469", - "support" - ], - "streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt": [ - "b082b3b2884e8e5c681980f4c77ec512cebbc469", - "support" - ], "streams/readable-streams/bad-underlying-sources.dedicatedworker.html": [ "4f1aac6cadab470ec4474741712bdd65d2670918", "testharness" @@ -373420,18 +373575,10 @@ "1135be491a7a5663041b8d6d6b65f0206970ab0e", "support" ], - "streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt": [ - "6464c7060aa0afeb13876942251a962dd00acb46", - "support" - ], "streams/readable-streams/bad-underlying-sources.serviceworker.https.html": [ "2e8501ec4c83340149486ea1f19d35a3c90d85e9", "testharness" ], - "streams/readable-streams/bad-underlying-sources.sharedworker-expected.txt": [ - "b082b3b2884e8e5c681980f4c77ec512cebbc469", - "support" - ], "streams/readable-streams/bad-underlying-sources.sharedworker.html": [ "e2631bf8eb2ecc8f54e45594a6f5176ceaa8ed62", "testharness" @@ -373496,14 +373643,6 @@ "42cf0e2dd45eae0311c210cced7d9c9c83620501", "testharness" ], - "streams/readable-streams/default-reader-expected.txt": [ - "9e64aef5c85f4e1052adca8eb7807f145d5349ae", - "support" - ], - "streams/readable-streams/default-reader.dedicatedworker-expected.txt": [ - "9e64aef5c85f4e1052adca8eb7807f145d5349ae", - "support" - ], "streams/readable-streams/default-reader.dedicatedworker.html": [ "42750f1d324f57507feb0260704a55c4cc0f8382", "testharness" @@ -373516,18 +373655,10 @@ "639fc79798f07714549495a52364408773ac830a", "support" ], - "streams/readable-streams/default-reader.serviceworker.https-expected.txt": [ - "00c50429a7ef205bffe70fefe1f9751f0869c3e3", - "support" - ], "streams/readable-streams/default-reader.serviceworker.https.html": [ "7a3f17c90551967ccc24bbc835eef2b521bf08b9", "testharness" ], - "streams/readable-streams/default-reader.sharedworker-expected.txt": [ - "9e64aef5c85f4e1052adca8eb7807f145d5349ae", - "support" - ], "streams/readable-streams/default-reader.sharedworker.html": [ "399221af8cca8157bcaa05582dc66e94e56bc856", "testharness" @@ -373552,14 +373683,6 @@ "00af09f46d126d6d2944d13831896e648094d1a8", "testharness" ], - "streams/readable-streams/garbage-collection-expected.txt": [ - "b747a6f0943c9a5a472b3a4c0ca39bd1aca30c6d", - "support" - ], - "streams/readable-streams/garbage-collection.dedicatedworker-expected.txt": [ - "b747a6f0943c9a5a472b3a4c0ca39bd1aca30c6d", - "support" - ], "streams/readable-streams/garbage-collection.dedicatedworker.html": [ "0c774ff797fda7a5b5a828a4600a39dae72cac0c", "testharness" @@ -373572,30 +373695,14 @@ "67871c1324ce268721015fcc59c6e78edc0a8e79", "support" ], - "streams/readable-streams/garbage-collection.serviceworker.https-expected.txt": [ - "465f75ace54b32df180cab25d64d02621fb0d573", - "support" - ], "streams/readable-streams/garbage-collection.serviceworker.https.html": [ "c35eb996cbf796eadbb52f4a3288c8452765b952", "testharness" ], - "streams/readable-streams/garbage-collection.sharedworker-expected.txt": [ - "b747a6f0943c9a5a472b3a4c0ca39bd1aca30c6d", - "support" - ], "streams/readable-streams/garbage-collection.sharedworker.html": [ "d22e9b8bc231b3c00be2de557c0f91dbb76dcd81", "testharness" ], - "streams/readable-streams/general-expected.txt": [ - "e2846b3e93c1b0e46f1f8176042a98d4b66982b6", - "support" - ], - "streams/readable-streams/general.dedicatedworker-expected.txt": [ - "e2846b3e93c1b0e46f1f8176042a98d4b66982b6", - "support" - ], "streams/readable-streams/general.dedicatedworker.html": [ "8583d80450b090c16ed0795170340d040449bbc1", "testharness" @@ -373608,22 +373715,34 @@ "72e37e692a88f6dd06f037f07e0d4fbd975f8aae", "support" ], - "streams/readable-streams/general.serviceworker.https-expected.txt": [ - "c58b51fb09c315fb5d1a4d517cbb80cab271d438", - "support" - ], "streams/readable-streams/general.serviceworker.https.html": [ "1792d6c45a5687777291a4dab031a954aa053752", "testharness" ], - "streams/readable-streams/general.sharedworker-expected.txt": [ - "e2846b3e93c1b0e46f1f8176042a98d4b66982b6", - "support" - ], "streams/readable-streams/general.sharedworker.html": [ "44f9ceaa3bfc9d8b92885997d322486bd0f237a6", "testharness" ], + "streams/readable-streams/patched-global.dedicatedworker.html": [ + "34bc5da1733179d1a4cd4bbbd4397146eafbb7e8", + "testharness" + ], + "streams/readable-streams/patched-global.html": [ + "a3c2a68709b9bf1eb3f34dd2d0f385689680a566", + "testharness" + ], + "streams/readable-streams/patched-global.js": [ + "acd674d94f102891043aa92113026aca6c1ae5d7", + "support" + ], + "streams/readable-streams/patched-global.serviceworker.https.html": [ + "79f5e148601acf4ad24952f8735908c3a1edc510", + "testharness" + ], + "streams/readable-streams/patched-global.sharedworker.html": [ + "477cc1ed4cc94ff6ee29dcd6f96c16768a2c7567", + "testharness" + ], "streams/readable-streams/reentrant-strategies.dedicatedworker.html": [ "6f9350ce1caf4fa9e6239693ec91b2249c2adab5", "testharness" @@ -376553,7 +376672,7 @@ "manual" ], "web-nfc/nfc_insecure_context.html": [ - "ca6795303e0d200904d47a1f80b7fc255c1d353b", + "a9fabb5e2f577581ff470924ee4c8c5f95c47f46", "testharness" ], "web-nfc/nfc_push.https-expected.txt": [ @@ -376784,6 +376903,10 @@ "a00d7729bc338c12846f36b450b895d7d118f95e", "support" ], + "webaudio/resources/mixing-rules.js": [ + "4508f0205419865b6166340ce6d4f955f914b6b1", + "support" + ], "webaudio/resources/panner-formulas.js": [ "872d9aa271558ee3e7aa293c8e3e44fd525461c0", "support" @@ -376860,10 +376983,38 @@ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html": [ + "74df9493bdb784280b15e0a57b1d61b5c51b386b", + "testharness" + ], + "webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html": [ + "11a238b69cbe5a4fa2f7d2e22eb9c479552d300e", + "testharness" + ], + "webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html": [ + "9bef407f0bc17f0d60bcf0eee623bdff7efabb79", + "testharness" + ], "webaudio/the-audio-api/the-audionode-interface/audionode-connect-return-value.html": [ "cf51d81770ad7163e44ce02a6f6fa9b6db34f1b9", "testharness" ], + "webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html": [ + "00c3d07eb5c64b3b9692ac24c3623479b7c84947", + "testharness" + ], + "webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html": [ + "76a9626c3b7697dda0e099a7c50ea31971818582", + "testharness" + ], + "webaudio/the-audio-api/the-audionode-interface/audionode.html": [ + "0da532bb8f2505949062709d618da73441968c4d", + "testharness" + ], + "webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html": [ + "a122bacd6494fb670b7dbd54dd1fce25c3a6e998", + "testharness" + ], "webaudio/the-audio-api/the-audioparam-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" @@ -378281,7 +378432,7 @@ "support" ], "webrtc/RTCPeerConnection-track-stats.https.html": [ - "512e40d1b6f95c86b90ba7b536b6ae049f6a04c0", + "71d7a85e16504ba67a718c2d50526b7d9f8fd4d0", "testharness" ], "webrtc/RTCPeerConnectionIceEvent-constructor-expected.txt": [ @@ -379873,7 +380024,7 @@ "support" ], "webusb/usb.https.html": [ - "47adf57ef06190594f80d8ae85d2ee8118889cb6", + "47be065f386fecc7557993c6d8ec61cac88fe71a", "testharness" ], "webusb/usbConnectionEvent.https.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/BackgroundSync/interfaces.any.js b/third_party/WebKit/LayoutTests/external/wpt/BackgroundSync/interfaces.any.js new file mode 100644 index 0000000..dd677fc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/BackgroundSync/interfaces.any.js
@@ -0,0 +1,29 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://wicg.github.io/BackgroundSync/spec/ + +promise_test(async () => { + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + const sw = await fetch('/interfaces/ServiceWorker.idl').then(r => r.text()); + const idl = await fetch('/interfaces/BackgroundSync.idl').then(response => response.text()); + + const idlArray = new IdlArray(); + idlArray.add_untested_idls(dom, { only: ['Event', 'EventInit', 'EventTarget'] }); + idlArray.add_untested_idls(html, { only: [ + 'WorkerGlobalScope', + 'WindowOrWorkerGlobalScope' + ] }); + idlArray.add_untested_idls(sw, { only: [ + 'ServiceWorkerRegistration', + 'ServiceWorkerGlobalScope', + 'ExtendableEvent', + 'ExtendableEventInit', + ] }); + idlArray.add_idls(idl); + idlArray.test(); + done(); +}, 'Background Sync interfaces.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker-expected.txt index 8340efd..ef51655 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker-expected.txt
@@ -1,8 +1,16 @@ This is a testharness.js-based test. -Found 69 tests; 50 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 77 tests; 56 PASS, 21 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Exposed interfaces in a Service Worker. FAIL ServiceWorkerRegistration interface: existence and properties of interface object assert_false: expected false got true -PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +FAIL ServiceWorkerGlobalScope interface: attribute onbackgroundfetched assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing +PASS Unscopable handled correctly for onbackgroundfetched property on ServiceWorkerGlobalScope +FAIL ServiceWorkerGlobalScope interface: attribute onbackgroundfetchfail assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing +PASS Unscopable handled correctly for onbackgroundfetchfail property on ServiceWorkerGlobalScope +FAIL ServiceWorkerGlobalScope interface: attribute onbackgroundfetchabort assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing +PASS Unscopable handled correctly for onbackgroundfetchabort property on ServiceWorkerGlobalScope +FAIL ServiceWorkerGlobalScope interface: attribute onbackgroundfetchclick assert_own_property: self does not have own property "ServiceWorkerGlobalScope" expected property "ServiceWorkerGlobalScope" missing +PASS Unscopable handled correctly for onbackgroundfetchclick property on ServiceWorkerGlobalScope +PASS ExtendableEvent interface: existence and properties of interface object PASS BackgroundFetchManager interface: existence and properties of interface object PASS BackgroundFetchManager interface object length PASS BackgroundFetchManager interface object name @@ -15,10 +23,10 @@ PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager PASS BackgroundFetchManager interface: operation getIds() PASS Unscopable handled correctly for getIds() on BackgroundFetchManager -FAIL BackgroundFetchRegistration interface: existence and properties of interface object Cannot read property 'has_extended_attribute' of undefined +PASS BackgroundFetchRegistration interface: existence and properties of interface object PASS BackgroundFetchRegistration interface object length PASS BackgroundFetchRegistration interface object name -FAIL BackgroundFetchRegistration interface: existence and properties of interface prototype object Cannot read property 'has_extended_attribute' of undefined +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property PASS BackgroundFetchRegistration interface: attribute id
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker.js index 9b8d0264..0760ffd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker.js +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.worker.js
@@ -9,7 +9,7 @@ var idlArray = new IdlArray(); idlArray.add_untested_idls('interface ServiceWorkerRegistration {};'); - idlArray.add_untested_idls('[Exposed=ServiceWorker] interface ServiceWorkerGlobalScope {};'); + idlArray.add_untested_idls('[SecureContext, Exposed = (Window, Worker)] interface ServiceWorkerGlobalScope {};'); idlArray.add_untested_idls('interface ExtendableEvent{};'); idlArray.add_untested_idls('dictionary ExtendableEventInit{};'); idlArray.add_untested_idls(dom, { only: ['EventTarget'] });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/requestDevice/consumes-user-gesture.https.html b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/requestDevice/doesnt-consume-user-gesture.https.html similarity index 73% rename from third_party/WebKit/LayoutTests/external/wpt/bluetooth/requestDevice/consumes-user-gesture.https.html rename to third_party/WebKit/LayoutTests/external/wpt/bluetooth/requestDevice/doesnt-consume-user-gesture.https.html index 12a062e..3394a591 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/requestDevice/consumes-user-gesture.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/requestDevice/doesnt-consume-user-gesture.https.html
@@ -6,10 +6,7 @@ <script src="/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -const test_desc = 'Consumes a user gesture.'; -const expected = new DOMException( - 'Must be handling a user gesture to show a permission request.', - 'SecurityError'); +const test_desc = 'requestDevice calls do not consume user gestures.'; bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices() .then(() => callWithTrustedClick(() => { @@ -20,8 +17,8 @@ return Promise.all([ first.then(device => assert_equals( device.constructor.name, 'BluetoothDevice')), - assert_promise_rejects_with_message(second, - expected, 'A request should consume a user gesture') + second.then(device => assert_equals( + device.constructor.name, 'BluetoothDevice')), ]); })), test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any-expected.txt new file mode 100644 index 0000000..397dfb4c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL budget-api interfaces. promise_test: Unhandled rejection with value: object "Multiple 'Exposed' extended attributes on Navigator" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any.js b/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any.js new file mode 100644 index 0000000..84e887418 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any.js
@@ -0,0 +1,24 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// See https://wicg.github.io/budget-api/ + +promise_test(async () => { + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + const workers = await fetch('/interfaces/dedicated-workers.idl').then(r => r.text()); + const idl = await fetch('/interfaces/budget-api.idl').then(r => r.text()); + + const idlArray = new IdlArray(); + idlArray.add_untested_idls(html, { only: [ + 'Navigator', + 'NavigatorContentUtils', + 'NavigatorCookies', + 'NavigatorPlugins', + ] }); + idlArray.add_untested_idls(workers); + idlArray.add_idls(idl); + idlArray.test(); + done(); +}, 'budget-api interfaces.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any.worker-expected.txt new file mode 100644 index 0000000..397dfb4c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/budget-api/interfaces.any.worker-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL budget-api interfaces. promise_test: Unhandled rejection with value: object "Multiple 'Exposed' extended attributes on Navigator" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/compat/interfaces.any.js b/third_party/WebKit/LayoutTests/external/wpt/compat/interfaces.any.js new file mode 100644 index 0000000..1b87c90 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/compat/interfaces.any.js
@@ -0,0 +1,17 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://compat.spec.whatwg.org/ + +promise_test(async () => { + const idl = await fetch('/interfaces/compat.idl').then(r => r.text()); + const idlArray = new IdlArray(); + idlArray.add_untested_idls('interface Window {};'); + idlArray.add_untested_idls('interface EventTarget{};'); + idlArray.add_untested_idls('interface HTMLBodyElement{};'); + idlArray.add_idls(idl); + idlArray.test(); + done(); +}, 'compat interfaces.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/compat/interfaces.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/compat/interfaces.any.worker-expected.txt new file mode 100644 index 0000000..70e5f023 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/compat/interfaces.any.worker-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS compat interfaces. +PASS Window interface: existence and properties of interface object +FAIL EventTarget interface: existence and properties of interface object assert_false: expected false got true +PASS HTMLBodyElement interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_expires_option.tentative.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_expires_option.tentative.window-expected.txt new file mode 100644 index 0000000..b889aba --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_expires_option.tentative.window-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS cookieStore.set with expires option: Date object +PASS cookieStore.set with expires option: milliseconds since epoch object +FAIL cookieStore.set with expires option: HTTP date string promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'name' of null" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_expires_option.tentative.window.js b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_expires_option.tentative.window.js new file mode 100644 index 0000000..fdbe2d92 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_expires_option.tentative.window.js
@@ -0,0 +1,59 @@ +'use strict'; + +// Workaround because add_cleanup doesn't support async functions yet. +// See https://github.com/w3c/web-platform-tests/issues/6075 +async function async_cleanup(cleanup_function) { + try { + await cleanup_function(); + } catch (e) { + // Errors in cleanup functions shouldn't result in test failures. + } +} + +promise_test(async testCase => { + const inTwentyFourHours = new Date(Date.now() + 24 * 60 * 60 * 1000); + + assert_equals( + await cookieStore.set( + 'cookie-name', 'cookie-value', { expires: inTwentyFourHours }), + undefined); + + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set with expires option: Date object'); + +promise_test(async testCase => { + const inTwentyFourHours = Date.now() + 24 * 60 * 60 * 1000; + + assert_equals( + await cookieStore.set( + 'cookie-name', 'cookie-value', { expires: inTwentyFourHours }), + undefined); + + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set with expires option: milliseconds since epoch object'); + +promise_test(async testCase => { + const year = (new Date()).getUTCFullYear() + 1; + const date = new Date('07 Jun ' + year + ' 07:07:07 UTC'); + const day = ('Sun Mon Tue Wed Thu Fri Sat'.split(' '))[date.getUTCDay()]; + const nextJune = `${day}, 07 Jun ${year} + ' 07:07:07 GMT`; + + assert_equals( + await cookieStore.set( + 'cookie-name', 'cookie-value', { expires: nextJune }), + undefined); + + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set with expires option: HTTP date string');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.html index 81b03d6c..9859e10 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.html +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.html
@@ -23,7 +23,7 @@ testCase, new TypeError(), cookieStore.set( `${prefix}cookie-name`, `secure-cookie-value`, { - expires: Date.now() + expires: Date.now() - (24 * 60 * 60 * 1000) }), `Setting expired ${prefix} cookies should fail in non-secure contexts`);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.https.html index 2af701e..0d1be12 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_special_names.tentative.https.html
@@ -20,9 +20,12 @@ }, `cookieStore.set with ${prefix} name on secure origin`); promise_test(async testCase => { + // This test is for symmetry with the non-secure case. In non-secure + // contexts, the set() should fail even if the expiration date makes + // the operation a no-op. await cookieStore.set( `${prefix}cookie-name`, `secure-cookie-value`, { - expires: Date.now() + expires: Date.now() - (24 * 60 * 60 * 1000) }); assert_equals(await cookieStore.get(`${prefix}cookie-name`), null); try { await cookieStore.delete(`${prefix}cookie-name`); } catch (e) {}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/expiration.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/expiration.tentative.html deleted file mode 100644 index d7164a94..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/expiration.tentative.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>Async Cookies: expiration</title> -<meta name="help" href="https://github.com/WICG/cookie-store/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/cookie-test-helpers.js"></script> -<script src="resources/expiration.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/expiration.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/expiration.tentative.https.html deleted file mode 100644 index 638b0477..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/expiration.tentative.https.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>Async Cookies: expiration (HTTPS)</title> -<meta name="help" href="https://github.com/WICG/cookie-store/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/cookie-test-helpers.js"></script> -<script src="resources/expiration.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/resources/expiration.js b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/resources/expiration.js deleted file mode 100644 index 816ace48..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/resources/expiration.js +++ /dev/null
@@ -1,89 +0,0 @@ -'use strict'; - -// Set the secure example.org-domain cookie __Secure-COOKIENAME with -// value cookie-value on path /cgi-bin/ and 24 hour duration; domain -// and path will be rewritten below. -// -// This uses a Date object for expiration. -async function setOneDaySecureCookieWithDate() { - // one day ahead, ignoring a possible leap-second - let inTwentyFourHours = new Date(Date.now() + 24 * 60 * 60 * 1000); - await cookieStore.set('__Secure-COOKIENAME', 'cookie-value', { - path: kPath, - expires: inTwentyFourHours, - secure: true, - domain: location.hostname - }); -} - -// Set the secured example.org-domain cookie __Secure-COOKIENAME with -// value cookie-value on path /cgi-bin/ and expiration in June of next -// year; domain and path will be rewritten below. -// -// This uses an HTTP-style date string for expiration. -async function setSecureCookieWithHttpLikeExpirationString() { - const year = (new Date()).getUTCFullYear() + 1; - const date = new Date('07 Jun ' + year + ' 07:07:07 UTC'); - const day = ('Sun Mon Tue Wed Thu Fri Sat'.split(' '))[date.getUTCDay()]; - await cookieStore.set('__Secure-COOKIENAME', 'cookie-value', { - path: kPath, - expires: day + ', 07 Jun ' + year + ' 07:07:07 GMT', - secure: true, - domain: location.hostname - }); -} - -// Set the unsecured example.org-domain cookie LEGACYCOOKIENAME with -// value cookie-value on path /cgi-bin/ and 24 hour duration; domain -// and path will be rewritten below. -// -// This uses milliseconds since the start of the Unix epoch for -// expiration. -async function setOneDayUnsecuredCookieWithMillisecondsSinceEpoch() { - // one day ahead, ignoring a possible leap-second - let inTwentyFourHours = Date.now() + 24 * 60 * 60 * 1000; - await cookieStore.set('LEGACYCOOKIENAME', 'cookie-value', { - path: kPath, - expires: inTwentyFourHours, - secure: false, - domain: location.hostname - }); -} - -// Delete the cookie written by -// setOneDayUnsecuredCookieWithMillisecondsSinceEpoch. -async function deleteUnsecuredCookieWithDomainAndPath() { - await cookieStore.delete('LEGACYCOOKIENAME', { - path: kPath, - secure: false, - domain: location.hostname - }); -} - -cookie_test(async testCase => { - await promise_rejects_when_unsecured( - testCase, - new TypeError(), - setOneDaySecureCookieWithDate(), - 'Secure cookies only writable from secure contexts'); - - const eventPromise = observeNextCookieChangeEvent(); - - await setOneDayUnsecuredCookieWithMillisecondsSinceEpoch(); - assert_equals( - await getCookieString('LEGACYCOOKIENAME'), - 'LEGACYCOOKIENAME=cookie-value', - 'Ensure unsecured cookie we set is visible'); - - await verifyCookieChangeEvent( - eventPromise, - {changed: [{name: 'LEGACYCOOKIENAME', value: 'cookie-value'}]}, - 'Ensure unsecured cookie we set is visible to observer'); - - await deleteUnsecuredCookieWithDomainAndPath(); - await promise_rejects_when_unsecured( - testCase, - new TypeError(), - setSecureCookieWithHttpLikeExpirationString(), - 'Secure cookies only writable from secure contexts'); -}, 'expiration');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/BackgroundSync.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/BackgroundSync.idl new file mode 100644 index 0000000..3580e3b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/BackgroundSync.idl
@@ -0,0 +1,28 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the Web Background Synchronization spec. +// See https://wicg.github.io/BackgroundSync/spec/ + +partial interface ServiceWorkerRegistration { + readonly attribute SyncManager sync; +}; + +[Exposed=(Window,Worker)] +interface SyncManager { + Promise<void> register(DOMString tag); + Promise<sequence<DOMString>> getTags(); +}; + +partial interface ServiceWorkerGlobalScope { + attribute EventHandler onsync; +}; + +[Constructor(DOMString type, SyncEventInit init), Exposed=ServiceWorker] +interface SyncEvent : ExtendableEvent { + readonly attribute DOMString tag; + readonly attribute boolean lastChance; +}; + +dictionary SyncEventInit : ExtendableEventInit { + required DOMString tag; + boolean lastChance = false; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/FileAPI.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/FileAPI.idl index 64aa0d6..af094c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/FileAPI.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/FileAPI.idl
@@ -1,29 +1,34 @@ -// https://w3c.github.io/FileAPI/#idl-index +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the FileAPI spec. +// See https://w3c.github.io/FileAPI/ -[Constructor(optional sequence<BlobPart> blobParts, optional BlobPropertyBag options), -Exposed=(Window,Worker)] +[Constructor(optional sequence<BlobPart> blobParts, + optional BlobPropertyBag options), + Exposed=(Window,Worker), Serializable] interface Blob { readonly attribute unsigned long long size; readonly attribute DOMString type; - //slice Blob into byte-ranged chunks - + // slice Blob into byte-ranged chunks Blob slice([Clamp] optional long long start, [Clamp] optional long long end, optional DOMString contentType); }; +enum EndingType { "transparent", "native" }; + dictionary BlobPropertyBag { DOMString type = ""; + EndingType endings = "transparent"; }; typedef (BufferSource or Blob or USVString) BlobPart; [Constructor(sequence<BlobPart> fileBits, - [EnsureUTF16] DOMString fileName, - optional FilePropertyBag options), -Exposed=(Window,Worker)] + USVString fileName, + optional FilePropertyBag options), + Exposed=(Window,Worker), Serializable] interface File : Blob { readonly attribute DOMString name; readonly attribute long long lastModified; @@ -33,7 +38,7 @@ long long lastModified; }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Serializable] interface FileList { getter File? item(unsigned long index); readonly attribute unsigned long length; @@ -55,7 +60,6 @@ const unsigned short LOADING = 1; const unsigned short DONE = 2; - readonly attribute unsigned short readyState; // File or Blob data @@ -73,7 +77,7 @@ }; -[Constructor, Exposed=Worker] +[Constructor, Exposed=(DedicatedWorker,SharedWorker)] interface FileReaderSync { // Synchronously return strings
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/budget-api.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/budget-api.idl new file mode 100644 index 0000000..a7fd1f2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/budget-api.idl
@@ -0,0 +1,31 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the budget-api spec. +// See https://wicg.github.io/budget-api/ + +[Exposed=Window] +partial interface Navigator { + [SameObject] readonly attribute BudgetService budget; +}; + +[Exposed=Worker] +partial interface WorkerNavigator { + [SameObject] readonly attribute BudgetService budget; +}; + +[Exposed=(Window,Worker)] +interface BudgetService { + Promise<double> getCost(OperationType operation); + Promise<sequence<BudgetState>> getBudget(); + + Promise<boolean> reserve(OperationType operation); +}; + +[Exposed=(Window,Worker)] +interface BudgetState { + readonly attribute double budgetAt; + readonly attribute DOMTimeStamp time; +}; + +enum OperationType { + "silent-push" +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/compat.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/compat.idl new file mode 100644 index 0000000..bbb268b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/compat.idl
@@ -0,0 +1,12 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the compat spec. +// See https://compat.spec.whatwg.org/ + +partial interface Window { + readonly attribute short orientation; + attribute EventHandler onorientationchange; +}; + +partial interface HTMLBodyElement { + attribute EventHandler onorientationchange; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/cssom.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/cssom.idl index b372ed6..708c6fc 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/cssom.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/cssom.idl
@@ -1,3 +1,7 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the CSS Object Model (CSSOM) spec. +// See https://drafts.csswg.org/cssom/ + typedef USVString CSSOMString; [Exposed=Window, @@ -47,6 +51,7 @@ }; ProcessingInstruction implements LinkStyle; + [Exposed=Window, LegacyArrayClass] interface CSSRuleList {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist index 0afffe07..8d3964b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist +++ b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
@@ -7,8 +7,6 @@ ## Whitespace rules that we can't enforce yet ## -CR AT EOL: svg/import/* - INDENT TABS: .gitmodules INDENT TABS: conformance-checkers/* INDENT TABS: content-security-policy/* @@ -16,7 +14,6 @@ INDENT TABS: old-tests/* INDENT TABS: pointerlock/* INDENT TABS: shadow-dom/* -INDENT TABS: svg/import/* INDENT TABS: tools/* INDENT TABS: web-animations/* INDENT TABS: webaudio/* @@ -32,7 +29,6 @@ TRAILING WHITESPACE: old-tests/* TRAILING WHITESPACE: pointerevents/* TRAILING WHITESPACE: shadow-dom/* -TRAILING WHITESPACE: svg/import/* TRAILING WHITESPACE: tools/* TRAILING WHITESPACE: webaudio/* TRAILING WHITESPACE: WebIDL/*
diff --git a/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/nav2_test_redirect_server.html b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/nav2_test_redirect_server.html index 41b24dd..1d7f6c92 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/nav2_test_redirect_server.html +++ b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/nav2_test_redirect_server.html
@@ -11,7 +11,7 @@ <script> function verifyTimingEventOrder(eventOrder, timingEntry) { - for (var i = 0; i < eventOrder.length - 1; i++) { + for (let i = 0; i < eventOrder.length - 1; i++) { assert_true(timingEntry[eventOrder[i]] < timingEntry[eventOrder[i + 1]], "Expected " + eventOrder[i] + " to be no greater than " + eventOrder[i + 1] + "."); } @@ -19,11 +19,13 @@ function onload_test() { - var frame_performance = document.getElementById("frameContext").contentWindow.performance; - assert_equals(frame_performance.getEntriesByType("navigation")[0].type, + const frame_performance = document.getElementById("frameContext").contentWindow.performance; + const navigation_entry = frame_performance.getEntriesByType("navigation")[0]; + assert_equals(navigation_entry.type, "navigate", "Expected navigation type to be navigate."); - assert_equals(frame_performance.getEntriesByType("navigation")[0].redirectCount, 1, "Expected redirectCount to be 1."); + assert_equals(navigation_entry.redirectCount, 1, "Expected redirectCount to be 1."); + assert_equals(navigation_entry.name, 'http://' + document.location.host + '/navigation-timing/resources/blank_page_green.html'); var timgingEvents = [ 'startTime',
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js index bfa8c2a2..76fcfd8f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
@@ -554,8 +554,9 @@ function exposure_set(object, default_set) { var exposed = object.extAttrs.filter(function(a) { return a.name == "Exposed" }); - if (exposed.length > 1 || exposed.length < 0) { - throw new IdlHarnessError("Unexpected Exposed extended attributes on " + memberName + ": " + exposed); + if (exposed.length > 1) { + throw new IdlHarnessError( + `Multiple 'Exposed' extended attributes on ${object.name}`); } if (exposed.length === 0) { @@ -684,7 +685,7 @@ this["includes"] = {}; // Assert B defined for A : B - for (const member of Object.values(this.members).filter(m => m.base)) { + for (var member of Object.values(this.members).filter(m => m.base)) { const lhs = member.name; const rhs = member.base; if (!(rhs in this.members)) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is undefined.`); @@ -2442,6 +2443,7 @@ } if (!exposed_in(exposure_set(member, this.exposureSet))) { test(function() { + assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_false(member.name in obj); }.bind(this), this.name + " interface: " + desc + ' must not have property "' + member.name + '"'); continue;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources-expected.txt deleted file mode 100644 index 51c23a8..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources-expected.txt +++ /dev/null
@@ -1,33 +0,0 @@ -This is a testharness.js-based test. -PASS Underlying source start: throwing getter -PASS Underlying source start: throwing method -FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({ - get pull() { - throw theError; - } - })" did not throw -PASS Underlying source: throwing pull method (initial pull) -FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string" -PASS Underlying source pull: throwing method (second pull) -FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({ - get cancel() { - throw theError; - } - })" did not throw -PASS Underlying source cancel: throwing method -PASS Underlying source: calling enqueue on an empty canceled stream should throw -PASS Underlying source: calling enqueue on a non-empty canceled stream should throw -PASS Underlying source: calling enqueue on a closed stream should throw -PASS Underlying source: calling enqueue on an errored stream should throw -PASS Underlying source: calling close twice on an empty stream should throw the second time -PASS Underlying source: calling close twice on a non-empty stream should throw the second time -PASS Underlying source: calling close on an empty canceled stream should throw -PASS Underlying source: calling close on a non-empty canceled stream should throw -PASS Underlying source: calling close after error should throw -FAIL Underlying source: calling error twice should not throw Cannot error a readable stream that is already errored -FAIL Underlying source: calling error after close should not throw Cannot error a close readable stream -PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error -PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error -PASS read should not error if it dequeues and pull() throws -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt deleted file mode 100644 index 51c23a8..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt +++ /dev/null
@@ -1,33 +0,0 @@ -This is a testharness.js-based test. -PASS Underlying source start: throwing getter -PASS Underlying source start: throwing method -FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({ - get pull() { - throw theError; - } - })" did not throw -PASS Underlying source: throwing pull method (initial pull) -FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string" -PASS Underlying source pull: throwing method (second pull) -FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({ - get cancel() { - throw theError; - } - })" did not throw -PASS Underlying source cancel: throwing method -PASS Underlying source: calling enqueue on an empty canceled stream should throw -PASS Underlying source: calling enqueue on a non-empty canceled stream should throw -PASS Underlying source: calling enqueue on a closed stream should throw -PASS Underlying source: calling enqueue on an errored stream should throw -PASS Underlying source: calling close twice on an empty stream should throw the second time -PASS Underlying source: calling close twice on a non-empty stream should throw the second time -PASS Underlying source: calling close on an empty canceled stream should throw -PASS Underlying source: calling close on a non-empty canceled stream should throw -PASS Underlying source: calling close after error should throw -FAIL Underlying source: calling error twice should not throw Cannot error a readable stream that is already errored -FAIL Underlying source: calling error after close should not throw Cannot error a close readable stream -PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error -PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error -PASS read should not error if it dequeues and pull() throws -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt deleted file mode 100644 index 8fe24a76..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt +++ /dev/null
@@ -1,34 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS Underlying source start: throwing getter -PASS Underlying source start: throwing method -FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({ - get pull() { - throw theError; - } - })" did not throw -PASS Underlying source: throwing pull method (initial pull) -FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string" -PASS Underlying source pull: throwing method (second pull) -FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({ - get cancel() { - throw theError; - } - })" did not throw -PASS Underlying source cancel: throwing method -PASS Underlying source: calling enqueue on an empty canceled stream should throw -PASS Underlying source: calling enqueue on a non-empty canceled stream should throw -PASS Underlying source: calling enqueue on a closed stream should throw -PASS Underlying source: calling enqueue on an errored stream should throw -PASS Underlying source: calling close twice on an empty stream should throw the second time -PASS Underlying source: calling close twice on a non-empty stream should throw the second time -PASS Underlying source: calling close on an empty canceled stream should throw -PASS Underlying source: calling close on a non-empty canceled stream should throw -PASS Underlying source: calling close after error should throw -FAIL Underlying source: calling error twice should not throw Cannot error a readable stream that is already errored -FAIL Underlying source: calling error after close should not throw Cannot error a close readable stream -PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error -PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error -PASS read should not error if it dequeues and pull() throws -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.sharedworker-expected.txt deleted file mode 100644 index 51c23a8..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/bad-underlying-sources.sharedworker-expected.txt +++ /dev/null
@@ -1,33 +0,0 @@ -This is a testharness.js-based test. -PASS Underlying source start: throwing getter -PASS Underlying source start: throwing method -FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({ - get pull() { - throw theError; - } - })" did not throw -PASS Underlying source: throwing pull method (initial pull) -FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string" -PASS Underlying source pull: throwing method (second pull) -FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({ - get cancel() { - throw theError; - } - })" did not throw -PASS Underlying source cancel: throwing method -PASS Underlying source: calling enqueue on an empty canceled stream should throw -PASS Underlying source: calling enqueue on a non-empty canceled stream should throw -PASS Underlying source: calling enqueue on a closed stream should throw -PASS Underlying source: calling enqueue on an errored stream should throw -PASS Underlying source: calling close twice on an empty stream should throw the second time -PASS Underlying source: calling close twice on a non-empty stream should throw the second time -PASS Underlying source: calling close on an empty canceled stream should throw -PASS Underlying source: calling close on a non-empty canceled stream should throw -PASS Underlying source: calling close after error should throw -FAIL Underlying source: calling error twice should not throw Cannot error a readable stream that is already errored -FAIL Underlying source: calling error after close should not throw Cannot error a close readable stream -PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error -PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error -PASS read should not error if it dequeues and pull() throws -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader-expected.txt deleted file mode 100644 index 0426dc27..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -This is a testharness.js-based test. -PASS Can get the ReadableStreamDefaultReader constructor indirectly -PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument -PASS ReadableStreamDefaultReader instances should have the correct list of properties -PASS ReadableStreamDefaultReader closed should always return the same promise object -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction) -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader) -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored -PASS Reading from a reader for an empty stream will wait until a chunk is available -PASS cancel() on a reader does not release the reader -PASS closed should be fulfilled after stream is closed (.closed access before acquiring) -PASS closed should be rejected after reader releases its lock (multiple stream locks) -PASS Multiple readers can access the stream in sequence -PASS Cannot use an already-released reader to unlock a stream again -PASS cancel() on a released reader is a no-op and does not pass through -PASS Getting a second reader after erroring the stream and releasing the reader should succeed -PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error -PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error -PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise -PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise -PASS Reading twice on a stream that gets closed -PASS Reading twice on a closed stream -PASS Reading twice on an errored stream -PASS Reading twice on a stream that gets errored -FAIL getReader() should call ToString() on mode assert_true: toString() should be called expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.dedicatedworker-expected.txt deleted file mode 100644 index 0426dc27..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.dedicatedworker-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -This is a testharness.js-based test. -PASS Can get the ReadableStreamDefaultReader constructor indirectly -PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument -PASS ReadableStreamDefaultReader instances should have the correct list of properties -PASS ReadableStreamDefaultReader closed should always return the same promise object -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction) -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader) -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored -PASS Reading from a reader for an empty stream will wait until a chunk is available -PASS cancel() on a reader does not release the reader -PASS closed should be fulfilled after stream is closed (.closed access before acquiring) -PASS closed should be rejected after reader releases its lock (multiple stream locks) -PASS Multiple readers can access the stream in sequence -PASS Cannot use an already-released reader to unlock a stream again -PASS cancel() on a released reader is a no-op and does not pass through -PASS Getting a second reader after erroring the stream and releasing the reader should succeed -PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error -PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error -PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise -PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise -PASS Reading twice on a stream that gets closed -PASS Reading twice on a closed stream -PASS Reading twice on an errored stream -PASS Reading twice on a stream that gets errored -FAIL getReader() should call ToString() on mode assert_true: toString() should be called expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.serviceworker.https-expected.txt deleted file mode 100644 index 1afbabd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.serviceworker.https-expected.txt +++ /dev/null
@@ -1,31 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS Can get the ReadableStreamDefaultReader constructor indirectly -PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument -PASS ReadableStreamDefaultReader instances should have the correct list of properties -PASS ReadableStreamDefaultReader closed should always return the same promise object -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction) -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader) -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored -PASS Reading from a reader for an empty stream will wait until a chunk is available -PASS cancel() on a reader does not release the reader -PASS closed should be fulfilled after stream is closed (.closed access before acquiring) -PASS closed should be rejected after reader releases its lock (multiple stream locks) -PASS Multiple readers can access the stream in sequence -PASS Cannot use an already-released reader to unlock a stream again -PASS cancel() on a released reader is a no-op and does not pass through -PASS Getting a second reader after erroring the stream and releasing the reader should succeed -PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error -PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error -PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise -PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise -PASS Reading twice on a stream that gets closed -PASS Reading twice on a closed stream -PASS Reading twice on an errored stream -PASS Reading twice on a stream that gets errored -FAIL getReader() should call ToString() on mode assert_true: toString() should be called expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.sharedworker-expected.txt deleted file mode 100644 index 0426dc27..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/default-reader.sharedworker-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -This is a testharness.js-based test. -PASS Can get the ReadableStreamDefaultReader constructor indirectly -PASS ReadableStreamDefaultReader constructor should get a ReadableStream object as argument -PASS ReadableStreamDefaultReader instances should have the correct list of properties -PASS ReadableStreamDefaultReader closed should always return the same promise object -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct construction) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct construction) -PASS Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader) -PASS Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader) -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed -PASS Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored -PASS Reading from a reader for an empty stream will wait until a chunk is available -PASS cancel() on a reader does not release the reader -PASS closed should be fulfilled after stream is closed (.closed access before acquiring) -PASS closed should be rejected after reader releases its lock (multiple stream locks) -PASS Multiple readers can access the stream in sequence -PASS Cannot use an already-released reader to unlock a stream again -PASS cancel() on a released reader is a no-op and does not pass through -PASS Getting a second reader after erroring the stream and releasing the reader should succeed -PASS ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error -PASS ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined error -PASS Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise -PASS Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise -PASS Reading twice on a stream that gets closed -PASS Reading twice on a closed stream -PASS Reading twice on an errored stream -PASS Reading twice on a stream that gets errored -FAIL getReader() should call ToString() on mode assert_true: toString() should be called expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection-expected.txt deleted file mode 100644 index 6dddfbf..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream promise_test: Unhandled rejection with value: object "TypeError: Cannot error a close readable stream" -PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost -PASS ReadableStream closed promise should reject even if stream and reader JS references are lost -PASS Garbage-collecting a ReadableStreamDefaultReader should not unlock its stream -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.dedicatedworker-expected.txt deleted file mode 100644 index 6dddfbf..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.dedicatedworker-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream promise_test: Unhandled rejection with value: object "TypeError: Cannot error a close readable stream" -PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost -PASS ReadableStream closed promise should reject even if stream and reader JS references are lost -PASS Garbage-collecting a ReadableStreamDefaultReader should not unlock its stream -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.serviceworker.https-expected.txt deleted file mode 100644 index 1187a9ef..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.serviceworker.https-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -FAIL ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream promise_test: Unhandled rejection with value: object "TypeError: Cannot error a close readable stream" -PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost -PASS ReadableStream closed promise should reject even if stream and reader JS references are lost -PASS Garbage-collecting a ReadableStreamDefaultReader should not unlock its stream -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.sharedworker-expected.txt deleted file mode 100644 index 6dddfbf..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/garbage-collection.sharedworker-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream promise_test: Unhandled rejection with value: object "TypeError: Cannot error a close readable stream" -PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost -PASS ReadableStream closed promise should reject even if stream and reader JS references are lost -PASS Garbage-collecting a ReadableStreamDefaultReader should not unlock its stream -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt deleted file mode 100644 index 8002502..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general-expected.txt +++ /dev/null
@@ -1,41 +0,0 @@ -This is a testharness.js-based test. -PASS ReadableStream can be constructed with no errors -PASS ReadableStream can't be constructed with garbage -PASS ReadableStream can't be constructed with an invalid type -PASS ReadableStream instances should have the correct list of properties -PASS ReadableStream constructor should throw for non-function start arguments -FAIL ReadableStream constructor will not tolerate initial garbage as cancel argument assert_throws: constructor should throw function "() => new ReadableStream({ cancel: '2' })" did not throw -FAIL ReadableStream constructor will not tolerate initial garbage as pull argument assert_throws: constructor should throw function "() => new ReadableStream({ pull: { } })" did not throw -FAIL ReadableStream start should be called with the proper parameters assert_equals: constructor should have no parameters expected 0 but got 5 -PASS ReadableStream start controller parameter should be extensible -PASS default ReadableStream getReader() should only accept mode:undefined -PASS ReadableStream should be able to call start method within prototype chain of its source -PASS ReadableStream start should be able to return a promise -PASS ReadableStream start should be able to return a promise and reject it -PASS ReadableStream should be able to enqueue different objects. -PASS ReadableStream: if pull rejects, it should error the stream -PASS ReadableStream: should only call pull once upon starting the stream -PASS ReadableStream: should call pull when trying to read from a started, empty stream -PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills -PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills -PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining -PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining -PASS ReadableStream: should not call pull until the previous pull call's promise fulfills -PASS ReadableStream: should pull after start, and after every read -PASS ReadableStream: should not call pull after start if the stream is now closed -PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows -PASS ReadableStream pull should be able to close a stream. -PASS ReadableStream pull should be able to error a stream. -PASS ReadableStream pull should be able to error a stream and throw. -PASS ReadableStream: enqueue should throw when the stream is readable but draining -PASS ReadableStream: enqueue should throw when the stream is closed -PASS ReadableStream: should call underlying source methods as methods -FAIL ReadableStream: desiredSize when closed assert_equals: after closing, desiredSize must be 0 expected 0 but got 10 -FAIL ReadableStream: desiredSize when errored assert_equals: after erroring, desiredSize must be null expected (object) null but got (number) 10 -PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue -PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately -PASS ReadableStream integration test: adapting a random push source -PASS ReadableStream integration test: adapting a sync pull source -PASS ReadableStream integration test: adapting an async pull source -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt deleted file mode 100644 index 8002502..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.dedicatedworker-expected.txt +++ /dev/null
@@ -1,41 +0,0 @@ -This is a testharness.js-based test. -PASS ReadableStream can be constructed with no errors -PASS ReadableStream can't be constructed with garbage -PASS ReadableStream can't be constructed with an invalid type -PASS ReadableStream instances should have the correct list of properties -PASS ReadableStream constructor should throw for non-function start arguments -FAIL ReadableStream constructor will not tolerate initial garbage as cancel argument assert_throws: constructor should throw function "() => new ReadableStream({ cancel: '2' })" did not throw -FAIL ReadableStream constructor will not tolerate initial garbage as pull argument assert_throws: constructor should throw function "() => new ReadableStream({ pull: { } })" did not throw -FAIL ReadableStream start should be called with the proper parameters assert_equals: constructor should have no parameters expected 0 but got 5 -PASS ReadableStream start controller parameter should be extensible -PASS default ReadableStream getReader() should only accept mode:undefined -PASS ReadableStream should be able to call start method within prototype chain of its source -PASS ReadableStream start should be able to return a promise -PASS ReadableStream start should be able to return a promise and reject it -PASS ReadableStream should be able to enqueue different objects. -PASS ReadableStream: if pull rejects, it should error the stream -PASS ReadableStream: should only call pull once upon starting the stream -PASS ReadableStream: should call pull when trying to read from a started, empty stream -PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills -PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills -PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining -PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining -PASS ReadableStream: should not call pull until the previous pull call's promise fulfills -PASS ReadableStream: should pull after start, and after every read -PASS ReadableStream: should not call pull after start if the stream is now closed -PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows -PASS ReadableStream pull should be able to close a stream. -PASS ReadableStream pull should be able to error a stream. -PASS ReadableStream pull should be able to error a stream and throw. -PASS ReadableStream: enqueue should throw when the stream is readable but draining -PASS ReadableStream: enqueue should throw when the stream is closed -PASS ReadableStream: should call underlying source methods as methods -FAIL ReadableStream: desiredSize when closed assert_equals: after closing, desiredSize must be 0 expected 0 but got 10 -FAIL ReadableStream: desiredSize when errored assert_equals: after erroring, desiredSize must be null expected (object) null but got (number) 10 -PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue -PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately -PASS ReadableStream integration test: adapting a random push source -PASS ReadableStream integration test: adapting a sync pull source -PASS ReadableStream integration test: adapting an async pull source -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt deleted file mode 100644 index 22d8dfbd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.serviceworker.https-expected.txt +++ /dev/null
@@ -1,42 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS ReadableStream can be constructed with no errors -PASS ReadableStream can't be constructed with garbage -PASS ReadableStream can't be constructed with an invalid type -PASS ReadableStream instances should have the correct list of properties -PASS ReadableStream constructor should throw for non-function start arguments -FAIL ReadableStream constructor will not tolerate initial garbage as cancel argument assert_throws: constructor should throw function "() => new ReadableStream({ cancel: '2' })" did not throw -FAIL ReadableStream constructor will not tolerate initial garbage as pull argument assert_throws: constructor should throw function "() => new ReadableStream({ pull: { } })" did not throw -FAIL ReadableStream start should be called with the proper parameters assert_equals: constructor should have no parameters expected 0 but got 5 -PASS ReadableStream start controller parameter should be extensible -PASS default ReadableStream getReader() should only accept mode:undefined -PASS ReadableStream should be able to call start method within prototype chain of its source -PASS ReadableStream start should be able to return a promise -PASS ReadableStream start should be able to return a promise and reject it -PASS ReadableStream should be able to enqueue different objects. -PASS ReadableStream: if pull rejects, it should error the stream -PASS ReadableStream: should only call pull once upon starting the stream -PASS ReadableStream: should call pull when trying to read from a started, empty stream -PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills -PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills -PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining -PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining -PASS ReadableStream: should not call pull until the previous pull call's promise fulfills -PASS ReadableStream: should pull after start, and after every read -PASS ReadableStream: should not call pull after start if the stream is now closed -PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows -PASS ReadableStream pull should be able to close a stream. -PASS ReadableStream pull should be able to error a stream. -PASS ReadableStream pull should be able to error a stream and throw. -PASS ReadableStream: enqueue should throw when the stream is readable but draining -PASS ReadableStream: enqueue should throw when the stream is closed -PASS ReadableStream: should call underlying source methods as methods -FAIL ReadableStream: desiredSize when closed assert_equals: after closing, desiredSize must be 0 expected 0 but got 10 -FAIL ReadableStream: desiredSize when errored assert_equals: after erroring, desiredSize must be null expected (object) null but got (number) 10 -PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue -PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately -PASS ReadableStream integration test: adapting a random push source -PASS ReadableStream integration test: adapting a sync pull source -PASS ReadableStream integration test: adapting an async pull source -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt deleted file mode 100644 index 8002502..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/general.sharedworker-expected.txt +++ /dev/null
@@ -1,41 +0,0 @@ -This is a testharness.js-based test. -PASS ReadableStream can be constructed with no errors -PASS ReadableStream can't be constructed with garbage -PASS ReadableStream can't be constructed with an invalid type -PASS ReadableStream instances should have the correct list of properties -PASS ReadableStream constructor should throw for non-function start arguments -FAIL ReadableStream constructor will not tolerate initial garbage as cancel argument assert_throws: constructor should throw function "() => new ReadableStream({ cancel: '2' })" did not throw -FAIL ReadableStream constructor will not tolerate initial garbage as pull argument assert_throws: constructor should throw function "() => new ReadableStream({ pull: { } })" did not throw -FAIL ReadableStream start should be called with the proper parameters assert_equals: constructor should have no parameters expected 0 but got 5 -PASS ReadableStream start controller parameter should be extensible -PASS default ReadableStream getReader() should only accept mode:undefined -PASS ReadableStream should be able to call start method within prototype chain of its source -PASS ReadableStream start should be able to return a promise -PASS ReadableStream start should be able to return a promise and reject it -PASS ReadableStream should be able to enqueue different objects. -PASS ReadableStream: if pull rejects, it should error the stream -PASS ReadableStream: should only call pull once upon starting the stream -PASS ReadableStream: should call pull when trying to read from a started, empty stream -PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills -PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills -PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining -PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining -PASS ReadableStream: should not call pull until the previous pull call's promise fulfills -PASS ReadableStream: should pull after start, and after every read -PASS ReadableStream: should not call pull after start if the stream is now closed -PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows -PASS ReadableStream pull should be able to close a stream. -PASS ReadableStream pull should be able to error a stream. -PASS ReadableStream pull should be able to error a stream and throw. -PASS ReadableStream: enqueue should throw when the stream is readable but draining -PASS ReadableStream: enqueue should throw when the stream is closed -PASS ReadableStream: should call underlying source methods as methods -FAIL ReadableStream: desiredSize when closed assert_equals: after closing, desiredSize must be 0 expected 0 but got 10 -FAIL ReadableStream: desiredSize when errored assert_equals: after erroring, desiredSize must be null expected (object) null but got (number) 10 -PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue -PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately -PASS ReadableStream integration test: adapting a random push source -PASS ReadableStream integration test: adapting a sync pull source -PASS ReadableStream integration test: adapting an async pull source -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.dedicatedworker.html b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.dedicatedworker.html new file mode 100644 index 0000000..327bc92f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.dedicatedworker.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>patched-global.js dedicated worker wrapper file</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +'use strict'; +fetch_tests_from_worker(new Worker('patched-global.js')); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.html b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.html new file mode 100644 index 0000000..869e910 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>patched-global.js browser context wrapper file</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + + + +<script src="patched-global.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.js b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.js new file mode 100644 index 0000000..e8117c48 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.js
@@ -0,0 +1,67 @@ +'use strict'; + +// Tests which patch the global environment are kept separate to avoid +// interfering with other tests. + +if (self.importScripts) { + self.importScripts('/resources/testharness.js'); +} + +const ReadableStream_prototype_locked_get = + Object.getOwnPropertyDescriptor(ReadableStream.prototype, 'locked').get; + +// Verify that |rs| passes the brand check as a readable stream. +function isReadableStream(rs) { + try { + ReadableStream_prototype_locked_get.call(rs); + return true; + } catch (e) { + return false; + } +} + +test(t => { + const rs = new ReadableStream(); + + const trappedProperties = ['highWaterMark', 'size', 'start', 'type', 'mode']; + for (const property of trappedProperties) { + // eslint-disable-next-line no-extend-native, accessor-pairs + Object.defineProperty(Object.prototype, property, { + get() { throw new Error(`${property} getter called`); }, + configurable: true + }); + } + t.add_cleanup(() => { + for (const property of trappedProperties) { + delete Object.prototype[property]; + } + }); + + const [branch1, branch2] = rs.tee(); + assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); + assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); +}, 'ReadableStream tee() should not touch Object.prototype properties'); + +test(t => { + const rs = new ReadableStream(); + + const oldReadableStream = self.ReadableStream; + + /* eslint-disable no-native-reassign */ + self.ReadableStream = function() { + throw new Error('ReadableStream called on global object'); + }; + + t.add_cleanup(() => { + self.ReadableStream = oldReadableStream; + }); + + const [branch1, branch2] = rs.tee(); + + assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); + assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); + + /* eslint-enable no-native-reassign */ +}, 'ReadableStream tee() should not call the global ReadableStream'); + +done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.serviceworker.https.html b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.serviceworker.https.html new file mode 100644 index 0000000..addb438 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.serviceworker.https.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>patched-global.js service worker wrapper file</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> + +<script> +'use strict'; +service_worker_test('patched-global.js', 'Service worker test setup'); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.sharedworker.html b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.sharedworker.html new file mode 100644 index 0000000..6dba52fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/patched-global.sharedworker.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>patched-global.js shared worker wrapper file</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +'use strict'; +fetch_tests_from_worker(new SharedWorker('patched-global.js')); +</script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/mixing-rules.js similarity index 100% rename from third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/mixing-rules.js
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-channel-rules.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html similarity index 96% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-channel-rules.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html index e5ce5ae9..a1c3273 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-channel-rules.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html
@@ -4,11 +4,11 @@ <title> audionode-channel-rules.html </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> - <script src="../resources/mixing-rules.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> + <script src="/webaudio/resources/mixing-rules.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html similarity index 95% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html index abd0da08..0a8c731 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-method-chaining.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html
@@ -4,10 +4,10 @@ <title> audionode-connect-method-chaining.html </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-order.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html similarity index 90% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-order.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html index be0ff4ae..eca15de 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-connect-order.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-connect-order.html
@@ -4,10 +4,10 @@ <title> audionode-connect-order.html </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-disconnect-audioparam.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html similarity index 96% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-disconnect-audioparam.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html index a24742c..c3d3fae 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-disconnect-audioparam.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html
@@ -4,10 +4,10 @@ <title> audionode-disconnect-audioparam.html </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-disconnect.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html similarity index 97% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-disconnect.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html index 8cecc7a..b29c09d 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode-disconnect.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html
@@ -4,10 +4,10 @@ <title> audionode-disconnect.html </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode.html similarity index 92% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode.html index 317a531..b75cd0b 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/audionode.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/audionode.html
@@ -4,10 +4,10 @@ <title> audionode.html </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> </head> <body> <div id="description"></div>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioNode/channel-mode-interp-basic.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html similarity index 89% rename from third_party/WebKit/LayoutTests/webaudio/AudioNode/channel-mode-interp-basic.html rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html index ecb958b..35cfca8 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioNode/channel-mode-interp-basic.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html
@@ -4,10 +4,10 @@ <title> Test Setting of channelCountMode and channelInterpretation </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audit.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> </head> <body> <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webusb/usb.https.html b/third_party/WebKit/LayoutTests/external/wpt/webusb/usb.https.html index 9ead12a8..05830798 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webusb/usb.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webusb/usb.https.html
@@ -130,4 +130,24 @@ }); }); }, 'ondisconnect event is triggered by removing a device'); + +usb_test(() => { + return getFakeDevice().then(({ device, fakeDevice }) => { + navigator.usb.test.onrequestdevice = event => { + event.respondWith(fakeDevice); + } + return callWithTrustedClick(() => { + let first = navigator.usb.requestDevice({ filters: [] }); + let second = navigator.usb.requestDevice({ filters: [] }); + return Promise.all([ + first.then(chosenDevice => { + assert_equals(chosenDevice, device); + }), + second.then(chosenDevice => { + assert_equals(chosenDevice, device); + }) + ]); + }); + }); +}, 'multiple requestDevice calls are allowed per user activation'); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt index 36691d6..f637c29 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -101,7 +101,6 @@ PASS oldChildWindow.onerror is newChildWindow.onerror PASS oldChildWindow.onfocus is newChildWindow.onfocus PASS oldChildWindow.onformdata is newChildWindow.onformdata -PASS oldChildWindow.onfreeze is newChildWindow.onfreeze PASS oldChildWindow.ongotpointercapture is newChildWindow.ongotpointercapture PASS oldChildWindow.onhashchange is newChildWindow.onhashchange PASS oldChildWindow.oninput is newChildWindow.oninput @@ -146,7 +145,6 @@ PASS oldChildWindow.onrejectionhandled is newChildWindow.onrejectionhandled PASS oldChildWindow.onreset is newChildWindow.onreset PASS oldChildWindow.onresize is newChildWindow.onresize -PASS oldChildWindow.onresume is newChildWindow.onresume PASS oldChildWindow.onscroll is newChildWindow.onscroll PASS oldChildWindow.onsearch is newChildWindow.onsearch PASS oldChildWindow.onseeked is newChildWindow.onseeked
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt index 014a2518..26239bf 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -69,7 +69,6 @@ PASS childWindow.onerror is null PASS childWindow.onfocus is null PASS childWindow.onformdata is null -PASS childWindow.onfreeze is null PASS childWindow.ongotpointercapture is null PASS childWindow.onhashchange is null PASS childWindow.oninput is null @@ -114,7 +113,6 @@ PASS childWindow.onrejectionhandled is null PASS childWindow.onreset is null PASS childWindow.onresize is null -PASS childWindow.onresume is null PASS childWindow.onscroll is null PASS childWindow.onsearch is null PASS childWindow.onseeked is null
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt index 4d4a025..d8badf9 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -69,7 +69,6 @@ PASS childWindow.onerror is null PASS childWindow.onfocus is null PASS childWindow.onformdata is null -PASS childWindow.onfreeze is null PASS childWindow.ongotpointercapture is null PASS childWindow.onhashchange is null PASS childWindow.oninput is null @@ -114,7 +113,6 @@ PASS childWindow.onrejectionhandled is null PASS childWindow.onreset is null PASS childWindow.onresize is null -PASS childWindow.onresume is null PASS childWindow.onscroll is null PASS childWindow.onsearch is null PASS childWindow.onseeked is null
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/recursive-delay-update-scroll-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/recursive-delay-update-scroll-expected.txt deleted file mode 100644 index aa44e7c..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/recursive-delay-update-scroll-expected.txt +++ /dev/null
@@ -1,2 +0,0 @@ - -PASS
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/monospace-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/monospace-expected.png index 4610aa27..d69fcea1 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/monospace-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/monospace-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/sans-serif-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/sans-serif-expected.png index ca521dc..19e801f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/sans-serif-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/sans-serif-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/serif-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/serif-expected.png index 984c6d9..18958c0 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/serif-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fonts/serif-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.png new file mode 100644 index 0000000..3d1b89d4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.txt index 8d273bb1..3a59909 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/tabular_data/td_colspan_rendering-expected.txt
@@ -4,9 +4,9 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x600 LayoutNGBlockFlow {BODY} at (8,8) size 784x584 LayoutNGBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 165x19 - text run at (0,0) width 165: "Tests: the colspan attribute" - LayoutBR {BR} at (165,0) size 0x0 + LayoutText {#text} at (0,0) size 166x19 + text run at (0,0) width 166: "Tests: the colspan attribute" + LayoutBR {BR} at (166,0) size 0x0 LayoutNGBlockFlow {P} at (0,36) size 784x80 LayoutText {#text} at (0,0) size 73x19 text run at (0,0) width 73: "Conditions:" @@ -19,13 +19,13 @@ LayoutText {#text} at (0,0) size 782x59 text run at (0,0) width 759: "The first table tests the default value of one, and an input of 7, which is within the normal range of expect input. The first" text run at (0,20) width 782: "column in the first row should span only column \"one\" and the second cell should span all of the other columns. The second" - text run at (0,40) width 520: "table tests the zero value. \"Just A\" should span \"A\" and \"Just B\" should span \"B.\"" + text run at (0,40) width 519: "table tests the zero value. \"Just A\" should span \"A\" and \"Just B\" should span \"B.\"" LayoutNGBlockFlow (anonymous) at (0,218) size 784x20 LayoutBR {BR} at (0,0) size 0x0 LayoutTable {TABLE} at (0,238) size 270x76 [border: (1px outset #808080)] LayoutBlockFlow {CAPTION} at (0,0) size 270x20 - LayoutText {#text} at (28,0) size 214x19 - text run at (28,0) width 214: "Testing Default and Regular Input" + LayoutText {#text} at (27,0) size 216x19 + text run at (27,0) width 216: "Testing Default and Regular Input" LayoutTableSection {TBODY} at (1,21) size 268x54 LayoutTableRow {TR} at (0,2) size 268x24 LayoutNGTableCell {TD} at (2,2) size 32x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] @@ -68,8 +68,8 @@ LayoutTableSection {TBODY} at (1,21) size 195x54 LayoutTableRow {TR} at (0,2) size 195x24 LayoutNGTableCell {TD} at (2,2) size 44x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 40x19 - text run at (2,2) width 40: "Just A" + LayoutText {#text} at (2,2) size 39x19 + text run at (2,2) width 39: "Just A" LayoutNGTableCell {TD} at (48,2) size 43x24 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1] LayoutText {#text} at (2,2) size 39x19 text run at (2,2) width 39: "Just B"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.png new file mode 100644 index 0000000..68b9c30 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.txt index 2c91839..31dcea1f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/iframe404-expected.txt
@@ -4,19 +4,19 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x600 LayoutNGBlockFlow {BODY} at (8,8) size 784x584 LayoutNGBlockFlow {P} at (0,0) size 784x40 - LayoutText {#text} at (0,0) size 51x19 - text run at (0,0) width 51: "Test for " + LayoutText {#text} at (0,0) size 52x19 + text run at (0,0) width 52: "Test for " LayoutInline {A} at (0,0) size 60x19 [color=#0000EE] - LayoutText {#text} at (51,0) size 60x19 - text run at (51,0) width 60: "bug 8121" - LayoutText {#text} at (111,0) size 289x19 - text run at (111,0) width 289: ": REGRESSION: 404s are not displayed and " + LayoutText {#text} at (52,0) size 60x19 + text run at (52,0) width 60: "bug 8121" + LayoutText {#text} at (112,0) size 289x19 + text run at (112,0) width 289: ": REGRESSION: 404s are not displayed and " LayoutInline {A} at (0,0) size 60x19 [color=#0000EE] - LayoutText {#text} at (400,0) size 60x19 - text run at (400,0) width 60: "bug 7739" - LayoutText {#text} at (460,0) size 770x39 - text run at (460,0) width 310: ": REGRESSION: Assertion failure loading acid2" - text run at (0,20) width 296: "test in -[WebCoreFrameBridge installInFrame:]" + LayoutText {#text} at (401,0) size 60x19 + text run at (401,0) width 60: "bug 7739" + LayoutText {#text} at (461,0) size 770x39 + text run at (461,0) width 309: ": REGRESSION: Assertion failure loading acid2" + text run at (0,20) width 297: "test in -[WebCoreFrameBridge installInFrame:]" LayoutNGBlockFlow {P} at (0,56) size 784x40 LayoutText {#text} at (0,0) size 774x39 text run at (0,0) width 774: "Here is an invalid iframe. It should contain a 404 error message, not any green fallback text. Note this will only work if this"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png new file mode 100644 index 0000000..3326cfa --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.txt index a387bf37..01b64ac 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.txt
@@ -6,8 +6,8 @@ LayoutText {#text} at (0,0) size 627x19 text run at (0,0) width 627: "This tests slow loading png images referenced from a image element inside a SVG pattern resource." LayoutBR {BR} at (627,0) size 0x0 - LayoutText {#text} at (0,20) size 561x19 - text run at (0,20) width 561: "You should see a 400x300 rect containing a tiled rendering of the Acid3 reference image." + LayoutText {#text} at (0,20) size 560x19 + text run at (0,20) width 560: "You should see a 400x300 rect containing a tiled rendering of the Acid3 reference image." layer at (10,50) size 406x306 clip at (13,53) size 400x300 LayoutSVGRoot (positioned) {svg} at (10,50) size 406x306 LayoutSVGHiddenContainer {defs} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-mask-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-mask-expected.png new file mode 100644 index 0000000..1d0f19bc --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-mask-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-mask-expected.txt new file mode 100644 index 0000000..5839a7d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-mask-expected.txt
@@ -0,0 +1,12 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x472 + LayoutNGBlockFlow {HTML} at (0,0) size 800x472 + LayoutNGBlockFlow {BODY} at (8,16) size 784x446 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 781x19 + text run at (0,0) width 781: "Tests that masked elements do not render until their mask images are fully loaded. You should not see any blue boxes below." +layer at (18,52) size 200x200 transparent + LayoutNGBlockFlow {DIV} at (10,36) size 200x200 [bgcolor=#0000FF] +layer at (18,262) size 200x200 transparent + LayoutNGBlockFlow {DIV} at (10,246) size 200x200 [bgcolor=#0000FF]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.png new file mode 100644 index 0000000..c6f5cc8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.txt index 5ebc74b..b924c59c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/http/tests/uri/css-href-expected.txt
@@ -4,13 +4,13 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x600 LayoutNGBlockFlow {BODY} at (8,8) size 784x576 LayoutNGBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 51x19 - text run at (0,0) width 51: "Test for " - LayoutInline {A} at (0,0) size 67x19 [color=#0000EE] - LayoutText {#text} at (51,0) size 67x19 - text run at (51,0) width 67: "bug 11141" - LayoutText {#text} at (118,0) size 341x19 - text run at (118,0) width 341: ": CSS '@import' doesn't respect HTML Base element." + LayoutText {#text} at (0,0) size 52x19 + text run at (0,0) width 52: "Test for " + LayoutInline {A} at (0,0) size 66x19 [color=#0000EE] + LayoutText {#text} at (52,0) size 66x19 + text run at (52,0) width 66: "bug 11141" + LayoutText {#text} at (118,0) size 340x19 + text run at (118,0) width 340: ": CSS '@import' doesn't respect HTML Base element." LayoutNGBlockFlow {P} at (0,36) size 784x20 [color=#008000] LayoutText {#text} at (0,0) size 163x19 text run at (0,0) width 163: "This text should be green."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.png index de27594b..31d5e720 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.txt index 88ede2b5..ad8eb18c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-applies-to-003-expected.txt
@@ -4,8 +4,8 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x162 LayoutNGBlockFlow {BODY} at (8,16) size 784x138 LayoutNGBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 353x19 - text run at (0,0) width 353: "Test passes if there is a box with rounded corners below." + LayoutText {#text} at (0,0) size 355x19 + text run at (0,0) width 355: "Test passes if there is a box with rounded corners below." LayoutNGListItem {DIV} at (0,36) size 102x102 [border: (3px solid #008000)] LayoutNGListMarker (anonymous) at (-18,3) size 10x20 LayoutText (anonymous) at (0,0) size 10x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.png index 99c684b6..20bf38f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.txt index 46a657f..ae6d3171 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/bordersbackgrounds/border-radius-clip-001-expected.txt
@@ -4,16 +4,16 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x162 LayoutNGBlockFlow {BODY} at (8,16) size 784x138 LayoutNGBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 514x19 - text run at (0,0) width 514: "Test passes if the 'Filler Text' below is clipped to the curve of the rounded corners." + LayoutText {#text} at (0,0) size 516x19 + text run at (0,0) width 516: "Test passes if the 'Filler Text' below is clipped to the curve of the rounded corners." layer at (8,52) size 198x102 clip at (11,55) size 192x96 scrollHeight 160 LayoutNGBlockFlow {DIV} at (0,36) size 198x102 [border: (3px solid #000000)] - LayoutText {#text} at (3,3) size 177x159 - text run at (3,3) width 177: "Filler Text. Filler Text. Filler" - text run at (3,23) width 175: "Text. Filler Text. Filler Text." - text run at (3,43) width 177: "Filler Text. Filler Text. Filler" - text run at (3,63) width 175: "Text. Filler Text. Filler Text." - text run at (3,83) width 177: "Filler Text. Filler Text. Filler" - text run at (3,103) width 175: "Text. Filler Text. Filler Text." - text run at (3,123) width 177: "Filler Text. Filler Text. Filler" - text run at (3,143) width 31: "Text." + LayoutText {#text} at (3,3) size 179x159 + text run at (3,3) width 179: "Filler Text. Filler Text. Filler" + text run at (3,23) width 178: "Text. Filler Text. Filler Text." + text run at (3,43) width 179: "Filler Text. Filler Text. Filler" + text run at (3,63) width 178: "Text. Filler Text. Filler Text." + text run at (3,83) width 179: "Filler Text. Filler Text. Filler" + text run at (3,103) width 178: "Text. Filler Text. Filler Text." + text run at (3,123) width 179: "Filler Text. Filler Text. Filler" + text run at (3,143) width 32: "Text."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/text/textshadow-002-expected.png index 5f30de1..be893eb 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-expected.png index d37208e..a6da3ca 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-image-document-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-image-document-expected.png index bbf86e87..b1308e9 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-aspect-ratio-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-aspect-ratio-expected.png new file mode 100644 index 0000000..b007d07 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-aspect-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-aspect-ratio-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-aspect-ratio-expected.txt new file mode 100644 index 0000000..af662a56 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-aspect-ratio-expected.txt
@@ -0,0 +1,73 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 619x19 + text run at (0,0) width 619: "Test video sizing. You should see one bigger image (paused video) and 7 small ones of 1/4 its size." + LayoutNGBlockFlow (anonymous) at (0,36) size 784x480 + LayoutBR {BR} at (320,240) size 0x0 + LayoutNGBlockFlow {DIV} at (160,240) size 320x120 + LayoutText {#text} at (0,0) size 0x0 + LayoutNGBlockFlow {DIV} at (0,360) size 320x120 + LayoutText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,44) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,284) size 160x120 + LayoutVideo {VIDEO} at (0,240) size 160x120 +layer at (168,284) size 160x120 + LayoutVideo {VIDEO} at (0,0) size 160x120 +layer at (328,284) size 160x120 + LayoutVideo {VIDEO} at (160,0) size 160x120 +layer at (8,404) size 160x120 + LayoutVideo {VIDEO} at (0,0) size 160x120 +layer at (168,404) size 160x120 + LayoutVideo {VIDEO} at (160,0) size 160x120 +layer at (8,44) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutNGBlockFlow {DIV} at (0,208) size 320x32 +layer at (8,44) size 320x198 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x198 +layer at (8,284) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (8,284) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78 +layer at (168,284) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (168,284) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78 +layer at (328,284) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (328,284) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78 +layer at (8,404) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (8,404) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78 +layer at (168,404) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (168,404) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78 +layer at (328,404) size 320x120 + LayoutNGBlockFlow (relative positioned) {DIV} at (320,360) size 320x120 +layer at (328,404) size 160x120 + LayoutVideo (positioned) {VIDEO} at (0,0) size 160x120 +layer at (328,404) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (328,404) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78 +layer at (488,404) size 160x120 + LayoutVideo (positioned) {VIDEO} at (160,0) size 160x120 +layer at (488,404) size 160x120 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x120 + LayoutNGBlockFlow {DIV} at (0,88) size 160x32 +layer at (488,404) size 160x78 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 160x78
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv420-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv420-expected.png new file mode 100644 index 0000000..4139d813 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv420-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv420-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv420-expected.txt new file mode 100644 index 0000000..18920923 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv420-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 327x19 + text run at (0,0) width 327: "Test correct colorspace for yuv420, i.e. YU12 video" + LayoutNGBlockFlow (anonymous) at (0,36) size 784x156 +layer at (8,44) size 206x156 + LayoutVideo {VIDEO} at (0,0) size 206x156 [border: (3px solid #FF0000)] +layer at (11,47) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutNGBlockFlow {DIV} at (0,118) size 200x32 +layer at (11,47) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv422-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv422-expected.png new file mode 100644 index 0000000..ad01466 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv422-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv422-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv422-expected.txt new file mode 100644 index 0000000..f4f9b688 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/media/video-colorspace-yuv422-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 327x19 + text run at (0,0) width 327: "Test correct colorspace for yuv422, i.e. YU16 video" + LayoutNGBlockFlow (anonymous) at (0,36) size 784x156 +layer at (8,44) size 206x156 + LayoutVideo {VIDEO} at (0,0) size 206x156 [border: (3px solid #FF0000)] +layer at (11,47) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutNGBlockFlow {DIV} at (0,118) size 200x32 +layer at (11,47) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-expected.png new file mode 100644 index 0000000..ca040691 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-expected.txt new file mode 100644 index 0000000..a84aaf13 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x362 + LayoutNGBlockFlow {HTML} at (0,0) size 800x362 + LayoutNGBlockFlow {BODY} at (8,16) size 784x338 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 425x19 + text run at (0,0) width 425: "Test for repaint in a composited layer. You should see no red below." +layer at (8,52) size 202x302 + LayoutNGBlockFlow {DIV} at (0,36) size 202x302 [border: (1px solid #000000)] + LayoutNGBlockFlow {DIV} at (51,51) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-rects-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-rects-expected.png new file mode 100644 index 0000000..95700b7f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-rects-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-rects-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-rects-expected.txt new file mode 100644 index 0000000..d971100 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/layer-repaint-rects-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x52 + LayoutNGBlockFlow {HTML} at (0,0) size 800x52 + LayoutNGBlockFlow {BODY} at (0,16) size 800x20 + LayoutNGBlockFlow {P} at (0,0) size 800x20 + LayoutText {#text} at (0,0) size 652x19 + text run at (0,0) width 652: "Tests repaint after a layer stops compositing. You should see no red below after the end of the transition." +layer at (0,100) size 402x232 + LayoutNGBlockFlow (positioned) {DIV} at (0,100) size 402x232 [border: (1px solid #000000)] +layer at (1,111) size 200x100 + LayoutNGBlockFlow (positioned) {DIV} at (1,11) size 200x100 [bgcolor=#8888FF] +layer at (1,221) size 200x100 + LayoutNGBlockFlow (positioned) {DIV} at (1,121) size 200x100 [bgcolor=#FF0000] +layer at (1,221) size 200x100 + LayoutNGBlockFlow (positioned) {DIV} at (1,221) size 200x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.png index ec42bc1..2a51a74 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt index a01a30b..2971601 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt
@@ -30,6 +30,11 @@ { "object": "NGPaintFragment", "rect": [14, 584, 406, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [14, 584, 406, 14], "reason": "disappeared" }, { @@ -64,11 +69,6 @@ }, { "object": "NGPaintFragment", - "rect": [14, 504, 406, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", "rect": [14, 344, 406, 14], "reason": "appeared" }, @@ -155,6 +155,11 @@ { "object": "NGPaintFragment", "rect": [14, 484, 354, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [14, 484, 354, 14], "reason": "disappeared" }, { @@ -204,17 +209,7 @@ }, { "object": "NGPaintFragment", - "rect": [14, 584, 353, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [100, 244, 321, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [56, 444, 313, 14], + "rect": [65, 424, 305, 14], "reason": "appeared" }, { @@ -224,7 +219,7 @@ }, { "object": "NGPaintFragment", - "rect": [65, 404, 305, 14], + "rect": [65, 364, 302, 14], "reason": "appeared" }, { @@ -235,11 +230,16 @@ { "object": "NGPaintFragment", "rect": [65, 404, 300, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [65, 404, 300, 14], "reason": "disappeared" }, { "object": "NGPaintFragment", - "rect": [65, 384, 300, 14], + "rect": [14, 444, 287, 14], "reason": "appeared" }, { @@ -249,12 +249,7 @@ }, { "object": "NGPaintFragment", - "rect": [65, 424, 285, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [194, 184, 227, 14], + "rect": [14, 244, 223, 14], "reason": "appeared" }, { @@ -265,11 +260,16 @@ { "object": "NGPaintFragment", "rect": [14, 184, 220, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [14, 184, 220, 14], "reason": "disappeared" }, { "object": "NGPaintFragment", - "rect": [14, 484, 212, 14], + "rect": [243, 244, 178, 14], "reason": "appeared" }, { @@ -280,31 +280,26 @@ { "object": "NGPaintFragment", "rect": [14, 504, 146, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [14, 504, 146, 14], "reason": "disappeared" }, { "object": "NGPaintFragment", "rect": [281, 184, 140, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [281, 184, 140, 14], "reason": "disappeared" }, { "object": "NGPaintFragment", - "rect": [176, 364, 137, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [14, 184, 134, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [65, 364, 108, 14], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [14, 244, 87, 14], + "rect": [65, 384, 84, 14], "reason": "appeared" }, { @@ -320,11 +315,21 @@ { "object": "NGPaintFragment", "rect": [302, 444, 68, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [302, 444, 68, 14], "reason": "disappeared" }, { "object": "NGPaintFragment", "rect": [371, 364, 49, 14], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [371, 364, 49, 14], "reason": "disappeared" }, { @@ -333,49 +338,25 @@ "reason": "subtree" }, { - "object": "LayoutNGBlockFlow (floating) SPAN id='greenFloat'", - "rect": [372, 383, 48, 81], - "reason": "subtree" - }, - { "object": "LayoutNGBlockFlow (floating) SPAN id='blueFloat'", "rect": [14, 363, 48, 65], "reason": "subtree" }, { "object": "NGPaintFragment", - "rect": [14, 444, 42, 14], + "rect": [238, 184, 41, 11], "reason": "appeared" }, { "object": "NGPaintFragment", "rect": [238, 184, 41, 11], "reason": "disappeared" - }, - { - "object": "NGPaintFragment", - "rect": [151, 184, 41, 11], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [349, 424, 20, 14], - "reason": "appeared" - }, - { - "object": "VerticalScrollbar", - "rect": [485, 0, 15, 600], - "reason": "scroll control" } ] } ], "objectPaintInvalidations": [ { - "object": "VerticalScrollbar", - "reason": "scroll control" - }, - { "object": "LayoutNGBlockFlow (floating) DIV id='pinkFloat'", "reason": "incremental" }, @@ -472,11 +453,11 @@ "reason": "subtree" }, { - "object": "LayoutNGBlockFlow (floating) SPAN id='greenFloat'", + "object": "NGPaintFragment", "reason": "subtree" }, { - "object": "NGPaintFragment", + "object": "LayoutNGBlockFlow (floating) SPAN id='greenFloat'", "reason": "subtree" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.png index 7e23df1..7da2987a 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt index e366611..88bf6e9ab 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt
@@ -269,7 +269,7 @@ }, { "object": "NGPaintFragment", - "rect": [14, 504, 212, 14], + "rect": [14, 504, 213, 14], "reason": "appeared" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.png index 1531eca..72cac4a 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt index 8e5567f..acbb43d 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt
@@ -349,7 +349,7 @@ }, { "object": "NGPaintFragment", - "rect": [235, 183, 46, 13], + "rect": [235, 184, 46, 12], "reason": "appeared" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.png index 12f271f..a5cd768 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.png index 9e7628d5..2e205dc4 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.png index 1d308d7..3d59164 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.png index c6ff39e..0b2c421 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.png index 2eec62e..0297e7c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt index 23d6cd89..8b011c8 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt
@@ -309,7 +309,7 @@ }, { "object": "NGPaintFragment", - "rect": [298, 444, 72, 14], + "rect": [298, 444, 72, 13], "reason": "appeared" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.png index c2d77af..ea17161 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.png index c3cc278..16d6cce 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt index 8ec4dcae..67d12aa3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt
@@ -264,7 +264,7 @@ }, { "object": "NGPaintFragment", - "rect": [14, 504, 212, 14], + "rect": [14, 504, 213, 14], "reason": "appeared" }, { @@ -279,7 +279,7 @@ }, { "object": "NGPaintFragment", - "rect": [211, 244, 158, 14], + "rect": [212, 244, 157, 14], "reason": "appeared" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.png index 98b5c88..7b613a07 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.txt index f4f0f28..acc3375e 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/inline-outline-repaint-expected.txt
@@ -39,12 +39,12 @@ }, { "object": "NGPaintFragment", - "rect": [104, 59, 662, 14], + "rect": [105, 59, 662, 14], "reason": "appeared" }, { "object": "NGPaintFragment", - "rect": [104, 59, 662, 14], + "rect": [105, 59, 662, 14], "reason": "disappeared" }, { @@ -59,12 +59,12 @@ }, { "object": "NGPaintFragment", - "rect": [191, 20, 325, 14], + "rect": [191, 20, 326, 14], "reason": "appeared" }, { "object": "NGPaintFragment", - "rect": [191, 20, 325, 14], + "rect": [191, 20, 326, 14], "reason": "disappeared" }, { @@ -118,6 +118,16 @@ "reason": "disappeared" }, { + "object": "NGPaintFragment", + "rect": [11, 59, 89, 11], + "reason": "appeared" + }, + { + "object": "NGPaintFragment", + "rect": [11, 59, 89, 11], + "reason": "disappeared" + }, + { "object": "InlineTextBox ' '", "rect": [8, 176, 88, 39], "reason": "appeared" @@ -134,32 +144,22 @@ }, { "object": "NGPaintFragment", - "rect": [11, 59, 88, 11], + "rect": [11, 121, 88, 11], "reason": "appeared" }, { "object": "NGPaintFragment", - "rect": [11, 59, 88, 11], + "rect": [11, 121, 88, 11], "reason": "disappeared" }, { "object": "NGPaintFragment", - "rect": [11, 121, 87, 11], + "rect": [8, 20, 61, 12], "reason": "appeared" }, { "object": "NGPaintFragment", - "rect": [11, 121, 87, 11], - "reason": "disappeared" - }, - { - "object": "NGPaintFragment", - "rect": [8, 20, 61, 11], - "reason": "appeared" - }, - { - "object": "NGPaintFragment", - "rect": [8, 20, 61, 11], + "rect": [8, 20, 61, 12], "reason": "disappeared" }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/overflow/paged-with-overflowing-block-rl-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/overflow/paged-with-overflowing-block-rl-expected.png new file mode 100644 index 0000000..50fbe2cf --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/overflow/paged-with-overflowing-block-rl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png index 01b096aa..0818885 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/repaint-across-writing-mode-boundary-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/hit-test-with-br-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/hit-test-with-br-expected.png new file mode 100644 index 0000000..ddd9db68 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/hit-test-with-br-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.png index 236b096..13b73e82 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.png index 921f55a..930592f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.txt index 1789c8c..ef93a927 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-composited-expected.txt
@@ -4,17 +4,17 @@ LayoutNGBlockFlow {HTML} at (0,0) size 1600x356 LayoutNGBlockFlow {BODY} at (16,16) size 1568x324 LayoutNGBlockFlow (anonymous) at (0,0) size 1568x37 - LayoutText {#text} at (0,0) size 59x36 - text run at (0,0) width 59: "LTR" + LayoutText {#text} at (0,0) size 58x36 + text run at (0,0) width 58: "LTR" LayoutNGBlockFlow (anonymous) at (0,81) size 1568x37 LayoutText {#text} at (0,0) size 59x36 text run at (0,0) width 59: "RTL" LayoutNGBlockFlow (anonymous) at (0,162) size 1568x37 - LayoutText {#text} at (0,0) size 368x36 - text run at (0,0) width 368: "LTR (text-overflow:ellipses)" + LayoutText {#text} at (0,0) size 367x36 + text run at (0,0) width 367: "LTR (text-overflow:ellipses)" LayoutNGBlockFlow (anonymous) at (0,243) size 1568x37 - LayoutText {#text} at (0,0) size 366x36 - text run at (0,0) width 366: "RTL (text-overflow:ellipses)" + LayoutText {#text} at (0,0) size 367x36 + text run at (0,0) width 367: "RTL (text-overflow:ellipses)" layer at (16,53) size 404x44 clip at (18,55) size 400x40 scrollWidth 452 LayoutBlockFlow {DIV} at (0,37) size 404x44 [border: (2px solid #000000)] LayoutText {#text} at (2,2) size 451x36
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.png index e31a0879..49322d85 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.txt index 1789c8c..ef93a927 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline-spelling-markers-hidpi-expected.txt
@@ -4,17 +4,17 @@ LayoutNGBlockFlow {HTML} at (0,0) size 1600x356 LayoutNGBlockFlow {BODY} at (16,16) size 1568x324 LayoutNGBlockFlow (anonymous) at (0,0) size 1568x37 - LayoutText {#text} at (0,0) size 59x36 - text run at (0,0) width 59: "LTR" + LayoutText {#text} at (0,0) size 58x36 + text run at (0,0) width 58: "LTR" LayoutNGBlockFlow (anonymous) at (0,81) size 1568x37 LayoutText {#text} at (0,0) size 59x36 text run at (0,0) width 59: "RTL" LayoutNGBlockFlow (anonymous) at (0,162) size 1568x37 - LayoutText {#text} at (0,0) size 368x36 - text run at (0,0) width 368: "LTR (text-overflow:ellipses)" + LayoutText {#text} at (0,0) size 367x36 + text run at (0,0) width 367: "LTR (text-overflow:ellipses)" LayoutNGBlockFlow (anonymous) at (0,243) size 1568x37 - LayoutText {#text} at (0,0) size 366x36 - text run at (0,0) width 366: "RTL (text-overflow:ellipses)" + LayoutText {#text} at (0,0) size 367x36 + text run at (0,0) width 367: "RTL (text-overflow:ellipses)" layer at (16,53) size 404x44 clip at (18,55) size 400x40 scrollWidth 452 LayoutBlockFlow {DIV} at (0,37) size 404x44 [border: (2px solid #000000)] LayoutText {#text} at (2,2) size 451x36
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png new file mode 100644 index 0000000..601c24a --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.txt new file mode 100644 index 0000000..5931b7e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.txt
@@ -0,0 +1,33 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x184 + LayoutNGBlockFlow {HTML} at (0,0) size 800x184 + LayoutNGBlockFlow {BODY} at (8,8) size 784x168 + LayoutNGBlockFlow (anonymous) at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 30x19 + text run at (0,0) width 30: "LTR" + LayoutNGBlockFlow (anonymous) at (0,42) size 784x20 + LayoutText {#text} at (0,0) size 30x19 + text run at (0,0) width 30: "RTL" + LayoutNGBlockFlow (anonymous) at (0,84) size 784x20 + LayoutText {#text} at (0,0) size 183x19 + text run at (0,0) width 183: "LTR (text-overflow:ellipses):" + LayoutNGBlockFlow (anonymous) at (0,126) size 784x20 + LayoutText {#text} at (0,0) size 182x19 + text run at (0,0) width 182: "RTL (text-overflow:ellipses):" +layer at (8,28) size 202x22 clip at (9,29) size 200x20 scrollWidth 221 + LayoutBlockFlow {DIV} at (0,20) size 202x22 [border: (1px solid #000000)] + LayoutText {#text} at (1,1) size 220x19 + text run at (1,1) width 220: "the the adlj adaasj sdklj. there there" +layer at (8,70) size 202x22 clip at (9,71) size 200x20 scrollX 20.00 scrollWidth 220 + LayoutBlockFlow {DIV} at (0,62) size 202x22 [border: (1px solid #000000)] + LayoutText {#text} at (-19,1) size 220x19 + text run at (-19,1) width 220 RTL override: "the the adlj adaasj sdklj. there there" +layer at (8,112) size 202x22 clip at (9,113) size 200x20 scrollWidth 221 + LayoutBlockFlow {DIV} at (0,104) size 202x22 [border: (1px solid #000000)] + LayoutText {#text} at (1,1) size 220x19 + text run at (1,1) width 220: "the the adlj adaasj sdklj. there there" +layer at (8,154) size 202x22 clip at (9,155) size 200x20 scrollX 20.00 scrollWidth 220 + LayoutBlockFlow {DIV} at (0,146) size 202x22 [border: (1px solid #000000)] + LayoutText {#text} at (-19,1) size 220x19 + text run at (-19,1) width 220 RTL override: "the the adlj adaasj sdklj. there there"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.png new file mode 100644 index 0000000..9f289d3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.txt index 7fe8995..4dee042 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/absolute-sized-svg-in-xhtml-expected.txt
@@ -2,22 +2,22 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x105 LayoutNGBlockFlow {html} at (0,0) size 800x105 - LayoutInline {body} at (0,0) size 224x104 + LayoutInline {body} at (0,0) size 225x104 LayoutText {#text} at (0,0) size 0x0 - LayoutInline {h1} at (0,0) size 53x19 - LayoutText {#text} at (0,85) size 53x19 - text run at (0,85) width 53: "Test 123" - LayoutText {#text} at (53,85) size 4x19 - text run at (53,85) width 4: " " - LayoutSVGRoot {svg} at (57,0) size 100x100 + LayoutInline {h1} at (0,0) size 54x19 + LayoutText {#text} at (0,85) size 54x19 + text run at (0,85) width 54: "Test 123" + LayoutText {#text} at (54,85) size 4x19 + text run at (54,85) width 4: " " + LayoutSVGRoot {svg} at (58,0) size 100x100 LayoutSVGText {text} at (0,-15) size 191x19 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,-15) size 191x19 chunk 1 text run 1 at (0.00,0.00) startOffset 0 endOffset 29 width 191.00: "You should see an error above" LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00] - LayoutText {#text} at (157,85) size 4x19 - text run at (157,85) width 4: " " + LayoutText {#text} at (158,85) size 4x19 + text run at (158,85) width 4: " " LayoutInline {h1} at (0,0) size 63x19 - LayoutText {#text} at (161,85) size 63x19 - text run at (161,85) width 63: "Test ABC" + LayoutText {#text} at (162,85) size 63x19 + text run at (162,85) width 63: "Test ABC" LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/clone-element-with-animated-svg-properties-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/clone-element-with-animated-svg-properties-expected.png new file mode 100644 index 0000000..ae5fa19 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/clone-element-with-animated-svg-properties-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/clone-element-with-animated-svg-properties-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/clone-element-with-animated-svg-properties-expected.txt new file mode 100644 index 0000000..d9e5fb4c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/clone-element-with-animated-svg-properties-expected.txt
@@ -0,0 +1,12 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 533x19 + text run at (0,0) width 533: "Here is an html paragraph. And below is a svg drawing. You should see two ellipses." + LayoutNGBlockFlow {DIV} at (0,36) size 784x400 + LayoutSVGRoot {svg} at (0,0) size 400x400 + LayoutSVGEllipse {ellipse} at (20,40) size 60x20 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#FF0000]}] [cx=50.00] [cy=50.00] [rx=30.00] [ry=10.00] + LayoutSVGEllipse {ellipse} at (70,40) size 60x20 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#FF0000]}] [cx=100.00] [cy=50.00] [rx=30.00] [ry=10.00]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.png new file mode 100644 index 0000000..285337b1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.txt index 4efa5f6..18973d7 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/getsvgdocument-expected.txt
@@ -4,8 +4,8 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x600 LayoutNGBlockFlow {BODY} at (8,8) size 784x584 LayoutNGBlockFlow {P} at (0,0) size 784x40 - LayoutText {#text} at (0,0) size 765x39 - text run at (0,0) width 765: "This tests to see if HTMLEmbedElement.getSVGDocument() and HTMLObjectElement.getSVGDocument() work. You" + LayoutText {#text} at (0,0) size 764x39 + text run at (0,0) width 764: "This tests to see if HTMLEmbedElement.getSVGDocument() and HTMLObjectElement.getSVGDocument() work. You" text run at (0,20) width 300: "should see SUCCESS printed twice below this:" LayoutNGBlockFlow (anonymous) at (0,56) size 784x60 LayoutBR {BR} at (85,20) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/inline-svg-in-xhtml-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/inline-svg-in-xhtml-expected.png new file mode 100644 index 0000000..bf9c9f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/inline-svg-in-xhtml-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/inline-svg-in-xhtml-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/inline-svg-in-xhtml-expected.txt new file mode 100644 index 0000000..24ee2b5c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/inline-svg-in-xhtml-expected.txt
@@ -0,0 +1,32 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutNGBlockFlow {html} at (0,0) size 800x0 +layer at (48,38) size 722x542 layerType: background only +layer at (49,39) size 720x540 + LayoutSVGRoot (positioned) {svg} at (1,1) size 720x540 + LayoutSVGResourceLinearGradient {linearGradient} [id="gradient"] [gradientUnits=objectBoundingBox] [stops=( #FFFF00@0.00 #008000@1.00 )] [start=(0,0)] [end=(1,0)] + LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=LINEAR-GRADIENT] [id="gradient"]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00] + LayoutSVGEllipse {circle} at (20,20) size 60x60 [fill={[type=LINEAR-GRADIENT] [id="gradient"]}] [cx=50.00] [cy=50.00] [r=30.00] +layer at (48,38) size 722x542 layerType: foreground only + LayoutNGBlockFlow (positioned) {body} at (48,38) size 722x542 [border: (1px solid #000000)] + LayoutNGBlockFlow {form} at (1,1) size 720x129.59 + LayoutFieldset {fieldset} at (2,0) size 716x129.59 [border: (2px groove #C0C0C0)] + LayoutNGBlockFlow {legend} at (14,0) size 87x20 + LayoutText {#text} at (2,0) size 83x19 + text run at (2,0) width 83: "HTML Form" + LayoutNGBlockFlow {p} at (14,41.59) size 688x22 + LayoutInline {label} at (0,0) size 107x19 + LayoutText {#text} at (0,1) size 107x19 + text run at (0,1) width 107: "Enter something:" + LayoutText {#text} at (107,1) size 4x19 + text run at (107,1) width 4: " " + LayoutTextControl {input} at (111,0) size 181x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutText {#text} at (0,0) size 0x0 + LayoutNGBlockFlow {p} at (14,79.59) size 688x22 + LayoutButton {button} at (0,0) size 68x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutNGBlockFlow (anonymous) at (8,3) size 52x16 + LayoutText {#text} at (0,0) size 52x16 + text run at (0,0) width 52: "Activate!" +layer at (178,84) size 177x16 + LayoutBlockFlow {div} at (2,3) size 177x16
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/no-inherited-dashed-stroke-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/no-inherited-dashed-stroke-expected.png index 48e77d6..b684ba2 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/no-inherited-dashed-stroke-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/no-inherited-dashed-stroke-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/object-sizing-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/object-sizing-expected.png index e8148798..e7b0fc5c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/object-sizing-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/object-sizing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/rootmost-svg-xy-attrs-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/rootmost-svg-xy-attrs-expected.png new file mode 100644 index 0000000..1384b6b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/rootmost-svg-xy-attrs-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/rootmost-svg-xy-attrs-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/rootmost-svg-xy-attrs-expected.txt new file mode 100644 index 0000000..2a1a870 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/rootmost-svg-xy-attrs-expected.txt
@@ -0,0 +1,44 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x310 + LayoutNGBlockFlow {html} at (0,0) size 800x309.88 + LayoutNGBlockFlow {body} at (8,21.44) size 784x280.44 + LayoutNGBlockFlow {h1} at (0,0) size 784x37 + LayoutText {#text} at (0,0) size 744x36 + text run at (0,0) width 744: "Test case for x/y attributes on root-most <svg> element" + LayoutNGBlockFlow {p} at (0,58.44) size 784x60 + LayoutText {#text} at (0,0) size 29x19 + text run at (0,0) width 29: "The " + LayoutInline {code} at (0,0) size 8x16 + LayoutText {#text} at (29,3) size 8x16 + text run at (29,3) width 8: "x" + LayoutText {#text} at (37,0) size 31x19 + text run at (37,0) width 31: " and " + LayoutInline {code} at (0,0) size 8x16 + LayoutText {#text} at (68,3) size 8x16 + text run at (68,3) width 8: "y" + LayoutText {#text} at (76,0) size 160x19 + text run at (76,0) width 160: " attributes on a root-most " + LayoutInline {code} at (0,0) size 40x16 + LayoutText {#text} at (236,3) size 40x16 + text run at (236,3) width 40: "<svg>" + LayoutText {#text} at (276,0) size 433x19 + text run at (276,0) width 433: " element should be ignored, as specified by SVG 1.1. The root-most " + LayoutInline {code} at (0,0) size 40x16 + LayoutText {#text} at (709,3) size 40x16 + text run at (709,3) width 40: "<svg>" + LayoutText {#text} at (0,20) size 742x39 + text run at (0,20) width 742: "element is the element at the root of an SVG fragment. For the following test to pass, the green SVG square should be" + text run at (0,40) width 622: "rendered aligned to the top-left of the red CSS-rendered square, which is 10 pixels wider and taller." + LayoutNGBlockFlow {p} at (0,134.44) size 784x20 + LayoutText {#text} at (0,0) size 27x19 + text run at (0,0) width 27: "See " + LayoutInline {a} at (0,0) size 71x19 [color=#0000EE] + LayoutText {#text} at (27,0) size 71x19 + text run at (27,0) width 71: "Bug 13828" + LayoutText {#text} at (98,0) size 4x19 + text run at (98,0) width 4: "." + LayoutNGBlockFlow {div} at (0,170.44) size 110x110 [bgcolor=#FF0000] + LayoutSVGRoot {svg} at (0,0) size 100x100 + LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00] + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-float-border-padding-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-float-border-padding-expected.png new file mode 100644 index 0000000..5562fff8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-float-border-padding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-fonts-in-html-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-fonts-in-html-expected.png index a23f0a25..c66c0c82 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-fonts-in-html-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/svg-fonts-in-html-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.png index c004767..5ffffde 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.txt index e02f4344..7b09d649 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/transformed-text-pattern-expected.txt
@@ -3,9 +3,9 @@ layer at (0,0) size 800x241 LayoutNGBlockFlow {HTML} at (0,0) size 800x241 LayoutNGBlockFlow {BODY} at (8,8) size 784x225 - LayoutText {#text} at (0,0) size 319x19 - text run at (0,0) width 319: "This test passes if there is an A and a green square." - LayoutBR {BR} at (319,0) size 0x0 + LayoutText {#text} at (0,0) size 318x19 + text run at (0,0) width 318: "This test passes if there is an A and a green square." + LayoutBR {BR} at (318,0) size 0x0 LayoutSVGRoot {svg} at (0,20) size 200x200 LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGResourcePattern {pattern} [id="pattern"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse] [patternTransform={m=((10.00,0.00)(0.00,10.00)) t=(0.00,0.00)}]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/dom/SVGStringList-basics-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/dom/SVGStringList-basics-expected.png new file mode 100644 index 0000000..6bf7bda --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/dom/SVGStringList-basics-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/foreignObject/svg-document-in-html-document-expected.png new file mode 100644 index 0000000..03edcce3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/foreignObject/svg-document-in-html-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/foreignObject/svg-document-in-html-document-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/foreignObject/svg-document-in-html-document-expected.txt new file mode 100644 index 0000000..9811ef3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/foreignObject/svg-document-in-html-document-expected.txt
@@ -0,0 +1,29 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGForeignObject {foreignObject} at (0,0) size 300x100 + LayoutNGBlockFlow {html} at (0,0) size 300x191 + LayoutNGBlockFlow {p} at (0,0) size 300x20 + LayoutText {#text} at (0,0) size 216x19 + text run at (0,0) width 216: "Test from HTML in foreignObject" + LayoutNGBlockFlow (anonymous) at (0,36) size 300x155 + LayoutSVGRoot {svg} at (0,0) size 300x150 + LayoutSVGRect {rect} at (0,0) size 20x20 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=20.00] [height=20.00] + LayoutSVGText {text} at (0,35) size 271x19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,35) size 271x19 + chunk 1 text run 1 at (0.00,50.00) startOffset 0 endOffset 38 width 270.00: "Test from SVG in HTML in foreignObject" + LayoutText {#text} at (0,0) size 0x0 +layer at (0,0) size 300x100 scrollHeight 191 + LayoutSVGForeignObject {foreignObject} at (0,0) size 300x100 + LayoutNGBlockFlow {html} at (0,0) size 300x191 + LayoutNGBlockFlow {p} at (0,0) size 300x20 + LayoutText {#text} at (0,0) size 216x19 + text run at (0,0) width 216: "Test from HTML in foreignObject" + LayoutNGBlockFlow (anonymous) at (0,36) size 300x155 + LayoutSVGRoot {svg} at (0,0) size 300x150 + LayoutSVGRect {rect} at (0,0) size 20x20 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=20.00] [height=20.00] + LayoutSVGText {text} at (0,35) size 271x19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,35) size 271x19 + chunk 1 text run 1 at (0.00,50.00) startOffset 0 endOffset 38 width 270.00: "Test from SVG in HTML in foreignObject" + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.png index 016f040..13c5ee8d 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.txt index a723e2c4..89059df 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-repaint-rects-expected.txt
@@ -4,9 +4,9 @@ LayoutNGBlockFlow {html} at (0,0) size 800x164 LayoutNGBlockFlow {body} at (8,16) size 784x132 LayoutNGBlockFlow {p} at (0,0) size 784x132 - LayoutText {#text} at (0,32) size 221x19 - text run at (0,32) width 221: "The alphabet A through M is here: " - LayoutSVGRoot {svg} at (221,0) size 500x47 + LayoutText {#text} at (0,32) size 220x19 + text run at (0,32) width 220: "The alphabet A through M is here: " + LayoutSVGRoot {svg} at (220,0) size 500x47 LayoutSVGContainer {g} at (0,-45) size 524x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,47.00)}] LayoutSVGText {text} at (0,-45) size 36x57 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,-45) size 36x57 @@ -35,11 +35,11 @@ LayoutSVGText {text} at (0,-45) size 17x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(320.00,0.00)}] contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,-45) size 17x57 chunk 1 text run 1 at (0.00,0.00) startOffset 0 endOffset 1 width 17.00: "I" - LayoutSVGText {text} at (0,-45) size 20x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(360.00,0.00)}] contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,-45) size 20x57 + LayoutSVGText {text} at (0,-45) size 19x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(360.00,0.00)}] contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,-45) size 19x57 chunk 1 text run 1 at (0.00,0.00) startOffset 0 endOffset 1 width 19.00: "J" - LayoutSVGText {text} at (0,-45) size 37x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(400.00,0.00)}] contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,-45) size 37x57 + LayoutSVGText {text} at (0,-45) size 36x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(400.00,0.00)}] contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,-45) size 36x57 chunk 1 text run 1 at (0.00,0.00) startOffset 0 endOffset 1 width 36.00: "K" LayoutSVGText {text} at (0,-45) size 31x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(440.00,0.00)}] contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,-45) size 31x57 @@ -47,9 +47,9 @@ LayoutSVGText {text} at (0,-45) size 44x57 [transform={m=((1.00,0.00)(0.00,1.00)) t=(480.00,0.00)}] contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,-45) size 44x57 chunk 1 text run 1 at (0.00,0.00) startOffset 0 endOffset 1 width 44.00: "M" - LayoutText {#text} at (721,32) size 784x99 - text run at (721,32) width 51: " this test" - text run at (0,52) width 784: "case is specially constructed so that when the view is sized to 800x600 (the default for DumpRenderTree) the text wraps and" - text run at (0,72) width 777: "not all of the text in the SVG is drawn correctly. You should see all of A-L (and half of M) above. The code was incorrectly" + LayoutText {#text} at (720,32) size 783x99 + text run at (720,32) width 51: " this test" + text run at (0,52) width 783: "case is specially constructed so that when the view is sized to 800x600 (the default for DumpRenderTree) the text wraps and" + text run at (0,72) width 775: "not all of the text in the SVG is drawn correctly. You should see all of A-L (and half of M) above. The code was incorrectly" text run at (0,92) width 757: "calculating the PaintInfo::rect (damage rect) when passing it through LayoutBlockFlow and render block was (correctly)" text run at (0,112) width 300: "clipping out some of the lineboxes during paint."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/zoom/page/zoom-svg-float-border-padding-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/zoom/page/zoom-svg-float-border-padding-expected.png new file mode 100644 index 0000000..53e67af --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/zoom/page/zoom-svg-float-border-padding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/zoom/text/zoom-svg-float-border-padding-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/zoom/text/zoom-svg-float-border-padding-expected.png new file mode 100644 index 0000000..e3e6146 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/zoom/text/zoom-svg-float-border-padding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug106158-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug106158-1-expected.png new file mode 100644 index 0000000..0ade942b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug106158-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug106158-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug106158-2-expected.png new file mode 100644 index 0000000..651c5b5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug106158-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug109043-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug109043-expected.png new file mode 100644 index 0000000..d0dfe17 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug109043-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384q-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384q-expected.png index 7d6f40ac..10a2dc2 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384q-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384q-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384s-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384s-expected.png index f6ed40b..5afdb44 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384s-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug11384s-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug1302-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug1302-expected.png new file mode 100644 index 0000000..85229da0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug1302-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020_iframe-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020_iframe-expected.png index 7f48cfb..94514994 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020_iframe-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020_iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug13118-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug13118-expected.png new file mode 100644 index 0000000..1c6f9c8c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug13118-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug13196-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug13196-expected.png new file mode 100644 index 0000000..37da28d3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug13196-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug139524-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug139524-2-expected.png index 7129f6c..dbf16408 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug139524-2-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug139524-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug1430-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug1430-expected.png new file mode 100644 index 0000000..953b39d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug1430-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug16252-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug16252-expected.png new file mode 100644 index 0000000..20223b79 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug16252-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug17130-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug17130-1-expected.png new file mode 100644 index 0000000..c185f3df --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug17130-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug18955-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug18955-expected.png new file mode 100644 index 0000000..eac8e1e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug18955-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2267-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2267-expected.png new file mode 100644 index 0000000..4af0433 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2267-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-1-expected.png new file mode 100644 index 0000000..63f295e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-3-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-3-expected.png index 879c8f6..fe4991e6 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-3-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-4-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-4-expected.png index 7bfa00a..c48ea7b 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-4-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2757-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2757-expected.png new file mode 100644 index 0000000..96d965a --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2757-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2962-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2962-expected.png index 25c6726..96284ab 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2962-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2962-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2981-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2981-2-expected.png new file mode 100644 index 0000000..5fd67a0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2981-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2997-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2997-expected.png new file mode 100644 index 0000000..c1ef24c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2997-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug38916-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug38916-expected.png index fe7c8ba..807a0a02 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug38916-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug38916-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug3977-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug3977-expected.png new file mode 100644 index 0000000..b67d44e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug3977-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43039-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43039-expected.png new file mode 100644 index 0000000..3fd509e2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43039-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43854-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43854-2-expected.png index c5e7d926..0a2aeb00 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43854-2-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug43854-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png new file mode 100644 index 0000000..8c1df49 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug44523-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug44523-expected.png new file mode 100644 index 0000000..dc336e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug44523-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4501-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4501-expected.png new file mode 100644 index 0000000..9947ef06 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4501-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4576-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4576-expected.png index f47a005..cdd379b 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4576-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4576-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-1-expected.png new file mode 100644 index 0000000..54f8a993 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-2-expected.png new file mode 100644 index 0000000..54f8a993 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-5-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-5-expected.png new file mode 100644 index 0000000..2f32213d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-5-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-expected.png new file mode 100644 index 0000000..2f32213d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46268-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46368-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46368-1-expected.png new file mode 100644 index 0000000..c21a455 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46368-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46368-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46368-2-expected.png new file mode 100644 index 0000000..4284e81 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46368-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-1-expected.png index 1f73763..1a1f1c6 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-1-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-2-expected.png index 75cf839..d1368bb 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-2-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46480-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46623-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46623-1-expected.png index d0eac1cd..c623f79 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46623-1-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46623-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46924-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46924-expected.png index 4f2d4d1..97ce7b2 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46924-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug46924-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4803-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4803-expected.png index 1b2d2b1..e90fdc74 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4803-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4803-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4849-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4849-2-expected.png new file mode 100644 index 0000000..d957029f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4849-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug48827-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug48827-expected.png new file mode 100644 index 0000000..bbc0c52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug48827-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png new file mode 100644 index 0000000..f1e26dd --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug59354-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug59354-expected.png new file mode 100644 index 0000000..a88c517 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug59354-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug6304-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug6304-expected.png new file mode 100644 index 0000000..19e7293 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug6304-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug69382-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug69382-2-expected.png new file mode 100644 index 0000000..95ef6063 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug69382-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug727-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug727-expected.png new file mode 100644 index 0000000..843787b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug727-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug7342-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug7342-expected.png new file mode 100644 index 0000000..4f44e50 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug7342-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png new file mode 100644 index 0000000..189ace9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-1-expected.png index 0a6b7ef..ad1e9d7 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-1-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-2-expected.png new file mode 100644 index 0000000..37154e8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug82946-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug9123-1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug9123-1-expected.png index 59dba5c..33e2fd13 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug9123-1-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug9123-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug93363-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug93363-expected.png new file mode 100644 index 0000000..8fa5f68 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug93363-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png index ea32d94..579f1a1 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/col_span-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/col_span-expected.png new file mode 100644 index 0000000..ef08c17 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/col_span-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_center-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_center-expected.png new file mode 100644 index 0000000..8d08c046a --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_center-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_justify-expected.png new file mode 100644 index 0000000..1a1ca925 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_left-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_left-expected.png new file mode 100644 index 0000000..5211a8c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_left-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_right-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_right-expected.png new file mode 100644 index 0000000..a476b3a9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_align_right-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_span-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_span-expected.png new file mode 100644 index 0000000..57de09f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_span-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_baseline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_baseline-expected.png new file mode 100644 index 0000000..882160a --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_baseline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_bottom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_bottom-expected.png new file mode 100644 index 0000000..a84af6f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_bottom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_middle-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_middle-expected.png new file mode 100644 index 0000000..cc45efb --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_middle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_top-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_top-expected.png new file mode 100644 index 0000000..23d79eb --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_valign_top-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_width_pct-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_width_pct-expected.png new file mode 100644 index 0000000..de2c5677 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_width_pct-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_width_px-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_width_px-expected.png new file mode 100644 index 0000000..1770f31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/colgroup_width_px-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_center-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_center-expected.png new file mode 100644 index 0000000..9a040ca --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_center-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_left-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_left-expected.png new file mode 100644 index 0000000..9af6224 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_left-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_right-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_right-expected.png new file mode 100644 index 0000000..5250451 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_td_align_right-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_center-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_center-expected.png new file mode 100644 index 0000000..3c624ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_center-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_left-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_left-expected.png new file mode 100644 index 0000000..c5f00de2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_left-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_right-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_right-expected.png new file mode 100644 index 0000000..fce5820 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tables_th_align_right-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_center-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_center-expected.png new file mode 100644 index 0000000..5209a4a --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_center-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_char-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_char-expected.png new file mode 100644 index 0000000..6585abb --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_char-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_justify-expected.png new file mode 100644 index 0000000..4e16b34 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_left-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_left-expected.png new file mode 100644 index 0000000..b5b4673 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_left-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_right-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_right-expected.png new file mode 100644 index 0000000..dd41cf8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_align_right-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_char-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_char-expected.png new file mode 100644 index 0000000..bfb15d1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_char-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_baseline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_baseline-expected.png new file mode 100644 index 0000000..61b3ac5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_baseline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_bottom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_bottom-expected.png new file mode 100644 index 0000000..9edc7009 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_bottom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_middle-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_middle-expected.png new file mode 100644 index 0000000..8868d858 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_middle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_top-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_top-expected.png new file mode 100644 index 0000000..e69eb15 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tbody_valign_top-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tfoot_align_char-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tfoot_align_char-expected.png new file mode 100644 index 0000000..d69f018 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tfoot_align_char-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tfoot_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tfoot_align_justify-expected.png new file mode 100644 index 0000000..8b2532b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/tfoot_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/thead_align_char-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/thead_align_char-expected.png new file mode 100644 index 0000000..643413f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/thead_align_char-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/thead_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/thead_align_justify-expected.png new file mode 100644 index 0000000..1e4e2724 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/thead_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_baseline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_baseline-expected.png new file mode 100644 index 0000000..6d7d48d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_baseline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_bottom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_bottom-expected.png new file mode 100644 index 0000000..be98fe1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_bottom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_middle-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_middle-expected.png new file mode 100644 index 0000000..37f14f5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_middle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_top-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_top-expected.png new file mode 100644 index 0000000..4354adf --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_valign_top-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_pct-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_pct-expected.png new file mode 100644 index 0000000..00581f8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_pct-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_px-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_px-expected.png new file mode 100644 index 0000000..1774b7f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_px-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_rel-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_rel-expected.png new file mode 100644 index 0000000..49f1052 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_col_width_rel-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_baseline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_baseline-expected.png new file mode 100644 index 0000000..6033aa3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_baseline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_bottom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_bottom-expected.png new file mode 100644 index 0000000..041a2990 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_bottom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_middle-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_middle-expected.png new file mode 100644 index 0000000..edb1397 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_middle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_top-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_top-expected.png new file mode 100644 index 0000000..17995c1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_valign_top-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_width_pct-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_width_pct-expected.png new file mode 100644 index 0000000..3c786d62 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_width_pct-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_width_rel-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_width_rel-expected.png new file mode 100644 index 0000000..de9430b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_colgroup_width_rel-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_table-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_table-expected.png new file mode 100644 index 0000000..b7021031 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_table-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_center-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_center-expected.png new file mode 100644 index 0000000..fd463ccac --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_center-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_char-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_char-expected.png new file mode 100644 index 0000000..1d2addfb --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_char-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_justify-expected.png new file mode 100644 index 0000000..4c686c59 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_left-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_left-expected.png new file mode 100644 index 0000000..10943c5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_left-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_right-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_right-expected.png new file mode 100644 index 0000000..3587a52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_align_right-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_baseline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_baseline-expected.png new file mode 100644 index 0000000..b3bf976f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_baseline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_bottom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_bottom-expected.png new file mode 100644 index 0000000..2583edd --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_bottom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_middle-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_middle-expected.png new file mode 100644 index 0000000..8868998 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_middle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_top-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_top-expected.png new file mode 100644 index 0000000..5e83389 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tbody_valign_top-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_td_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_td_align_justify-expected.png index aef1907b..1a07d26 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_td_align_justify-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_td_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_th_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_th_align_justify-expected.png index b058d75f..571942f31 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_th_align_justify-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_th_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tr_align_justify-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tr_align_justify-expected.png index d0a8e8e..0fa4660 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tr_align_justify-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/marvin/x_tr_align_justify-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/cellspacing-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/cellspacing-expected.png new file mode 100644 index 0000000..4346807 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/cellspacing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test3-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test3-expected.png index c2deb1d..896f71f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test3-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test6-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test6-expected.png index b7b5945..86881eb3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test6-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/test6-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_thtd_rowspan-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_thtd_rowspan-expected.png index 8e77ab1..d66114a 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_thtd_rowspan-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_thtd_rowspan-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_tr_align-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_tr_align-expected.png index cc6b060..1bff1b64 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_tr_align-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/other/wa_table_tr_align-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1010-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1010-expected.png new file mode 100644 index 0000000..7852395 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1055-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1055-2-expected.png new file mode 100644 index 0000000..520d5a6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1055-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1128-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1128-expected.png index 09cae5f..0cf29ec 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1128-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug1128-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug21518-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug21518-expected.png new file mode 100644 index 0000000..a455a6c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug21518-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug22122-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug22122-expected.png new file mode 100644 index 0000000..444e7664 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug22122-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug2479-5-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug2479-5-expected.png new file mode 100644 index 0000000..3481f8f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug2479-5-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug32205-4-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug32205-4-expected.png index 23e00d2..557383c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug32205-4-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug32205-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug4294-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug4294-expected.png new file mode 100644 index 0000000..4d3f849 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug4294-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug51000-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug51000-expected.png new file mode 100644 index 0000000..07e55331 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug51000-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png new file mode 100644 index 0000000..bc95339 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug80762-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug80762-2-expected.png new file mode 100644 index 0000000..034cf67 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug80762-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug85016-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug85016-expected.png new file mode 100644 index 0000000..d8199083 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug85016-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug89315-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug89315-expected.png new file mode 100644 index 0000000..06c3ce2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug89315-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug91057-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug91057-expected.png index 33bc838b..9a4b3f85 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug91057-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug91057-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/core/standards1-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/core/standards1-expected.png new file mode 100644 index 0000000..f73db97 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/core/standards1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png index 961b431..0596666 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/x_colgroup_width_px-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/x_colgroup_width_px-expected.png new file mode 100644 index 0000000..7c26151 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/marvin/x_colgroup_width_px-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/2d/transform-fixed-container-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/2d/transform-fixed-container-expected.png new file mode 100644 index 0000000..a308ec4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/2d/transform-fixed-container-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/2d/transform-fixed-container-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/2d/transform-fixed-container-expected.txt new file mode 100644 index 0000000..0d76fb78 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/2d/transform-fixed-container-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollY 100.00 scrollHeight 1150 + LayoutView at (0,0) size 800x600 +layer at (0,-100) size 785x1150 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutNGBlockFlow {HTML} at (0,0) size 785x1150 + LayoutNGBlockFlow {BODY} at (0,150) size 785x1000 + LayoutNGBlockFlow {P} at (0,250) size 785x20 + LayoutText {#text} at (0,0) size 542x19 + text run at (0,0) width 542: "Tests fixed position elements combined with transforms. You should see no red above." +layer at (50,100) size 100x100 + LayoutNGBlockFlow (positioned) {DIV} at (50,200) size 100x100 [bgcolor=#FF0000] +layer at (250,100) size 100x100 + LayoutNGBlockFlow (positioned) {DIV} at (250,200) size 100x100 [bgcolor=#FF0000] +layer at (50,50) size 100x100 + LayoutNGBlockFlow {DIV} at (50,0) size 100x100 +layer at (50,100) size 100x100 + LayoutNGBlockFlow (positioned) {DIV} at (0,50) size 100x100 [bgcolor=#008000] +layer at (250,50) size 100x100 + LayoutNGBlockFlow (positioned) {DIV} at (250,50) size 100x100 +layer at (250,100) size 100x100 + LayoutNGBlockFlow {DIV} at (0,50) size 100x100 [bgcolor=#008000] +scrolled to 0,100
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.png new file mode 100644 index 0000000..beedef9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.txt index dd3b317e..e36a25c 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/3d/general/perspective-units-expected.txt
@@ -4,8 +4,8 @@ LayoutNGBlockFlow {HTML} at (0,0) size 800x581 LayoutNGBlockFlow {BODY} at (8,16) size 784x557 LayoutNGBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 501x19 - text run at (0,0) width 501: "-webkit-perspective should take units. All four should look qualitatively similar." + LayoutText {#text} at (0,0) size 499x19 + text run at (0,0) width 499: "-webkit-perspective should take units. All four should look qualitatively similar." LayoutNGBlockFlow (anonymous) at (0,36) size 784x521 LayoutText {#text} at (242,157) size 4x19 text run at (242,157) width 4: " "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transform-on-inline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transform-on-inline-expected.png index 156bfe3..124b3a1 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transform-on-inline-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transform-on-inline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transforms-with-zoom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transforms-with-zoom-expected.png new file mode 100644 index 0000000..399203e8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transforms-with-zoom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transforms-with-zoom-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transforms-with-zoom-expected.txt new file mode 100644 index 0000000..0f7c9a7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/transforms/transforms-with-zoom-expected.txt
@@ -0,0 +1,20 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (0,0) size 800x580.81 + LayoutNGBlockFlow {P} at (0,0) size 800x22 + LayoutInline {A} at (0,0) size 375x21 [color=#0000EE] + LayoutText {#text} at (0,0) size 375x21 + text run at (0,0) width 375: "https://bugs.webkit.org/show_bug.cgi?id=24784" + LayoutNGBlockFlow {P} at (0,41.19) size 800x22 + LayoutText {#text} at (0,0) size 639x21 + text run at (0,0) width 639: "Test transform lengths with zoom. You should see two green squares below, no red." +layer at (120,84) size 120x120 + LayoutNGBlockFlow (positioned) {DIV} at (120,84) size 120x120 [bgcolor=#FF0000] +layer at (300,84) size 120x120 + LayoutNGBlockFlow (positioned) {DIV} at (300,84) size 120x120 [bgcolor=#FF0000] +layer at (0,24) size 120x120 + LayoutNGBlockFlow (positioned) {DIV} at (0,24) size 120x120 [bgcolor=#008000] +layer at (0,24) size 120x120 + LayoutNGBlockFlow (positioned) {DIV} at (0,24) size 120x120 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-expected.png index cb8d6f42..2129ae3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-image-document-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-image-document-expected.png index d8abfef..5d9130d 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png new file mode 100644 index 0000000..f9a19fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/image-object-in-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/patternfill-repeat-expected.png new file mode 100644 index 0000000..f1a008b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/patternfill-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt new file mode 100644 index 0000000..50f4ffbe --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x469 + LayoutNGBlockFlow {HTML} at (0,0) size 800x469 + LayoutNGBlockFlow {BODY} at (8,16) size 784x437 + LayoutNGBlockFlow {P} at (0,0) size 784x80 + LayoutText {#text} at (0,0) size 771x79 + text run at (0,0) width 750: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit" + text run at (0,20) width 771: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square." + text run at (0,40) width 763: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be" + text run at (0,60) width 218: "one Apple image in top left corner." + LayoutNGBlockFlow {P} at (0,96) size 784x341 +layer at (8,112) size 336x336 + LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.png index d26363c..4572884 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.txt index b138d3f..31b0b24 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/pointer-events-2-expected.txt
@@ -10,7 +10,7 @@ LayoutText {#text} at (0,0) size 777x79 text run at (0,0) width 777: "This test is expected to be run from within DumpRenderTree. If running manually, click on the elements in the first column," text run at (0,20) width 766: "making sure the actual result (3rd column) matches the expected result (2nd column). Repeat for click target (4th column)," - text run at (0,40) width 776: "expected result (5th column) and actual result (6th column). Note: You should click on a yellow inline element if one exists," + text run at (0,40) width 775: "expected result (5th column) and actual result (6th column). Note: You should click on a yellow inline element if one exists," text run at (0,60) width 198: "otherwise anywhere in the box." layer at (10,140) size 300x100 LayoutNGBlockFlow (positioned) {DIV} at (10,140) size 300x100 @@ -130,12 +130,12 @@ LayoutImage (positioned) {IMG} at (0,0) size 80x80 layer at (440,240) size 80x80 LayoutNGBlockFlow (positioned) {DIV} at (100,0) size 80x80 - LayoutText {#text} at (0,0) size 24x19 - text run at (0,0) width 24: "p11" + LayoutText {#text} at (0,0) size 23x19 + text run at (0,0) width 23: "p11" layer at (540,240) size 80x80 LayoutNGBlockFlow (positioned) {DIV} at (200,0) size 80x80 - LayoutText {#text} at (0,0) size 24x19 - text run at (0,0) width 24: "p11" + LayoutText {#text} at (0,0) size 23x19 + text run at (0,0) width 23: "p11" layer at (340,340) size 300x100 LayoutNGBlockFlow (positioned) {DIV} at (340,340) size 300x100 layer at (340,340) size 80x80
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png new file mode 100644 index 0000000..46734dc4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png new file mode 100644 index 0000000..46734dc4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-on-both-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-on-both-expected.txt new file mode 100644 index 0000000..50823d1c --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-on-both-expected.txt
@@ -0,0 +1,6 @@ +Tests that a request can be intercepted on both request and response stages. +intercepted request: http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html +request will be sent http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html +intercepted response: http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html 200 +response received http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-on-both.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-on-both.js new file mode 100644 index 0000000..a6291b06 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-on-both.js
@@ -0,0 +1,36 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank( + `Tests that a request can be intercepted on both request and response stages.`); + + await session.protocol.Network.clearBrowserCookies(); + await session.protocol.Network.clearBrowserCache(); + await session.protocol.Network.setCacheDisabled({cacheDisabled: true}); + await session.protocol.Network.enable(); + await session.protocol.Runtime.enable(); + + session.protocol.Network.onRequestWillBeSent(event => { + testRunner.log(`request will be sent ${event.params.request.url}`); + }); + session.protocol.Network.onResponseReceived(event => { + testRunner.log(`response received ${event.params.response.url}`); + }); + + await dp.Network.setRequestInterception({patterns: [ + {urlPattern: '*', interceptionStage: 'Request'}, + {urlPattern: '*', interceptionStage: 'HeadersReceived'} + ]}); + + session.evaluate(`fetch('${testRunner.url('../network/resources/simple-iframe.html')}')`); + + const intercepted1 = (await dp.Network.onceRequestIntercepted()).params; + testRunner.log(`intercepted request: ${intercepted1.request.url}`); + + dp.Network.continueInterceptedRequest({interceptionId: intercepted1.interceptionId}); + + const intercepted2 = (await dp.Network.onceRequestIntercepted()).params; + testRunner.log(`intercepted response: ${intercepted2.request.url} ${intercepted2.responseStatusCode}`); + dp.Network.continueInterceptedRequest({interceptionId: intercepted2.interceptionId}); + + await dp.Network.onceLoadingFinished(); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-response-interception-disable-between.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-response-interception-disable-between.js index 54ece424..f887318 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-response-interception-disable-between.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-response-interception-disable-between.js
@@ -16,7 +16,10 @@ await session.protocol.Network.setCacheDisabled({cacheDisabled: true}); session.protocol.Network.enable(); testRunner.log('Network agent enabled'); - await session.protocol.Network.setRequestInterception({patterns: [{urlPattern: "*", interceptionStage: 'Request'}, {urlPattern: "*", interceptionStage: 'HeadersReceived'}]}); + await session.protocol.Network.setRequestInterception({patterns: [ + {urlPattern: "*", interceptionStage: 'Request'}, + {urlPattern: "*", interceptionStage: 'HeadersReceived'} + ]}); var responseContent = await session.evaluateAsync(`fetch('/devtools/network/resources/resource.php?size=10').then(response => response.text())`); testRunner.log('Body: ');
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt index c8659d2..ff0ed78 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/malformed-xss-protection-header-1-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE ERROR: Error parsing header X-XSS-Protection: 12345678901234567: expected semicolon at character position 2. The default protections will be applied. +CONSOLE ERROR: Error parsing header X-XSS-Protection: 12345678901234567: expected token to be 0 or 1 at character position 0. The default protections will be applied. CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=1&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header. ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=1&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' This tests that a malformed X-XSS-Protection header is not ignored when the length of its value exceeds 16 characters, and that an error is reported.
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint-expected.txt deleted file mode 100644 index 6f576d0..0000000 --- a/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint-expected.txt +++ /dev/null
@@ -1,90 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF" - }, - { - "name": "LayoutVideo VIDEO id='v'", - "position": [8, 8], - "bounds": [700, 525], - "drawsContent": false - }, - { - "name": "Squashing Containment Layer", - "drawsContent": false - }, - { - "name": "LayoutFlexibleBox (relative positioned) DIV class='phase-ready state-stopped'", - "position": [8, 8], - "bounds": [700, 525] - }, - { - "name": "Squashing Layer (first squashed layer: LayoutFlexibleBox (relative positioned) DIV)", - "position": [8, 8], - "bounds": [700, 525], - "paintInvalidations": [ - { - "object": "LayoutBlockFlow (positioned) DIV", - "rect": [580, 508, 70, 2], - "reason": "disappeared" - }, - { - "object": "LayoutBlockFlow (positioned) DIV id='thumb'", - "rect": [632, 493, 36, 32], - "reason": "full" - }, - { - "object": "LayoutBlockFlow (positioned) DIV id='thumb'", - "rect": [562, 493, 36, 32], - "reason": "full" - }, - { - "object": "LayoutButton INPUT class='muted'", - "rect": [530, 493, 32, 32], - "reason": "full" - } - ] - } - ], - "objectPaintInvalidations": [ - { - "object": "LayoutVideo VIDEO id='v'", - "reason": "style change" - }, - { - "object": "LayoutFlexibleBox (relative positioned) DIV class='phase-ready state-stopped'", - "reason": "geometry" - }, - { - "object": "LayoutButton INPUT class='muted'", - "reason": "full" - }, - { - "object": "LayoutFlexibleBox DIV", - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (positioned) DIV id='thumb'", - "reason": "full" - }, - { - "object": "LayoutBlockFlow (positioned) DIV", - "reason": "disappeared" - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint.html b/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint.html deleted file mode 100644 index 20bff96..0000000 --- a/third_party/WebKit/LayoutTests/paint/invalidation/video-mute-repaint.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html> -<title>Test for crbug.com/190880</title> -<script src="../../resources/run-after-layout-and-paint.js"></script> -<script src="resources/text-based-repaint.js"></script> -<style> - video { width: 700px; } -</style> - -<video id="v" controls autoload src="../../media/content/test.ogv"> -</video> - -<script> - window.testIsAsync = true; - - var video = document.getElementById("v"); - video.addEventListener("canplaythrough", runRepaintTest, true); - - function repaintTest() { - video.volume = 0; - // Volume change is handled in another document cycle. - runAfterLayoutAndPaint(finishRepaintTest); - } -</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint-expected.txt deleted file mode 100644 index 2a9746c..0000000 --- a/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint-expected.txt +++ /dev/null
@@ -1,90 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF" - }, - { - "name": "LayoutVideo VIDEO id='v'", - "position": [8, 8], - "bounds": [700, 525], - "drawsContent": false - }, - { - "name": "Squashing Containment Layer", - "drawsContent": false - }, - { - "name": "LayoutFlexibleBox (relative positioned) DIV class='phase-ready state-stopped'", - "position": [8, 8], - "bounds": [700, 525] - }, - { - "name": "Squashing Layer (first squashed layer: LayoutFlexibleBox (relative positioned) DIV)", - "position": [8, 8], - "bounds": [700, 525], - "paintInvalidations": [ - { - "object": "LayoutBlockFlow (positioned) DIV id='thumb'", - "rect": [597, 493, 36, 32], - "reason": "full" - }, - { - "object": "LayoutBlockFlow (positioned) DIV id='thumb'", - "rect": [562, 493, 36, 32], - "reason": "full" - }, - { - "object": "LayoutBlockFlow (positioned) DIV", - "rect": [580, 508, 35, 2], - "reason": "appeared" - }, - { - "object": "LayoutButton INPUT", - "rect": [530, 493, 32, 32], - "reason": "full" - } - ] - } - ], - "objectPaintInvalidations": [ - { - "object": "LayoutVideo VIDEO id='v'", - "reason": "style change" - }, - { - "object": "LayoutFlexibleBox (relative positioned) DIV class='phase-ready state-stopped'", - "reason": "geometry" - }, - { - "object": "LayoutButton INPUT", - "reason": "full" - }, - { - "object": "LayoutFlexibleBox DIV", - "reason": "geometry" - }, - { - "object": "LayoutBlockFlow (positioned) DIV id='thumb'", - "reason": "full" - }, - { - "object": "LayoutBlockFlow (positioned) DIV", - "reason": "appeared" - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint.html b/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint.html deleted file mode 100644 index a8dd824..0000000 --- a/third_party/WebKit/LayoutTests/paint/invalidation/video-unmute-repaint.html +++ /dev/null
@@ -1,29 +0,0 @@ -<!DOCTYPE html> -<title>Test for crbug.com/190880</title> -<script src="../../resources/run-after-layout-and-paint.js"></script> -<script src="resources/text-based-repaint.js"></script> -<style> - video { width: 700px; } -</style> - -<video id="v" controls autoload src="../../media/content/test.ogv"> -</video> - -<p>This tests that we repaint the mute button when we change the volume</p> - -<script> - window.testIsAsync = true; - - var video = document.getElementById("v"); - video.addEventListener("canplaythrough", runTest, true); - function repaintTest() { - video.volume = 0.5; - // Volume change is handled in another document cycle. - runAfterLayoutAndPaint(finishRepaintTest); - } - - function runTest() { - video.volume = 0; - runRepaintTest(); - } -</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short-expected.txt deleted file mode 100644 index c504f44..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Test that player will jump to the end if less than 10 seconds remaining. assert_not_equals: got disallowed value 57 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https-expected.txt deleted file mode 100644 index 5b21388..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Post an extendable message from a top-level client assert_equals: event `source` property `focused` expected true but got false -PASS Post an extendable message from a nested client -PASS Post loopback extendable messages -PASS Post extendable messages among service workers -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-003-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-003-expected.txt deleted file mode 100644 index 9fdd8358..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-003-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL A_05_03_03_T01 assert_true: Event listener was not invoked expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/background-fetch/interfaces.worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/background-fetch/interfaces.worker-expected.txt deleted file mode 100644 index 2faa453..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/background-fetch/interfaces.worker-expected.txt +++ /dev/null
@@ -1,74 +0,0 @@ -This is a testharness.js-based test. -Found 70 tests; 53 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS Exposed interfaces in a Service Worker. -FAIL ServiceWorkerRegistration interface: existence and properties of interface object assert_false: expected false got true -PASS ServiceWorkerGlobalScope interface: existence and properties of interface object -PASS ExtendableEvent interface: existence and properties of interface object -PASS BackgroundFetchManager interface: existence and properties of interface object -PASS BackgroundFetchManager interface object length -PASS BackgroundFetchManager interface object name -PASS BackgroundFetchManager interface: existence and properties of interface prototype object -PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property -PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property -PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) -PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager -PASS BackgroundFetchManager interface: operation get(DOMString) -PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager -PASS BackgroundFetchManager interface: operation getIds() -PASS Unscopable handled correctly for getIds() on BackgroundFetchManager -PASS BackgroundFetchRegistration interface: existence and properties of interface object -PASS BackgroundFetchRegistration interface object length -PASS BackgroundFetchRegistration interface object name -PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object -PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property -PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property -PASS BackgroundFetchRegistration interface: attribute id -PASS Unscopable handled correctly for id property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute uploadTotal -PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute uploaded -PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute downloadTotal -PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute downloaded -PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration -FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false -PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute onprogress -PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: operation abort() -PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration -PASS BackgroundFetchFetch interface: existence and properties of interface object -PASS BackgroundFetchFetch interface object length -PASS BackgroundFetchFetch interface object name -PASS BackgroundFetchFetch interface: existence and properties of interface prototype object -PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property -PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property -PASS BackgroundFetchFetch interface: attribute request -PASS Unscopable handled correctly for request property on BackgroundFetchFetch -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -PASS Unscopable handled correctly for match(RequestInfo) on BackgroundFetchActiveFetches -FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch -PASS BackgroundFetchEvent interface: existence and properties of interface object -PASS BackgroundFetchSettledEvent interface: existence and properties of interface object -PASS BackgroundFetchSettledFetches interface: existence and properties of interface object -PASS BackgroundFetchSettledFetch interface: existence and properties of interface object -PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object -PASS BackgroundFetchClickEvent interface: existence and properties of interface object -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/compat/interfaces.any-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/compat/interfaces.any-expected.txt new file mode 100644 index 0000000..9a4306b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/compat/interfaces.any-expected.txt
@@ -0,0 +1,10 @@ +This is a testharness.js-based test. +PASS compat interfaces. +FAIL Window interface: attribute orientation assert_true: The prototype object must have a property "orientation" expected true got false +PASS Unscopable handled correctly for orientation property on Window +FAIL Window interface: attribute onorientationchange assert_true: The prototype object must have a property "onorientationchange" expected true got false +PASS Unscopable handled correctly for onorientationchange property on Window +FAIL HTMLBodyElement interface: attribute onorientationchange assert_true: The prototype object must have a property "onorientationchange" expected true got false +PASS Unscopable handled correctly for onorientationchange property on HTMLBodyElement +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/block/basic/014-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/layout_ng/fast/block/basic/014-expected.png similarity index 100% rename from third_party/WebKit/LayoutTests/virtual/layout_ng/fast/block/basic/014-expected.png rename to third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/layout_ng/fast/block/basic/014-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png similarity index 100% rename from third_party/WebKit/LayoutTests/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png rename to third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https-expected.txt deleted file mode 100644 index 5b21388..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/external/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Post an extendable message from a top-level client assert_equals: event `source` property `focused` expected true but got false -PASS Post an extendable message from a nested client -PASS Post loopback extendable messages -PASS Post extendable messages among service workers -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/background-fetch/interfaces.worker-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/background-fetch/interfaces.worker-expected.txt deleted file mode 100644 index 2faa453..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/background-fetch/interfaces.worker-expected.txt +++ /dev/null
@@ -1,74 +0,0 @@ -This is a testharness.js-based test. -Found 70 tests; 53 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS Exposed interfaces in a Service Worker. -FAIL ServiceWorkerRegistration interface: existence and properties of interface object assert_false: expected false got true -PASS ServiceWorkerGlobalScope interface: existence and properties of interface object -PASS ExtendableEvent interface: existence and properties of interface object -PASS BackgroundFetchManager interface: existence and properties of interface object -PASS BackgroundFetchManager interface object length -PASS BackgroundFetchManager interface object name -PASS BackgroundFetchManager interface: existence and properties of interface prototype object -PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property -PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property -PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) -PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager -PASS BackgroundFetchManager interface: operation get(DOMString) -PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager -PASS BackgroundFetchManager interface: operation getIds() -PASS Unscopable handled correctly for getIds() on BackgroundFetchManager -PASS BackgroundFetchRegistration interface: existence and properties of interface object -PASS BackgroundFetchRegistration interface object length -PASS BackgroundFetchRegistration interface object name -PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object -PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property -PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property -PASS BackgroundFetchRegistration interface: attribute id -PASS Unscopable handled correctly for id property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute uploadTotal -PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute uploaded -PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute downloadTotal -PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute downloaded -PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration -FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false -PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: attribute onprogress -PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration -PASS BackgroundFetchRegistration interface: operation abort() -PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration -PASS BackgroundFetchFetch interface: existence and properties of interface object -PASS BackgroundFetchFetch interface object length -PASS BackgroundFetchFetch interface object name -PASS BackgroundFetchFetch interface: existence and properties of interface prototype object -PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property -PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property -PASS BackgroundFetchFetch interface: attribute request -PASS Unscopable handled correctly for request property on BackgroundFetchFetch -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -PASS Unscopable handled correctly for match(RequestInfo) on BackgroundFetchActiveFetches -FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing -PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing -PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch -PASS BackgroundFetchEvent interface: existence and properties of interface object -PASS BackgroundFetchSettledEvent interface: existence and properties of interface object -PASS BackgroundFetchSettledFetches interface: existence and properties of interface object -PASS BackgroundFetchSettledFetch interface: existence and properties of interface object -PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object -PASS BackgroundFetchClickEvent interface: existence and properties of interface object -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/compat/interfaces.any-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/compat/interfaces.any-expected.txt new file mode 100644 index 0000000..9a4306b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/compat/interfaces.any-expected.txt
@@ -0,0 +1,10 @@ +This is a testharness.js-based test. +PASS compat interfaces. +FAIL Window interface: attribute orientation assert_true: The prototype object must have a property "orientation" expected true got false +PASS Unscopable handled correctly for orientation property on Window +FAIL Window interface: attribute onorientationchange assert_true: The prototype object must have a property "onorientationchange" expected true got false +PASS Unscopable handled correctly for onorientationchange property on Window +FAIL HTMLBodyElement interface: attribute onorientationchange assert_true: The prototype object must have a property "onorientationchange" expected true got false +PASS Unscopable handled correctly for onorientationchange property on HTMLBodyElement +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-zero-length-lineCap-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-zero-length-lineCap-expected.png similarity index 100% rename from third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-zero-length-lineCap-expected.png rename to third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-zero-length-lineCap-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/layout_ng/fast/block/basic/014-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/layout_ng/fast/block/basic/014-expected.png deleted file mode 100644 index 35e0149..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/layout_ng/fast/block/basic/014-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png deleted file mode 100644 index 1b2aff88..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short-expected.txt deleted file mode 100644 index c504f44..0000000 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Test that player will jump to the end if less than 10 seconds remaining. assert_not_equals: got disallowed value 57 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt deleted file mode 100644 index 65ef853f..0000000 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/http/tests/devtools/tracing/timeline-js/compile-script-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -Tests the Timeline instrumentation for CompileScript event. - -v8.compile Properties: -{ - data : { - columnNumber : 0 - lineNumber : 0 - streamed : <boolean> - url : - } - endTime : <number> - startTime : <number> - type : "v8.compile" -} -Text details for v8.compile: undefined -
diff --git a/third_party/WebKit/LayoutTests/plugins/resources/test.testnetscape b/third_party/WebKit/LayoutTests/plugins/resources/test.testnetscape deleted file mode 100644 index e69de29..0000000 --- a/third_party/WebKit/LayoutTests/plugins/resources/test.testnetscape +++ /dev/null
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index e56bd115..1f51a222 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -16,6 +16,15 @@ getter onabort method constructor setter onabort +interface AbsoluteOrientationSensor : OrientationSensor + attribute @@toStringTag + method constructor +interface Accelerometer : Sensor + attribute @@toStringTag + getter x + getter y + getter z + method constructor interface AnalyserNode : AudioNode attribute @@toStringTag getter fftSize @@ -1750,6 +1759,12 @@ attribute @@toStringTag getter gamepad method constructor +interface Gyroscope : Sensor + attribute @@toStringTag + getter x + getter y + getter z + method constructor interface HTMLAllCollection attribute @@toStringTag getter length @@ -3559,6 +3574,9 @@ method constructor method getModifierState method initKeyboardEvent +interface LinearAccelerationSensor : Accelerometer + attribute @@toStringTag + method constructor interface Location attribute @@toStringTag method constructor @@ -4147,6 +4165,11 @@ setter selected setter text setter value +interface OrientationSensor : Sensor + attribute @@toStringTag + getter quaternion + method constructor + method populateMatrix interface OscillatorNode : AudioScheduledSourceNode attribute @@toStringTag getter detune @@ -4750,6 +4773,9 @@ method pipeThrough method pipeTo method tee +interface RelativeOrientationSensor : OrientationSensor + attribute @@toStringTag + method constructor interface RemotePlayback : EventTarget attribute @@toStringTag getter onconnect @@ -5971,6 +5997,24 @@ method setBaseAndExtent method setPosition method toString +interface Sensor : EventTarget + attribute @@toStringTag + getter activated + getter hasReading + getter onactivate + getter onerror + getter onreading + getter timestamp + method constructor + method start + method stop + setter onactivate + setter onerror + setter onreading +interface SensorErrorEvent : Event + attribute @@toStringTag + getter error + method constructor interface ServiceWorker : EventTarget attribute @@toStringTag getter onerror
diff --git a/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html b/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html index 2547aaa..68545a3 100644 --- a/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html +++ b/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html
@@ -15,6 +15,7 @@ vr_test( (t) => { return navigator.getVRDisplays().then( (displays) => { let display = displays[0]; + let scale = fakeDisplay.defaultFramebufferScale; function compareEyes(actual, expected) { t.step( () => { @@ -24,8 +25,8 @@ FLOAT_EPSILON); } - assert_equals(actual.renderWidth, expected.renderWidth); - assert_equals(actual.renderHeight, expected.renderHeight); + assert_equals(actual.renderWidth, expected.renderWidth * scale); + assert_equals(actual.renderHeight, expected.renderHeight * scale); }, "Returned eye parameters match provided parameters"); }
diff --git a/third_party/WebKit/LayoutTests/vr/requestAnimationFrame_submitFrame_combinations.html b/third_party/WebKit/LayoutTests/vr/requestAnimationFrame_submitFrame_combinations.html index 66fb082..c629d03 100644 --- a/third_party/WebKit/LayoutTests/vr/requestAnimationFrame_submitFrame_combinations.html +++ b/third_party/WebKit/LayoutTests/vr/requestAnimationFrame_submitFrame_combinations.html
@@ -10,7 +10,7 @@ <script> let fakeDisplays = fakeVRDisplays(); -vr_test( (t) => { +vr_test( (t, mock_service) => { return navigator.getVRDisplays().then( (displays) => { let display = displays[0]; @@ -33,31 +33,51 @@ } } + function getSubmitFrameCount() { + return mock_service.mockVRDisplays_[0].getSubmitFrameCount(); + } + + function getMissingFrameCount() { + return mock_service.mockVRDisplays_[0].getMissingFrameCount(); + } + function onFrame1() { + assert_equals(getSubmitFrameCount(), 0); + assert_equals(getMissingFrameCount(), 0); // case (b): submit frame first, then rAF display.submitFrame(); display.requestAnimationFrame(onFrame2); } function onFrame2() { + assert_equals(getSubmitFrameCount(), 1); + assert_equals(getMissingFrameCount(), 0); // case (c): rAF first, then submit frame display.requestAnimationFrame(onFrame3); display.submitFrame(); } function onFrame3(time) { + assert_equals(getSubmitFrameCount(), 2); + assert_equals(getMissingFrameCount(), 0); // case (d): don't submit a frame. display.requestAnimationFrame(onFrame4); } function onFrame4(time) { // If we get here, we're done. + assert_equals(getSubmitFrameCount(), 2); + assert_equals(getMissingFrameCount(), 1); t.done(); } function startPresentation() { + assert_equals(getSubmitFrameCount(), 0); + assert_equals(getMissingFrameCount(), 0); display.requestPresent([{ source : webglCanvas }]).then( () => { t.step( () => { + assert_equals(getSubmitFrameCount(), 0); + assert_equals(getMissingFrameCount(), 0); // case (a): in requestPresent promise, outside animating context. assert_true(display.isPresenting); display.requestAnimationFrame(onFrame1);
diff --git a/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js b/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js index c65733a..63bd606 100644 --- a/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js +++ b/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js
@@ -40,6 +40,7 @@ stageParameters : null, leftEye : null, rightEye : null, + defaultFramebufferScale: 1.0, }, FakeRoomScale: { @@ -60,6 +61,7 @@ }, leftEye : generic_left_eye, rightEye : generic_right_eye, + defaultFramebufferScale: 1.0, }, Pixel: { // Pixel info as of Dec. 22 2016 @@ -79,8 +81,8 @@ rightDegrees : 50.899, }, offset : [-0.032, 0, 0], - renderWidth : 960, - renderHeight : 1080 + renderWidth : 1920, + renderHeight : 2160 }, rightEye : { fieldOfView : { @@ -90,9 +92,10 @@ rightDegrees: 35.197 }, offset : [0.032, 0, 0], - renderWidth : 960, - renderHeight : 1080 - } + renderWidth : 1920, + renderHeight : 2160 + }, + defaultFramebufferScale: 0.5, } // TODO(bsheedy) add more displays like Rift/Vive };
diff --git a/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js b/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js index 1c6d124c..14d965c 100644 --- a/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js +++ b/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js
@@ -43,6 +43,10 @@ return this.presentation_provider_.submit_frame_count_; } + getMissingFrameCount() { + return this.presentation_provider_.missing_frame_count_; + } + forceActivate(reason) { this.displayClient_.onActivate(reason); } @@ -69,6 +73,7 @@ this.binding_ = new mojo.Binding(device.mojom.VRPresentationProvider, this); this.pose_ = null; this.submit_frame_count_ = 0; + this.missing_frame_count_ = 0; } bind(client, request) { @@ -77,6 +82,10 @@ this.binding_.bind(request); } + submitFrameMissing(frameId, syncToken) { + this.missing_frame_count_++; + } + submitFrame(frameId, mailboxHolder, timeWaited) { this.submit_frame_count_++;
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt index 81b9e3ba..5c65b298 100644 --- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -381,7 +381,6 @@ property onafterprint property onbeforeprint property onbeforeunload - property onfreeze property onhashchange property onlanguagechange property onmessage @@ -392,7 +391,6 @@ property onpageshow property onpopstate property onrejectionhandled - property onresume property onstorage property onunhandledrejection property onunload @@ -534,7 +532,6 @@ property onafterprint property onbeforeprint property onbeforeunload - property onfreeze property onhashchange property onlanguagechange property onmessage @@ -545,7 +542,6 @@ property onpageshow property onpopstate property onrejectionhandled - property onresume property onstorage property onunhandledrejection property onunload
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index bce2a68f..f69142b 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1517,6 +1517,7 @@ getter onerror getter onfocus getter onformdata + getter onfreeze getter onfullscreenchange getter onfullscreenerror getter ongotpointercapture @@ -1557,6 +1558,7 @@ getter onreadystatechange getter onreset getter onresize + getter onresume getter onscroll getter onsearch getter onsecuritypolicyviolation @@ -1704,6 +1706,7 @@ setter onerror setter onfocus setter onformdata + setter onfreeze setter onfullscreenchange setter onfullscreenerror setter ongotpointercapture @@ -1744,6 +1747,7 @@ setter onreadystatechange setter onreset setter onresize + setter onresume setter onscroll setter onsearch setter onsecuritypolicyviolation @@ -2270,7 +2274,6 @@ getter onblur getter onerror getter onfocus - getter onfreeze getter onhashchange getter onlanguagechange getter onload @@ -2283,7 +2286,6 @@ getter onpopstate getter onrejectionhandled getter onresize - getter onresume getter onscroll getter onstorage getter onunhandledrejection @@ -2301,7 +2303,6 @@ setter onblur setter onerror setter onfocus - setter onfreeze setter onhashchange setter onlanguagechange setter onload @@ -2314,7 +2315,6 @@ setter onpopstate setter onrejectionhandled setter onresize - setter onresume setter onscroll setter onstorage setter onunhandledrejection @@ -2719,7 +2719,6 @@ getter onblur getter onerror getter onfocus - getter onfreeze getter onhashchange getter onlanguagechange getter onload @@ -2732,7 +2731,6 @@ getter onpopstate getter onrejectionhandled getter onresize - getter onresume getter onscroll getter onstorage getter onunhandledrejection @@ -2746,7 +2744,6 @@ setter onblur setter onerror setter onfocus - setter onfreeze setter onhashchange setter onlanguagechange setter onload @@ -2759,7 +2756,6 @@ setter onpopstate setter onrejectionhandled setter onresize - setter onresume setter onscroll setter onstorage setter onunhandledrejection @@ -9336,7 +9332,6 @@ getter onerror getter onfocus getter onformdata - getter onfreeze getter ongotpointercapture getter onhashchange getter oninput @@ -9381,7 +9376,6 @@ getter onrejectionhandled getter onreset getter onresize - getter onresume getter onscroll getter onsearch getter onseeked @@ -9522,7 +9516,6 @@ setter onerror setter onfocus setter onformdata - setter onfreeze setter ongotpointercapture setter onhashchange setter oninput @@ -9567,7 +9560,6 @@ setter onrejectionhandled setter onreset setter onresize - setter onresume setter onscroll setter onsearch setter onseeked
diff --git a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js index f36ebf3..c02811b 100644 --- a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js +++ b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js
@@ -36,6 +36,11 @@ return mockVRService.mockVRDisplays_[0].getSubmitFrameCount(); } +// Returns the missing (not submitted) frame count for the first display +function getMissingFrameCount() { + return mockVRService.mockVRDisplays_[0].getMissingFrameCount(); +} + function addInputSource(input_source) { return mockVRService.mockVRDisplays_[0].addInputSource(input_source); } @@ -81,6 +86,7 @@ stageParameters: null, leftEye: null, rightEye: null, + defaultFramebufferScale: 1.0, }, FakeRoomScale: { @@ -101,6 +107,7 @@ }, leftEye: generic_left_eye, rightEye: generic_right_eye, + defaultFramebufferScale: 1.0, }, FakeGooglePixelPhone: { @@ -121,8 +128,8 @@ rightDegrees: 50.899, }, offset: [-0.032, 0, 0], - renderWidth: 960, - renderHeight: 1080 + renderWidth: 1920, + renderHeight: 2160 }, rightEye: { fieldOfView: { @@ -132,9 +139,10 @@ rightDegrees: 35.197 }, offset: [0.032, 0, 0], - renderWidth: 960, - renderHeight: 1080 - } + renderWidth: 1920, + renderHeight: 2160 + }, + defaultFramebufferScale: 0.5, } }; } @@ -293,6 +301,10 @@ return this.presentation_provider_.submit_frame_count_; } + getMissingFrameCount() { + return this.presentation_provider_.missing_frame_count_; + } + forceActivate(reason) { this.displayClient_.onActivate(reason); } @@ -329,6 +341,7 @@ this.pose_ = null; this.next_frame_id_ = 0; this.submit_frame_count_ = 0; + this.missing_frame_count_ = 0; this.input_sources_ = []; this.next_input_source_index_ = 1; @@ -340,6 +353,10 @@ this.binding_.bind(request); } + submitFrameMissing(frameId, mailboxHolder, timeWaited) { + this.missing_frame_count_++; + } + submitFrame(frameId, mailboxHolder, timeWaited) { this.submit_frame_count_++;
diff --git a/third_party/WebKit/LayoutTests/xr/xrWebGLLayer_dirty_framebuffer.html b/third_party/WebKit/LayoutTests/xr/xrWebGLLayer_dirty_framebuffer.html index e33d436..018e9c3 100644 --- a/third_party/WebKit/LayoutTests/xr/xrWebGLLayer_dirty_framebuffer.html +++ b/third_party/WebKit/LayoutTests/xr/xrWebGLLayer_dirty_framebuffer.html
@@ -17,6 +17,8 @@ session.baseLayer = webglLayer; function onSkipFrame(time, xrFrame) { + assert_equals(getSubmitFrameCount(), 0); + assert_equals(getMissingFrameCount(), 0); // No GL commands issued. session.requestAnimationFrame(onDrawToCanvas); } @@ -24,15 +26,17 @@ function onDrawToCanvas(time, xrFrame) { // Ensure the previous step did not submit a frame. assert_equals(getSubmitFrameCount(), 0); + assert_equals(getMissingFrameCount(), 1); - // Clear the canvas. + // Clear the canvas, but don't touch the framebuffer. gl.clear(gl.COLOR_BUFFER_BIT); session.requestAnimationFrame(onDrawToFramebuffer); } function onDrawToFramebuffer(time, xrFrame) { - // Ensure the previous step did not submit a frame. + // Ensure both previous steps did not submit frames. assert_equals(getSubmitFrameCount(), 0); + assert_equals(getMissingFrameCount(), 2); // Clear the VRWebGLLayer framebuffer. gl.bindFramebuffer(gl.FRAMEBUFFER, webglLayer.framebuffer); @@ -41,6 +45,7 @@ // After the function returns ensure the frame was submitted. window.setTimeout(() => { assert_equals(getSubmitFrameCount(), 1); + assert_equals(getMissingFrameCount(), 2); // Finished test. resolve(); }, 100);
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueThreadedTest.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueThreadedTest.cpp index 6df66ef..0b7808b 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueThreadedTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueThreadedTest.cpp
@@ -26,7 +26,7 @@ WorkerReportingProxy proxy; WorkerThreadForTest worker_thread(nullptr, proxy); ParentFrameTaskRunners* parent_frame_task_runners = - ParentFrameTaskRunners::Create(scope.GetFrame()); + ParentFrameTaskRunners::Create(&scope.GetDocument()); worker_thread.StartWithSourceCode(scope.GetDocument().GetSecurityOrigin(), "/* no worker script */", parent_frame_task_runners);
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index cdf5de27..7447ddb 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -299,10 +299,12 @@ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(freeze); DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange); DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror); DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(resume); DEFINE_ATTRIBUTE_EVENT_LISTENER(search); DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation); DEFINE_ATTRIBUTE_EVENT_LISTENER(selectionchange);
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl index 471ba07..5ceccd3 100644 --- a/third_party/WebKit/Source/core/dom/Document.idl +++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -229,7 +229,9 @@ attribute EventHandler onbeforepaste; attribute EventHandler oncopy; attribute EventHandler oncut; + [RuntimeEnabled=PageLifecycle] attribute EventHandler onfreeze; attribute EventHandler onpaste; + [RuntimeEnabled=PageLifecycle] attribute EventHandler onresume; attribute EventHandler onsearch; [RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] attribute EventHandler onsecuritypolicyviolation; attribute EventHandler onselectionchange;
diff --git a/third_party/WebKit/Source/core/editing/InlineBoxPosition.cpp b/third_party/WebKit/Source/core/editing/InlineBoxPosition.cpp index f20216d..3db0b20e 100644 --- a/third_party/WebKit/Source/core/editing/InlineBoxPosition.cpp +++ b/third_party/WebKit/Source/core/editing/InlineBoxPosition.cpp
@@ -189,7 +189,7 @@ } if (prev_box->BidiLevel() <= level) - return InlineBoxPosition(inline_box, caret_offset); + return InlineBoxPosition(inline_box, inline_box->CaretLeftmostOffset()); // Right edge of a "tertiary" run. Set to the left edge of that run. InlineBox* const result_box = InlineBoxTraversal::FindLeftBoundaryOfBidiRunIgnoringLineBreak( @@ -208,7 +208,7 @@ } if (next_box->BidiLevel() <= level) - return InlineBoxPosition(inline_box, caret_offset); + return InlineBoxPosition(inline_box, inline_box->CaretRightmostOffset()); // Left edge of a "tertiary" run. Set to the right edge of that run. InlineBox* const result_box =
diff --git a/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp b/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp index 42c5aa5..c7130102 100644 --- a/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp +++ b/third_party/WebKit/Source/core/editing/RenderedPositionTest.cpp
@@ -32,19 +32,19 @@ LoadAhem(); } - void FocusAndSelectAll() { - HTMLInputElement* target = - ToHTMLInputElement(GetDocument().getElementById("target")); - DCHECK(target); - target->focus(); + void FocusAndSelectAll(Element* focus, const Node& select) { + DCHECK(focus); + focus->focus(); Selection().SetSelection( - SelectionInDOMTree::Builder() - .SelectAllChildren(*target->InnerEditorElement()) - .Build(), + SelectionInDOMTree::Builder().SelectAllChildren(select).Build(), SetSelectionOptions::Builder().SetShouldShowHandle(true).Build()); UpdateAllLifecyclePhases(); } + void FocusAndSelectAll(TextControlElement* target) { + FocusAndSelectAll(target, *target->InnerEditorElement()); + } + private: UseMockScrollbarSettings mock_scrollbars_; }; @@ -63,7 +63,7 @@ style='width: 100px; height: 20px;'> )HTML"); - FocusAndSelectAll(); + FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target"))); const CompositedSelection& composited_selection = RenderedPosition::ComputeCompositedSelection(Selection()); @@ -94,7 +94,7 @@ <input id=target width=20 value='test test test test test tes tes test'> )HTML"); - FocusAndSelectAll(); + FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target"))); ScrollableArea* root_scroller = GetDocument().View()->GetScrollableArea(); root_scroller->SetScrollOffset(ScrollOffset(800, 500), kProgrammaticScroll); @@ -158,7 +158,7 @@ </div> )HTML"); - FocusAndSelectAll(); + FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target"))); Element* e = GetDocument().getElementById("scroller"); PaintLayerScrollableArea* scroller = @@ -182,39 +182,13 @@ composited_selection.end.edge_bottom_in_layer); } -// TODO(yoichio): These helper static functions are introduced to avoid -// conflicting while merging this change into M66. -// Refactor them into RenderedPositionTest member. -namespace rendered_position_test { -static void SetUpinternal(RenderedPositionTest* test) { - // Enable compositing. - test->GetPage().GetSettings().SetAcceleratedCompositingEnabled(true); - test->GetDocument().View()->SetParentVisible(true); - test->GetDocument().View()->SetSelfVisible(true); - test->GetDocument().View()->UpdateAllLifecyclePhases(); -} - -static void FocusAndSelect(RenderedPositionTest* test, - Element* focus, - const Node& select) { - DCHECK(focus); - focus->focus(); - test->Selection().SetSelection( - SelectionInDOMTree::Builder().SelectAllChildren(select).Build(), - SetSelectionOptions::Builder().SetShouldShowHandle(true).Build()); - test->UpdateAllLifecyclePhases(); -} -} // namespace rendered_position_test - // crbug.com/807930 TEST_P(RenderedPositionTest, ContentEditableLinebreak) { - rendered_position_test::SetUpinternal(this); - LoadAhem(); SetBodyContent( "<div style='font: 10px/10px Ahem;' contenteditable>" "test<br><br></div>"); Element* target = GetDocument().QuerySelector("div"); - rendered_position_test::FocusAndSelect(this, target, *target); + FocusAndSelectAll(target, *target); const CompositedSelection& composited_selection = RenderedPosition::ComputeCompositedSelection(Selection()); EXPECT_EQ(composited_selection.start.edge_top_in_layer, @@ -229,15 +203,10 @@ // crbug.com/807930 TEST_P(RenderedPositionTest, TextAreaLinebreak) { - rendered_position_test::SetUpinternal(this); - LoadAhem(); SetBodyContent( "<textarea style='font: 10px/10px Ahem;'>" "test\n</textarea>"); - TextControlElement* target = - ToTextControl(GetDocument().QuerySelector("textarea")); - rendered_position_test::FocusAndSelect(this, target, - *target->InnerEditorElement()); + FocusAndSelectAll(ToTextControl(GetDocument().QuerySelector("textarea"))); const CompositedSelection& composited_selection = RenderedPosition::ComputeCompositedSelection(Selection()); EXPECT_EQ(composited_selection.start.edge_top_in_layer,
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp index 2b1894b82..033cac21 100644 --- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -343,6 +343,20 @@ return node_count; } + static void GetElementAndCaretBonundsForFocusedEditableElement( + FrameTestHelpers::WebViewHelper& helper, + IntRect& element_bounds, + IntRect& caret_bounds) { + Element* element = helper.GetWebView()->FocusedElement(); + WebRect caret_in_viewport, unused; + helper.GetWebView()->SelectionBounds(caret_in_viewport, unused); + caret_bounds = + helper.GetWebView()->GetPage()->GetVisualViewport().ViewportToRootFrame( + caret_in_viewport); + element_bounds = element->GetDocument().View()->AbsoluteToRootFrame( + PixelSnappedIntRect(element->Node::BoundingBox())); + } + std::string base_url_; std::string not_base_url_; std::string chrome_url_; @@ -4093,7 +4107,10 @@ // Focus the first textbox that's in a touch-action: pan-x ancestor, this // shouldn't cause an autozoom since pan-x disables pinch-zoom. web_view_helper.GetWebView()->AdvanceFocus(false); - web_view_helper.GetWebView()->ScrollFocusedEditableElementIntoView(); + web_view_helper.GetWebView() + ->MainFrameImpl() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); EXPECT_EQ( web_view_helper.GetWebView()->FakePageScaleAnimationPageScaleForTesting(), 0); @@ -4105,7 +4122,10 @@ // Focus the second textbox that's in a touch-action: manipulation ancestor, // this should cause an autozoom since it allows pinch-zoom. web_view_helper.GetWebView()->AdvanceFocus(false); - web_view_helper.GetWebView()->ScrollFocusedEditableElementIntoView(); + web_view_helper.GetWebView() + ->MainFrameImpl() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); EXPECT_GT( web_view_helper.GetWebView()->FakePageScaleAnimationPageScaleForTesting(), initial_scale); @@ -4118,7 +4138,10 @@ // should cause an autozoom since it's seperated from the node with the // touch-action by an overflow:scroll element. web_view_helper.GetWebView()->AdvanceFocus(false); - web_view_helper.GetWebView()->ScrollFocusedEditableElementIntoView(); + web_view_helper.GetWebView() + ->MainFrameImpl() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); EXPECT_GT( web_view_helper.GetWebView()->FakePageScaleAnimationPageScaleForTesting(), initial_scale); @@ -4170,9 +4193,12 @@ float scale; IntPoint scroll; bool need_animation; - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + IntRect element_bounds, caret_bounds; + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); EXPECT_TRUE(need_animation); // The edit box should be left aligned with a margin for possible label. int h_scroll = edit_box_with_text.x - left_box_ratio * viewport_width / scale; @@ -4188,9 +4214,11 @@ web_view_helper.Resize(WebSize(viewport_width, viewport_height)); SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0), initial_scale); - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); EXPECT_TRUE(need_animation); // The caret should be right aligned since the caret would be offscreen when // the edit box is left aligned. @@ -4202,9 +4230,11 @@ initial_scale); // Move focus to edit box with text. web_view_helper.GetWebView()->AdvanceFocus(false); - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); EXPECT_TRUE(need_animation); // The edit box should be left aligned. h_scroll = edit_box_with_no_text.x; @@ -4222,9 +4252,11 @@ within_tolerance_scale); // Move focus back to the second edit box. web_view_helper.GetWebView()->AdvanceFocus(false); - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); // The scale should not be adjusted as the zoomed out scale was sufficiently // close to the previously focused scale. EXPECT_FALSE(need_animation); @@ -4269,9 +4301,12 @@ float scale; IntPoint scroll; bool need_animation; - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + IntRect element_bounds, caret_bounds; + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); EXPECT_TRUE(need_animation); // Edit box and caret should be left alinged int h_scroll = edit_box_with_text.x; @@ -4287,9 +4322,11 @@ h_scroll = 200; SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(h_scroll, 0), new_scale); - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); EXPECT_TRUE(need_animation); // Horizontal scroll have to be the same EXPECT_NEAR(h_scroll, scroll.X(), 1); @@ -4343,9 +4380,12 @@ float scale; IntPoint scroll; bool need_animation; - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + IntRect element_bounds, caret_bounds; + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); // There should be no change in page scale. EXPECT_EQ(initial_scale, scale); @@ -4364,9 +4404,11 @@ web_view_helper.GetWebView()->AdvanceFocus(true); WebRect rect, caret; web_view_helper.GetWebView()->SelectionBounds(caret, rect); - web_view_helper.GetWebView()->ComputeScaleAndScrollForFocusedNode( - web_view_helper.GetWebView()->FocusedElement(), kAutoZoomToLegibleScale, - scale, scroll, need_animation); + GetElementAndCaretBonundsForFocusedEditableElement( + web_view_helper, element_bounds, caret_bounds); + web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects( + element_bounds, caret_bounds, kAutoZoomToLegibleScale, scale, scroll, + need_animation); // There should be no change at all since the textbox is fully visible // already. @@ -11748,7 +11790,10 @@ ASSERT_EQ(FloatPoint(), visual_viewport.VisibleRectInDocument().Location()); - WebView().ScrollFocusedEditableElementIntoView(); + WebView() + .MainFrameImpl() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); EXPECT_EQ(1, WebView().FakePageScaleAnimationPageScaleForTesting()); @@ -11762,7 +11807,10 @@ WebView().EnableFakePageScaleAnimationForTesting(true); // This input is already in view, this shouldn't cause a scroll. - WebView().ScrollFocusedEditableElementIntoView(); + WebView() + .MainFrameImpl() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); EXPECT_EQ(0, WebView().FakePageScaleAnimationPageScaleForTesting()); EXPECT_EQ(IntPoint(), @@ -11773,7 +11821,10 @@ WebView().ResizeVisualViewport(IntSize(200, 100)); ASSERT_FALSE(visual_viewport.VisibleRectInDocument().Contains(inputRect)); - WebView().ScrollFocusedEditableElementIntoView(); + WebView() + .MainFrameImpl() + ->FrameWidget() + ->ScrollFocusedEditableElementIntoView(); frame_view->GetScrollableArea()->SetScrollOffset( ToFloatSize(WebView().FakePageScaleAnimationTargetPositionForTesting()), kProgrammaticScroll);
diff --git a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp index b0836050..8dc6ce5 100644 --- a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp
@@ -41,6 +41,15 @@ namespace blink { +namespace { +FloatRect DeNormalizeRect(const WebFloatRect& normalized, const IntRect& base) { + FloatRect result = normalized; + result.Scale(base.Width(), base.Height()); + result.MoveBy(base.Location()); + return result; +} +} // namespace + WebRemoteFrame* WebRemoteFrame::Create(WebTreeScopeType scope, WebRemoteFrameClient* client) { return WebRemoteFrameImpl::Create(scope, client); @@ -344,12 +353,33 @@ } // Schedule the scroll. - LayoutRect new_rect_to_scroll = EnclosingLayoutRect( + LayoutRect absolute_rect = EnclosingLayoutRect( owner_object ->LocalToAncestorQuad(FloatRect(rect_to_scroll), owner_object->View(), - kUseTransforms | kTraverseDocumentBoundaries) + kUseTransforms) .BoundingBox()); - owner_object->ScrollRectToVisible(new_rect_to_scroll, params); + + if (!params.zoom_into_rect || + !owner_object->GetDocument().GetFrame()->LocalFrameRoot().IsMainFrame()) { + owner_object->ScrollRectToVisible(absolute_rect, params); + return; + } + + // This is due to something such as scroll focused editable element into + // view on Android which also requires an automatic zoom into legible scale. + // This is handled by main frame's WebView. + WebViewImpl* view_impl = static_cast<WebViewImpl*>(View()); + IntRect rect_in_document = + view_impl->MainFrameImpl()->GetFrame()->View()->RootFrameToDocument( + EnclosingIntRect( + owner_element->GetDocument().View()->AbsoluteToRootFrame( + absolute_rect))); + IntRect element_bounds_in_document = EnclosingIntRect( + DeNormalizeRect(params.relative_element_bounds, rect_in_document)); + IntRect caret_bounds_in_document = EnclosingIntRect( + DeNormalizeRect(params.relative_caret_bounds, rect_in_document)); + view_impl->ZoomAndScrollToFocusedEditableElementRect( + element_bounds_in_document, caret_bounds_in_document, true); } void WebRemoteFrameImpl::IntrinsicSizingInfoChanged(
diff --git a/third_party/WebKit/Source/core/exported/WebViewImpl.cpp b/third_party/WebKit/Source/core/exported/WebViewImpl.cpp index 861b85b..24e9c8b 100644 --- a/third_party/WebKit/Source/core/exported/WebViewImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
@@ -27,7 +27,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "core/exported/WebViewImpl.h" #include <algorithm> @@ -2397,59 +2396,64 @@ } bool WebViewImpl::ScrollFocusedEditableElementIntoView() { - Frame* frame = GetPage()->MainFrame(); - if (!frame) + DCHECK(MainFrameImpl()); + LocalFrameView* main_frame_view = MainFrameImpl()->GetFrame()->View(); + if (!main_frame_view) return false; Element* element = FocusedElement(); if (!element || !IsElementEditable(element)) return false; - if (frame->IsRemoteFrame()) { - // The rest of the logic here is not implemented for OOPIFs. For now instead - // of implementing the logic below (which involves finding the scale and - // scrolling point), editable elements inside OOPIFs are scrolled into view - // instead. However, a common logic should be implemented for both OOPIFs - // and in-process frames to assure a consistent behavior across all frame - // types (https://crbug.com/784982). - LayoutObject* layout_object = element->GetLayoutObject(); - if (!layout_object) - return false; - layout_object->ScrollRectToVisible(element->BoundingBoxForScrollIntoView(), - WebScrollIntoViewParams()); - return true; - } - - if (!frame->View()) - return false; - element->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - bool zoom_in_to_legible_scale = + ZoomAndScrollToFocusedEditableElementRect( + main_frame_view->RootFrameToDocument( + element->GetDocument().View()->AbsoluteToRootFrame( + element->GetLayoutObject()->AbsoluteBoundingBoxRect())), + main_frame_view->RootFrameToDocument( + element->GetDocument().View()->AbsoluteToRootFrame( + element->GetDocument() + .GetFrame() + ->Selection() + .AbsoluteCaretBounds())), + ShouldZoomToLegibleScale(*element)); + + return true; +} + +bool WebViewImpl::ShouldZoomToLegibleScale(const Element& element) { + bool zoom_into_legible_scale = web_settings_->AutoZoomFocusedNodeToLegibleScale() && !GetPage()->GetVisualViewport().ShouldDisableDesktopWorkarounds(); - if (zoom_in_to_legible_scale) { + if (zoom_into_legible_scale) { // When deciding whether to zoom in on a focused text box, we should // decide not to zoom in if the user won't be able to zoom out. e.g if the // textbox is within a touch-action: none container the user can't zoom // back out. - TouchAction action = TouchActionUtil::ComputeEffectiveTouchAction(*element); + TouchAction action = TouchActionUtil::ComputeEffectiveTouchAction(element); if (!(action & TouchAction::kTouchActionPinchZoom)) - zoom_in_to_legible_scale = false; + zoom_into_legible_scale = false; } + return zoom_into_legible_scale; +} + +void WebViewImpl::ZoomAndScrollToFocusedEditableElementRect( + const IntRect& element_bounds_in_document, + const IntRect& caret_bounds_in_document, + bool zoom_into_legible_scale) { float scale; IntPoint scroll; - bool need_animation; - ComputeScaleAndScrollForFocusedNode(element, zoom_in_to_legible_scale, scale, - scroll, need_animation); + bool need_animation = false; + ComputeScaleAndScrollForEditableElementRects( + element_bounds_in_document, caret_bounds_in_document, + zoom_into_legible_scale, scale, scroll, need_animation); if (need_animation) { StartPageScaleAnimation(scroll, false, scale, scrollAndScaleAnimationDurationInSeconds); } - - return true; } void WebViewImpl::SmoothScroll(int target_x, int target_y, long duration_ms) { @@ -2458,41 +2462,29 @@ (double)duration_ms / 1000); } -void WebViewImpl::ComputeScaleAndScrollForFocusedNode( - Node* focused_node, - bool zoom_in_to_legible_scale, +void WebViewImpl::ComputeScaleAndScrollForEditableElementRects( + const IntRect& element_bounds_in_document, + const IntRect& caret_bounds_in_document, + bool zoom_into_legible_scale, float& new_scale, IntPoint& new_scroll, bool& need_animation) { VisualViewport& visual_viewport = GetPage()->GetVisualViewport(); - LocalFrameView* main_frame_view = MainFrameImpl()->GetFrameView(); - WebRect caret_in_viewport, unused_end; - SelectionBounds(caret_in_viewport, unused_end); - - // 'caretInDocument' is rect encompassing the blinking cursor relative to the - // root document. - IntRect caret_in_document = main_frame_view->RootFrameToDocument( - visual_viewport.ViewportToRootFrame(caret_in_viewport)); - - LocalFrameView* textbox_view = focused_node->GetDocument().View(); - IntRect textbox_rect_in_document = - main_frame_view->RootFrameToDocument(textbox_view->AbsoluteToRootFrame( - PixelSnappedIntRect(focused_node->Node::BoundingBox()))); - - if (!zoom_in_to_legible_scale) { + if (!zoom_into_legible_scale) { new_scale = PageScaleFactor(); } else { // Pick a scale which is reasonably readable. This is the scale at which // the caret height will become minReadableCaretHeightForNode (adjusted // for dpi and font scale factor). const int min_readable_caret_height_for_node = - textbox_rect_in_document.Height() >= 2 * caret_in_document.Height() + element_bounds_in_document.Height() >= + 2 * caret_bounds_in_document.Height() ? minReadableCaretHeightForTextArea : minReadableCaretHeight; new_scale = ClampPageScaleFactorToLimits( MaximumLegiblePageScale() * min_readable_caret_height_for_node / - caret_in_document.Height()); + caret_bounds_in_document.Height()); new_scale = std::max(new_scale, PageScaleFactor()); } const float delta_scale = new_scale / PageScaleFactor(); @@ -2506,17 +2498,18 @@ new_scale = PageScaleFactor(); // If the caret is offscreen, then animate. - if (!visual_viewport.VisibleRectInDocument().Contains(caret_in_document)) + if (!visual_viewport.VisibleRectInDocument().Contains( + caret_bounds_in_document)) need_animation = true; // If the box is partially offscreen and it's possible to bring it fully // onscreen, then animate. if (visual_viewport.VisibleRect().Width() >= - textbox_rect_in_document.Width() && + element_bounds_in_document.Width() && visual_viewport.VisibleRect().Height() >= - textbox_rect_in_document.Height() && + element_bounds_in_document.Height() && !visual_viewport.VisibleRectInDocument().Contains( - textbox_rect_in_document)) + element_bounds_in_document)) need_animation = true; if (!need_animation) @@ -2525,37 +2518,37 @@ FloatSize target_viewport_size(visual_viewport.Size()); target_viewport_size.Scale(1 / new_scale); - if (textbox_rect_in_document.Width() <= target_viewport_size.Width()) { + if (element_bounds_in_document.Width() <= target_viewport_size.Width()) { // Field is narrower than screen. Try to leave padding on left so field's // label is visible, but it's more important to ensure entire field is // onscreen. int ideal_left_padding = target_viewport_size.Width() * leftBoxRatio; int max_left_padding_keeping_box_onscreen = - target_viewport_size.Width() - textbox_rect_in_document.Width(); - new_scroll.SetX(textbox_rect_in_document.X() - + target_viewport_size.Width() - element_bounds_in_document.Width(); + new_scroll.SetX(element_bounds_in_document.X() - std::min<int>(ideal_left_padding, max_left_padding_keeping_box_onscreen)); } else { // Field is wider than screen. Try to left-align field, unless caret would // be offscreen, in which case right-align the caret. - new_scroll.SetX(std::max<int>(textbox_rect_in_document.X(), - caret_in_document.X() + - caret_in_document.Width() + caretPadding - - target_viewport_size.Width())); + new_scroll.SetX(std::max<int>( + element_bounds_in_document.X(), + caret_bounds_in_document.X() + caret_bounds_in_document.Width() + + caretPadding - target_viewport_size.Width())); } - if (textbox_rect_in_document.Height() <= target_viewport_size.Height()) { + if (element_bounds_in_document.Height() <= target_viewport_size.Height()) { // Field is shorter than screen. Vertically center it. new_scroll.SetY( - textbox_rect_in_document.Y() - - (target_viewport_size.Height() - textbox_rect_in_document.Height()) / + element_bounds_in_document.Y() - + (target_viewport_size.Height() - element_bounds_in_document.Height()) / 2); } else { // Field is taller than screen. Try to top align field, unless caret would // be offscreen, in which case bottom-align the caret. - new_scroll.SetY( - std::max<int>(textbox_rect_in_document.Y(), - caret_in_document.Y() + caret_in_document.Height() + - caretPadding - target_viewport_size.Height())); + new_scroll.SetY(std::max<int>( + element_bounds_in_document.Y(), + caret_bounds_in_document.Y() + caret_bounds_in_document.Height() + + caretPadding - target_viewport_size.Height())); } }
diff --git a/third_party/WebKit/Source/core/exported/WebViewImpl.h b/third_party/WebKit/Source/core/exported/WebViewImpl.h index 7554b174..bee56d6 100644 --- a/third_party/WebKit/Source/core/exported/WebViewImpl.h +++ b/third_party/WebKit/Source/core/exported/WebViewImpl.h
@@ -172,7 +172,6 @@ void FocusDocumentView(WebFrame*) override; void SetInitialFocus(bool reverse) override; void ClearFocusedElement() override; - bool ScrollFocusedEditableElementIntoView() override; void SmoothScroll(int target_x, int target_y, long duration_ms) override; void ZoomToFindInPageRect(const WebRect&); void AdvanceFocus(bool reverse) override; @@ -370,12 +369,6 @@ void EnableTapHighlightAtPoint( const GestureEventWithHitTestResults& targeted_tap_event); void EnableTapHighlights(HeapVector<Member<Node>>&); - void ComputeScaleAndScrollForFocusedNode(Node* focused_node, - bool zoom_in_to_legible_scale, - float& scale, - IntPoint& scroll, - bool& need_animation); - void AnimateDoubleTapZoom(const IntPoint&); void ResolveTapDisambiguation(double timestamp_seconds, @@ -464,7 +457,20 @@ last_hidden_page_popup_ = page_popup; } + bool ShouldZoomToLegibleScale(const Element&); + void ZoomAndScrollToFocusedEditableElementRect( + const IntRect& element_bounds_in_document, + const IntRect& caret_bounds_in_document, + bool zoom_into_legible_scale); + private: + FRIEND_TEST_ALL_PREFIXES(ParameterizedWebFrameTest, + DivScrollIntoEditableTest); + FRIEND_TEST_ALL_PREFIXES(ParameterizedWebFrameTest, + DivScrollIntoEditablePreservePageScaleTest); + FRIEND_TEST_ALL_PREFIXES(ParameterizedWebFrameTest, + DivScrollIntoEditableTestZoomToLegibleScaleDisabled); + void SetPageScaleFactorAndLocation(float, const FloatPoint&); void PropagateZoomFactorToLocalFrameRoots(Frame*, float); @@ -552,6 +558,22 @@ base::WeakPtr<CompositorMutatorImpl> EnsureCompositorMutator( scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner); + bool ScrollFocusedEditableElementIntoView(); + // Finds the zoom and scroll parameters for zooming into an editable element + // with bounds |element_bounds_in_document| and caret bounds + // |caret_bounds_in_document|. If the original element belongs to the local + // root of MainFrameImpl(), then the bounds are exactly those of the element + // and caret. Otherwise (when the editable element is inside an OOPIF), the + // bounds are projection of the original element's bounds in the main frame + // which is inside the layout area of some remote frame in this frame tree. + void ComputeScaleAndScrollForEditableElementRects( + const IntRect& element_bounds_in_document, + const IntRect& caret_bounds_in_document, + bool zoom_into_legible_scale, + float& scale, + IntPoint& scroll, + bool& need_animation); + WebViewClient* client_; // Can be 0 (e.g. unittests, shared workers, etc.) Persistent<ChromeClient> chrome_client_;
diff --git a/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h b/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h index 444460d3..8f38e1f 100644 --- a/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h +++ b/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h
@@ -38,7 +38,6 @@ DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(afterprint); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeprint); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload); -DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(freeze); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(languagechange); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(message); @@ -49,7 +48,6 @@ DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pageshow); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(rejectionhandled); -DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(resume); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unhandledrejection); DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload);
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp index 7820504..23b9234 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -517,9 +517,9 @@ void LocalFrame::DidFreeze() { DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled()); - if (DomWindow()) { + if (GetDocument()) { const double freeze_event_start = CurrentTimeTicksInSeconds(); - DomWindow()->DispatchEvent(Event::Create(EventTypeNames::freeze)); + GetDocument()->DispatchEvent(Event::Create(EventTypeNames::freeze)); const double freeze_event_end = CurrentTimeTicksInSeconds(); DEFINE_STATIC_LOCAL( CustomCountHistogram, freeze_histogram, @@ -530,9 +530,9 @@ void LocalFrame::DidResume() { DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled()); - if (DomWindow()) { + if (GetDocument()) { const double resume_event_start = CurrentTimeTicksInSeconds(); - DomWindow()->DispatchEvent(Event::Create(EventTypeNames::resume)); + GetDocument()->DispatchEvent(Event::Create(EventTypeNames::resume)); const double resume_event_end = CurrentTimeTicksInSeconds(); DEFINE_STATIC_LOCAL( CustomCountHistogram, resume_histogram,
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index 4e6dae8..188d3ea 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -5683,6 +5683,9 @@ if (frame_view.ShouldThrottleRendering()) return; + if (!frame_view.LayoutViewportScrollableArea()) + return; + reasons |= frame_view.MainThreadScrollingReasonsPerFrame(); if (GraphicsLayer* layer_for_scrolling = ToLocalFrame(frame) .View()
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp index 049ddfd9..51bdfd38 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp
@@ -75,13 +75,30 @@ #include "platform/graphics/CompositorMutatorImpl.h" #include "platform/wtf/AutoReset.h" #include "platform/wtf/Optional.h" +#include "public/platform/WebScrollIntoViewParams.h" #include "public/web/WebAutofillClient.h" +#include "public/web/WebElement.h" #include "public/web/WebPlugin.h" #include "public/web/WebRange.h" #include "public/web/WebWidgetClient.h" #include "third_party/WebKit/public/mojom/page/page_visibility_state.mojom-blink.h" namespace blink { +namespace { +const int kCaretPadding = 10; +const float kIdealPaddingRatio = 0.3f; + +// Returns a rect which is offset and scaled accordingly to |base_rect|'s +// location and size. +FloatRect NormalizeRect(const FloatRect& to_normalize, + const FloatRect& base_rect) { + FloatRect result(to_normalize); + result.SetLocation(to_normalize.Location() + (-base_rect.Location())); + result.Scale(1.0 / base_rect.Width(), 1.0 / base_rect.Height()); + return result; +} + +} // namespace // WebFrameWidget ------------------------------------------------------------ @@ -520,6 +537,21 @@ return local_frame ? local_frame->GetInputMethodController() : nullptr; } +bool WebFrameWidgetImpl::ScrollFocusedEditableElementIntoView() { + Element* element = FocusedElement(); + if (!element || !WebElement(element).IsEditable()) + return false; + + if (!element->GetLayoutObject()) + return false; + + LayoutRect rect_to_scroll; + WebScrollIntoViewParams params; + GetScrollParamsForFocusedEditableElement(*element, rect_to_scroll, params); + element->GetLayoutObject()->ScrollRectToVisible(rect_to_scroll, params); + return true; +} + void WebFrameWidgetImpl::ScheduleAnimation() { if (layer_tree_view_) { layer_tree_view_->SetNeedsBeginFrame(); @@ -1126,4 +1158,52 @@ } } +void WebFrameWidgetImpl::GetScrollParamsForFocusedEditableElement( + const Element& element, + LayoutRect& rect_to_scroll, + WebScrollIntoViewParams& params) { + LocalFrameView& frame_view = *element.GetDocument().View(); + IntRect absolute_element_bounds = + element.GetLayoutObject()->AbsoluteBoundingBoxRect(); + IntRect absolute_caret_bounds = + element.GetDocument().GetFrame()->Selection().AbsoluteCaretBounds(); + // Ideally, the chosen rectangle includes the element box and caret bounds + // plus some margin on the left. If this does not work (i.e., does not fit + // inside the frame view), then choose a subrect which includes the caret + // bounds. It is preferrable to also include element bounds' location and left + // align the scroll. If this cant be satisfied, the scroll will be right + // aligned. + IntRect maximal_rect = + UnionRect(absolute_element_bounds, absolute_caret_bounds); + + // Set the ideal margin. + maximal_rect.ShiftXEdgeTo( + maximal_rect.X() - + static_cast<int>(kIdealPaddingRatio * absolute_element_bounds.Width())); + + bool maximal_rect_fits_in_frame = + !(frame_view.Size() - maximal_rect.Size()).IsEmpty(); + + if (!maximal_rect_fits_in_frame) { + IntRect frame_rect(maximal_rect.Location(), frame_view.Size()); + maximal_rect.Intersect(frame_rect); + IntPoint point_forced_to_be_visible = + absolute_caret_bounds.MaxXMaxYCorner() + + IntSize(kCaretPadding, kCaretPadding); + if (!maximal_rect.Contains(point_forced_to_be_visible)) { + // Move the rect towards the point until the point is barely contained. + maximal_rect.Move(point_forced_to_be_visible - + maximal_rect.MaxXMaxYCorner()); + } + } + + params.zoom_into_rect = View()->ShouldZoomToLegibleScale(element); + params.relative_element_bounds = NormalizeRect( + Intersection(absolute_element_bounds, maximal_rect), maximal_rect); + params.relative_caret_bounds = NormalizeRect( + Intersection(absolute_caret_bounds, maximal_rect), maximal_rect); + params.behavior = WebScrollIntoViewParams::kInstant; + rect_to_scroll = LayoutRect(maximal_rect); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h index e4f1d08..9665ebd 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h
@@ -119,6 +119,7 @@ void ClearBaseBackgroundColorOverride() override; void SetBaseBackgroundColor(WebColor) override; WebInputMethodController* GetActiveWebInputMethodController() const override; + bool ScrollFocusedEditableElementIntoView() override; Frame* FocusedCoreFrame() const; @@ -192,6 +193,15 @@ LocalFrame* FocusedLocalFrameAvailableForIme() const; + // Finds the parameters required for scrolling the focused editable |element| + // into view. |rect_to_scroll| is used for recursive scrolling of the element + // into view and contains all or part of element's bounding box and always + // includes the caret and is with respect to absolute coordinates. + void GetScrollParamsForFocusedEditableElement( + const Element& element, + LayoutRect& rect_to_scroll, + WebScrollIntoViewParams& params); + WebWidgetClient* client_; // WebFrameWidget is associated with a subtree of the frame tree,
diff --git a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp index d4bcccb..4aabb9d3 100644 --- a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp +++ b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp
@@ -196,6 +196,10 @@ return web_view_->GetActiveWebInputMethodController(); } +bool WebViewFrameWidget::ScrollFocusedEditableElementIntoView() { + return web_view_->ScrollFocusedEditableElementIntoView(); +} + void WebViewFrameWidget::ScheduleAnimation() { web_view_->ScheduleAnimationForWidget(); }
diff --git a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h index 94028e9f..61d5171 100644 --- a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h +++ b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h
@@ -86,6 +86,7 @@ void SetBaseBackgroundColor(WebColor) override; WebLocalFrameImpl* LocalRoot() const override; WebInputMethodController* GetActiveWebInputMethodController() const override; + bool ScrollFocusedEditableElementIntoView() override; // WebFrameWidgetBase overrides: bool ForSubframe() const override { return false; }
diff --git a/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl b/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl index a83cb64f..9bd850d0 100644 --- a/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl +++ b/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl
@@ -38,7 +38,6 @@ attribute EventHandler onbeforeprint; // FIXME: onbeforeunload should be an OnBeforeUnloadEventHandler. attribute EventHandler onbeforeunload; - [RuntimeEnabled=PageLifecycle] attribute EventHandler onfreeze; attribute EventHandler onhashchange; attribute EventHandler onlanguagechange; attribute EventHandler onmessage; @@ -49,7 +48,6 @@ attribute EventHandler onpageshow; attribute EventHandler onpopstate; attribute EventHandler onrejectionhandled; - [RuntimeEnabled=PageLifecycle] attribute EventHandler onresume; attribute EventHandler onstorage; attribute EventHandler onunhandledrejection; attribute EventHandler onunload;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp index 3e50e62..a0594c8 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
@@ -197,8 +197,7 @@ idle_task_status_ = kIdleTaskNotSupported; num_rows_completed_ = 0; if (context->IsDocument()) { - parent_frame_task_runner_ = - ParentFrameTaskRunners::Create(*ToDocument(context)->GetFrame()); + parent_frame_task_runner_ = ParentFrameTaskRunners::Create(context); } if (script_promise_resolver_) { function_type_ = kOffscreenCanvasToBlobPromise;
diff --git a/third_party/WebKit/Source/core/html/media/MediaControls.h b/third_party/WebKit/Source/core/html/media/MediaControls.h index b56d217..b3bebc88 100644 --- a/third_party/WebKit/Source/core/html/media/MediaControls.h +++ b/third_party/WebKit/Source/core/html/media/MediaControls.h
@@ -51,6 +51,9 @@ // TODO(mlamouri): required by LayoutVTTCue. virtual LayoutObject* ContainerLayoutObject() = 0; + // Used for layout tests to disable some animations. + virtual void SetTestMode(bool) = 0; + // TODO: the following are required by other parts of the media controls // implementation and could be removed when the full implementation has moved // to modules.
diff --git a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp index 3d2074f..55f4caa51 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp
@@ -74,7 +74,7 @@ BlinkLeakDetector& detector = BlinkLeakDetector::Instance(); detector.SetClient(this); - detector.PrepareForLeakDetection(frames_->Root()->Client()->GetWebFrame()); + detector.PrepareForLeakDetection(); detector.CollectGarbage(); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.h b/third_party/WebKit/Source/core/layout/LayoutImage.h index db6475a..c2609ad 100644 --- a/third_party/WebKit/Source/core/layout/LayoutImage.h +++ b/third_party/WebKit/Source/core/layout/LayoutImage.h
@@ -41,7 +41,7 @@ // There is 2 types of images: // * normal images, e.g. <image>, <picture>. // * content images with "content: url(path/to/image.png)". -// We store the type inside m_isGeneratedContent. +// We store the type inside |is_generated_content_|. // // The class is image type agnostic as it only manipulates decoded images. // See LayoutImageResource that holds this image.
diff --git a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp index b1395b4..8d28179 100644 --- a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp
@@ -7,6 +7,7 @@ #include "core/frame/LocalFrameView.h" #include "core/frame/VisualViewport.h" #include "core/frame/WebLocalFrameImpl.h" +#include "core/html/HTMLIFrameElement.h" #include "core/input/EventHandler.h" #include "core/inspector/DevToolsEmulator.h" #include "core/layout/LayoutScrollbarPart.h" @@ -1868,6 +1869,60 @@ EXPECT_FALSE(scrollable_div->ScrollbarsHiddenIfOverlay()); } +TEST_P(ScrollbarsTest, OverlayScrollbarHitTest) { + WebView().Resize(WebSize(300, 300)); + + SimRequest main_resource("https://example.com/", "text/html"); + SimRequest frame_resource("https://example.com/iframe.html", "text/html"); + LoadURL("https://example.com/"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + height: 2000px; + } + iframe { + height: 200px; + width: 200px; + } + </style> + <iframe id='iframe' src='iframe.html'> + </iframe> + )HTML"); + Compositor().BeginFrame(); + + // Enable the main frame scrollbar. + WebView() + .MainFrameImpl() + ->GetFrameView() + ->LayoutViewportScrollableArea() + ->SetScrollbarsHiddenIfOverlay(false); + + frame_resource.Complete("<!DOCTYPE html><body style='height: 999px'></body>"); + Compositor().BeginFrame(); + + // Enable the iframe scrollbar. + auto* iframe_element = + ToHTMLIFrameElement(GetDocument().getElementById("iframe")); + iframe_element->contentDocument() + ->View() + ->LayoutViewportScrollableArea() + ->SetScrollbarsHiddenIfOverlay(false); + + // Hit test on and off the main frame scrollbar. + HitTestResult hit_test_result = HitTest(295, 5); + EXPECT_TRUE(hit_test_result.GetScrollbar()); + hit_test_result = HitTest(250, 5); + EXPECT_FALSE(hit_test_result.GetScrollbar()); + + // Hit test on and off the iframe scrollbar. + hit_test_result = HitTest(195, 5); + EXPECT_TRUE(hit_test_result.GetScrollbar()); + hit_test_result = HitTest(150, 5); + EXPECT_FALSE(hit_test_result.GetScrollbar()); +} + class ScrollbarTrackMarginsTest : public ScrollbarsTest { public: void PrepareTest(const String& track_style) {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc index 2889535..1d0a9a4 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -48,26 +48,17 @@ DCHECK_GE(constraint_space.AvailableSize().inline_size, LayoutUnit()); DCHECK_GE(constraint_space.PercentageResolutionSize().inline_size, LayoutUnit()); - // TODO(layout-dev) enable this DCHECK - // DCHECK_EQ(constraint_space.WritingMode(), - // style.GetWritingMode()); + DCHECK_EQ(constraint_space.GetWritingMode(), style.GetWritingMode()); if (constraint_space.IsAnonymous()) return constraint_space.AvailableSize().inline_size; + NGBoxStrut border_and_padding = ComputeBorders(constraint_space, style) + + ComputePadding(constraint_space, style); + if (type == LengthResolveType::kMinSize && length.IsAuto()) - return LayoutUnit(); + return border_and_padding.InlineSum(); - if (type == LengthResolveType::kMarginBorderPaddingSize && length.IsAuto()) - return LayoutUnit(); - - // We don't need this when we're resolving margin/border/padding; skip - // computing it as an optimization and to simplify the code below. - NGBoxStrut border_and_padding; - if (type != LengthResolveType::kMarginBorderPaddingSize) { - border_and_padding = ComputeBorders(constraint_space, style) + - ComputePadding(constraint_space, style); - } switch (length.GetType()) { case kAuto: case kFillAvailable: { @@ -80,10 +71,7 @@ case kFixed: case kCalculated: { LayoutUnit percentage_resolution_size = - type == LengthResolveType::kMarginBorderPaddingSize - ? constraint_space - .PercentageResolutionInlineSizeForParentWritingMode() - : constraint_space.PercentageResolutionSize().inline_size; + constraint_space.PercentageResolutionSize().inline_size; LayoutUnit value = ValueForLength(length, percentage_resolution_size); if (style.BoxSizing() == EBoxSizing::kContentBox) { value += border_and_padding.InlineSum(); @@ -130,15 +118,11 @@ LayoutUnit content_size, LengthResolveType type) { DCHECK(!length.IsMaxSizeNone()); - DCHECK_NE(type, LengthResolveType::kMarginBorderPaddingSize); DCHECK_EQ(constraint_space.GetWritingMode(), style.GetWritingMode()); if (constraint_space.IsAnonymous()) return content_size; - if (type == LengthResolveType::kMinSize && length.IsAuto()) - return LayoutUnit(); - if (length.IsPercentOrCalc() && constraint_space.PercentageResolutionSize().block_size == NGSizeIndefinite) { @@ -155,13 +139,12 @@ return LayoutUnit(); } - // We don't need this when we're resolving margin/border/padding; skip - // computing it as an optimization and to simplify the code below. - NGBoxStrut border_and_padding; - if (type != LengthResolveType::kMarginBorderPaddingSize) { - border_and_padding = ComputeBorders(constraint_space, style) + - ComputePadding(constraint_space, style); - } + NGBoxStrut border_and_padding = ComputeBorders(constraint_space, style) + + ComputePadding(constraint_space, style); + + if (type == LengthResolveType::kMinSize && length.IsAuto()) + return border_and_padding.BlockSum(); + switch (length.GetType()) { case kFillAvailable: { LayoutUnit content_size = constraint_space.AvailableSize().block_size; @@ -208,6 +191,38 @@ } } +LayoutUnit ResolveMarginPaddingLength(const NGConstraintSpace& constraint_space, + const Length& length) { + DCHECK_GE(constraint_space.AvailableSize().inline_size, LayoutUnit()); + + // Margins and padding always get computed relative to the inline size: + // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width + // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width + switch (length.GetType()) { + case kAuto: + return LayoutUnit(); + case kPercent: + case kFixed: + case kCalculated: { + LayoutUnit percentage_resolution_size = + constraint_space.PercentageResolutionInlineSizeForParentWritingMode(); + return ValueForLength(length, percentage_resolution_size); + } + case kMinContent: + case kMaxContent: + case kFillAvailable: + case kFitContent: + case kExtendToZoom: + case kDeviceWidth: + case kDeviceHeight: + case kMaxSizeNone: + FALLTHROUGH; + default: + NOTREACHED(); + return LayoutUnit(); + } +} + MinMaxSize ComputeMinAndMaxContentContribution( const ComputedStyle& style, const WTF::Optional<MinMaxSize>& min_and_max) { @@ -441,23 +456,17 @@ NGPhysicalBoxStrut ComputePhysicalMargins( const NGConstraintSpace& constraint_space, const ComputedStyle& style) { - // We don't need these for margin computations - MinMaxSize empty_sizes; - // Margins always get computed relative to the inline size: - // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width + if (constraint_space.IsAnonymous()) + return NGPhysicalBoxStrut(); NGPhysicalBoxStrut physical_dim; - physical_dim.left = ResolveInlineLength( - constraint_space, style, empty_sizes, style.MarginLeft(), - LengthResolveType::kMarginBorderPaddingSize); - physical_dim.right = ResolveInlineLength( - constraint_space, style, empty_sizes, style.MarginRight(), - LengthResolveType::kMarginBorderPaddingSize); - physical_dim.top = ResolveInlineLength( - constraint_space, style, empty_sizes, style.MarginTop(), - LengthResolveType::kMarginBorderPaddingSize); - physical_dim.bottom = ResolveInlineLength( - constraint_space, style, empty_sizes, style.MarginBottom(), - LengthResolveType::kMarginBorderPaddingSize); + physical_dim.left = + ResolveMarginPaddingLength(constraint_space, style.MarginLeft()); + physical_dim.right = + ResolveMarginPaddingLength(constraint_space, style.MarginRight()); + physical_dim.top = + ResolveMarginPaddingLength(constraint_space, style.MarginTop()); + physical_dim.bottom = + ResolveMarginPaddingLength(constraint_space, style.MarginBottom()); return physical_dim; } @@ -532,23 +541,15 @@ if (constraint_space.IsAnonymous()) return NGBoxStrut(); - // We don't need these for padding computations - MinMaxSize empty_sizes; - // Padding always gets computed relative to the inline size: - // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width NGBoxStrut padding; - padding.inline_start = ResolveInlineLength( - constraint_space, style, empty_sizes, style.PaddingStart(), - LengthResolveType::kMarginBorderPaddingSize); - padding.inline_end = ResolveInlineLength( - constraint_space, style, empty_sizes, style.PaddingEnd(), - LengthResolveType::kMarginBorderPaddingSize); - padding.block_start = ResolveInlineLength( - constraint_space, style, empty_sizes, style.PaddingBefore(), - LengthResolveType::kMarginBorderPaddingSize); - padding.block_end = ResolveInlineLength( - constraint_space, style, empty_sizes, style.PaddingAfter(), - LengthResolveType::kMarginBorderPaddingSize); + padding.inline_start = + ResolveMarginPaddingLength(constraint_space, style.PaddingStart()); + padding.inline_end = + ResolveMarginPaddingLength(constraint_space, style.PaddingEnd()); + padding.block_start = + ResolveMarginPaddingLength(constraint_space, style.PaddingBefore()); + padding.block_end = + ResolveMarginPaddingLength(constraint_space, style.PaddingAfter()); return padding; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h index 48eb391..ff417088f 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
@@ -21,12 +21,7 @@ class NGBlockNode; class NGLayoutInputNode; -enum class LengthResolveType { - kMinSize, - kMaxSize, - kContentSize, - kMarginBorderPaddingSize -}; +enum class LengthResolveType { kMinSize, kMaxSize, kContentSize }; // Whether the caller needs to compute min-content and max-content sizes to // pass them to ResolveInlineLength / ComputeInlineSizeForFragment. @@ -56,6 +51,11 @@ LayoutUnit content_size, LengthResolveType); +// Convert margin/border/padding length to a layout unit using the +// given constraint space. +CORE_EXPORT LayoutUnit ResolveMarginPaddingLength(const NGConstraintSpace&, + const Length&); + // For the given style and min/max content sizes, computes the min and max // content contribution (https://drafts.csswg.org/css-sizing/#contributions). // This is similar to ComputeInlineSizeForFragment except that it does not
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc index 1abe233..7afc0cd7 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
@@ -371,7 +371,7 @@ #ifndef NDEBUG void NGPhysicalFragment::ShowFragmentTree() const { - fprintf(stderr, "%s\n", DumpFragmentTree(DumpAll).Utf8().data()); + LOG(INFO) << "\n" << DumpFragmentTree(DumpAll).Utf8().data(); } #endif // !NDEBUG
diff --git a/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp b/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp index 621968fd..bcaa2007 100644 --- a/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp +++ b/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp
@@ -12,6 +12,7 @@ #include "core/frame/LocalFrame.h" #include "core/frame/WebLocalFrameImpl.h" #include "core/leak_detector/BlinkLeakDetectorClient.h" +#include "core/page/Page.h" #include "core/workers/DedicatedWorkerMessagingProxy.h" #include "core/workers/WorkerThread.h" #include "platform/Timer.h" @@ -36,7 +37,7 @@ BlinkLeakDetector::~BlinkLeakDetector() = default; -void BlinkLeakDetector::PrepareForLeakDetection(WebFrame* frame) { +void BlinkLeakDetector::PrepareForLeakDetection() { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope handle_scope(isolate); @@ -58,10 +59,13 @@ // Currently PrepareForLeakDetection takes frame to get the spellchecker, // but in the future when leak detection runs with multiple frames, // this code must be refactored so that it iterates thru all the frames. - if (WebLocalFrameImpl::ToCoreFrame(*frame)->IsLocalFrame()) { - ToLocalFrame(WebLocalFrameImpl::ToCoreFrame(*frame)) - ->GetSpellChecker() - .PrepareForLeakDetection(); + for (Page* page : Page::OrdinaryPages()) { + for (Frame* frame = page->MainFrame(); frame; + frame = frame->Tree().TraverseNext()) { + if (!frame->IsLocalFrame()) + continue; + ToLocalFrame(frame)->GetSpellChecker().PrepareForLeakDetection(); + } } // FIXME: HTML5 Notification should be closed because notification affects
diff --git a/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.h b/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.h index b23dbb75..2ad097a 100644 --- a/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.h +++ b/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.h
@@ -11,7 +11,6 @@ namespace blink { class BlinkLeakDetectorClient; -class WebFrame; class ResourceFetcher; // This class is responsible for stabilizing the detection results which are @@ -24,7 +23,7 @@ static BlinkLeakDetector& Instance(); ~BlinkLeakDetector(); - void PrepareForLeakDetection(WebFrame*); + void PrepareForLeakDetection(); void CollectGarbage(); void SetClient(BlinkLeakDetectorClient*);
diff --git a/third_party/WebKit/Source/core/leak_detector/WebLeakDetector.cpp b/third_party/WebKit/Source/core/leak_detector/WebLeakDetector.cpp index 32a80ce4..7849848 100644 --- a/third_party/WebKit/Source/core/leak_detector/WebLeakDetector.cpp +++ b/third_party/WebKit/Source/core/leak_detector/WebLeakDetector.cpp
@@ -52,7 +52,7 @@ ~WebLeakDetectorImpl() override = default; - void PrepareForLeakDetection(WebFrame*) override; + void PrepareForLeakDetection() override; void CollectGarbageAndReport() override; // BlinkLeakDetectorClient: @@ -63,10 +63,10 @@ DISALLOW_COPY_AND_ASSIGN(WebLeakDetectorImpl); }; -void WebLeakDetectorImpl::PrepareForLeakDetection(WebFrame* frame) { +void WebLeakDetectorImpl::PrepareForLeakDetection() { BlinkLeakDetector& detector = BlinkLeakDetector::Instance(); detector.SetClient(this); - detector.PrepareForLeakDetection(frame); + detector.PrepareForLeakDetection(); } void WebLeakDetectorImpl::CollectGarbageAndReport() {
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index ec64056f..db10e36 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -93,6 +93,7 @@ #include "public/platform/modules/fetch/fetch_api_request.mojom-shared.h" #include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "services/network/public/mojom/request_context_frame_type.mojom-blink.h" +#include "third_party/WebKit/public/common/client_hints/client_hints.h" #include "third_party/WebKit/public/common/device_memory/approximated_device_memory.h" namespace blink { @@ -941,6 +942,36 @@ "Viewport-Width", AtomicString(String::Number(GetFrame()->View()->ViewportWidth()))); } + + if (ShouldSendClientHint(mojom::WebClientHintsType::kRtt, hints_preferences, + enabled_hints)) { + unsigned long rtt = GetNetworkStateNotifier().RoundRtt( + request.Url().Host(), GetNetworkStateNotifier().HttpRtt()); + request.AddHTTPHeaderField( + blink::kClientHintsHeaderMapping[static_cast<size_t>( + mojom::WebClientHintsType::kRtt)], + AtomicString(String::Number(rtt))); + } + + if (ShouldSendClientHint(mojom::WebClientHintsType::kDownlink, + hints_preferences, enabled_hints)) { + double mbps = GetNetworkStateNotifier().RoundMbps( + request.Url().Host(), + GetNetworkStateNotifier().DownlinkThroughputMbps()); + request.AddHTTPHeaderField( + blink::kClientHintsHeaderMapping[static_cast<size_t>( + mojom::WebClientHintsType::kDownlink)], + AtomicString(String::Number(mbps))); + } + + if (ShouldSendClientHint(mojom::WebClientHintsType::kEct, hints_preferences, + enabled_hints)) { + request.AddHTTPHeaderField( + blink::kClientHintsHeaderMapping[static_cast<size_t>( + mojom::WebClientHintsType::kEct)], + AtomicString(NetworkStateNotifier::EffectiveConnectionTypeToString( + GetNetworkStateNotifier().EffectiveType()))); + } } void FrameFetchContext::PopulateResourceRequest(
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp index a7c3bf9..200b0e3 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
@@ -601,6 +601,16 @@ EXPECT_EQ(is_present ? String(header_value) : String(), resource_request.HttpHeaderField(header_name)); } + + String GetHeaderValue(const char* input, const char* header_name) { + ClientHintsPreferences hints_preferences; + FetchParameters::ResourceWidth resource_width; + const KURL input_url(input); + ResourceRequest resource_request(input_url); + fetch_context->AddClientHintsIfNecessary(hints_preferences, resource_width, + resource_request); + return resource_request.HttpHeaderField(header_name); + } }; // Verify that the client hints should be attached for subresources fetched @@ -786,6 +796,9 @@ ExpectHeader("https://www.example.com/1.gif", "DPR", false, ""); ExpectHeader("https://www.example.com/1.gif", "Viewport-Width", false, ""); ExpectHeader("https://www.example.com/1.gif", "Width", false, ""); + ExpectHeader("https://www.example.com/1.gif", "rtt", false, ""); + ExpectHeader("https://www.example.com/1.gif", "downlink", false, ""); + ExpectHeader("https://www.example.com/1.gif", "ect", false, ""); ClientHintsPreferences preferences; preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDeviceMemory); @@ -794,12 +807,33 @@ mojom::WebClientHintsType::kResourceWidth); preferences.SetShouldSendForTesting( mojom::WebClientHintsType::kViewportWidth); + preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kRtt); + preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDownlink); + preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kEct); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(4096); document->GetClientHintsPreferences().UpdateFrom(preferences); ExpectHeader("https://www.example.com/1.gif", "Device-Memory", true, "4"); ExpectHeader("https://www.example.com/1.gif", "DPR", true, "1"); ExpectHeader("https://www.example.com/1.gif", "Width", true, "400", 400); ExpectHeader("https://www.example.com/1.gif", "Viewport-Width", true, "500"); + + // Value of network quality client hints may vary, so only check if the + // header is present and the values are non-negative/non-empty. + bool conversion_ok = false; + int rtt_header_value = GetHeaderValue("https://www.example.com/1.gif", "rtt") + .ToIntStrict(&conversion_ok); + EXPECT_TRUE(conversion_ok); + EXPECT_LE(0, rtt_header_value); + + float downlink_header_value = + GetHeaderValue("https://www.example.com/1.gif", "downlink") + .ToFloat(&conversion_ok); + EXPECT_TRUE(conversion_ok); + EXPECT_LE(0, downlink_header_value); + + EXPECT_LT( + 0u, + GetHeaderValue("https://www.example.com/1.gif", "ect").Ascii().length()); } TEST_F(FrameFetchContextTest, MainResourceCachePolicy) {
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp index 6647966..29bb14d 100644 --- a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp +++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
@@ -326,8 +326,7 @@ void OnSetUp() override { reporting_proxy_ = std::make_unique<WorkerReportingProxy>(); security_origin_ = GetDocument().GetSecurityOrigin(); - parent_frame_task_runners_ = - ParentFrameTaskRunners::Create(dummy_page_holder_->GetFrame()); + parent_frame_task_runners_ = ParentFrameTaskRunners::Create(&GetDocument()); worker_thread_ = std::make_unique<WorkerThreadForTest>( ThreadableLoadingContext::Create(GetDocument()), *reporting_proxy_); WorkerClients* worker_clients = WorkerClients::Create();
diff --git a/third_party/WebKit/Source/core/loader/private/FrameClientHintsPreferencesContext.cpp b/third_party/WebKit/Source/core/loader/private/FrameClientHintsPreferencesContext.cpp index 238aabe2..6d9b55e 100644 --- a/third_party/WebKit/Source/core/loader/private/FrameClientHintsPreferencesContext.cpp +++ b/third_party/WebKit/Source/core/loader/private/FrameClientHintsPreferencesContext.cpp
@@ -13,9 +13,13 @@ // Mapping from WebClientHintsType to WebFeature. The ordering should match the // ordering of enums in WebClientHintsType. static constexpr WebFeature kWebFeatureMapping[] = { - WebFeature::kClientHintsDeviceMemory, WebFeature::kClientHintsDPR, + WebFeature::kClientHintsDeviceMemory, + WebFeature::kClientHintsDPR, WebFeature::kClientHintsResourceWidth, WebFeature::kClientHintsViewportWidth, + WebFeature::kClientHintsRtt, + WebFeature::kClientHintsDownlink, + WebFeature::kClientHintsEct, }; static_assert(static_cast<int>(mojom::WebClientHintsType::kMaxValue) + 1 ==
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp index 9eeefb5..101eed3 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -44,6 +44,7 @@ #include "core/paint/PaintLayerClipper.h" +#include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameView.h" #include "core/frame/Settings.h" #include "core/layout/LayoutView.h" @@ -514,10 +515,11 @@ // rect if layer_ is the same as the root. OverlayScrollbarClipBehavior clip_behavior = context.overlay_scrollbar_clip_behavior; - if (&layer_ == context.root_layer) + + if (is_clipping_root) clip_behavior = kIgnorePlatformOverlayScrollbarSize; - FloatClipRect clip_rect((FloatRect(LocalVisualRect(context)))); + FloatClipRect clip_rect(FloatRect(LocalVisualRect(context))); clip_rect.MoveBy(FloatPoint(fragment_data.PaintOffset())); GeometryMapper::LocalToAncestorVisualRect(source_property_tree_state, @@ -536,6 +538,24 @@ output.MoveBy( -context.root_layer->GetLayoutObject().FirstFragment().PaintOffset()); + // The root LayoutView clip node does not store a rect excluding scrollbars + // for hit testing (see FragmentPaintPropertyTreeBuilder::UpdateOverflowClip). + // To calculate the correct clip at the root, we need to apply the LayoutView + // overflow clip excluding scrollbars here. + auto& root = context.root_layer->GetLayoutObject(); + bool is_root_layout_view = + root.IsLayoutView() && !root.GetFrame()->Tree().Parent(); + bool root_should_clip = HasOverflowClip(*context.root_layer) && + !is_clipping_root && + context.ShouldRespectRootLayerClip(); + if (context.overlay_scrollbar_clip_behavior == + kExcludeOverlayScrollbarSizeForHitTesting && + is_root_layout_view && root_should_clip) { + ClipRect root_overflow_clip = ToLayoutView(root).OverflowClipRect( + LayoutPoint(), kExcludeOverlayScrollbarSizeForHitTesting); + output.Intersect(root_overflow_clip); + } + output.Move(context.sub_pixel_accumulation); }
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp index 72a3cd8..e807778 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -1168,10 +1168,23 @@ } else if (object_.IsBox()) { clip_rect = ToClipRect(ToLayoutBox(object_).OverflowClipRect( context_.current.paint_offset)); - clip_rect_excluding_overlay_scrollbars = - ToClipRect(ToLayoutBox(object_).OverflowClipRect( - context_.current.paint_offset, - kExcludeOverlayScrollbarSizeForHitTesting)); + + bool is_root_layout_view = + object_.IsLayoutView() && !object_.GetFrame()->Tree().Parent(); + if (is_root_layout_view) { + // Overlay scrollbar hiding frequently changes clip rects which + // requires invalidating all clip nodes. To avoid this expensive + // operation at the root, we do not set + // |clip_rect_excluding_overlay_scrollbars| and instead special-case + // hit test clipping at the root (see: + // PaintLayerClipper::CalculateBackgroundClipRectWithGeometryMapper). + clip_rect_excluding_overlay_scrollbars = clip_rect; + } else { + clip_rect_excluding_overlay_scrollbars = + ToClipRect(ToLayoutBox(object_).OverflowClipRect( + context_.current.paint_offset, + kExcludeOverlayScrollbarSizeForHitTesting)); + } } else { DCHECK(object_.IsSVGViewportContainer()); const auto& viewport_container = ToLayoutSVGViewportContainer(object_);
diff --git a/third_party/WebKit/Source/core/script/DocumentWriteIntervention.cpp b/third_party/WebKit/Source/core/script/DocumentWriteIntervention.cpp index b98e35f2..e0ca115 100644 --- a/third_party/WebKit/Source/core/script/DocumentWriteIntervention.cpp +++ b/third_party/WebKit/Source/core/script/DocumentWriteIntervention.cpp
@@ -53,8 +53,8 @@ url + ", invoked via document.write was BLOCKED by the browser due to poor " "network connectivity. "; - document.AddConsoleMessage( - ConsoleMessage::Create(kJSMessageSource, kErrorMessageLevel, message)); + document.AddConsoleMessage(ConsoleMessage::Create( + kInterventionMessageSource, kErrorMessageLevel, message)); } void AddWarningHeader(FetchParameters* params) {
diff --git a/third_party/WebKit/Source/core/streams/CommonOperations.js b/third_party/WebKit/Source/core/streams/CommonOperations.js index e1cc679..f35f6d13f 100644 --- a/third_party/WebKit/Source/core/streams/CommonOperations.js +++ b/third_party/WebKit/Source/core/streams/CommonOperations.js
@@ -155,19 +155,6 @@ return highWaterMark; } - // TODO(ricea): Remove this once all its callers have been updated to use - // ValidateAndNormalizeHighWaterMark instead. - function ValidateAndNormalizeQueuingStrategy(size, highWaterMark) { - if (size !== undefined && typeof size !== 'function') { - throw new TypeError(binding.streamErrors.sizeNotAFunction); - } - - highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark); - - return {size, highWaterMark}; - } - - // Unlike the version in the standard, this implementation returns the // original function as-is if it is set. This means users of the return value // need to be careful to explicitly set |this| when calling it. @@ -271,15 +258,6 @@ return callFunction(method, O, arg0); } - // Modified from PromiseInvokeOrNoop in spec. Takes 1 argument. - function PromiseCallOrNoop1(O, P, arg0, nameForError) { - try { - return Promise_resolve(CallOrNoop1(O, P, arg0, nameForError)); - } catch (e) { - return Promise_reject(e); - } - } - function PromiseCall0(F, V) { // assert(typeof F === 'function', 'IsCallable(F) is true.'); // assert(V !== undefined, 'V is not undefined.'); @@ -325,10 +303,8 @@ PeekQueueValue, ResetQueue, ValidateAndNormalizeHighWaterMark, - ValidateAndNormalizeQueuingStrategy, MakeSizeAlgorithmFromSizeFunction, CallOrNoop1, - PromiseCallOrNoop1, PromiseCall2 }; });
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js index f88f0772..a5ec08c 100644 --- a/third_party/WebKit/Source/core/streams/ReadableStream.js +++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -28,22 +28,30 @@ const STATE_CLOSED = 1; const STATE_ERRORED = 2; - const _underlyingSource = v8.createPrivateSymbol('[[underlyingSource]]'); const _controlledReadableStream = v8.createPrivateSymbol('[[controlledReadableStream]]'); - const _strategySize = v8.createPrivateSymbol('[[strategySize]]'); const _strategyHWM = v8.createPrivateSymbol('[[strategyHWM]]'); const _readableStreamDefaultControllerBits = v8.createPrivateSymbol( 'bit field for [[started]], [[closeRequested]], [[pulling]], ' + '[[pullAgain]]'); + // Remove this once C++ code has been updated to use CreateReadableStream. + const _lockNotifyTarget = v8.createPrivateSymbol('[[lockNotifyTarget]]'); + const _strategySizeAlgorithm = v8.createPrivateSymbol( + '[[strategySizeAlgorithm]]'); + const _pullAlgorithm = v8.createPrivateSymbol('[[pullAlgorithm]]'); + const _cancelAlgorithm = v8.createPrivateSymbol('[[cancelAlgorithm]]'); const STARTED = 0b1; const CLOSE_REQUESTED = 0b10; const PULLING = 0b100; const PULL_AGAIN = 0b1000; - const EXTERNALLY_CONTROLLED = 0b10000; + // TODO(ricea): Remove this once blink::UnderlyingSourceBase no longer needs + // it. + const BLINK_LOCK_NOTIFICATIONS = 0b10000; const defineProperty = global.Object.defineProperty; + const ObjectCreate = global.Object.create; + const callFunction = v8.uncurryThis(global.Function.prototype.call); const applyFunction = v8.uncurryThis(global.Function.prototype.apply); @@ -66,11 +74,13 @@ rejectPromise, resolvePromise, markPromiseAsHandled, + CallOrNoop1, + CreateAlgorithmFromUnderlyingMethod, + CreateAlgorithmFromUnderlyingMethodPassingController, DequeueValue, EnqueueValueWithSize, - ValidateAndNormalizeQueuingStrategy, - CallOrNoop1, - PromiseCallOrNoop1 + MakeSizeAlgorithmFromSizeFunction, + ValidateAndNormalizeHighWaterMark, } = binding.streamOperations; const streamErrors = binding.streamErrors; @@ -94,9 +104,6 @@ 'Cannot enqueue a chunk into an errored readable stream'; const errCloseClosedStream = 'Cannot close a closed readable stream'; const errCloseErroredStream = 'Cannot close an errored readable stream'; - const errErrorClosedStream = 'Cannot error a close readable stream'; - const errErrorErroredStream = - 'Cannot error a readable stream that is already errored'; const errGetReaderNotByteStream = 'This readable stream does not support BYOB readers'; const errGetReaderBadMode = @@ -126,38 +133,42 @@ let useCounted = false; class ReadableStream { - constructor(underlyingSource = {}, { size, highWaterMark = 1 } = {}, + // TODO(ricea): Remove |internalArgument| once + // blink::ReadableStreamOperations has been updated to use + // CreateReadableStream. + constructor(underlyingSource = {}, strategy = {}, internalArgument = undefined) { - const internal = + const enableBlinkLockNotifications = internalArgument === createWithExternalControllerSentinel; - if (!useCounted && !internal) { + if (!useCounted && !enableBlinkLockNotifications) { binding.countUse('ReadableStreamConstructor'); useCounted = true; } - this[_readableStreamBits] = 0b0; - ReadableStreamSetState(this, STATE_READABLE); - this[_reader] = undefined; - this[_storedError] = undefined; - - // Avoid allocating the controller if the stream is going to be controlled - // externally (i.e. from C++) anyway. All calls to underlyingSource - // methods will disregard their controller argument in such situations - // (but see below). - - this[_controller] = undefined; - + InitializeReadableStream(this); const type = underlyingSource.type; + const size = strategy.size; + let highWaterMark = strategy.highWaterMark; const typeString = String(type); + if (typeString === 'bytes') { throw new RangeError('bytes type is not yet implemented'); - } else if (type !== undefined) { + } + + if (type !== undefined) { throw new RangeError(streamErrors.invalidType); } - this[_controller] = new ReadableStreamDefaultController( - this, underlyingSource, size, highWaterMark, internal); + if (highWaterMark === undefined) { + highWaterMark = 1; + } + + highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark); + const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size); + SetUpReadableStreamDefaultControllerFromUnderlyingSource( + this, underlyingSource, highWaterMark, sizeAlgorithm, + enableBlinkLockNotifications); } get locked() { @@ -185,20 +196,19 @@ throw new TypeError(streamErrors.illegalInvocation); } + if (mode === undefined) { + return AcquireReadableStreamDefaultReader(this); + } + + mode = String(mode); + if (mode === 'byob') { // TODO(ricea): When BYOB readers are supported: // - // a. If - // ! IsReadableByteStreamController(this.[[_controller]]) - // is false, throw a TypeError exception. - // b. Return ? AcquireReadableStreamBYOBReader(this). + // Return ? AcquireReadableStreamBYOBReader(this). throw new TypeError(errGetReaderNotByteStream); } - if (mode === undefined) { - return AcquireReadableStreamDefaultReader(this); - } - throw new RangeError(errGetReaderBadMode); } @@ -251,6 +261,8 @@ } } + const ReadableStream_prototype = ReadableStream.prototype; + function ReadableStreamPipeTo( readable, dest, preventClose, preventAbort, preventCancel) { // Callers of this function must ensure that the following invariants @@ -444,6 +456,35 @@ return new ReadableStreamDefaultReader(stream); } + // The non-standard boolean |enableBlinkLockNotifications| argument indicates + // whether the stream is being created from C++. + function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, + highWaterMark, sizeAlgorithm, + enableBlinkLockNotifications) { + if (highWaterMark === undefined) { + highWaterMark = 1; + } + if (sizeAlgorithm === undefined) { + sizeAlgorithm = () => 1; + } + // assert(IsNonNegativeNumber(highWaterMark), + // '! IsNonNegativeNumber(highWaterMark) is true.'); + const stream = ObjectCreate(ReadableStream_prototype); + InitializeReadableStream(stream); + const controller = ObjectCreate(ReadableStreamDefaultController_prototype); + SetUpReadableStreamDefaultController( + stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, + highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); + return stream; + } + + function InitializeReadableStream(stream) { + stream[_readableStreamBits] = 0b0; + ReadableStreamSetState(stream, STATE_READABLE); + stream[_reader] = undefined; + stream[_storedError] = undefined; + } + function IsReadableStream(x) { return hasOwnPropertyNoThrow(x, _controller); } @@ -456,11 +497,7 @@ return stream[_reader] !== undefined; } - // Potential future optimization: use class instances for the underlying - // sources, so that we don't re-create - // closures every time. - - // TODO(domenic): shouldClone argument from spec not supported yet + // TODO(domenic): cloneForBranch2 argument from spec not supported yet function ReadableStreamTee(stream) { const reader = AcquireReadableStreamDefaultReader(stream); @@ -469,82 +506,84 @@ let canceled2 = false; let reason1; let reason2; - const promise = v8.createPromise(); + const cancelPromise = v8.createPromise(); - const branch1Stream = new ReadableStream({pull, cancel: cancel1}); - - const branch2Stream = new ReadableStream({pull, cancel: cancel2}); - - const branch1 = branch1Stream[_controller]; - const branch2 = branch2Stream[_controller]; - - thenPromise(reader[_closedPromise], undefined, function(r) { - if (closedOrErrored === true) { - return; - } - - ReadableStreamDefaultControllerError(branch1, r); - ReadableStreamDefaultControllerError(branch2, r); - closedOrErrored = true; - }); - - return [branch1Stream, branch2Stream]; - - function pull() { + function pullAlgorithm() { return thenPromise( - ReadableStreamDefaultReaderRead(reader), function(result) { - const value = result.value; - const done = result.done; - - if (done === true && closedOrErrored === false) { - if (canceled1 === false) { - ReadableStreamDefaultControllerClose(branch1); + ReadableStreamDefaultReaderRead(reader), ({value, done}) => { + if (done && !closedOrErrored) { + if (!canceled1) { + ReadableStreamDefaultControllerClose(branch1controller); } - if (canceled2 === false) { - ReadableStreamDefaultControllerClose(branch2); + if (!canceled2) { + ReadableStreamDefaultControllerClose(branch2controller); } closedOrErrored = true; } - if (closedOrErrored === true) { + if (closedOrErrored) { return; } - if (canceled1 === false) { - ReadableStreamDefaultControllerEnqueue(branch1, value); + // TODO(ricea): Implement these steps for cloning. + // + // vii. Let _value1_ and _value2_ be _value_. + // viii. If _canceled2_ is false and _cloneForBranch2_ is true, set + // value2 to ? StructuredDeserialize(? StructuredSerialize(value2), + // the current Realm Record). + + if (!canceled1) { + ReadableStreamDefaultControllerEnqueue(branch1controller, value); } - if (canceled2 === false) { - ReadableStreamDefaultControllerEnqueue(branch2, value); + if (!canceled2) { + ReadableStreamDefaultControllerEnqueue(branch2controller, value); } }); } - function cancel1(reason) { + function cancel1Algorithm(reason) { canceled1 = true; reason1 = reason; - - if (canceled2 === true) { - const compositeReason = [reason1, reason2]; - const cancelResult = ReadableStreamCancel(stream, compositeReason); - resolvePromise(promise, cancelResult); + if (canceled2) { + const cancelResult = ReadableStreamCancel(stream, [reason1, reason2]); + resolvePromise(cancelPromise, cancelResult); } - - return promise; + return cancelPromise; } - function cancel2(reason) { + function cancel2Algorithm(reason) { canceled2 = true; reason2 = reason; + if (canceled1) { + const cancelResult = ReadableStreamCancel(stream, [reason1, reason2]); + resolvePromise(cancelPromise, cancelResult); + } + return cancelPromise; + } - if (canceled1 === true) { - const compositeReason = [reason1, reason2]; - const cancelResult = ReadableStreamCancel(stream, compositeReason); - resolvePromise(promise, cancelResult); + const startAlgorithm = () => undefined; + + const branch1Stream = CreateReadableStream( + startAlgorithm, pullAlgorithm, cancel1Algorithm, undefined, undefined, + false); + const branch2Stream = CreateReadableStream( + startAlgorithm, pullAlgorithm, cancel2Algorithm, undefined, undefined, + false); + const branch1controller = branch1Stream[_controller]; + const branch2controller = branch2Stream[_controller]; + + thenPromise(reader[_closedPromise], undefined, r => { + if (closedOrErrored === true) { + return; } - return promise; - } + ReadableStreamDefaultControllerError(branch1controller, r); + ReadableStreamDefaultControllerError(branch2controller, r); + closedOrErrored = true; + }); + + return [branch1Stream, branch2Stream]; } // @@ -580,7 +619,7 @@ const reader = stream[_reader]; if (reader === undefined) { - return undefined; + return; } if (IsReadableStreamDefaultReader(reader) === true) { @@ -594,12 +633,12 @@ } function ReadableStreamError(stream, e) { - stream[_storedError] = e; ReadableStreamSetState(stream, STATE_ERRORED); + stream[_storedError] = e; const reader = stream[_reader]; if (reader === undefined) { - return undefined; + return; } if (IsReadableStreamDefaultReader(reader) === true) { @@ -653,8 +692,7 @@ return Promise_reject(new TypeError(streamErrors.illegalInvocation)); } - const stream = this[_ownerReadableStream]; - if (stream === undefined) { + if (this[_ownerReadableStream] === undefined) { return Promise_reject(new TypeError(errCancelReleasedReader)); } @@ -678,9 +716,8 @@ throw new TypeError(streamErrors.illegalInvocation); } - const stream = this[_ownerReadableStream]; - if (stream === undefined) { - return undefined; + if (this[_ownerReadableStream] === undefined) { + return; } if (this[_readRequests].length > 0) { @@ -708,11 +745,11 @@ // blink::UnderlyingSourceBase. const controller = stream[_controller]; if (controller[_readableStreamDefaultControllerBits] & - EXTERNALLY_CONTROLLED) { + BLINK_LOCK_NOTIFICATIONS) { // The stream is created with an external controller (i.e. made in // Blink). - const underlyingSource = controller[_underlyingSource]; - callFunction(underlyingSource.notifyLockAcquired, underlyingSource); + const lockNotifyTarget = controller[_lockNotifyTarget]; + callFunction(lockNotifyTarget.notifyLockAcquired, lockNotifyTarget); } reader[_ownerReadableStream] = stream; @@ -737,11 +774,11 @@ // blink::UnderlyingSourceBase. const controller = reader[_ownerReadableStream][_controller]; if (controller[_readableStreamDefaultControllerBits] & - EXTERNALLY_CONTROLLED) { + BLINK_LOCK_NOTIFICATIONS) { // The stream is created with an external controller (i.e. made in // Blink). - const underlyingSource = controller[_underlyingSource]; - callFunction(underlyingSource.notifyLockReleased, underlyingSource); + const lockNotifyTarget = controller[_lockNotifyTarget]; + callFunction(lockNotifyTarget.notifyLockReleased, lockNotifyTarget); } if (ReadableStreamGetState(reader[_ownerReadableStream]) === @@ -763,15 +800,16 @@ const stream = reader[_ownerReadableStream]; stream[_readableStreamBits] |= DISTURBED; - if (ReadableStreamGetState(stream) === STATE_CLOSED) { - return Promise_resolve(CreateIterResultObject(undefined, true)); - } + switch (ReadableStreamGetState(stream)) { + case STATE_CLOSED: + return Promise_resolve(CreateIterResultObject(undefined, true)); - if (ReadableStreamGetState(stream) === STATE_ERRORED) { - return Promise_reject(stream[_storedError]); - } + case STATE_ERRORED: + return Promise_reject(stream[_storedError]); - return ReadableStreamDefaultControllerPull(stream[_controller]); + default: + return ReadableStreamDefaultControllerPull(stream[_controller]); + } } // @@ -779,48 +817,8 @@ // class ReadableStreamDefaultController { - constructor( - stream, underlyingSource, size, highWaterMark, isExternallyControlled) { - if (IsReadableStream(stream) === false) { - throw new TypeError(streamErrors.illegalConstructor); - } - - if (stream[_controller] !== undefined) { - throw new TypeError(streamErrors.illegalConstructor); - } - - this[_controlledReadableStream] = stream; - - this[_underlyingSource] = underlyingSource; - - this[_queue] = new binding.SimpleQueue(); - this[_queueTotalSize] = 0; - - this[_readableStreamDefaultControllerBits] = 0b0; - if (isExternallyControlled === true) { - this[_readableStreamDefaultControllerBits] |= EXTERNALLY_CONTROLLED; - } - - const normalizedStrategy = - ValidateAndNormalizeQueuingStrategy(size, highWaterMark); - this[_strategySize] = normalizedStrategy.size; - this[_strategyHWM] = normalizedStrategy.highWaterMark; - - const controller = this; - - const startResult = CallOrNoop1( - underlyingSource, 'start', this, 'underlyingSource.start'); - thenPromise( - Promise_resolve(startResult), - () => { - controller[_readableStreamDefaultControllerBits] |= STARTED; - ReadableStreamDefaultControllerCallPullIfNeeded(controller); - }, - r => { - if (ReadableStreamGetState(stream) === STATE_READABLE) { - ReadableStreamDefaultControllerError(controller, r); - } - }); + constructor() { + throw new TypeError(streamErrors.illegalConstructor); } get desiredSize() { @@ -836,18 +834,23 @@ throw new TypeError(streamErrors.illegalInvocation); } - const stream = this[_controlledReadableStream]; + if (ReadableStreamDefaultControllerCanCloseOrEnqueue(this) === false) { + let errorDescription; + if (this[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { + errorDescription = errCloseCloseRequestedStream; + } else { + const stream = this[_controlledReadableStream]; + switch (ReadableStreamGetState(stream)) { + case STATE_ERRORED: + errorDescription = errCloseErroredStream; + break; - if (this[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { - throw new TypeError(errCloseCloseRequestedStream); - } - - const state = ReadableStreamGetState(stream); - if (state === STATE_ERRORED) { - throw new TypeError(errCloseErroredStream); - } - if (state === STATE_CLOSED) { - throw new TypeError(errCloseClosedStream); + case STATE_CLOSED: + errorDescription = errCloseClosedStream; + break; + } + } + throw new TypeError(errorDescription); } return ReadableStreamDefaultControllerClose(this); @@ -871,27 +874,17 @@ throw new TypeError(streamErrors.illegalInvocation); } - const stream = this[_controlledReadableStream]; - - const state = ReadableStreamGetState(stream); - if (state === STATE_ERRORED) { - throw new TypeError(errErrorErroredStream); - } - if (state === STATE_CLOSED) { - throw new TypeError(errErrorClosedStream); - } - return ReadableStreamDefaultControllerError(this, e); } } + const ReadableStreamDefaultController_prototype = + ReadableStreamDefaultController.prototype; + // [[CancelSteps]] in the standard. function ReadableStreamDefaultControllerCancel(controller, reason) { controller[_queue] = new binding.SimpleQueue(); - - const underlyingSource = controller[_underlyingSource]; - return PromiseCallOrNoop1( - underlyingSource, 'cancel', reason, 'underlyingSource.cancel'); + return controller[_cancelAlgorithm](reason); } // [[PullSteps]] in the standard. @@ -929,22 +922,18 @@ const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller); if (shouldPull === false) { - return undefined; + return; } if (controller[_readableStreamDefaultControllerBits] & PULLING) { controller[_readableStreamDefaultControllerBits] |= PULL_AGAIN; - return undefined; + return; } controller[_readableStreamDefaultControllerBits] |= PULLING; - const underlyingSource = controller[_underlyingSource]; - const pullPromise = PromiseCallOrNoop1( - underlyingSource, 'pull', controller, 'underlyingSource.pull'); - thenPromise( - pullPromise, + controller[_pullAlgorithm](), () => { controller[_readableStreamDefaultControllerBits] &= ~PULLING; @@ -954,29 +943,19 @@ } }, e => { - if (ReadableStreamGetState(controller[_controlledReadableStream]) === - STATE_READABLE) { - ReadableStreamDefaultControllerError(controller, e); - } + ReadableStreamDefaultControllerError(controller, e); }); } function ReadableStreamDefaultControllerShouldCallPull(controller) { - const stream = controller[_controlledReadableStream]; - - const state = ReadableStreamGetState(stream); - if (state === STATE_CLOSED || state === STATE_ERRORED) { + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { return false; } - - if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { - return false; - } - if (!(controller[_readableStreamDefaultControllerBits] & STARTED)) { return false; } + const stream = controller[_controlledReadableStream]; if (IsReadableStreamLocked(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) { return true; @@ -984,20 +963,14 @@ const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller); - if (desiredSize > 0) { - return true; - } - - return false; + return desiredSize > 0; } function ReadableStreamDefaultControllerClose(controller) { - const stream = controller[_controlledReadableStream]; - controller[_readableStreamDefaultControllerBits] |= CLOSE_REQUESTED; if (controller[_queue].length === 0) { - ReadableStreamClose(stream); + ReadableStreamClose(controller[_controlledReadableStream]); } } @@ -1008,26 +981,24 @@ ReadableStreamGetNumReadRequests(stream) > 0) { ReadableStreamFulfillReadRequest(stream, chunk, false); } else { - let chunkSize = 1; + let chunkSize; - const strategySize = controller[_strategySize]; - if (strategySize !== undefined) { - try { - chunkSize = strategySize(chunk); - } catch (chunkSizeE) { - if (ReadableStreamGetState(stream) === STATE_READABLE) { - ReadableStreamDefaultControllerError(controller, chunkSizeE); - } - throw chunkSizeE; - } + // TODO(ricea): Would it be more efficient if we avoided the + // try ... catch when we're using the default strategy size algorithm? + try { + // Unlike other algorithms, strategySizeAlgorithm isn't indirected, so + // we need to be careful with the |this| value. + chunkSize = callFunction(controller[_strategySizeAlgorithm], undefined, + chunk); + } catch (chunkSizeE) { + ReadableStreamDefaultControllerError(controller, chunkSizeE); + throw chunkSizeE; } try { EnqueueValueWithSize(controller, chunk, chunkSize); } catch (enqueueE) { - if (ReadableStreamGetState(stream) === STATE_READABLE) { - ReadableStreamDefaultControllerError(controller, enqueueE); - } + ReadableStreamDefaultControllerError(controller, enqueueE); throw enqueueE; } } @@ -1036,13 +1007,25 @@ } function ReadableStreamDefaultControllerError(controller, e) { - controller[_queue] = new binding.SimpleQueue(); const stream = controller[_controlledReadableStream]; + if (ReadableStreamGetState(stream) !== STATE_READABLE) { + return; + } + controller[_queue] = new binding.SimpleQueue(); ReadableStreamError(stream, e); } function ReadableStreamDefaultControllerGetDesiredSize(controller) { - return controller[_strategyHWM] - controller[_queueTotalSize]; + switch (ReadableStreamGetState(controller[_controlledReadableStream])) { + case STATE_ERRORED: + return null; + + case STATE_CLOSED: + return 0; + + default: + return controller[_strategyHWM] - controller[_queueTotalSize]; + } } function ReadableStreamDefaultControllerHasBackpressure(controller) { @@ -1057,6 +1040,46 @@ return state === STATE_READABLE; } + function SetUpReadableStreamDefaultController( + stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, + highWaterMark, sizeAlgorithm, enableBlinkLockNotifications) { + controller[_controlledReadableStream] = stream; + controller[_queue] = new binding.SimpleQueue(); + controller[_queueTotalSize] = 0; + controller[_readableStreamDefaultControllerBits] = + enableBlinkLockNotifications ? BLINK_LOCK_NOTIFICATIONS : 0b0; + controller[_strategySizeAlgorithm] = sizeAlgorithm; + controller[_strategyHWM] = highWaterMark; + controller[_pullAlgorithm] = pullAlgorithm; + controller[_cancelAlgorithm] = cancelAlgorithm; + stream[_controller] = controller; + + thenPromise(Promise_resolve(startAlgorithm()), () => { + controller[_readableStreamDefaultControllerBits] |= STARTED; + ReadableStreamDefaultControllerCallPullIfNeeded(controller); + }, r => ReadableStreamDefaultControllerError(controller, r)); + } + + function SetUpReadableStreamDefaultControllerFromUnderlyingSource( + stream, underlyingSource, highWaterMark, sizeAlgorithm, + enableBlinkLockNotifications) { + const controller = ObjectCreate(ReadableStreamDefaultController_prototype); + const startAlgorithm = + () => CallOrNoop1(underlyingSource, 'start', controller, + 'underlyingSource.start'); + const pullAlgorithm = CreateAlgorithmFromUnderlyingMethodPassingController( + underlyingSource, 'pull', 0, controller, 'underlyingSource.pull'); + const cancelAlgorithm = CreateAlgorithmFromUnderlyingMethod( + underlyingSource, 'cancel', 1, 'underlyingSource.cancel'); + // TODO(ricea): Remove this once C++ API has been updated. + if (enableBlinkLockNotifications) { + controller[_lockNotifyTarget] = underlyingSource; + } + SetUpReadableStreamDefaultController( + stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, + highWaterMark, sizeAlgorithm, enableBlinkLockNotifications); + } + // // Internal functions. Not part of the standard. // @@ -1160,6 +1183,8 @@ binding.ReadableStreamDefaultControllerError = ReadableStreamDefaultControllerError; + // TODO(ricea): Remove this once the C++ code switches to calling + // CreateReadableStream(). binding.createReadableStreamWithExternalController = (underlyingSource, strategy) => { return new ReadableStream( @@ -1169,7 +1194,7 @@ // // Exports to TransformStream // - binding.ReadableStream = ReadableStream; + binding.CreateReadableStream = CreateReadableStream; binding.ReadableStreamDefaultControllerCanCloseOrEnqueue = ReadableStreamDefaultControllerCanCloseOrEnqueue; binding.ReadableStreamDefaultControllerHasBackpressure =
diff --git a/third_party/WebKit/Source/core/streams/TransformStream.js b/third_party/WebKit/Source/core/streams/TransformStream.js index 7670a5b..fc8f9695 100644 --- a/third_party/WebKit/Source/core/streams/TransformStream.js +++ b/third_party/WebKit/Source/core/streams/TransformStream.js
@@ -176,18 +176,15 @@ stream[_writable] = binding.CreateWritableStream( startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm); - // TODO(ricea): Use CreateReadableStream() once it is implemented. - stream[_readable] = new binding.ReadableStream({ - start: startAlgorithm, - pull() { - return TransformStreamDefaultSourcePullAlgorithm(stream); - }, - cancel(reason) { - TransformStreamErrorWritableAndUnblockWrite(stream, reason); - return Promise_resolve(); - }, - type: undefined, - }, {highWaterMark: readableHighWaterMark, size: readableSizeAlgorithm}); + const pullAlgorithm = () => + TransformStreamDefaultSourcePullAlgorithm(stream); + const cancelAlgorithm = reason => { + TransformStreamErrorWritableAndUnblockWrite(stream, reason); + return Promise_resolve(undefined); + }; + stream[_readable] = binding.CreateReadableStream( + startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, + readableSizeAlgorithm, false); stream[_backpressure] = undefined; stream[_backpressureChangePromise] = undefined; TransformStreamSetBackpressure(stream, true);
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index 7e33341..04e8fe57 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -2518,6 +2518,14 @@ return false; } +void Internals::setMediaControlsTestMode(HTMLMediaElement* media_element, + bool enable) { + DCHECK(media_element); + MediaControls* media_controls = media_element->GetMediaControls(); + DCHECK(media_controls); + media_controls->SetTestMode(enable); +} + void Internals::registerURLSchemeAsBypassingContentSecurityPolicy( const String& scheme) { SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy(scheme);
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index 433e504..f25e1472 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -394,6 +394,7 @@ void setPersistent(HTMLVideoElement*, bool); void forceStaleStateForMediaElement(HTMLMediaElement*, int target_state); bool isMediaElementSuspended(HTMLMediaElement*); + void setMediaControlsTestMode(HTMLMediaElement*, bool); void registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme); void registerURLSchemeAsBypassingContentSecurityPolicy(
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl index 0316d440..ef90d2b 100644 --- a/third_party/WebKit/Source/core/testing/Internals.idl +++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -240,6 +240,7 @@ void setPersistent(HTMLVideoElement video, boolean persistent); void forceStaleStateForMediaElement(HTMLMediaElement mediaElement, long state); boolean isMediaElementSuspended(HTMLMediaElement mediaElement); + void setMediaControlsTestMode(HTMLMediaElement mediaElement, boolean enable); void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme); void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme, sequence<DOMString> policyAreas);
diff --git a/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp index d204947..2ff0d01 100644 --- a/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp +++ b/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp
@@ -21,10 +21,11 @@ ResourceTimingInfo* info, TimeTicks time_origin, const WebVector<WebServerTimingInfo>& server_timing) - : PerformanceResourceTiming(info ? info->InitialURL().GetString() : "", - "navigation", - time_origin, - server_timing), + : PerformanceResourceTiming( + info ? info->FinalResponse().Url().GetString() : "", + "navigation", + time_origin, + server_timing), ContextClient(frame), resource_timing_info_(info) { DCHECK(frame);
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp index 9b7c56a..f21620a6a 100644 --- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp +++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
@@ -4,8 +4,7 @@ #include "core/workers/ParentFrameTaskRunners.h" -#include "core/dom/Document.h" -#include "core/frame/LocalFrame.h" +#include "core/execution_context/ExecutionContext.h" #include "platform/wtf/Assertions.h" #include "platform/wtf/ThreadingPrimitives.h" #include "public/platform/Platform.h" @@ -13,27 +12,27 @@ namespace blink { -ParentFrameTaskRunners* ParentFrameTaskRunners::Create(LocalFrame& frame) { - DCHECK(frame.GetDocument()); - DCHECK(frame.GetDocument()->IsContextThread()); - DCHECK(IsMainThread()); - return new ParentFrameTaskRunners(&frame); +ParentFrameTaskRunners* ParentFrameTaskRunners::Create( + ExecutionContext* context) { + DCHECK(context); + DCHECK(context->IsContextThread()); + return new ParentFrameTaskRunners(context); } ParentFrameTaskRunners* ParentFrameTaskRunners::Create() { return new ParentFrameTaskRunners(nullptr); } -ParentFrameTaskRunners::ParentFrameTaskRunners(LocalFrame* frame) - : ContextLifecycleObserver(frame ? frame->GetDocument() : nullptr) { +ParentFrameTaskRunners::ParentFrameTaskRunners(ExecutionContext* context) + : ContextLifecycleObserver(context) { // For now we only support very limited task types. for (auto type : {TaskType::kUnspecedTimer, TaskType::kUnspecedLoading, TaskType::kNetworking, TaskType::kPostedMessage, TaskType::kCanvasBlobSerialization, TaskType::kUnthrottled, TaskType::kInternalTest}) { - auto task_runner = frame - ? frame->GetTaskRunner(type) - : Platform::Current()->MainThread()->GetTaskRunner(); + auto task_runner = + context ? context->GetTaskRunner(type) + : Platform::Current()->CurrentThread()->GetTaskRunner(); task_runners_.insert(type, std::move(task_runner)); } }
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h index 1e136ee..9737ea7 100644 --- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h +++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
@@ -17,24 +17,21 @@ namespace blink { -class LocalFrame; - -// Represents a set of task runners of the parent (or associated) document's -// frame, or default task runners of the main thread. -// -// This observes LocalFrame lifecycle only when this is created with LocalFrame. +// Represents a set of task runners of the parent execution context, or default +// task runners for the current thread if no execution context is available. +// TODO(japhet): Rename to something like ParentExecutionContextTaskRunners. class CORE_EXPORT ParentFrameTaskRunners final : public GarbageCollectedFinalized<ParentFrameTaskRunners>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(ParentFrameTaskRunners); public: - // Returns task runners associated with a given frame. This must be called on - // the frame's context thread, that is, the main thread. The given frame must - // have a valid execution context. - static ParentFrameTaskRunners* Create(LocalFrame&); + // Returns task runners associated with a given context. This must be called + // on the context's context thread, that is, the thread where the context was + // created. + static ParentFrameTaskRunners* Create(ExecutionContext*); - // Returns default task runners of the main thread. This can be called from + // Returns default task runners of the current thread. This can be called from // any threads. This must be used only for shared workers, service workers and // tests that don't have a parent frame. static ParentFrameTaskRunners* Create(); @@ -52,9 +49,9 @@ WTF::IntHash<TaskType>, TaskTypeTraits>; - // LocalFrame could be nullptr if the worker is not associated with a - // particular local frame. - explicit ParentFrameTaskRunners(LocalFrame*); + // ExecutionContext could be nullptr if the worker is not associated with a + // particular context. + explicit ParentFrameTaskRunners(ExecutionContext*); void ContextDestroyed(ExecutionContext*) LOCKS_EXCLUDED(mutex_) override;
diff --git a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp index de5c243..87d8b549 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
@@ -13,6 +13,7 @@ #include "core/loader/ThreadableLoadingContext.h" #include "core/loader/WorkerFetchContext.h" #include "core/workers/GlobalScopeCreationParams.h" +#include "core/workers/WorkerGlobalScope.h" #include "core/workers/WorkerInspectorProxy.h" #include "platform/loader/fetch/ResourceFetcher.h" #include "platform/wtf/Time.h" @@ -32,8 +33,8 @@ ExecutionContext* execution_context) : execution_context_(execution_context), worker_inspector_proxy_(WorkerInspectorProxy::Create()), - parent_frame_task_runners_(ParentFrameTaskRunners::Create( - *ToDocument(execution_context_.Get())->GetFrame())), + parent_frame_task_runners_( + ParentFrameTaskRunners::Create(execution_context_.Get())), terminate_sync_load_event_( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED), @@ -61,22 +62,27 @@ const WTF::Optional<WorkerBackingThreadStartupData>& thread_startup_data) { DCHECK(IsParentContextThread()); - Document* document = ToDocument(GetExecutionContext()); KURL script_url = global_scope_creation_params->script_url.Copy(); - WebLocalFrameImpl* web_frame = - WebLocalFrameImpl::FromFrame(document->GetFrame()); - // |web_frame| is null in some unit tests. - if (web_frame) { - std::unique_ptr<WebWorkerFetchContext> web_worker_fetch_context = - web_frame->Client()->CreateWorkerFetchContext(); - DCHECK(web_worker_fetch_context); + std::unique_ptr<WebWorkerFetchContext> web_worker_fetch_context; + if (execution_context_->IsDocument()) { + // |web_frame| is null in some unit tests. + if (WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame( + ToDocument(GetExecutionContext())->GetFrame())) { + web_worker_fetch_context = + web_frame->Client()->CreateWorkerFetchContext(); + DCHECK(web_worker_fetch_context); + web_worker_fetch_context->SetApplicationCacheHostID( + GetExecutionContext()->Fetcher()->Context().ApplicationCacheHostID()); + web_worker_fetch_context->SetIsOnSubframe(web_frame != web_frame->Top()); + } + } + // TODO(japhet): Add a way to clone a WebWorkerFetchContext between worker + // threads for nested workers. + + if (web_worker_fetch_context) { web_worker_fetch_context->SetTerminateSyncLoadEvent( &terminate_sync_load_event_); - web_worker_fetch_context->SetApplicationCacheHostID( - document->Fetcher()->Context().ApplicationCacheHostID()); - web_worker_fetch_context->SetIsOnSubframe( - document->GetFrame() != document->GetFrame()->Tree().Top()); ProvideWorkerFetchContextToWorker( global_scope_creation_params->worker_clients, std::move(web_worker_fetch_context)); @@ -85,10 +91,10 @@ worker_thread_ = CreateWorkerThread(); worker_thread_->Start( std::move(global_scope_creation_params), thread_startup_data, - GetWorkerInspectorProxy()->ShouldPauseOnWorkerStart(document), + GetWorkerInspectorProxy()->ShouldPauseOnWorkerStart(execution_context_), GetParentFrameTaskRunners()); - GetWorkerInspectorProxy()->WorkerThreadCreated(document, GetWorkerThread(), - script_url); + GetWorkerInspectorProxy()->WorkerThreadCreated(execution_context_, + GetWorkerThread(), script_url); } void ThreadedMessagingProxyBase::CountFeature(WebFeature feature) { @@ -166,7 +172,7 @@ ThreadableLoadingContext* ThreadedMessagingProxyBase::CreateThreadableLoadingContext() const { DCHECK(IsParentContextThread()); - return ThreadableLoadingContext::Create(*ToDocument(execution_context_)); + return ThreadableLoadingContext::Create(*execution_context_); } ExecutionContext* ThreadedMessagingProxyBase::GetExecutionContext() const { @@ -192,10 +198,7 @@ } bool ThreadedMessagingProxyBase::IsParentContextThread() const { - // TODO(nhiroki): Nested worker is not supported yet, so the parent context - // thread should be equal to the main thread (http://crbug.com/31666). - DCHECK(execution_context_->IsDocument()); - return IsMainThread(); + return execution_context_->IsContextThread(); } } // namespace blink
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index 913d62a..78a107a 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -461,6 +461,9 @@ "front_end/perf_ui/pieChart.css", "front_end/perf_ui/timelineGrid.css", "front_end/perf_ui/timelineOverviewInfo.css", + "front_end/performance_monitor/PerformanceMonitor.js", + "front_end/performance_monitor/performanceMonitor.css", + "front_end/performance_monitor/module.json", "front_end/performance_test_runner/module.json", "front_end/performance_test_runner/TimelineDataTestRunner.js", "front_end/performance_test_runner/TimelineTestRunner.js", @@ -742,8 +745,6 @@ "front_end/timeline/timelineStatusDialog.css", "front_end/timeline/TimelineTreeView.js", "front_end/timeline/TimelineUIUtils.js", - "front_end/timeline/PerformanceMonitor.js", - "front_end/timeline/performanceMonitor.css", "front_end/toolbox_bootstrap/module.json", "front_end/toolbox_bootstrap/Toolbox.js", "front_end/toolbox.js", @@ -1028,6 +1029,7 @@ "$resources_out_dir/node_debugger/node_debugger_module.js", "$resources_out_dir/object_ui/object_ui_module.js", "$resources_out_dir/perf_ui/perf_ui_module.js", + "$resources_out_dir/performance_monitor/performance_monitor_module.js", "$resources_out_dir/profiler/profiler_module.js", "$resources_out_dir/quick_open/quick_open_module.js", "$resources_out_dir/resources/resources_module.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/devtools_app.json b/third_party/WebKit/Source/devtools/front_end/devtools_app.json index 4298706..e444158 100644 --- a/third_party/WebKit/Source/devtools/front_end/devtools_app.json +++ b/third_party/WebKit/Source/devtools/front_end/devtools_app.json
@@ -19,6 +19,7 @@ { "name": "layers" }, { "name": "layer_viewer" }, { "name": "network" }, + { "name": "performance_monitor" }, { "name": "product_registry_impl", "type": "remote" }, { "name": "resources" }, { "name": "security" },
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceMonitor.js b/third_party/WebKit/Source/devtools/front_end/performance_monitor/PerformanceMonitor.js similarity index 86% rename from third_party/WebKit/Source/devtools/front_end/timeline/PerformanceMonitor.js rename to third_party/WebKit/Source/devtools/front_end/performance_monitor/PerformanceMonitor.js index b3e4db97..cd83433 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceMonitor.js +++ b/third_party/WebKit/Source/devtools/front_end/performance_monitor/PerformanceMonitor.js
@@ -5,10 +5,10 @@ /** * @unrestricted */ -Timeline.PerformanceMonitor = class extends UI.HBox { +PerformanceMonitor.PerformanceMonitor = class extends UI.HBox { constructor() { super(true); - this.registerRequiredCSS('timeline/performanceMonitor.css'); + this.registerRequiredCSS('performance_monitor/performanceMonitor.css'); this.contentElement.classList.add('perfmon-pane'); this._model = SDK.targetManager.mainTarget().model(SDK.PerformanceMetricsModel); /** @type {!Array<!{timestamp: number, metrics: !Map<string, number>}>} */ @@ -22,13 +22,13 @@ /** @const */ this._graphHeight = 90; this._gridColor = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.08)', UI.ThemeSupport.ColorUsage.Foreground); - this._controlPane = new Timeline.PerformanceMonitor.ControlPane(this.contentElement); + this._controlPane = new PerformanceMonitor.PerformanceMonitor.ControlPane(this.contentElement); const chartContainer = this.contentElement.createChild('div', 'perfmon-chart-container'); this._canvas = /** @type {!HTMLCanvasElement} */ (chartContainer.createChild('canvas')); this.contentElement.createChild('div', 'perfmon-chart-suspend-overlay fill').createChild('div').textContent = Common.UIString('Paused'); this._controlPane.addEventListener( - Timeline.PerformanceMonitor.ControlPane.Events.MetricChanged, this._recalcChartHeight, this); + PerformanceMonitor.PerformanceMonitor.ControlPane.Events.MetricChanged, this._recalcChartHeight, this); } /** @@ -66,7 +66,7 @@ animate.call(this); /** - * @this {Timeline.PerformanceMonitor} + * @this {PerformanceMonitor.PerformanceMonitor} */ function animate() { this._draw(); @@ -135,7 +135,7 @@ /** * @param {!CanvasRenderingContext2D} ctx - * @param {!Timeline.PerformanceMonitor.ChartInfo} chartInfo + * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} chartInfo * @param {number} height */ _drawChart(ctx, chartInfo, height) { @@ -172,7 +172,7 @@ } /** - * @param {!Timeline.PerformanceMonitor.ChartInfo} chartInfo + * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} chartInfo * @return {number} */ _calcMax(chartInfo) { @@ -205,7 +205,7 @@ * @param {!CanvasRenderingContext2D} ctx * @param {number} height * @param {number} max - * @param {!Timeline.PerformanceMonitor.ChartInfo} info + * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} info */ _drawVerticalGrid(ctx, height, max, info) { let base = Math.pow(10, Math.floor(Math.log10(max))); @@ -222,7 +222,7 @@ ctx.beginPath(); for (let i = 0; i < 2; ++i) { const y = calcY(scaleValue); - const labelText = Timeline.PerformanceMonitor.MetricIndicator._formatNumber(scaleValue, info); + const labelText = PerformanceMonitor.PerformanceMonitor.MetricIndicator._formatNumber(scaleValue, info); ctx.moveTo(0, y); ctx.lineTo(4, y); ctx.moveTo(ctx.measureText(labelText).width + 12, y); @@ -246,8 +246,8 @@ } /** - * @param {!Timeline.PerformanceMonitor.ChartInfo} chartInfo - * @param {!Timeline.PerformanceMonitor.MetricInfo} metricInfo + * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} chartInfo + * @param {!PerformanceMonitor.PerformanceMonitor.MetricInfo} metricInfo * @param {number} height * @param {number} scaleMax * @param {?Map<number, number>} stackedChartBaseLandscape @@ -333,7 +333,7 @@ }; /** @enum {symbol} */ -Timeline.PerformanceMonitor.Format = { +PerformanceMonitor.PerformanceMonitor.Format = { Percent: Symbol('Percent'), Bytes: Symbol('Bytes'), }; @@ -341,14 +341,14 @@ /** * @typedef {!{ * title: string, - * metrics: !Array<!Timeline.PerformanceMonitor.MetricInfo>, + * metrics: !Array<!PerformanceMonitor.PerformanceMonitor.MetricInfo>, * max: (number|undefined), * currentMax: (number|undefined), - * format: (!Timeline.PerformanceMonitor.Format|undefined), + * format: (!PerformanceMonitor.PerformanceMonitor.Format|undefined), * smooth: (boolean|undefined) * }} */ -Timeline.PerformanceMonitor.ChartInfo; +PerformanceMonitor.PerformanceMonitor.ChartInfo; /** * @typedef {!{ @@ -356,9 +356,9 @@ * color: string * }} */ -Timeline.PerformanceMonitor.MetricInfo; +PerformanceMonitor.PerformanceMonitor.MetricInfo; -Timeline.PerformanceMonitor.ControlPane = class extends Common.Object { +PerformanceMonitor.PerformanceMonitor.ControlPane = class extends Common.Object { /** * @param {!Element} parent */ @@ -370,9 +370,9 @@ Common.settings.createSetting('perfmonActiveIndicators2', ['TaskDuration', 'JSHeapTotalSize', 'Nodes']); /** @type {!Set<string>} */ this._enabledCharts = new Set(this._enabledChartsSetting.get()); - const format = Timeline.PerformanceMonitor.Format; + const format = PerformanceMonitor.PerformanceMonitor.Format; - /** @type {!Array<!Timeline.PerformanceMonitor.ChartInfo>} */ + /** @type {!Array<!PerformanceMonitor.PerformanceMonitor.ChartInfo>} */ this._chartsInfo = [ { title: Common.UIString('CPU usage'), @@ -404,12 +404,12 @@ metric.color = UI.themeSupport.patchColorText(metric.color, UI.ThemeSupport.ColorUsage.Foreground); } - /** @type {!Map<string, !Timeline.PerformanceMonitor.MetricIndicator>} */ + /** @type {!Map<string, !PerformanceMonitor.PerformanceMonitor.MetricIndicator>} */ this._indicators = new Map(); for (const chartInfo of this._chartsInfo) { const chartName = chartInfo.metrics[0].name; const active = this._enabledCharts.has(chartName); - const indicator = new Timeline.PerformanceMonitor.MetricIndicator( + const indicator = new PerformanceMonitor.PerformanceMonitor.MetricIndicator( this.element, chartInfo, active, this._onToggle.bind(this, chartName)); this._indicators.set(chartName, indicator); } @@ -425,11 +425,11 @@ else this._enabledCharts.delete(chartName); this._enabledChartsSetting.set(Array.from(this._enabledCharts)); - this.dispatchEventToListeners(Timeline.PerformanceMonitor.ControlPane.Events.MetricChanged); + this.dispatchEventToListeners(PerformanceMonitor.PerformanceMonitor.ControlPane.Events.MetricChanged); } /** - * @return {!Array<!Timeline.PerformanceMonitor.ChartInfo>} + * @return {!Array<!PerformanceMonitor.PerformanceMonitor.ChartInfo>} */ charts() { return this._chartsInfo; @@ -455,14 +455,14 @@ }; /** @enum {symbol} */ -Timeline.PerformanceMonitor.ControlPane.Events = { +PerformanceMonitor.PerformanceMonitor.ControlPane.Events = { MetricChanged: Symbol('MetricChanged') }; -Timeline.PerformanceMonitor.MetricIndicator = class { +PerformanceMonitor.PerformanceMonitor.MetricIndicator = class { /** * @param {!Element} parent - * @param {!Timeline.PerformanceMonitor.ChartInfo} info + * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} info * @param {boolean} active * @param {function(boolean)} onToggle */ @@ -484,14 +484,14 @@ /** * @param {number} value - * @param {!Timeline.PerformanceMonitor.ChartInfo} info + * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} info * @return {string} */ static _formatNumber(value, info) { switch (info.format) { - case Timeline.PerformanceMonitor.Format.Percent: + case PerformanceMonitor.PerformanceMonitor.Format.Percent: return value.toLocaleString('en-US', {maximumFractionDigits: 1, style: 'percent'}); - case Timeline.PerformanceMonitor.Format.Bytes: + case PerformanceMonitor.PerformanceMonitor.Format.Bytes: return Number.bytesToString(value); default: return value.toLocaleString('en-US', {maximumFractionDigits: 1}); @@ -502,7 +502,8 @@ * @param {number} value */ setValue(value) { - this._valueElement.textContent = Timeline.PerformanceMonitor.MetricIndicator._formatNumber(value, this._info); + this._valueElement.textContent = + PerformanceMonitor.PerformanceMonitor.MetricIndicator._formatNumber(value, this._info); } _toggleIndicator() { @@ -512,4 +513,5 @@ } }; -Timeline.PerformanceMonitor.MetricIndicator._format = new Intl.NumberFormat('en-US', {maximumFractionDigits: 1}); +PerformanceMonitor.PerformanceMonitor.MetricIndicator._format = + new Intl.NumberFormat('en-US', {maximumFractionDigits: 1});
diff --git a/third_party/WebKit/Source/devtools/front_end/performance_monitor/module.json b/third_party/WebKit/Source/devtools/front_end/performance_monitor/module.json new file mode 100644 index 0000000..e86cc98 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/performance_monitor/module.json
@@ -0,0 +1,24 @@ +{ + "extensions": [ + { + "type": "view", + "location": "drawer-view", + "id": "performance.monitor", + "title": "Performance monitor", + "persistence": "closeable", + "order": 100, + "className": "PerformanceMonitor.PerformanceMonitor", + "tags": "performance, system monitor, monitor, activity, metrics" + } + ], + "dependencies": [ + "sdk", + "ui" + ], + "scripts": [ + "PerformanceMonitor.js" + ], + "resources": [ + "performanceMonitor.css" + ] +}
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/performanceMonitor.css b/third_party/WebKit/Source/devtools/front_end/performance_monitor/performanceMonitor.css similarity index 100% rename from third_party/WebKit/Source/devtools/front_end/timeline/performanceMonitor.css rename to third_party/WebKit/Source/devtools/front_end/performance_monitor/performanceMonitor.css
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/module.json b/third_party/WebKit/Source/devtools/front_end/timeline/module.json index c3450ac..75f4094 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/module.json +++ b/third_party/WebKit/Source/devtools/front_end/timeline/module.json
@@ -9,16 +9,6 @@ "className": "Timeline.TimelinePanel" }, { - "type": "view", - "location": "drawer-view", - "id": "performance.monitor", - "title": "Performance monitor", - "persistence": "closeable", - "order": 100, - "className": "Timeline.PerformanceMonitor", - "tags": "performance, system monitor, monitor, activity, metrics" - }, - { "type": "setting", "category": "Performance", "title": "Hide chrome frame in Layers view", @@ -239,7 +229,6 @@ "mobile_throttling" ], "scripts": [ - "PerformanceMonitor.js", "CountersGraph.js", "ExtensionTracingSession.js", "PerformanceModel.js", @@ -260,7 +249,6 @@ "TimelinePanel.js" ], "resources": [ - "performanceMonitor.css", "historyToolbarButton.css", "invalidationsTree.css", "timelineFlamechartPopover.css",
diff --git a/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp b/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp index f27da6e3..57ea9adc 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp
@@ -32,6 +32,8 @@ #include "core/layout/LayoutText.h" #include "core/layout/api/LineLayoutAPIShim.h" #include "modules/accessibility/AXObjectCacheImpl.h" +#include "modules/accessibility/AXPosition.h" +#include "modules/accessibility/AXRange.h" #include "platform/LayoutUnit.h" namespace blink { @@ -115,12 +117,14 @@ if (!inline_text_box_ || inline_text_box_->GetText().ContainsOnlyWhitespace()) return; - Vector<AbstractInlineTextBox::WordBoundaries> word_boundaries; - inline_text_box_->GetWordBoundaries(word_boundaries); - words.resize(word_boundaries.size()); - for (unsigned i = 0; i < word_boundaries.size(); i++) - words[i] = - AXRange(word_boundaries[i].start_index, word_boundaries[i].end_index); + Vector<AbstractInlineTextBox::WordBoundaries> boundaries; + inline_text_box_->GetWordBoundaries(boundaries); + words.ReserveCapacity(boundaries.size()); + for (const auto& boundary : boundaries) { + words.emplace_back( + AXPosition::CreatePositionInTextObject(*this, boundary.start_index), + AXPosition::CreatePositionInTextObject(*this, boundary.end_index)); + } } String AXInlineTextBox::GetName(AXNameFrom& name_from,
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp index fe1208a3..d3ea566 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -1775,13 +1775,13 @@ // Functions that retrieve the current selection. // -AXObject::AXRange AXLayoutObject::Selection() const { - AXRange text_selection = TextControlSelection(); +AXObject::AXSelection AXLayoutObject::Selection() const { + AXSelection text_selection = TextControlSelection(); if (text_selection.IsValid()) return text_selection; if (!GetLayoutObject() || !GetLayoutObject()->GetFrame()) - return AXRange(); + return {}; VisibleSelection selection = GetLayoutObject() @@ -1789,7 +1789,7 @@ ->Selection() .ComputeVisibleSelectionInDOMTreeDeprecated(); if (selection.IsNone()) - return AXRange(); + return {}; VisiblePosition visible_start = selection.VisibleStart(); Position start = visible_start.ToParentAnchoredPosition(); @@ -1812,12 +1812,12 @@ anchor_node = anchor_node->parentNode(); } if (!anchor_object) - return AXRange(); + return {}; int anchor_offset = anchor_object->IndexForVisiblePosition(visible_start); DCHECK_GE(anchor_offset, 0); if (selection.IsCaret()) { - return AXRange(anchor_object, anchor_offset, start_affinity, anchor_object, - anchor_offset, start_affinity); + return {anchor_object, anchor_offset, start_affinity, + anchor_object, anchor_offset, start_affinity}; } VisiblePosition visible_end = selection.VisibleEnd(); @@ -1837,23 +1837,23 @@ focus_node = focus_node->parentNode(); } if (!focus_object) - return AXRange(); + return {}; int focus_offset = focus_object->IndexForVisiblePosition(visible_end); DCHECK_GE(focus_offset, 0); - return AXRange(anchor_object, anchor_offset, start_affinity, focus_object, - focus_offset, end_affinity); + return {anchor_object, anchor_offset, start_affinity, + focus_object, focus_offset, end_affinity}; } // Gets only the start and end offsets of the selection computed using the // current object as the starting point. Returns a null selection if there is // no selection in the subtree rooted at this object. -AXObject::AXRange AXLayoutObject::SelectionUnderObject() const { - AXRange text_selection = TextControlSelection(); +AXObject::AXSelection AXLayoutObject::SelectionUnderObject() const { + AXSelection text_selection = TextControlSelection(); if (text_selection.IsValid()) return text_selection; if (!GetNode() || !GetLayoutObject()->GetFrame()) - return AXRange(); + return {}; VisibleSelection selection = GetLayoutObject() @@ -1870,7 +1870,7 @@ IGNORE_EXCEPTION_FOR_TESTING) < 0 && selection_range->comparePoint(parent_node, node_index + 1, IGNORE_EXCEPTION_FOR_TESTING) > 0)) { - return AXRange(); + return {}; } int start = IndexForVisiblePosition(selection.VisibleStart()); @@ -1878,12 +1878,12 @@ int end = IndexForVisiblePosition(selection.VisibleEnd()); DCHECK_GE(end, 0); - return AXRange(start, end); + return {start, end}; } -AXObject::AXRange AXLayoutObject::TextControlSelection() const { +AXObject::AXSelection AXLayoutObject::TextControlSelection() const { if (!GetLayoutObject()) - return AXRange(); + return {}; LayoutObject* layout = nullptr; if (GetLayoutObject()->IsTextControl()) { @@ -1896,11 +1896,11 @@ } if (!layout) - return AXRange(); + return {}; AXObject* ax_object = AXObjectCache().GetOrCreate(layout); if (!ax_object || !ax_object->IsAXLayoutObject()) - return AXRange(); + return {}; VisibleSelection selection = layout->GetFrame() @@ -1912,8 +1912,8 @@ int start = text_control->selectionStart(); int end = text_control->selectionEnd(); - return AXRange(ax_object, start, selection.VisibleStart().Affinity(), - ax_object, end, selection.VisibleEnd().Affinity()); + return {ax_object, start, selection.VisibleStart().Affinity(), + ax_object, end, selection.VisibleEnd().Affinity()}; } int AXLayoutObject::IndexForVisiblePosition( @@ -2028,7 +2028,7 @@ return blink::VisiblePositionForIndex(node_index + offset, parent); } -bool AXLayoutObject::OnNativeSetSelectionAction(const AXRange& selection) { +bool AXLayoutObject::OnNativeSetSelectionAction(const AXSelection& selection) { if (!GetLayoutObject() || !selection.IsValid()) return false;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h index a9afe6d..9a96523f 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h
@@ -137,12 +137,12 @@ NameSources*) const override; // Modify or take an action on an object. - bool OnNativeSetSelectionAction(const AXRange&) override; + bool OnNativeSetSelectionAction(const AXSelection&) override; bool OnNativeSetValueAction(const String&) override; // Methods that retrieve or manipulate the current selection. - AXRange Selection() const override; - AXRange SelectionUnderObject() const override; + AXSelection Selection() const override; + AXSelection SelectionUnderObject() const override; // Hit testing. AXObject* AccessibilityHitTest(const IntPoint&) const override; @@ -203,7 +203,7 @@ void AddInlineTextBoxChildren(bool force); LayoutRect ComputeElementRect() const; - AXRange TextControlSelection() const; + AXSelection TextControlSelection() const; int IndexForVisiblePosition(const VisiblePosition&) const; AXLayoutObject* GetUnignoredObjectFromNode(Node&) const;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index f5bca07..9ae11d6 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -69,6 +69,8 @@ #include "core/layout/LayoutObject.h" #include "core/svg/SVGElement.h" #include "modules/accessibility/AXObjectCacheImpl.h" +#include "modules/accessibility/AXPosition.h" +#include "modules/accessibility/AXRange.h" #include "modules/media_controls/elements/MediaControlElementsHelper.h" #include "platform/text/PlatformLocale.h" #include "platform/weborigin/KURL.h" @@ -1151,14 +1153,18 @@ if (!GetNode() || !GetDocument() || !GetDocument()->View()) return; + if (!GetNode()->IsTextNode()) + return; + DocumentMarkerController& marker_controller = GetDocument()->Markers(); DocumentMarkerVector markers = marker_controller.MarkersFor(GetNode()); for (size_t i = 0; i < markers.size(); ++i) { DocumentMarker* marker = markers[i]; if (MarkerTypeIsUsedForAccessibility(marker->GetType())) { marker_types.push_back(marker->GetType()); - marker_ranges.push_back( - AXRange(marker->StartOffset(), marker->EndOffset())); + marker_ranges.emplace_back( + AXPosition::CreatePositionInTextObject(*this, marker->StartOffset()), + AXPosition::CreatePositionInTextObject(*this, marker->EndOffset())); } } }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp index 1a093c1..8db07e6 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp
@@ -51,6 +51,7 @@ #include "core/layout/LayoutView.h" #include "core/page/Page.h" #include "modules/accessibility/AXObjectCacheImpl.h" +#include "modules/accessibility/AXRange.h" #include "modules/accessibility/AXSparseAttributeSetter.h" #include "platform/scroll/ScrollAlignment.h" #include "platform/text/PlatformLocale.h" @@ -1475,6 +1476,13 @@ return kAccessibilityOrientationUndefined; } +void AXObject::Markers(Vector<DocumentMarker::MarkerType>&, + Vector<AXRange>&) const {} + +void AXObject::TextCharacterOffsets(Vector<int>&) const {} + +void AXObject::GetWordBoundaries(Vector<AXRange>&) const {} + AXDefaultActionVerb AXObject::Action() const { Element* action_element = ActionElement(); if (!action_element) @@ -2334,8 +2342,8 @@ return OnNativeSetSelectedAction(selected); } -bool AXObject::RequestSetSelectionAction(const AXRange& range) { - return OnNativeSetSelectionAction(range); +bool AXObject::RequestSetSelectionAction(const AXSelection& selection) { + return OnNativeSetSelectionAction(selection); } bool AXObject::RequestSetSequentialFocusNavigationStartingPointAction() { @@ -2446,7 +2454,7 @@ return false; } -bool AXObject::OnNativeSetSelectionAction(const AXRange& range) { +bool AXObject::OnNativeSetSelectionAction(const AXSelection& selection) { return false; }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.h b/third_party/WebKit/Source/modules/accessibility/AXObject.h index c2d90dc..2c208e65 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.h
@@ -53,6 +53,7 @@ class AccessibleNodeList; class AXObject; class AXObjectCacheImpl; +class AXRange; class IntPoint; class LayoutObject; class LocalFrameView; @@ -165,7 +166,7 @@ public: typedef HeapVector<Member<AXObject>> AXObjectVector; - struct AXRange { + struct AXSelection { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); // The deepest descendant in which the range starts. // (nullptr means the current object.) @@ -189,7 +190,7 @@ // than the next line. TextAffinity focus_affinity; - AXRange() + AXSelection() : anchor_object(nullptr), anchor_offset(-1), anchor_affinity(TextAffinity::kUpstream), @@ -197,7 +198,7 @@ focus_offset(-1), focus_affinity(TextAffinity::kDownstream) {} - AXRange(int start_offset, int end_offset) + AXSelection(int start_offset, int end_offset) : anchor_object(nullptr), anchor_offset(start_offset), anchor_affinity(TextAffinity::kUpstream), @@ -205,12 +206,12 @@ focus_offset(end_offset), focus_affinity(TextAffinity::kDownstream) {} - AXRange(AXObject* anchor_object, - int anchor_offset, - TextAffinity anchor_affinity, - AXObject* focus_object, - int focus_offset, - TextAffinity focus_affinity) + AXSelection(AXObject* anchor_object, + int anchor_offset, + TextAffinity anchor_affinity, + AXObject* focus_object, + int focus_offset, + TextAffinity focus_affinity) : anchor_object(anchor_object), anchor_offset(anchor_offset), anchor_affinity(anchor_affinity), @@ -524,13 +525,13 @@ // For all node objects. The start and end character offset of each // marker, such as spelling or grammar error. virtual void Markers(Vector<DocumentMarker::MarkerType>&, - Vector<AXRange>&) const {} + Vector<AXRange>&) const; // For an inline text box. // The integer horizontal pixel offset of each character in the string; // negative values for RTL. - virtual void TextCharacterOffsets(Vector<int>&) const {} + virtual void TextCharacterOffsets(Vector<int>&) const; // The start and end character offset of each word in the object's text. - virtual void GetWordBoundaries(Vector<AXRange>&) const {} + virtual void GetWordBoundaries(Vector<AXRange>&) const; // Properties of interactive elements. AXDefaultActionVerb Action() const; @@ -692,11 +693,11 @@ // Methods that retrieve or manipulate the current selection. // Get the current selection from anywhere in the accessibility tree. - virtual AXRange Selection() const { return AXRange(); } + virtual AXSelection Selection() const { return AXSelection(); } // Gets only the start and end offsets of the selection computed using the // current object as the starting point. Returns a null selection if there is // no selection in the subtree rooted at this object. - virtual AXRange SelectionUnderObject() const { return AXRange(); } + virtual AXSelection SelectionUnderObject() const { return AXSelection(); } // Scrollable containers. bool IsScrollableContainer() const; @@ -729,7 +730,7 @@ bool RequestScrollToMakeVisibleAction(); bool RequestScrollToMakeVisibleWithSubFocusAction(const IntRect&); bool RequestSetSelectedAction(bool); - bool RequestSetSelectionAction(const AXRange&); + bool RequestSetSelectionAction(const AXSelection&); bool RequestSetSequentialFocusNavigationStartingPointAction(); bool RequestSetValueAction(const String&); bool RequestShowContextMenuAction(); @@ -745,7 +746,7 @@ virtual bool OnNativeScrollToMakeVisibleWithSubFocusAction( const IntRect&) const; virtual bool OnNativeSetSelectedAction(bool); - virtual bool OnNativeSetSelectionAction(const AXRange&); + virtual bool OnNativeSetSelectionAction(const AXSelection&); virtual bool OnNativeSetSequentialFocusNavigationStartingPointAction(); virtual bool OnNativeSetValueAction(const String&); virtual bool OnNativeShowContextMenuAction();
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.cpp index 8439a00..c974ca17 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.cpp +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.cpp
@@ -19,12 +19,16 @@ #include "public/platform/WebSize.h" #include "public/platform/WebURLRequest.h" #include "skia/ext/image_operations.h" +#include "third_party/WebKit/Source/platform/wtf/text/StringImpl.h" namespace blink { namespace { const unsigned long kIconFetchTimeoutInMs = 30000; +const int kMinimumIconSizeInPx = 16; +const double kAnySizeScore = 0.8; +const double kUnspecifiedSizeScore = 0.4; } // namespace @@ -34,7 +38,6 @@ DCHECK(stopped_ || icon_callback_.is_null()); } -// TODO(nator): Add functionality to select which icon to load. void BackgroundFetchIconLoader::Start(BackgroundFetchBridge* bridge, ExecutionContext* execution_context, HeapVector<IconDefinition> icons, @@ -54,19 +57,20 @@ ExecutionContext* execution_context, IconCallback icon_callback, const WebSize& icon_display_size_pixels) { - // TODO(nator): Pick the appropriate icon based on display size instead, - // and resize it, if needed. - if (icon_display_size_pixels.IsEmpty() || !icons_[0].hasSrc()) { + if (icon_display_size_pixels.IsEmpty()) { std::move(icon_callback).Run(SkBitmap()); return; } - KURL first_icon_url = execution_context->CompleteURL(icons_[0].src()); - if (!first_icon_url.IsValid() || first_icon_url.IsEmpty()) { + int best_icon_index = + PickBestIconForDisplay(execution_context, icon_display_size_pixels); + if (best_icon_index < 0) { + // None of the icons provided was suitable. std::move(icon_callback).Run(SkBitmap()); return; } - + KURL best_icon_url = + execution_context->CompleteURL(icons_[best_icon_index].src()); icon_callback_ = std::move(icon_callback); ThreadableLoaderOptions threadable_loader_options; @@ -76,7 +80,7 @@ if (execution_context->IsWorkerGlobalScope()) resource_loader_options.request_initiator_context = kWorkerContext; - ResourceRequest resource_request(first_icon_url); + ResourceRequest resource_request(best_icon_url); resource_request.SetRequestContext(WebURLRequest::kRequestContextImage); resource_request.SetPriority(ResourceLoadPriority::kMedium); resource_request.SetRequestorOrigin(execution_context->GetSecurityOrigin()); @@ -88,6 +92,96 @@ threadable_loader_->Start(resource_request); } +int BackgroundFetchIconLoader::PickBestIconForDisplay( + ExecutionContext* execution_context, + const WebSize& icon_display_size_pixels) { + int best_index = -1; + double best_score = 0.0; + for (size_t i = 0; i < icons_.size(); ++i) { + // If the icon has no or invalid src, move on. + if (!icons_[i].hasSrc()) + continue; + KURL icon_url = execution_context->CompleteURL(icons_[i].src()); + if (!icon_url.IsValid() || icon_url.IsEmpty()) + continue; + + double score = GetIconScore(icons_[i], icon_display_size_pixels.width); + if (!score) + continue; + // According to the spec, if two icons get the same score, we must use the + // one that's declared last. (https://w3c.github.io/manifest/#icons-member). + if (score >= best_score) { + best_score = score; + best_index = i; + } + } + return best_index; +} + +// The scoring works as follows: +// When the size is "any", the icon size score is kAnySizeScore. +// If unspecified, use the unspecified size score, kUnspecifiedSizeScore as +// icon score. + +// For other sizes, the icon score lies in [0,1] and is computed by multiplying +// the dominant size score and aspect ratio score. +// +// The dominant size score lies in [0, 1] and is computed using +// dominant size and and |ideal_size|: +// - If dominant_size < kMinimumIconSizeInPx, the size score is 0.0. +// - For all other sizes, the score is calculated as +// 1/(1 + abs(dominant_size-ideal_size)) +// - If dominant_size < ideal_size, there is an upscaling penalty, which is +// dominant_size/ideal_size. +// +// The aspect ratio score lies in [0, 1] and is computed by dividing the short +// edge length by the long edge. (Bias towards square icons assumed). +// +// Note: If this is an ico file containing multiple sizes, return the best +// score. +double BackgroundFetchIconLoader::GetIconScore(IconDefinition icon, + const int ideal_size) { + // Extract sizes from the icon definition, expressed as "<width>x<height> + // <width>x<height> ...." + if (!icon.hasSizes() || icon.sizes().IsEmpty()) + return kUnspecifiedSizeScore; + + String sizes = icon.sizes(); + // if any size is set to "any" return kAnySizeScore; + if (sizes.LowerASCII() == "any") + return kAnySizeScore; + + Vector<String> sizes_str; + sizes.Split(" ", false /* allow_empty_entries*/, sizes_str); + + // Pick the first size. + // TODO(nator): Add support for multiple sizes (.ico files). + Vector<String> width_and_height_str; + sizes_str[0].Split("x", false /* allow_empty_entries */, + width_and_height_str); + // If sizes isn't in this format, consider it as 'unspecified'. + if (width_and_height_str.size() != 2) + return kUnspecifiedSizeScore; + double width = width_and_height_str[0].ToDouble(); + double height = width_and_height_str[1].ToDouble(); + + // Compute dominant size score + int dominant_size = std::max(width, height); + int short_size = std::min(width, height); + if (dominant_size < kMinimumIconSizeInPx) + return 0.0; + + double dominant_size_score = 1.0 / (1.0 + abs(dominant_size - ideal_size)); + if (dominant_size < ideal_size) + dominant_size_score = dominant_size_score * dominant_size / ideal_size; + // Compute aspect ratio score. If dominant_size is zero, we'd have returned + // by now. + double aspect_ratio_score = short_size / dominant_size; + + // Compute icon score. + return aspect_ratio_score * dominant_size_score; +} + void BackgroundFetchIconLoader::Stop() { if (stopped_) return;
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.h b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.h index 17fcd1f..54a51b4d 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.h +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoader.h
@@ -68,6 +68,16 @@ IconCallback, const WebSize& icon_display_size_pixels); + // Picks the best icon from the list of developer provided icons, for current + // display, given the ideal |icon_display_size_pixels|, and returns its index + // in the icons_ array. + int PickBestIconForDisplay(ExecutionContext*, + const WebSize& icon_display_size_pixels); + + // Get a score for the given icon, based on ideal_size. The icon with the + // highest score is chosen. + double GetIconScore(IconDefinition, const int ideal_size); + bool stopped_ = false; scoped_refptr<SharedBuffer> data_; IconCallback icon_callback_;
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoaderTest.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoaderTest.cpp index ff796ad..703f3f0 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoaderTest.cpp +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchIconLoaderTest.cpp
@@ -28,6 +28,9 @@ constexpr char kBackgroundFetchImageLoaderBaseUrl[] = "http://test.com/"; constexpr char kBackgroundFetchImageLoaderBaseDir[] = "notifications/"; constexpr char kBackgroundFetchImageLoaderIcon500x500[] = "500x500.png"; +constexpr char kBackgroundFetchImageLoaderIcon48x48[] = "48x48.png"; +constexpr char kBackgroundFetchImageLoaderIcon3000x2000[] = "3000x2000.png"; +constexpr char kBackgroundFetchImageLoaderIcon[] = "3000x2000.png"; } // namespace @@ -60,6 +63,21 @@ loaded_ = BackgroundFetchLoadState::kLoadFailed; } + IconDefinition CreateTestIcon(const String& url_str, const String& size) { + KURL url = RegisterMockedURL(url_str); + IconDefinition icon; + icon.setSrc(url.GetString()); + icon.setType("image/png"); + icon.setSizes(size); + return icon; + } + + int PickRightIcon(HeapVector<IconDefinition> icons, + const WebSize& ideal_display_size) { + loader_->icons_ = std::move(icons); + return loader_->PickBestIconForDisplay(GetContext(), ideal_display_size); + } + void LoadIcon(const KURL& url) { IconDefinition icon; icon.setSrc(url.GetString()); @@ -90,4 +108,54 @@ EXPECT_EQ(BackgroundFetchLoadState::kLoadSuccessful, loaded_); } +TEST_F(BackgroundFetchIconLoaderTest, PickRightIconTest) { + IconDefinition icon0 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500"); + IconDefinition icon1 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon48x48, "48x48"); + IconDefinition icon2 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon3000x2000, "3000x2000"); + + HeapVector<IconDefinition> icons; + icons.push_back(icon0); + icons.push_back(icon1); + icons.push_back(icon2); + + int index = PickRightIcon(std::move(icons), WebSize(50, 50)); + EXPECT_EQ(index, 1); +} + +TEST_F(BackgroundFetchIconLoaderTest, PickRightIconGivenAnyTest) { + IconDefinition icon0 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500"); + IconDefinition icon1 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon48x48, "48x48"); + IconDefinition icon2 = CreateTestIcon(kBackgroundFetchImageLoaderIcon, "any"); + + HeapVector<IconDefinition> icons; + icons.push_back(icon0); + icons.push_back(icon1); + icons.push_back(icon2); + + int index = PickRightIcon(std::move(icons), WebSize(50, 50)); + EXPECT_EQ(index, 2); +} + +TEST_F(BackgroundFetchIconLoaderTest, PickRightIconWithTieBreakTest) { + // Test that if two icons get the same score, the one declared last gets + // picked. + IconDefinition icon0 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500"); + IconDefinition icon1 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon48x48, "48x48"); + IconDefinition icon2 = + CreateTestIcon(kBackgroundFetchImageLoaderIcon3000x2000, "48x48"); + HeapVector<IconDefinition> icons; + icons.push_back(icon0); + icons.push_back(icon1); + icons.push_back(icon2); + int index = PickRightIcon(std::move(icons), WebSize(50, 50)); + EXPECT_EQ(index, 2); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp index 603aba6a..cad11690b 100644 --- a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp +++ b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
@@ -169,7 +169,7 @@ // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. Document* doc = ToDocumentOrNull(context); - if (!Frame::ConsumeTransientUserActivation(doc ? doc->GetFrame() : nullptr)) { + if (!Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) { return ScriptPromise::RejectWithDOMException( script_state, DOMException::Create(
diff --git a/third_party/WebKit/Source/modules/exported/WebAXObject.cpp b/third_party/WebKit/Source/modules/exported/WebAXObject.cpp index 366767e..bdf573fe 100644 --- a/third_party/WebKit/Source/modules/exported/WebAXObject.cpp +++ b/third_party/WebKit/Source/modules/exported/WebAXObject.cpp
@@ -47,6 +47,7 @@ #include "core/style/ComputedStyle.h" #include "modules/accessibility/AXObject.h" #include "modules/accessibility/AXObjectCacheImpl.h" +#include "modules/accessibility/AXRange.h" #include "modules/accessibility/AXTable.h" #include "modules/accessibility/AXTableCell.h" #include "modules/accessibility/AXTableColumn.h" @@ -754,7 +755,7 @@ return; } - AXObject::AXRange ax_selection = private_->Selection(); + AXObject::AXSelection ax_selection = private_->Selection(); anchor_object = WebAXObject(ax_selection.anchor_object); anchor_offset = ax_selection.anchor_offset; anchor_affinity = @@ -779,9 +780,9 @@ if (IsDetached()) return false; - AXObject::AXRange ax_selection(anchor_object, anchor_offset, - TextAffinity::kUpstream, focus_object, - focus_offset, TextAffinity::kDownstream); + AXObject::AXSelection ax_selection(anchor_object, anchor_offset, + TextAffinity::kUpstream, focus_object, + focus_offset, TextAffinity::kDownstream); return private_->RequestSetSelectionAction(ax_selection); } @@ -789,7 +790,7 @@ if (IsDetached()) return 0; - AXObject::AXRange ax_selection = private_->SelectionUnderObject(); + AXObject::AXSelection ax_selection = private_->SelectionUnderObject(); if (ax_selection.focus_offset < 0) return 0; @@ -800,7 +801,7 @@ if (IsDetached()) return 0; - AXObject::AXRange ax_selection = private_->SelectionUnderObject(); + AXObject::AXSelection ax_selection = private_->SelectionUnderObject(); if (ax_selection.anchor_offset < 0) return 0; @@ -1346,7 +1347,7 @@ return; Vector<DocumentMarker::MarkerType> marker_types; - Vector<AXObject::AXRange> marker_ranges; + Vector<AXRange> marker_ranges; private_->Markers(marker_types, marker_ranges); DCHECK_EQ(marker_types.size(), marker_ranges.size()); @@ -1355,9 +1356,11 @@ WebVector<int> end_offsets(marker_ranges.size()); for (size_t i = 0; i < marker_types.size(); ++i) { web_marker_types[i] = static_cast<WebAXMarkerType>(marker_types[i]); - DCHECK(marker_ranges[i].IsSimple()); - start_offsets[i] = marker_ranges[i].anchor_offset; - end_offsets[i] = marker_ranges[i].focus_offset; + DCHECK(marker_ranges[i].IsValid()); + DCHECK_EQ(marker_ranges[i].Start().ContainerObject(), + marker_ranges[i].End().ContainerObject()); + start_offsets[i] = marker_ranges[i].Start().TextOffset(); + end_offsets[i] = marker_ranges[i].End().TextOffset(); } types.Swap(web_marker_types); @@ -1384,15 +1387,17 @@ if (IsDetached()) return; - Vector<AXObject::AXRange> word_boundaries; + Vector<AXRange> word_boundaries; private_->GetWordBoundaries(word_boundaries); WebVector<int> word_start_offsets(word_boundaries.size()); WebVector<int> word_end_offsets(word_boundaries.size()); for (size_t i = 0; i < word_boundaries.size(); ++i) { - DCHECK(word_boundaries[i].IsSimple()); - word_start_offsets[i] = word_boundaries[i].anchor_offset; - word_end_offsets[i] = word_boundaries[i].focus_offset; + DCHECK(word_boundaries[i].IsValid()); + DCHECK_EQ(word_boundaries[i].Start().ContainerObject(), + word_boundaries[i].End().ContainerObject()); + word_start_offsets[i] = word_boundaries[i].Start().TextOffset(); + word_end_offsets[i] = word_boundaries[i].End().TextOffset(); } starts.Swap(word_start_offsets);
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp index d840592..5121f514 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -155,10 +155,10 @@ return true; } -void MaybeAppendChild(Element* parent, Element* child) { +void MaybeParserAppendChild(Element* parent, Element* child) { DCHECK(parent); if (child) - parent->AppendChild(child); + parent->ParserAppendChild(child); } bool ShouldShowPictureInPictureButton(HTMLMediaElement& media_element) { @@ -410,7 +410,7 @@ MediaControlsResourceLoader::InjectMediaControlsUAStyleSheet(); - shadow_root.AppendChild(controls); + shadow_root.ParserAppendChild(controls); return controls; } @@ -487,7 +487,7 @@ void MediaControlsImpl::InitializeControls() { if (IsModern() && MediaElement().IsHTMLVideoElement()) { loading_panel_ = new MediaControlLoadingPanelElement(*this); - AppendChild(loading_panel_); + ParserAppendChild(loading_panel_); } overlay_enclosure_ = new MediaControlOverlayEnclosureElement(*this); @@ -497,13 +497,13 @@ overlay_play_button_ = new MediaControlOverlayPlayButtonElement(*this); if (!IsModern()) - overlay_enclosure_->AppendChild(overlay_play_button_); + overlay_enclosure_->ParserAppendChild(overlay_play_button_); } overlay_cast_button_ = new MediaControlCastButtonElement(*this, true); - overlay_enclosure_->AppendChild(overlay_cast_button_); + overlay_enclosure_->ParserAppendChild(overlay_cast_button_); - AppendChild(overlay_enclosure_); + ParserAppendChild(overlay_enclosure_); // Create an enclosing element for the panel so we can visually offset the // controls correctly. @@ -549,36 +549,35 @@ overflow_menu_ = new MediaControlOverflowMenuButtonElement(*this); PopulatePanel(); - enclosure_->AppendChild(panel_); + enclosure_->ParserAppendChild(panel_); - AppendChild(enclosure_); + ParserAppendChild(enclosure_); text_track_list_ = new MediaControlTextTrackListElement(*this); - AppendChild(text_track_list_); - + ParserAppendChild(text_track_list_); overflow_list_ = new MediaControlOverflowMenuListElement(*this); - AppendChild(overflow_list_); + ParserAppendChild(overflow_list_); // The order in which we append elements to the overflow list is significant // because it determines how the elements show up in the overflow menu // relative to each other. The first item appended appears at the top of the // overflow menu. - overflow_list_->AppendChild(play_button_->CreateOverflowElement( + overflow_list_->ParserAppendChild(play_button_->CreateOverflowElement( new MediaControlPlayButtonElement(*this))); - overflow_list_->AppendChild(fullscreen_button_->CreateOverflowElement( + overflow_list_->ParserAppendChild(fullscreen_button_->CreateOverflowElement( new MediaControlFullscreenButtonElement(*this))); - overflow_list_->AppendChild(download_button_->CreateOverflowElement( + overflow_list_->ParserAppendChild(download_button_->CreateOverflowElement( new MediaControlDownloadButtonElement(*this))); - overflow_list_->AppendChild(mute_button_->CreateOverflowElement( + overflow_list_->ParserAppendChild(mute_button_->CreateOverflowElement( new MediaControlMuteButtonElement(*this))); - overflow_list_->AppendChild(cast_button_->CreateOverflowElement( + overflow_list_->ParserAppendChild(cast_button_->CreateOverflowElement( new MediaControlCastButtonElement(*this, false))); - overflow_list_->AppendChild( + overflow_list_->ParserAppendChild( toggle_closed_captions_button_->CreateOverflowElement( new MediaControlToggleClosedCaptionsButtonElement(*this))); if (RuntimeEnabledFeatures::PictureInPictureEnabled()) { - overflow_list_->AppendChild( + overflow_list_->ParserAppendChild( picture_in_picture_button_->CreateOverflowElement( new MediaControlPictureInPictureButtonElement(*this))); } @@ -596,9 +595,9 @@ Element* button_panel = panel_; if (IsModern() && MediaElement().IsHTMLVideoElement() && !is_acting_as_audio_controls_) { - MaybeAppendChild(panel_, scrubbing_message_); - panel_->AppendChild(overlay_play_button_); - panel_->AppendChild(media_button_panel_); + MaybeParserAppendChild(panel_, scrubbing_message_); + panel_->ParserAppendChild(overlay_play_button_); + panel_->ParserAppendChild(media_button_panel_); button_panel = media_button_panel_; } @@ -606,35 +605,35 @@ // only or are using the legacy controls. if (!IsModern() || is_acting_as_audio_controls_ || MediaElement().IsHTMLAudioElement()) { - button_panel->AppendChild(play_button_); + button_panel->ParserAppendChild(play_button_); } - button_panel->AppendChild(current_time_display_); - button_panel->AppendChild(duration_display_); + button_panel->ParserAppendChild(current_time_display_); + button_panel->ParserAppendChild(duration_display_); if (IsModern() && MediaElement().IsHTMLVideoElement()) { MediaControlElementsHelper::CreateDiv( "-internal-media-controls-button-spacer", button_panel); } - panel_->AppendChild(timeline_); + panel_->ParserAppendChild(timeline_); - button_panel->AppendChild(mute_button_); + button_panel->ParserAppendChild(mute_button_); - MaybeAppendChild(button_panel, volume_slider_); - MaybeAppendChild(button_panel, picture_in_picture_button_); + MaybeParserAppendChild(button_panel, volume_slider_); + MaybeParserAppendChild(button_panel, picture_in_picture_button_); - button_panel->AppendChild(fullscreen_button_); + button_panel->ParserAppendChild(fullscreen_button_); // The download, cast and captions buttons should not be present on the modern // controls button panel. if (!IsModern()) { - button_panel->AppendChild(download_button_); - button_panel->AppendChild(cast_button_); - button_panel->AppendChild(toggle_closed_captions_button_); + button_panel->ParserAppendChild(download_button_); + button_panel->ParserAppendChild(cast_button_); + button_panel->ParserAppendChild(toggle_closed_captions_button_); } - button_panel->AppendChild(overflow_menu_); + button_panel->ParserAppendChild(overflow_menu_); } Node::InsertionNotificationRequest MediaControlsImpl::InsertedInto( @@ -808,6 +807,18 @@ return GetLayoutObject(); } +void MediaControlsImpl::SetTestMode(bool enable) { + is_test_mode_ = enable; + if (loading_panel_) + loading_panel_->OnTestModeUpdated(); + // TODO(steimel): Add other test mode changes, such as stopping the overlay + // play button transition. +} + +bool MediaControlsImpl::GetTestMode() const { + return is_test_mode_; +} + void MediaControlsImpl::MaybeShow() { panel_->SetIsWanted(true); panel_->SetIsDisplayed(true); @@ -1784,25 +1795,7 @@ !is_acting_as_audio_controls_; } -void MediaControlsImpl::Invalidate(Element* element) { - if (!element) - return; - - if (LayoutObject* layout_object = element->GetLayoutObject()) { - layout_object - ->SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); - } -} - void MediaControlsImpl::NetworkStateChanged() { - Invalidate(play_button_); - Invalidate(overlay_play_button_); - Invalidate(mute_button_); - Invalidate(fullscreen_button_); - Invalidate(download_button_); - Invalidate(timeline_); - Invalidate(volume_slider_); - // Update the display state of the download button in case we now have a // source or no longer have a source. download_button_->SetIsWanted(
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h index f3b2703a..b18dcd1 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
@@ -100,6 +100,7 @@ void NetworkStateChanged() override; LayoutObject* PanelLayoutObject() override; LayoutObject* ContainerLayoutObject() override; + void SetTestMode(bool) override; // Return the internal elements, which is used by registering clicking // EventHandlers from MediaControlsWindowEventListener. HTMLDivElement* PanelElement() override; @@ -110,6 +111,8 @@ RefreshCastButtonVisibilityWithoutUpdate(); } + bool GetTestMode() const; + // Called by the fullscreen buttons to toggle fulllscreen on/off. void EnterFullscreen(); void ExitFullscreen(); @@ -201,8 +204,6 @@ class MediaControlsResizeObserverDelegate; class MediaElementMutationCallback; - void Invalidate(Element*); - // Notify us that our controls enclosure has changed size. void NotifyElementSizeChanged(DOMRectReadOnly* new_size); @@ -363,6 +364,8 @@ // certain pointer events. In particular, when the user is interacting via // touch events, we want to ignore pointerover/pointerout/pointermove events. bool is_touch_interaction_ = false; + + bool is_test_mode_ = false; }; DEFINE_ELEMENT_TYPE_CASTS(MediaControlsImpl, IsMediaControls());
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementBase.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementBase.cpp index c18de9d..18a2381 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementBase.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementBase.cpp
@@ -5,7 +5,6 @@ #include "modules/media_controls/elements/MediaControlElementBase.h" #include "core/html/media/HTMLMediaElement.h" -#include "core/layout/LayoutObject.h" #include "modules/media_controls/MediaControlsImpl.h" namespace blink { @@ -67,12 +66,7 @@ void MediaControlElementBase::SetDisplayType( MediaControlElementType display_type) { - if (display_type == display_type_) - return; - display_type_ = display_type; - if (LayoutObject* object = element_->GetLayoutObject()) - object->SetShouldDoFullPaintInvalidation(); } void MediaControlElementBase::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementsHelper.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementsHelper.cpp index 57fcd2e..a9df2f4 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementsHelper.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlElementsHelper.cpp
@@ -82,7 +82,7 @@ DCHECK(parent); HTMLDivElement* element = HTMLDivElement::Create(parent->GetDocument()); element->SetShadowPseudoId(id); - parent->AppendChild(element); + parent->ParserAppendChild(element); return element; } @@ -112,7 +112,7 @@ DCHECK(parent); HTMLDivElement* element = HTMLDivElement::Create(parent->GetDocument()); element->setAttribute("id", id); - parent->AppendChild(element); + parent->ParserAppendChild(element); return element; }
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp index c536c25..7ee81e4 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp
@@ -66,15 +66,15 @@ AtomicString("-internal-media-controls-overflow-menu-list-item")); // Appending a button to a label element ensures that clicks on the label // are passed down to the button, performing the action we'd expect. - element->AppendChild(button); + element->ParserAppendChild(button); if (MediaControlsImpl::IsModern()) { overflow_menu_container_ = HTMLDivElement::Create(GetDocument()); - overflow_menu_container_->AppendChild(overflow_menu_text_); + overflow_menu_container_->ParserAppendChild(overflow_menu_text_); UpdateOverflowSubtitleElement(button->GetOverflowMenuSubtitleString()); - element->AppendChild(overflow_menu_container_); + element->ParserAppendChild(overflow_menu_container_); } else { - element->AppendChild(overflow_menu_text_); + element->ParserAppendChild(overflow_menu_text_); } // Initialize the internal states of the main element and the overflow one. @@ -108,7 +108,7 @@ overflow_menu_subtitle_->setInnerText(text, ASSERT_NO_EXCEPTION); overflow_menu_subtitle_->setAttribute("class", kOverflowSubtitleCSSClass); - overflow_menu_container_->AppendChild(overflow_menu_subtitle_); + overflow_menu_container_->ParserAppendChild(overflow_menu_subtitle_); overflow_menu_container_->setAttribute( "class", kOverflowContainerWithSubtitleCSSClass); }
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.cpp index b95bcdc7..0d8f0cc 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.cpp
@@ -63,7 +63,7 @@ auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); style->setTextContent( MediaControlsResourceLoader::GetShadowLoadingStyleSheet()); - shadow_root->AppendChild(style); + shadow_root->ParserAppendChild(style); // The spinner frame is centers the spinner in the middle of the element and // cuts off any overflowing content. It also contains a SVG mask which will @@ -157,6 +157,14 @@ return; } + // If the controls are in test mode, we always hide the loading panel. So hide + // if necessary and return. + if (GetMediaControls().GetTestMode()) { + if (state_ != State::kHidden) + HideAnimation(); + return; + } + switch (state_) { case State::kHidden: // If the media controls are loading metadata then we should show the @@ -205,6 +213,10 @@ UpdateDisplayState(); } +void MediaControlLoadingPanelElement::OnTestModeUpdated() { + UpdateDisplayState(); +} + void MediaControlLoadingPanelElement::OnAnimationEnd() { // If we have gone back to the loading metadata state (e.g. the source // changed). Then we should jump back to playing.
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.h index 24e6761..da3c110 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.h +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlLoadingPanelElement.h
@@ -33,6 +33,8 @@ void OnControlsHidden(); // Inform the loading panel that the Media Controls have been shown. void OnControlsShown(); + // Inform the loading panel that the Media Controls are entering test mode. + void OnTestModeUpdated(); void Trace(Visitor*);
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverlayPlayButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverlayPlayButtonElement.cpp index 8d8f609f..596436e 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverlayPlayButtonElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlOverlayPlayButtonElement.cpp
@@ -182,17 +182,18 @@ auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); style->setTextContent( MediaControlsResourceLoader::GetOverlayPlayStyleSheet()); - shadow_root->AppendChild(style); + shadow_root->ParserAppendChild(style); // Insert the left jump arrow to the left of the play button. left_jump_arrow_ = new MediaControlOverlayPlayButtonElement::AnimatedArrow( "left-arrow", GetDocument()); - shadow_root->InsertBefore(left_jump_arrow_, shadow_root->firstChild()); + shadow_root->ParserInsertBefore(left_jump_arrow_, + *shadow_root->firstChild()); // Insert the right jump arrow to the right of the play button. right_jump_arrow_ = new MediaControlOverlayPlayButtonElement::AnimatedArrow( "right-arrow", GetDocument()); - shadow_root->AppendChild(right_jump_arrow_); + shadow_root->ParserAppendChild(right_jump_arrow_); } DCHECK(left_jump_arrow_ && right_jump_arrow_);
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlScrubbingMessageElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlScrubbingMessageElement.cpp index 74e9ee6e..fa275453 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlScrubbingMessageElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlScrubbingMessageElement.cpp
@@ -32,7 +32,7 @@ HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); style->setTextContent( MediaControlsResourceLoader::GetScrubbingMessageStyleSheet()); - shadow_root->AppendChild(style); + shadow_root->ParserAppendChild(style); HTMLDivElement* arrow_left_div1 = MediaControlElementsHelper::CreateDivWithId("arrow-left1", shadow_root);
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTextTrackListElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTextTrackListElement.cpp index 6cf3e656..7f1aad1 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTextTrackListElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTextTrackListElement.cpp
@@ -120,11 +120,11 @@ // Modern media controls should have the checkbox after the text instead of // the other way around. if (!MediaControlsImpl::IsModern()) - track_item->AppendChild(track_item_input); + track_item->ParserAppendChild(track_item_input); String track_label = GetMediaControls().GetTextTrackLabel(track); - track_item->AppendChild(Text::Create(GetDocument(), track_label)); + track_item->ParserAppendChild(Text::Create(GetDocument(), track_label)); if (MediaControlsImpl::IsModern()) - track_item->AppendChild(track_item_input); + track_item->ParserAppendChild(track_item_input); // Add a track kind marker icon if there are multiple tracks with the same // label or if the track has no label. @@ -138,7 +138,7 @@ track_kind_marker->SetShadowPseudoId(AtomicString( "-internal-media-controls-text-track-list-kind-subtitles")); } - track_item->AppendChild(track_kind_marker); + track_item->ParserAppendChild(track_kind_marker); } return track_item; } @@ -147,7 +147,7 @@ HTMLLabelElement* header_item = HTMLLabelElement::Create(GetDocument()); header_item->SetShadowPseudoId( "-internal-media-controls-text-track-list-header"); - header_item->AppendChild( + header_item->ParserAppendChild( Text::Create(GetDocument(), GetLocale().QueryString( WebLocalizedString::kOverflowMenuCaptionsSubmenuTitle))); @@ -164,18 +164,18 @@ RemoveChildren(kOmitSubtreeModifiedEvent); if (MediaControlsImpl::IsModern()) - AppendChild(CreateTextTrackHeaderItem()); + ParserAppendChild(CreateTextTrackHeaderItem()); // Construct a menu for subtitles and captions. Pass in a nullptr to // createTextTrackListItem to create the "Off" track item. - AppendChild(CreateTextTrackListItem(nullptr)); + ParserAppendChild(CreateTextTrackListItem(nullptr)); TextTrackList* track_list = MediaElement().textTracks(); for (unsigned i = 0; i < track_list->length(); i++) { TextTrack* track = track_list->AnonymousIndexedGetter(i); if (!track->CanBeRendered()) continue; - AppendChild(CreateTextTrackListItem(track)); + ParserAppendChild(CreateTextTrackListItem(track)); } }
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp index 7322266..15e9e86 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp
@@ -77,7 +77,7 @@ auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); style->setTextContent( MediaControlsResourceLoader::GetShadowTimelineStyleSheet()); - track.AppendChild(style); + track.ParserAppendChild(style); } }
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp index 1dbc4262..191a614 100644 --- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -139,8 +139,10 @@ DCHECK_GT(display->leftEye->renderWidth, 0u); is_valid = true; - eye_parameters_left_ = new VREyeParameters(display->leftEye); - eye_parameters_right_ = new VREyeParameters(display->rightEye); + eye_parameters_left_ = new VREyeParameters( + display->leftEye, display->default_framebuffer_scale); + eye_parameters_right_ = new VREyeParameters( + display->rightEye, display->default_framebuffer_scale); } bool need_on_present_change = false; @@ -244,27 +246,6 @@ if (pending_presenting_vsync_) return; - // The logic here is a bit subtle. We get called from one of the following - // four contexts: - // - // (a) from requestAnimationFrame if outside an animating context (i.e. the - // first rAF call from inside a getVRDisplays() promise) - // - // (b) from requestAnimationFrame in an animating context if the JS code - // calls rAF after submitFrame. - // - // (c) from submitFrame if that is called after rAF. - // - // (d) from ProcessScheduledAnimations if a rAF callback finishes without - // submitting a frame. - // - // These cases are mutually exclusive which prevents duplicate GetVSync - // calls. Case (a) only applies outside an animating context - // (in_animation_frame_ is false), and (b,c,d) all require an animating - // context. While in an animating context, submitFrame is called either - // before rAF (b), after rAF (c), or not at all (d). If rAF isn't called at - // all, there won't be future frames. - pending_magic_window_vsync_ = false; pending_presenting_vsync_ = true; vr_presentation_provider_->GetVSync( @@ -281,13 +262,8 @@ return 0; pending_vrdisplay_raf_ = true; - // We want to delay the GetVSync call while presenting to ensure it doesn't - // arrive earlier than frame submission, but other than that we want to call - // it as early as possible. See comments inside RequestVSync() for more - // details on the applicable cases. - if (!is_presenting_ || !in_animation_frame_ || did_submit_this_frame_) { - RequestVSync(); - } + RequestVSync(); + FrameRequestCallbackCollection::V8FrameCallback* frame_callback = FrameRequestCallbackCollection::V8FrameCallback::Create(callback); frame_callback->SetUseLegacyTimeBase(false); @@ -756,8 +732,6 @@ // Reset our frame id, since anything we'd want to do (resizing/etc) can // no-longer happen to this frame. vr_frame_id_ = -1; - // If we were deferring a rAF-triggered vsync request, do this now. - RequestVSync(); // If preserveDrawingBuffer is false, must clear now. Normally this // happens as part of compositing, but that's not active while @@ -908,10 +882,19 @@ pending_vrdisplay_raf_ = false; did_submit_this_frame_ = false; scripted_animation_controller_->ServiceScriptedAnimations(timestamp); - // requestAnimationFrame may have deferred RequestVSync, call it now to - // cover the case where no frame was submitted, or where presentation ended - // while servicing the scripted animation. - RequestVSync(); + // If presenting and the script didn't call SubmitFrame, let the device + // side know so that it can cleanly reuse resources and make appropriate + // timing decisions. Note that is_presenting_ could become false during + // an animation loop due to reentrant mojo processing in SubmitFrame, + // so there's no guarantee that this is called for the last animating + // frame. That's OK since the sync token placed by FrameSubmitMissing + // is only intended to separate frames while presenting. + if (is_presenting_ && !did_submit_this_frame_) { + DCHECK(frame_transport_); + DCHECK(context_gl_); + frame_transport_->FrameSubmitMissing(vr_presentation_provider_.get(), + context_gl_, vr_frame_id_); + } } if (pending_pose_) frame_pose_ = std::move(pending_pose_);
diff --git a/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp b/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp index a5c21e4..6efe94b9 100644 --- a/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp +++ b/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
@@ -7,7 +7,8 @@ namespace blink { VREyeParameters::VREyeParameters( - const device::mojom::blink::VREyeParametersPtr& eye_parameters) { + const device::mojom::blink::VREyeParametersPtr& eye_parameters, + double render_scale) { // TODO(offenwanger): Convert this into initializers. offset_ = DOMFloat32Array::Create(3); field_of_view_ = new VRFieldOfView(); @@ -21,8 +22,8 @@ field_of_view_->SetLeftDegrees(eye_parameters->fieldOfView->leftDegrees); field_of_view_->SetRightDegrees(eye_parameters->fieldOfView->rightDegrees); - render_width_ = eye_parameters->renderWidth; - render_height_ = eye_parameters->renderHeight; + render_width_ = eye_parameters->renderWidth * render_scale; + render_height_ = eye_parameters->renderHeight * render_scale; } void VREyeParameters::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/modules/vr/VREyeParameters.h b/third_party/WebKit/Source/modules/vr/VREyeParameters.h index ce6edd3..55102e8 100644 --- a/third_party/WebKit/Source/modules/vr/VREyeParameters.h +++ b/third_party/WebKit/Source/modules/vr/VREyeParameters.h
@@ -19,7 +19,8 @@ DEFINE_WRAPPERTYPEINFO(); public: - explicit VREyeParameters(const device::mojom::blink::VREyeParametersPtr&); + explicit VREyeParameters(const device::mojom::blink::VREyeParametersPtr&, + double render_scale); DOMFloat32Array* offset() const { return offset_; } VRFieldOfView* FieldOfView() const { return field_of_view_; }
diff --git a/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl b/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl index 49a80ad..7593662 100644 --- a/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-analysernode-interface +// See https://webaudio.github.io/web-audio-api/#analysernode [ Constructor(BaseAudioContext context, optional AnalyserOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceOptions.idl b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceOptions.idl index 5dd5e85..d95bce3 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#audiobuffersourceoptions +// See hhttps://webaudio.github.io/web-audio-api/#dictdef-audiobuffersourceoptions dictionary AudioBufferSourceOptions { AudioBuffer? buffer; float detune = 0;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContextOptions.idl b/third_party/WebKit/Source/modules/webaudio/AudioContextOptions.idl index 6fc6a38..bfab28c 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContextOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioContextOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#audiocontextoptions +// See https://webaudio.github.io/web-audio-api/#AudioContextOptions dictionary AudioContextOptions { // If passed as a double this should be the requested output latency in // seconds, without taking into account double buffering (same as
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioListener.idl b/third_party/WebKit/Source/modules/webaudio/AudioListener.idl index e4af5a6..de2f898 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioListener.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioListener.idl
@@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#AudioListener +// See https://webaudio.github.io/web-audio-api/#audiolistener interface AudioListener { [RaisesException, MeasureAs=AudioListenerSetPosition] void setPosition(float x, float y, float z); [RaisesException, MeasureAs=AudioListenerSetOrientation] void setOrientation(float x, float y, float z, float xUp, float yUp, float zUp);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.idl b/third_party/WebKit/Source/modules/webaudio/AudioNode.idl index 516456f0..3bf9da4 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// https://webaudio.github.io/web-audio-api/#the-audionode-interface +// See https://webaudio.github.io/web-audio-api/#audionode enum ChannelCountMode { "max",
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNodeOptions.idl b/third_party/WebKit/Source/modules/webaudio/AudioNodeOptions.idl index 48ca7cc..f14f9ed 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNodeOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioNodeOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#dictionary-audionodeoptions-members +// See https://webaudio.github.io/web-audio-api/#dictdef-audionodeoptions dictionary AudioNodeOptions { unsigned long channelCount; ChannelCountMode channelCountMode;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamDescriptor.idl b/third_party/WebKit/Source/modules/webaudio/AudioParamDescriptor.idl index 70cd045..0aed454e 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParamDescriptor.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioParamDescriptor.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See: https://webaudio.github.io/web-audio-api/#idl-def-AudioParamDescriptor +// See: https://webaudio.github.io/web-audio-api/#dictdef-audioparamdescriptor dictionary AudioParamDescriptor { required DOMString name; float defaultValue = 0;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamMap.idl b/third_party/WebKit/Source/modules/webaudio/AudioParamMap.idl index 71dd5ebd..4055562 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParamMap.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioParamMap.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://webaudio.github.io/web-audio-api/#idl-def-AudioParamMap +// See https://webaudio.github.io/web-audio-api/#audioparammap interface AudioParamMap { readonly maplike<DOMString, AudioParam>;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.idl b/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.idl index ad82edd..947990e 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-audioprocessingevent-interface---deprecated +// See https://webaudio.github.io/web-audio-api/#audioprocessingevent [ Constructor(DOMString type, AudioProcessingEventInit eventInitDict) ]
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioProcessingEventInit.idl b/third_party/WebKit/Source/modules/webaudio/AudioProcessingEventInit.idl index eda9d939..32e12a7 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioProcessingEventInit.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioProcessingEventInit.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#audioprocessingeventinit +// See https://webaudio.github.io/web-audio-api/#dictdef-audioprocessingeventinit dictionary AudioProcessingEventInit : EventInit { required double playbackTime; required AudioBuffer inputBuffer;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl index cd66814..07466238 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/ +// See https://webaudio.github.io/web-audio-api/#AudioScheduledSourceNode [ ActiveScriptWrappable ]
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioTimestamp.idl b/third_party/WebKit/Source/modules/webaudio/AudioTimestamp.idl index e1b738e..6a417f79 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioTimestamp.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioTimestamp.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#audiotimestamp +// See https://webaudio.github.io/web-audio-api/#dictdef-audiotimestamp dictionary AudioTimestamp { double contextTime; DOMHighResTimeStamp performanceTime;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl index 2233b03..e24cf62 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://webaudio.github.io/web-audio-api/#AudioWorklet +// See https://webaudio.github.io/web-audio-api/#audioworklet [ SecureContext
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.idl b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.idl index 1a00dc4..ccdbf87 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://webaudio.github.io/web-audio-api/#AudioWorkletGlobalScope +// See https://webaudio.github.io/web-audio-api/#audioworkletglobalscope [ Exposed=AudioWorklet,
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.idl b/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.idl index b7f58d0f..4772e75 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://webaudio.github.io/web-audio-api/#AudioWorkletNode +// See https://webaudio.github.io/web-audio-api/#audioworkletnode [ ActiveScriptWrappable,
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletNodeOptions.idl b/third_party/WebKit/Source/modules/webaudio/AudioWorkletNodeOptions.idl index 238e3c0..5741f31 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletNodeOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletNodeOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See: https://webaudio.github.io/web-audio-api/#AudioWorkletNodeOptions +// See: https://webaudio.github.io/web-audio-api/#dictdef-audioworkletnodeoptions dictionary AudioWorkletNodeOptions : AudioNodeOptions { unsigned long numberOfInputs = 1; unsigned long numberOfOutputs = 1;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessor.idl b/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessor.idl index 395dcbbf..9853c97 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessor.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessor.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://webaudio.github.io/web-audio-api/#AudioWorkletProcessor +// See https://webaudio.github.io/web-audio-api/#audioworkletprocessor [ Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl index cd743d1..63fb78f 100644 --- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface +// See https://webaudio.github.io/web-audio-api/#biquadfilternode enum BiquadFilterType { "lowpass", "highpass",
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterOptions.idl b/third_party/WebKit/Source/modules/webaudio/BiquadFilterOptions.idl index 3d8c7b8..fe29d87 100644 --- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#biquadfilteroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-biquadfilteroptions dictionary BiquadFilterOptions : AudioNodeOptions { BiquadFilterType type = "lowpass"; float Q = 1;
diff --git a/third_party/WebKit/Source/modules/webaudio/ChannelMergerNode.idl b/third_party/WebKit/Source/modules/webaudio/ChannelMergerNode.idl index 7573a9f..4998b14 100644 --- a/third_party/WebKit/Source/modules/webaudio/ChannelMergerNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/ChannelMergerNode.idl
@@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-channelmergernode-interface +// See https://webaudio.github.io/web-audio-api/#channelmergernode [ Constructor(BaseAudioContext context, optional ChannelMergerOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/ChannelMergerOptions.idl b/third_party/WebKit/Source/modules/webaudio/ChannelMergerOptions.idl index 1e9e7d24..f7b8208 100644 --- a/third_party/WebKit/Source/modules/webaudio/ChannelMergerOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/ChannelMergerOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#channelmergeroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-channelmergeroptions dictionary ChannelMergerOptions : AudioNodeOptions { unsigned long numberOfInputs = 6; }; \ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/webaudio/ChannelSplitterNode.idl b/third_party/WebKit/Source/modules/webaudio/ChannelSplitterNode.idl index c651a69..8f8d721 100644 --- a/third_party/WebKit/Source/modules/webaudio/ChannelSplitterNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/ChannelSplitterNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-channelsplitternode-interface +// See https://webaudio.github.io/web-audio-api/#channelsplitternode [ Constructor(BaseAudioContext context, optional ChannelSplitterOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/ChannelSplitterOptions.idl b/third_party/WebKit/Source/modules/webaudio/ChannelSplitterOptions.idl index b97a616a..7bc68cf 100644 --- a/third_party/WebKit/Source/modules/webaudio/ChannelSplitterOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/ChannelSplitterOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#channelsplitteroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-channelsplitteroptions dictionary ChannelSplitterOptions : AudioNodeOptions { unsigned long numberOfOutputs = 6; }; \ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/webaudio/ConstantSourceOptions.idl b/third_party/WebKit/Source/modules/webaudio/ConstantSourceOptions.idl index 5cd584c..dee2256 100644 --- a/third_party/WebKit/Source/modules/webaudio/ConstantSourceOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/ConstantSourceOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#constantsourceoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-constantsourceoptions dictionary ConstantSourceOptions { float offset = 1; }; \ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/webaudio/ConvolverOptions.idl b/third_party/WebKit/Source/modules/webaudio/ConvolverOptions.idl index 4db8a86..637e6e4 100644 --- a/third_party/WebKit/Source/modules/webaudio/ConvolverOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/ConvolverOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#convolveroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-convolveroptions dictionary ConvolverOptions : AudioNodeOptions { AudioBuffer? buffer; boolean disableNormalization = false;
diff --git a/third_party/WebKit/Source/modules/webaudio/DelayOptions.idl b/third_party/WebKit/Source/modules/webaudio/DelayOptions.idl index 9ace73f..d2c89651 100644 --- a/third_party/WebKit/Source/modules/webaudio/DelayOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/DelayOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#delayoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-delayoptions dictionary DelayOptions : AudioNodeOptions { double maxDelayTime = 1; double delayTime = 0;
diff --git a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.idl b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.idl index 1aee7117..41c9008 100644 --- a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface +// See https://webaudio.github.io/web-audio-api/#dynamicscompressornode [ Constructor(BaseAudioContext context, optional DynamicsCompressorOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorOptions.idl b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorOptions.idl index d182297..0bdd0ce 100644 --- a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#dynamicscompressoroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-dynamicscompressoroptions dictionary DynamicsCompressorOptions : AudioNodeOptions { float attack = 0.003; float knee = 30;
diff --git a/third_party/WebKit/Source/modules/webaudio/GainNode.idl b/third_party/WebKit/Source/modules/webaudio/GainNode.idl index 74eb6c1..4eb0275e 100644 --- a/third_party/WebKit/Source/modules/webaudio/GainNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/GainNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#GainNode +// See https://webaudio.github.io/web-audio-api/#gainnode [ Constructor(BaseAudioContext context, optional GainOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/GainOptions.idl b/third_party/WebKit/Source/modules/webaudio/GainOptions.idl index 65fb4fe..6a677065 100644 --- a/third_party/WebKit/Source/modules/webaudio/GainOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/GainOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#gainoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-gainoptions dictionary GainOptions : AudioNodeOptions { float gain = 1; };
diff --git a/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.idl b/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.idl index 1780a79..b98d3196 100644 --- a/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#the-iirfilternode-interface +// See https://webaudio.github.io/web-audio-api/#iirfilternode [ Constructor(BaseAudioContext context, IIRFilterOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/IIRFilterOptions.idl b/third_party/WebKit/Source/modules/webaudio/IIRFilterOptions.idl index b42d86d..22804d8 100644 --- a/third_party/WebKit/Source/modules/webaudio/IIRFilterOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/IIRFilterOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#iirfilteroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-iirfilteroptions dictionary IIRFilterOptions : AudioNodeOptions { required sequence<double> feedforward; required sequence<double> feedback;
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.idl b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.idl index 5d1260f..8a1df10e 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#MediaElementAudioSourceNode +// See https://webaudio.github.io/web-audio-api/#mediaelementaudiosourcenode [ // TODO(rtoy): This should be AudioContext, not BaseAudioContext. Constructor(BaseAudioContext context, MediaElementAudioSourceOptions options),
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceOptions.idl b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceOptions.idl index d5d5641..074ed84 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#mediaelementaudiosourceoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-mediaelementaudiosourceoptions dictionary MediaElementAudioSourceOptions { required HTMLMediaElement mediaElement; };
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioDestinationNode.idl b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioDestinationNode.idl index dc74efa..7cc91d8 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioDestinationNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioDestinationNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-mediastreamaudiodestinationnode-interface +// See https://webaudio.github.io/web-audio-api/#mediastreamaudiodestinationnode [ Constructor(BaseAudioContext context, optional AudioNodeOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.idl b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.idl index 999d6a72..1e8713d 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#MediaStreamAudioSourceNode +// See https://webaudio.github.io/web-audio-api/#mediastreamaudiosourcenode [ Constructor(BaseAudioContext context, MediaStreamAudioSourceOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceOptions.idl b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceOptions.idl index 7d74a79a..f6762af 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#mediastreamaudiosourceoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-mediastreamaudiosourceoptions dictionary MediaStreamAudioSourceOptions { required MediaStream mediaStream; };
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.idl b/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.idl index 4aed122..368ff9df 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.idl +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#OfflineAudioCompletionEvent +// See https://webaudio.github.io/web-audio-api/#offlineaudiocompletionevent [ Constructor(DOMString type, OfflineAudioCompletionEventInit eventInitDict) ]
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEventInit.idl b/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEventInit.idl index c70ba7c..fe37190 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEventInit.idl +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEventInit.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#offlineaudiocompletioneventinit +// See https://webaudio.github.io/web-audio-api/#dictdef-offlineaudiocompletioneventinit dictionary OfflineAudioCompletionEventInit : EventInit { required AudioBuffer renderedBuffer; };
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContextOptions.idl b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContextOptions.idl index 99a9383..d3adc6b8 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContextOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContextOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#offlineaudiocontextoptions +// See hhttps://webaudio.github.io/web-audio-api/#dictdef-offlineaudiocontextoptions dictionary OfflineAudioContextOptions { unsigned long numberOfChannels = 1; required unsigned long length;
diff --git a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl index 1f3e3052..d5cf7b82 100644 --- a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-oscillatornode-interface +// See https://webaudio.github.io/web-audio-api/#oscillatornode enum OscillatorType { "sine", "square",
diff --git a/third_party/WebKit/Source/modules/webaudio/OscillatorOptions.idl b/third_party/WebKit/Source/modules/webaudio/OscillatorOptions.idl index 689ec4ab..d9e7ef88b 100644 --- a/third_party/WebKit/Source/modules/webaudio/OscillatorOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/OscillatorOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#oscillatoroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-oscillatoroptions dictionary OscillatorOptions : AudioNodeOptions { OscillatorType type = "sine"; float detune = 0;
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerNode.idl b/third_party/WebKit/Source/modules/webaudio/PannerNode.idl index a47cc5de..3acde7e5 100644 --- a/third_party/WebKit/Source/modules/webaudio/PannerNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/PannerNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-pannernode-interface +// See https://webaudio.github.io/web-audio-api/#pannernode enum PanningModelType { "equalpower", "HRTF"
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerOptions.idl b/third_party/WebKit/Source/modules/webaudio/PannerOptions.idl index 4cf7042..a119529e9 100644 --- a/third_party/WebKit/Source/modules/webaudio/PannerOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/PannerOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#panneroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-panneroptions dictionary PannerOptions : AudioNodeOptions { PanningModelType panningModel = "equalpower"; DistanceModelType distanceModel = "inverse";
diff --git a/third_party/WebKit/Source/modules/webaudio/PeriodicWave.idl b/third_party/WebKit/Source/modules/webaudio/PeriodicWave.idl index 9ae8e25..f640cfa 100644 --- a/third_party/WebKit/Source/modules/webaudio/PeriodicWave.idl +++ b/third_party/WebKit/Source/modules/webaudio/PeriodicWave.idl
@@ -24,7 +24,7 @@ */ // PeriodicWave represents a periodic audio waveform given by its Fourier coefficients. -// See https://webaudio.github.io/web-audio-api/#the-periodicwave-interface +// See https://webaudio.github.io/web-audio-api/#periodicwave [ Constructor(BaseAudioContext context, optional PeriodicWaveOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/PeriodicWaveConstraints.idl b/third_party/WebKit/Source/modules/webaudio/PeriodicWaveConstraints.idl index 6c8e6890..d5cf4526 100644 --- a/third_party/WebKit/Source/modules/webaudio/PeriodicWaveConstraints.idl +++ b/third_party/WebKit/Source/modules/webaudio/PeriodicWaveConstraints.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#periodicwaveconstraints +// Seehttps://webaudio.github.io/web-audio-api/#dictdef-periodicwaveconstraints dictionary PeriodicWaveConstraints { boolean disableNormalization = false; };
diff --git a/third_party/WebKit/Source/modules/webaudio/PeriodicWaveOptions.idl b/third_party/WebKit/Source/modules/webaudio/PeriodicWaveOptions.idl index f797ce22..e452f31 100644 --- a/third_party/WebKit/Source/modules/webaudio/PeriodicWaveOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/PeriodicWaveOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#periodicwaveoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-periodicwaveoptions dictionary PeriodicWaveOptions : PeriodicWaveConstraints { sequence<float> real; sequence<float> imag;
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl index edcf701..43b8b00 100644 --- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#the-scriptprocessornode-interface---deprecated +// See https://webaudio.github.io/web-audio-api/#scriptprocessornode // For real-time audio stream synthesis/processing in JavaScript [ ActiveScriptWrappable
diff --git a/third_party/WebKit/Source/modules/webaudio/StereoPannerNode.idl b/third_party/WebKit/Source/modules/webaudio/StereoPannerNode.idl index 355fb12d..2753d91 100644 --- a/third_party/WebKit/Source/modules/webaudio/StereoPannerNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/StereoPannerNode.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#the-stereopannernode-interface +// See https://webaudio.github.io/web-audio-api/#stereopannernode [ Constructor(BaseAudioContext context, optional StereoPannerOptions options), RaisesException=Constructor,
diff --git a/third_party/WebKit/Source/modules/webaudio/StereoPannerOptions.idl b/third_party/WebKit/Source/modules/webaudio/StereoPannerOptions.idl index 87713a0..6e597f99 100644 --- a/third_party/WebKit/Source/modules/webaudio/StereoPannerOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/StereoPannerOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://webaudio.github.io/web-audio-api/#stereopanneroptions +// See https://webaudio.github.io/web-audio-api/#dictdef-stereopanneroptions dictionary StereoPannerOptions : AudioNodeOptions { float pan = 0; }; \ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl index 6289d54..bfecb7e3 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl
@@ -23,7 +23,7 @@ * DAMAGE. */ -// See https://webaudio.github.io/web-audio-api/#WaveShaperNode +// See https://webaudio.github.io/web-audio-api/#waveshapernode enum OverSampleType { "none", "2x",
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperOptions.idl b/third_party/WebKit/Source/modules/webaudio/WaveShaperOptions.idl index c004b3f..2a0ec145 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperOptions.idl +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://webaudio.github.io/web-audio-api/#waveshaperoptions +// See https://webaudio.github.io/web-audio-api/#dictdef-waveshaperoptions dictionary WaveShaperOptions : AudioNodeOptions { sequence<float> curve; OverSampleType oversample = "none";
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index c404e86d..def741e0 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -783,8 +783,6 @@ ScriptPromise WebGLRenderingContextBase::setCompatibleXRDevice( ScriptState* script_state, XRDevice* xr_device) { - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); - ScriptPromise promise = resolver->Promise(); if (isContextLost()) { return ScriptPromise::RejectWithDOMException( @@ -793,13 +791,13 @@ } if (xr_device == compatible_xr_device_) { - resolver->Resolve(); - return promise; + // Returns a script promise resolved with undefined. + return ScriptPromise::CastUndefined(script_state); } if (ContextCreatedOnCompatibleAdapter(xr_device)) { compatible_xr_device_ = xr_device; - resolver->Resolve(); + return ScriptPromise::CastUndefined(script_state); } else { // TODO(offenwanger): Trigger context loss and recreate on compatible GPU. return ScriptPromise::RejectWithDOMException( @@ -808,8 +806,6 @@ kNotSupportedError, "Context is not compatible. Switching not yet implemented.")); } - - return promise; } bool WebGLRenderingContextBase::IsXRDeviceCompatible(
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp index 7f7863b..8c79ee7 100644 --- a/third_party/WebKit/Source/modules/webusb/USB.cpp +++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -128,7 +128,7 @@ &USB::OnChooserServiceConnectionError, WrapWeakPersistent(this))); } - if (!Frame::ConsumeTransientUserActivation(frame)) { + if (!Frame::HasTransientUserActivation(frame)) { return ScriptPromise::RejectWithDOMException( script_state, DOMException::Create(
diff --git a/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp b/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp index eea2f60..a41fcdb 100644 --- a/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp +++ b/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp
@@ -150,7 +150,6 @@ pending_exclusive_session_resolver_->Reject(exception); pending_exclusive_session_resolver_ = nullptr; } - presentation_provider_.reset(); if (vsync_connection_failed_) return; @@ -321,7 +320,7 @@ } } -void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer) { +void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) { DCHECK(layer); DCHECK(layer->session() == exclusive_session_); DCHECK(presentation_provider_); @@ -330,6 +329,14 @@ WebGLRenderingContextBase* webgl_context = layer->context(); + if (!was_changed) { + // Just tell the device side that there was no submitted frame instead + // of executing the implicit end-of-frame submit. + frame_transport_->FrameSubmitMissing(presentation_provider_.get(), + webgl_context->ContextGL(), frame_id_); + return; + } + frame_transport_->FramePreImage(webgl_context->ContextGL()); std::unique_ptr<viz::SingleReleaseCallback> image_release_callback;
diff --git a/third_party/WebKit/Source/modules/xr/XRFrameProvider.h b/third_party/WebKit/Source/modules/xr/XRFrameProvider.h index d478eae5..9ee1c28 100644 --- a/third_party/WebKit/Source/modules/xr/XRFrameProvider.h +++ b/third_party/WebKit/Source/modules/xr/XRFrameProvider.h
@@ -35,7 +35,7 @@ void OnNonExclusiveVSync(double timestamp); - void SubmitWebGLLayer(XRWebGLLayer*); + void SubmitWebGLLayer(XRWebGLLayer*, bool was_changed); void UpdateWebGLLayerViewports(XRWebGLLayer*); void Dispose();
diff --git a/third_party/WebKit/Source/modules/xr/XRSession.cpp b/third_party/WebKit/Source/modules/xr/XRSession.cpp index 0c50de77..d36dd45 100644 --- a/third_party/WebKit/Source/modules/xr/XRSession.cpp +++ b/third_party/WebKit/Source/modules/xr/XRSession.cpp
@@ -258,6 +258,12 @@ DispatchEvent(XRSessionEvent::Create(EventTypeNames::end, this)); } +double XRSession::DefaultFramebufferScale() const { + if (exclusive_) + return device_->xrDisplayInfoPtr()->default_framebuffer_scale; + return 1.0; +} + DoubleSize XRSession::IdealFramebufferSize() const { if (!exclusive_) { return OutputCanvasSize(); @@ -329,7 +335,10 @@ AutoReset<bool> resolving(&resolving_frame_, true); callback_collection_.ExecuteCallbacks(this, presentation_frame); - frame_base_layer->OnFrameEnd(); + // The session might have ended in the middle of the frame. Only call + // OnFrameEnd if it's still valid. + if (!ended_) + frame_base_layer->OnFrameEnd(); } }
diff --git a/third_party/WebKit/Source/modules/xr/XRSession.h b/third_party/WebKit/Source/modules/xr/XRSession.h index 94484e0..7b8359c 100644 --- a/third_party/WebKit/Source/modules/xr/XRSession.h +++ b/third_party/WebKit/Source/modules/xr/XRSession.h
@@ -85,7 +85,7 @@ // Describes the default scalar to be applied to the ideal framebuffer // dimensions when the developer does not specify one. Should be a value that // provides a good balance between quality and performance. - double DefaultFramebufferScale() const { return 1.0; } + double DefaultFramebufferScale() const; // Describes the ideal dimensions of layer framebuffers, preferrably defined // as the size which gives 1:1 pixel ratio at the center of the user's view.
diff --git a/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp b/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp index 2b7a0f9..68c485c 100644 --- a/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp +++ b/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp
@@ -25,7 +25,7 @@ namespace { const double kFramebufferMinScale = 0.2; -const double kFramebufferMaxScale = 1.2; +const double kFramebufferMaxScale = 1.0; const double kViewportMinScale = 0.2; const double kViewportMaxScale = 1.0; @@ -254,17 +254,19 @@ void XRWebGLLayer::OnFrameEnd() { framebuffer_->MarkOpaqueBufferComplete(false); - // Exit early if the framebuffer contents have not changed. - if (!framebuffer_->HaveContentsChanged()) - return; // Submit the frame to the XR compositor. if (session()->exclusive()) { - session()->device()->frameProvider()->SubmitWebGLLayer(this); + // Always call submit, but notify if the contents were changed or not. + session()->device()->frameProvider()->SubmitWebGLLayer( + this, framebuffer_->HaveContentsChanged()); } else if (session()->outputContext()) { - ImageBitmap* image_bitmap = - ImageBitmap::Create(TransferToStaticBitmapImage(nullptr)); - session()->outputContext()->SetImage(image_bitmap); + // Nothing to do if the framebuffer contents have not changed. + if (framebuffer_->HaveContentsChanged()) { + ImageBitmap* image_bitmap = + ImageBitmap::Create(TransferToStaticBitmapImage(nullptr)); + session()->outputContext()->SetImage(image_bitmap); + } } }
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayer.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayer.cpp index b4af440e..9a4227c 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayer.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayer.cpp
@@ -30,6 +30,7 @@ current_transform_(layer_state.Transform()), current_clip_(layer_state.Clip()), current_effect_(layer_state.Effect()), + chunk_to_layer_mapper_(layer_state_, layer_offset_), cc_list_(cc_list) {} ~ConversionContext(); @@ -82,6 +83,15 @@ void Convert(const Vector<const PaintChunk*>&, const DisplayItemList&); private: + // Adjust the translation of the whole display list relative to layer offset. + // It's only called if we actually paint anything. + void TranslateForLayerOffsetOnce(); + + // Switch the current property tree state to the chunk's state. It's only + // called if we actually paint anything, and should execute for a chunk + // only once. + void SwitchToChunkState(const PaintChunk&); + // Switch the current clip to the target state, staying in the same effect. // It is no-op if the context is already in the target state. // Otherwise zero or more clips will be popped from or pushed onto the @@ -109,6 +119,13 @@ // The current effect will change to the target effect. void SwitchToEffect(const EffectPaintPropertyNode*); + // Switch the current transform to the target state. + void SwitchToTransform(const TransformPaintPropertyNode*); + // End the transform state that is estalished by SwitchToTransform(). + // Called when the next chunk has different property tree state and when we + // have processed all chunks. + void EndTransform(); + // Applies combined transform from |current_transform_| to |target_transform| // This function doesn't change |current_transform_|. void ApplyTransform(const TransformPaintPropertyNode* target_transform) { @@ -160,11 +177,17 @@ const PropertyTreeState& layer_state_; gfx::Vector2dF layer_offset_; + bool translated_for_layer_offset_ = false; const TransformPaintPropertyNode* current_transform_; const ClipPaintPropertyNode* current_clip_; const EffectPaintPropertyNode* current_effect_; + // The previous transform state before SwitchToTransform(). When the next + // chunk's state is different from the current state we should restore to + // this transform. + const TransformPaintPropertyNode* previous_transform_ = nullptr; + // State stack. // The size of the stack is the number of nested paired items that are // currently nested. Note that this is a "restore stack", i.e. the top @@ -200,17 +223,46 @@ }; Vector<EffectBoundsInfo> effect_bounds_stack_; + ChunkToLayerMapper chunk_to_layer_mapper_; + cc::DisplayItemList& cc_list_; }; ConversionContext::~ConversionContext() { // End all states. + EndTransform(); while (state_stack_.size()) { if (state_stack_.back().type == StateEntry::kEffect) EndEffect(); else EndClip(); } + if (translated_for_layer_offset_) + AppendRestore(1); +} + +void ConversionContext::TranslateForLayerOffsetOnce() { + if (translated_for_layer_offset_ || layer_offset_.IsZero()) + return; + + cc_list_.StartPaint(); + cc_list_.push<cc::SaveOp>(); + cc_list_.push<cc::TranslateOp>(-layer_offset_.x(), -layer_offset_.y()); + cc_list_.EndPaintOfPairedBegin(); + translated_for_layer_offset_ = true; +} + +void ConversionContext::SwitchToChunkState(const PaintChunk& chunk) { + chunk_to_layer_mapper_.SwitchToChunk(chunk); + + const auto& chunk_state = chunk.properties.property_tree_state; + if (chunk_state.Effect() != current_effect_ || + chunk_state.Clip() != current_clip_ || + chunk_state.Transform() != current_transform_) + EndTransform(); + SwitchToEffect(chunk_state.Effect()); + SwitchToClip(chunk_state.Clip()); + SwitchToTransform(chunk_state.Transform()); } void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { @@ -529,51 +581,38 @@ state_stack_.pop_back(); } +void ConversionContext::SwitchToTransform( + const TransformPaintPropertyNode* target_transform) { + if (target_transform == current_transform_) + return; + + DCHECK_EQ(nullptr, previous_transform_); + cc_list_.StartPaint(); + cc_list_.push<cc::SaveOp>(); + ApplyTransform(target_transform); + cc_list_.EndPaintOfPairedBegin(); + previous_transform_ = current_transform_; + current_transform_ = target_transform; +} + +void ConversionContext::EndTransform() { + if (!previous_transform_) + return; + + cc_list_.StartPaint(); + cc_list_.push<cc::RestoreOp>(); + cc_list_.EndPaintOfPairedEnd(); + current_transform_ = previous_transform_; + previous_transform_ = nullptr; +} + void ConversionContext::Convert(const Vector<const PaintChunk*>& paint_chunks, const DisplayItemList& display_items) { - bool translated = false; - bool need_translate = !layer_offset_.IsZero(); - // This functor adjust the translation of the whole display list relative to - // layer offset. It's only called if we actually paint anything. - auto translate_once = [this, &translated, need_translate] { - if (translated || !need_translate) - return; - cc_list_.StartPaint(); - cc_list_.push<cc::SaveOp>(); - cc_list_.push<cc::TranslateOp>(-layer_offset_.x(), -layer_offset_.y()); - cc_list_.EndPaintOfPairedBegin(); - translated = true; - }; - - ChunkToLayerMapper mapper(layer_state_, layer_offset_); - for (auto chunk_it = paint_chunks.begin(); chunk_it != paint_chunks.end(); chunk_it++) { const PaintChunk& chunk = **chunk_it; - const PropertyTreeState& chunk_state = - chunk.properties.property_tree_state.GetPropertyTreeState(); - bool transformed = false; - bool properties_adjusted = false; - // This functor adjusts the properties for the current effect and clip once. - // It's called if a DrawingDisplayItem draws content or is under an effect - // that may draw content. - auto adjust_properties_once = [this, &chunk_state, &transformed, - &properties_adjusted] { - if (properties_adjusted) - return; - SwitchToEffect(chunk_state.Effect()); - SwitchToClip(chunk_state.Clip()); - if (chunk_state.Transform() != current_transform_) { - transformed = true; - cc_list_.StartPaint(); - cc_list_.push<cc::SaveOp>(); - ApplyTransform(chunk_state.Transform()); - cc_list_.EndPaintOfPairedBegin(); - } - properties_adjusted = true; - }; - - mapper.SwitchToChunk(chunk); + const auto& chunk_state = chunk.properties.property_tree_state; + bool switched_to_chunk_state = false; for (const auto& item : display_items.ItemsInPaintChunk(chunk)) { DCHECK(item.IsDrawing()); @@ -589,19 +628,20 @@ continue; } - translate_once(); - adjust_properties_once(); + TranslateForLayerOffsetOnce(); + if (!switched_to_chunk_state) { + SwitchToChunkState(chunk); + switched_to_chunk_state = true; + } + cc_list_.StartPaint(); if (record && record->size() != 0) cc_list_.push<cc::DrawRecordOp>(std::move(record)); - cc_list_.EndPaintOfUnpaired(mapper.MapVisualRect(item.VisualRect())); + cc_list_.EndPaintOfUnpaired( + chunk_to_layer_mapper_.MapVisualRect(item.VisualRect())); } - if (transformed) - AppendRestore(1); UpdateEffectBounds(chunk.bounds, chunk_state.Transform()); } - if (translated) - AppendRestore(1); } } // unnamed namespace
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayerTest.cpp index 5d869ad..7c300e2 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintChunksToCcLayerTest.cpp
@@ -824,5 +824,47 @@ cc::PaintOpType::Restore})); // </c1+c2> } +TEST_F(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) { + auto t1 = TransformPaintPropertyNode::Create( + t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); + auto t2 = TransformPaintPropertyNode::Create( + t1.get(), TransformationMatrix().Scale(3.f), FloatPoint3D()); + auto c1 = ClipPaintPropertyNode::Create(c0(), t1.get(), + FloatRoundedRect(0, 0, 100, 100)); + + TestChunks chunks; + chunks.AddChunk(t0(), c0(), e0()); + chunks.AddChunk(t1.get(), c0(), e0()); + chunks.AddChunk(t1.get(), c0(), e0()); + chunks.AddChunk(t1.get(), c1.get(), e0()); + chunks.AddChunk(t1.get(), c1.get(), e0()); + chunks.AddChunk(t2.get(), c1.get(), e0()); + chunks.AddChunk(t2.get(), c1.get(), e0()); + + sk_sp<PaintRecord> output = + PaintChunksToCcLayer::Convert( + chunks.GetChunkList(), PropertyTreeState(t0(), c0(), e0()), + gfx::Vector2dF(), chunks.items, + cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + ->ReleaseAsRecord(); + + EXPECT_THAT(*output, + PaintRecordMatcher::Make( + {cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1> + cc::PaintOpType::DrawRecord, // <p1/> + cc::PaintOpType::DrawRecord, // <p2/> + cc::PaintOpType::Restore, // </t1> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1> + cc::PaintOpType::ClipRect, // <c1> + cc::PaintOpType::DrawRecord, // <p3/> + cc::PaintOpType::DrawRecord, // <p4/> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t2> + cc::PaintOpType::DrawRecord, // <p5/> + cc::PaintOpType::DrawRecord, // <p6/> + cc::PaintOpType::Restore, // </t2> + cc::PaintOpType::Restore})); // </c1></t1> +} + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp index fd6dbde..eff49f1d 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp
@@ -156,7 +156,7 @@ image_for_compositor->height()), viz::RGBA_8888); auto func = WTF::Bind(&ImageLayerBridge::ResourceReleasedSoftware, - WrapWeakPersistent(this), base::Passed(&bitmap), + WrapWeakPersistent(this), std::move(bitmap), image_for_compositor->Size()); *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func)); }
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.cpp b/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.cpp index 3f90469..3bf6b353 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.cpp
@@ -66,6 +66,16 @@ } } +void XRFrameTransport::FrameSubmitMissing( + device::mojom::blink::VRPresentationProvider* vr_presentation_provider, + gpu::gles2::GLES2Interface* gl, + int16_t vr_frame_id) { + TRACE_EVENT0("gpu", __FUNCTION__); + gpu::SyncToken sync_token; + gl->GenSyncTokenCHROMIUM(sync_token.GetData()); + vr_presentation_provider->SubmitFrameMissing(vr_frame_id, sync_token); +} + void XRFrameTransport::FrameSubmit( device::mojom::blink::VRPresentationProvider* vr_presentation_provider, gpu::gles2::GLES2Interface* gl,
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.h b/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.h index 6b845e9..a291c7c 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/XRFrameTransport.h
@@ -53,6 +53,10 @@ int16_t vr_frame_id, bool needs_copy); + void FrameSubmitMissing(device::mojom::blink::VRPresentationProvider*, + gpu::gles2::GLES2Interface*, + int16_t vr_frame_id); + virtual void Trace(blink::Visitor*); private:
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp index ff2ae9ff..eaedd75 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.cpp +++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -136,7 +136,6 @@ free_page_pool_(std::make_unique<PagePool>()), marking_worklist_(nullptr), not_fully_constructed_worklist_(nullptr), - post_marking_worklist_(nullptr), weak_callback_worklist_(nullptr), vector_backing_arena_index_(BlinkGC::kVector1ArenaIndex), current_arena_ages_(0), @@ -226,7 +225,6 @@ void ThreadHeap::CommitCallbackStacks() { marking_worklist_.reset(new MarkingWorklist()); not_fully_constructed_worklist_.reset(new NotFullyConstructedWorklist()); - post_marking_worklist_.reset(new PostMarkingWorklist()); weak_callback_worklist_.reset(new WeakCallbackWorklist()); DCHECK(ephemeron_callbacks_.IsEmpty()); } @@ -234,7 +232,6 @@ void ThreadHeap::DecommitCallbackStacks() { marking_worklist_.reset(nullptr); not_fully_constructed_worklist_.reset(nullptr); - post_marking_worklist_.reset(nullptr); weak_callback_worklist_.reset(nullptr); ephemeron_callbacks_.clear(); } @@ -329,18 +326,6 @@ return true; } -void ThreadHeap::PostMarkingProcessing(Visitor* visitor) { - TRACE_EVENT0("blink_gc", "ThreadHeap::PostMarkingProcessing"); - // Call post marking callbacks on collection backings to mark them if they are - // only reachable from their front objects. - CustomCallbackItem item; - while (post_marking_worklist_->Pop(WorklistTaskId::MainThread, &item)) { - item.callback(visitor, item.object); - } - // Post marking callbacks should not add any new objects for marking. - DCHECK(marking_worklist_->IsGlobalEmpty()); -} - void ThreadHeap::WeakProcessing(Visitor* visitor) { TRACE_EVENT0("blink_gc", "ThreadHeap::WeakProcessing"); double start_time = WTF::CurrentTimeTicksInMilliseconds();
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h index 73aca75..9e0a095 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.h +++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -71,8 +71,6 @@ using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>; using NotFullyConstructedWorklist = Worklist<NotFullyConstructedItem, 16 /* local entries */>; -using PostMarkingWorklist = - Worklist<CustomCallbackItem, 128 /* local entries */>; using WeakCallbackWorklist = Worklist<CustomCallbackItem, 256 /* local entries */>; @@ -255,10 +253,6 @@ return not_fully_constructed_worklist_.get(); } - PostMarkingWorklist* GetPostMarkingWorklist() const { - return post_marking_worklist_.get(); - } - WeakCallbackWorklist* GetWeakCallbackWorklist() const { return weak_callback_worklist_.get(); } @@ -348,7 +342,6 @@ static Address Reallocate(void* previous, size_t); void ProcessMarkingStack(Visitor*); - void PostMarkingProcessing(Visitor*); void WeakProcessing(Visitor*); void MarkNotFullyConstructedObjects(Visitor*); bool AdvanceMarkingStackProcessing(Visitor*, double deadline_seconds); @@ -513,7 +506,6 @@ std::unique_ptr<PagePool> free_page_pool_; std::unique_ptr<MarkingWorklist> marking_worklist_; std::unique_ptr<NotFullyConstructedWorklist> not_fully_constructed_worklist_; - std::unique_ptr<PostMarkingWorklist> post_marking_worklist_; std::unique_ptr<WeakCallbackWorklist> weak_callback_worklist_; // No duplicates allowed for ephemeron callbacks. Hence, we use a hashmap // with the key being the HashTable.
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.h b/third_party/WebKit/Source/platform/heap/HeapAllocator.h index 258c042e..7926b4e 100644 --- a/third_party/WebKit/Source/platform/heap/HeapAllocator.h +++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
@@ -181,13 +181,6 @@ } template <typename VisitorDispatcher> - static void RegisterWeakMembers(VisitorDispatcher visitor, - const void* closure, - WeakCallback callback) { - visitor->RegisterWeakCallback(const_cast<void*>(closure), callback); - } - - template <typename VisitorDispatcher> static bool RegisterWeakTable(VisitorDispatcher visitor, const void* closure, EphemeronCallback iteration_callback) { @@ -288,9 +281,21 @@ template <typename T, typename HashTable> static void TraceHashTableBackingWeakly(Visitor* visitor, T* backing, - T** backing_slot) { + T** backing_slot, + WeakCallback callback, + void* parameter) { visitor->TraceBackingStoreWeakly( reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing), + reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot), + callback, parameter); + } + + template <typename T, typename HashTable> + static void TraceHashTableBackingOnly(Visitor* visitor, + T* backing, + T** backing_slot) { + visitor->TraceBackingStoreOnly( + reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing), reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot)); }
diff --git a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp index b928694..59f35ed 100644 --- a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp +++ b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
@@ -58,9 +58,12 @@ void VisitBackingStoreStrongly(void* object, void** object_slot, TraceDescriptor desc) final {} - void VisitBackingStoreWeakly(void* object, - void** object_slot, - TraceDescriptor desc) final {} + void VisitBackingStoreWeakly(void*, + void**, + TraceDescriptor, + WeakCallback, + void*) final {} + void VisitBackingStoreOnly(void*, void**) final {} void RegisterBackingStoreCallback(void* backing_store, MovingObjectCallback, void* callback_data) final {} @@ -110,7 +113,6 @@ thread_state_->DisableIncrementalMarkingBarrier(); // Need to clear out unused worklists that might have been polluted during // test. - heap_.GetPostMarkingWorklist()->Clear(); heap_.GetWeakCallbackWorklist()->Clear(); thread_state_->SetGCPhase(ThreadState::GCPhase::kSweeping); thread_state_->SetGCPhase(ThreadState::GCPhase::kNone); @@ -1581,6 +1583,81 @@ EXPECT_NE(uninitialized_value, header); } +// ============================================================================= +// Tests that execute complete incremental garbage collections. ================ +// ============================================================================= + +// Test driver for incremental marking. Assumes that no stack handling is +// required. +class IncrementalMarkingTestDriver { + public: + explicit IncrementalMarkingTestDriver(ThreadState* thread_state) + : thread_state_(thread_state) {} + ~IncrementalMarkingTestDriver() { + if (thread_state_->IsIncrementalMarking()) + FinishGC(); + } + + void Start() { + thread_state_->ScheduleIncrementalMarkingStart(); + thread_state_->RunScheduledGC(BlinkGC::kNoHeapPointersOnStack); + } + + bool SingleStep() { + CHECK(thread_state_->IsIncrementalMarking()); + if (thread_state_->GcState() == + ThreadState::kIncrementalMarkingStepScheduled) { + thread_state_->RunScheduledGC(BlinkGC::kNoHeapPointersOnStack); + return true; + } + return false; + } + + void FinishSteps() { + CHECK(thread_state_->IsIncrementalMarking()); + while (SingleStep()) { + } + } + + void FinishGC() { + CHECK(thread_state_->IsIncrementalMarking()); + FinishSteps(); + CHECK_EQ(ThreadState::kIncrementalMarkingFinalizeScheduled, + thread_state_->GcState()); + thread_state_->RunScheduledGC(BlinkGC::kNoHeapPointersOnStack); + CHECK(!thread_state_->IsIncrementalMarking()); + thread_state_->CompleteSweep(); + } + + private: + ThreadState* const thread_state_; +}; + +TEST(IncrementalMarkingTest, TestDriver) { + IncrementalMarkingTestDriver driver(ThreadState::Current()); + driver.Start(); + EXPECT_TRUE(ThreadState::Current()->IsIncrementalMarking()); + driver.SingleStep(); + EXPECT_TRUE(ThreadState::Current()->IsIncrementalMarking()); + driver.FinishGC(); + EXPECT_FALSE(ThreadState::Current()->IsIncrementalMarking()); +} + +TEST(IncrementalMarkingTest, DropBackingStore) { + // Regression test: crbug.com/828537 + using WeakStore = HeapHashCountedSet<WeakMember<Object>>; + + Persistent<WeakStore> persistent(new WeakStore); + persistent->insert(Object::Create()); + IncrementalMarkingTestDriver driver(ThreadState::Current()); + driver.Start(); + driver.FinishSteps(); + persistent->clear(); + // Marking verifier should not crash on a black backing store with all + // black->white edges. + driver.FinishGC(); +} + } // namespace incremental_marking_test } // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/MarkingVerifier.h b/third_party/WebKit/Source/platform/heap/MarkingVerifier.h index 28e7c2f..feab107 100644 --- a/third_party/WebKit/Source/platform/heap/MarkingVerifier.h +++ b/third_party/WebKit/Source/platform/heap/MarkingVerifier.h
@@ -45,16 +45,15 @@ } // Unused overrides. - void VisitBackingStoreStrongly(void* object, - void** object_slot, - TraceDescriptor desc) final {} - void VisitBackingStoreWeakly(void* object, - void** object_slot, - TraceDescriptor desc) final {} - void RegisterBackingStoreCallback(void* backing_store, - MovingObjectCallback, - void* callback_data) final {} - void RegisterWeakCallback(void* closure, WeakCallback) final {} + void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final {} + void VisitBackingStoreWeakly(void*, + void**, + TraceDescriptor, + WeakCallback, + void*) final {} + void VisitBackingStoreOnly(void*, void**) final {} + void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {} + void RegisterWeakCallback(void*, WeakCallback) final {} private: void VerifyChild(void* base_object_payload) {
diff --git a/third_party/WebKit/Source/platform/heap/MarkingVisitor.cpp b/third_party/WebKit/Source/platform/heap/MarkingVisitor.cpp index 7a0863f22..fb536f8 100644 --- a/third_party/WebKit/Source/platform/heap/MarkingVisitor.cpp +++ b/third_party/WebKit/Source/platform/heap/MarkingVisitor.cpp
@@ -20,8 +20,6 @@ WorklistTaskId::MainThread), not_fully_constructed_worklist_(Heap().GetNotFullyConstructedWorklist(), WorklistTaskId::MainThread), - post_marking_worklist_(Heap().GetPostMarkingWorklist(), - WorklistTaskId::MainThread), weak_callback_worklist_(Heap().GetWeakCallbackWorklist(), WorklistTaskId::MainThread), marking_mode_(marking_mode) { @@ -103,11 +101,6 @@ } } -void MarkingVisitor::MarkNoTracingCallback(Visitor* visitor, void* object) { - reinterpret_cast<MarkingVisitor*>(visitor)->MarkHeaderNoTracing( - HeapObjectHeader::FromPayload(object)); -} - void MarkingVisitor::RegisterWeakCallback(void* object, WeakCallback callback) { // We don't want to run weak processings when taking a snapshot. if (marking_mode_ == kSnapshotMarking)
diff --git a/third_party/WebKit/Source/platform/heap/MarkingVisitor.h b/third_party/WebKit/Source/platform/heap/MarkingVisitor.h index 569ad56..7c86203 100644 --- a/third_party/WebKit/Source/platform/heap/MarkingVisitor.h +++ b/third_party/WebKit/Source/platform/heap/MarkingVisitor.h
@@ -111,17 +111,21 @@ Visit(object, desc); } - // Used to delay the marking of objects until the usual marking including - // ephemeron iteration is done. This is used to delay the marking of - // collection backing stores until we know if they are reachable from - // locations other than the collection front object. If collection backings - // are reachable from other locations we strongify them to avoid issues with - // iterators and weak processing. + // All work is registered through RegisterWeakCallback. void VisitBackingStoreWeakly(void* object, void** object_slot, - TraceDescriptor desc) final { + TraceDescriptor desc, + WeakCallback callback, + void* parameter) final { + RegisterWeakCallback(parameter, callback); + } + + // Used to only mark the backing store when it has been registered for weak + // processing. In this case, the contents are processed separately using + // the corresponding traits but the backing store requires marking. + void VisitBackingStoreOnly(void* object, void** object_slot) final { + MarkHeaderNoTracing(HeapObjectHeader::FromPayload(object)); RegisterBackingStoreReference(object_slot); - post_marking_worklist_.Push({object, &MarkNoTracingCallback}); } void RegisterBackingStoreCallback(void* backing_store, @@ -132,15 +136,12 @@ void RegisterWeakCallback(void* closure, WeakCallback) final; private: - static void MarkNoTracingCallback(Visitor*, void*); - void RegisterBackingStoreReference(void* slot); void ConservativelyMarkHeader(HeapObjectHeader*); MarkingWorklist::View marking_worklist_; NotFullyConstructedWorklist::View not_fully_constructed_worklist_; - PostMarkingWorklist::View post_marking_worklist_; WeakCallbackWorklist::View weak_callback_worklist_; const MarkingMode marking_mode_; };
diff --git a/third_party/WebKit/Source/platform/heap/RunAllTests.cpp b/third_party/WebKit/Source/platform/heap/RunAllTests.cpp index 830a17bd..d6af904 100644 --- a/third_party/WebKit/Source/platform/heap/RunAllTests.cpp +++ b/third_party/WebKit/Source/platform/heap/RunAllTests.cpp
@@ -54,5 +54,5 @@ int main(int argc, char** argv) { base::TestSuite testSuite(argc, argv); return base::LaunchUnitTests( - argc, argv, base::Bind(runHelper, base::Unretained(&testSuite))); + argc, argv, base::BindOnce(runHelper, base::Unretained(&testSuite))); }
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp index 3eb63807..2cff28a6 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -1463,7 +1463,6 @@ visitor, std::numeric_limits<double>::infinity())); VisitWeakPersistents(visitor); - Heap().PostMarkingProcessing(visitor); Heap().WeakProcessing(visitor); Heap().DecommitCallbackStacks();
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h index 78aaf85a..482db41c 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.h +++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -59,6 +59,7 @@ namespace incremental_marking_test { class IncrementalMarkingScope; +class IncrementalMarkingTestDriver; } // namespace incremental_marking_test class GarbageCollectedMixinConstructorMarkerBase; @@ -584,6 +585,7 @@ private: // Needs to set up visitor for testing purposes. friend class incremental_marking_test::IncrementalMarkingScope; + friend class incremental_marking_test::IncrementalMarkingTestDriver; template <typename T> friend class PrefinalizerRegistration;
diff --git a/third_party/WebKit/Source/platform/heap/Visitor.h b/third_party/WebKit/Source/platform/heap/Visitor.h index eb43dfb..376c0da 100644 --- a/third_party/WebKit/Source/platform/heap/Visitor.h +++ b/third_party/WebKit/Source/platform/heap/Visitor.h
@@ -129,7 +129,10 @@ } template <typename T> - void TraceBackingStoreWeakly(T* backing_store, T** backing_store_slot) { + void TraceBackingStoreWeakly(T* backing_store, + T** backing_store_slot, + WeakCallback callback, + void* parameter) { static_assert(sizeof(T), "T must be fully defined"); static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); @@ -139,7 +142,20 @@ VisitBackingStoreWeakly(reinterpret_cast<void*>(backing_store), reinterpret_cast<void**>(backing_store_slot), TraceTrait<T>::GetTraceDescriptor( - reinterpret_cast<void*>(backing_store))); + reinterpret_cast<void*>(backing_store)), + callback, parameter); + } + + template <typename T> + void TraceBackingStoreOnly(T* backing_store, T** backing_store_slot) { + static_assert(sizeof(T), "T must be fully defined"); + static_assert(IsGarbageCollectedType<T>::value, + "T needs to be a garbage collected object"); + + if (!backing_store) + return; + VisitBackingStoreOnly(reinterpret_cast<void*>(backing_store), + reinterpret_cast<void**>(backing_store_slot)); } // WeakMember version of the templated trace method. It doesn't keep @@ -202,7 +218,12 @@ // Visitors for collection backing stores. virtual void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) = 0; - virtual void VisitBackingStoreWeakly(void*, void**, TraceDescriptor) = 0; + virtual void VisitBackingStoreWeakly(void*, + void**, + TraceDescriptor, + WeakCallback, + void*) = 0; + virtual void VisitBackingStoreOnly(void*, void**) = 0; // Registers backing store pointers so that they can be moved and properly // updated.
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferences.cpp b/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferences.cpp index b00ab4f..357f4da 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferences.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferences.cpp
@@ -32,6 +32,21 @@ mojom::WebClientHintsType::kDeviceMemory, enabled_hints.IsEnabled(mojom::WebClientHintsType::kDeviceMemory) && RuntimeEnabledFeatures::DeviceMemoryHeaderEnabled()); + + enabled_hints.SetIsEnabled( + mojom::WebClientHintsType::kRtt, + enabled_hints.IsEnabled(mojom::WebClientHintsType::kRtt) && + RuntimeEnabledFeatures::NetInfoRttHeaderEnabled()); + + enabled_hints.SetIsEnabled( + mojom::WebClientHintsType::kDownlink, + enabled_hints.IsEnabled(mojom::WebClientHintsType::kDownlink) && + RuntimeEnabledFeatures::NetInfoDownlinkHeaderEnabled()); + + enabled_hints.SetIsEnabled( + mojom::WebClientHintsType::kEct, + enabled_hints.IsEnabled(mojom::WebClientHintsType::kEct) && + RuntimeEnabledFeatures::NetInfoEffectiveTypeHeaderEnabled()); } } // namespace
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferencesTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferencesTest.cpp index ec0f18f..9dfe98db 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferencesTest.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ClientHintsPreferencesTest.cpp
@@ -21,13 +21,19 @@ bool expectation_resource_width; bool expectation_dpr; bool expectation_viewport_width; + bool expectation_rtt; + bool expectation_downlink; + bool expectation_ect; } cases[] = { - {"width, dpr, viewportWidth", true, true, false}, - {"WiDtH, dPr, viewport-width", true, true, true}, - {"WIDTH, DPR, VIWEPROT-Width", true, true, false}, - {"VIewporT-Width, wutwut, width", true, false, true}, - {"dprw", false, false, false}, - {"DPRW", false, false, false}, + {"width, dpr, viewportWidth", true, true, false, false, false, false}, + {"WiDtH, dPr, viewport-width, rtt, downlink, ect", true, true, true, true, + true, true}, + {"WiDtH, dPr, viewport-width, rtt, downlink, effective-connection-type", + true, true, true, true, true, false}, + {"WIDTH, DPR, VIWEPROT-Width", true, true, false, false, false, false}, + {"VIewporT-Width, wutwut, width", true, false, true, false, false, false}, + {"dprw", false, false, false, false, false, false}, + {"DPRW", false, false, false, false, false, false}, }; for (const auto& test_case : cases) { @@ -43,6 +49,12 @@ EXPECT_EQ( test_case.expectation_viewport_width, preferences.ShouldSend(mojom::WebClientHintsType::kViewportWidth)); + EXPECT_EQ(test_case.expectation_rtt, + preferences.ShouldSend(mojom::WebClientHintsType::kRtt)); + EXPECT_EQ(test_case.expectation_downlink, + preferences.ShouldSend(mojom::WebClientHintsType::kDownlink)); + EXPECT_EQ(test_case.expectation_ect, + preferences.ShouldSend(mojom::WebClientHintsType::kEct)); // Calling UpdateFromAcceptClientHintsHeader with empty header should have // no impact on client hint preferences. @@ -94,7 +106,7 @@ {true, "width, dpr, viewportWidth", "1000s", 0}, {true, "width, dpr, viewportWidth", "1000.5", 0}, {false, "width, dpr, viewportWidth", "1000", 0}, - {true, "width, dpr, viewportWidth", "1000", 1000}, + {true, "width, dpr, rtt, downlink, ect", "1000", 1000}, }; for (const auto& test : test_cases) { @@ -123,6 +135,10 @@ enabled_types.IsEnabled(mojom::WebClientHintsType::kResourceWidth)); EXPECT_FALSE( enabled_types.IsEnabled(mojom::WebClientHintsType::kViewportWidth)); + EXPECT_TRUE(enabled_types.IsEnabled(mojom::WebClientHintsType::kRtt)); + EXPECT_TRUE( + enabled_types.IsEnabled(mojom::WebClientHintsType::kDownlink)); + EXPECT_TRUE(enabled_types.IsEnabled(mojom::WebClientHintsType::kEct)); } else { EXPECT_FALSE( enabled_types.IsEnabled(mojom::WebClientHintsType::kDeviceMemory)); @@ -131,6 +147,10 @@ enabled_types.IsEnabled(mojom::WebClientHintsType::kResourceWidth)); EXPECT_FALSE( enabled_types.IsEnabled(mojom::WebClientHintsType::kViewportWidth)); + EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kRtt)); + EXPECT_FALSE( + enabled_types.IsEnabled(mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kEct)); } } }
diff --git a/third_party/WebKit/Source/platform/mojo/InterfaceInvalidatorTest.cpp b/third_party/WebKit/Source/platform/mojo/InterfaceInvalidatorTest.cpp index e883361..3f1fd6e 100644 --- a/third_party/WebKit/Source/platform/mojo/InterfaceInvalidatorTest.cpp +++ b/third_party/WebKit/Source/platform/mojo/InterfaceInvalidatorTest.cpp
@@ -74,7 +74,7 @@ error_handler_called_(false), binding_(this, std::move(request)) { binding_.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &error_handler_called_)); + base::BindOnce(DoSetFlag, &error_handler_called_)); } ~PingServiceImpl() override {} @@ -142,7 +142,7 @@ bool error_handler_called = false; wptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &error_handler_called)); + base::BindOnce(DoSetFlag, &error_handler_called)); invalidator.reset(); impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); @@ -178,7 +178,7 @@ bool impl_called = false; impl.set_ping_handler(base::BindRepeating(DoSetFlag, &impl_called)); - wptr.set_connection_error_handler(base::BindRepeating([] { FAIL(); })); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); mojo::test::blink::PingServicePtr ptr(wptr.PassInterface()); invalidator.reset(); @@ -199,7 +199,7 @@ impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); bool error_handler_called = false; wptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &error_handler_called)); + base::BindOnce(DoSetFlag, &error_handler_called)); // This also destroys the original invalidator. invalidator = std::make_unique<InterfaceInvalidator>(); @@ -220,7 +220,7 @@ PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); - wptr.set_connection_error_handler(base::BindRepeating([] { FAIL(); })); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); // This also destroys the original invalidator. invalidator = std::make_unique<InterfaceInvalidator>(); @@ -235,7 +235,7 @@ mojo::test::blink::RevocablePingServicePtr wptr; auto invalidator = std::make_unique<InterfaceInvalidator>(); PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); - wptr.set_connection_error_handler(base::BindRepeating([] { FAIL(); })); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); wptr.reset(); invalidator.reset(); @@ -248,7 +248,7 @@ mojo::test::blink::RevocablePingServicePtr wptr; auto invalidator = std::make_unique<InterfaceInvalidator>(); PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); - wptr.set_connection_error_handler(base::BindRepeating([] { FAIL(); })); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); invalidator.reset(); wptr.reset(); @@ -292,7 +292,7 @@ auto wptr2(std::move(wptr)); bool called = false; - wptr2.set_connection_error_handler(base::BindRepeating(DoSetFlag, &called)); + wptr2.set_connection_error_handler(base::BindOnce(DoSetFlag, &called)); invalidator.reset(); wptr2->Ping(base::BindRepeating([] { FAIL(); })); @@ -346,7 +346,7 @@ error_handler_called_(false), binding_(this, std::move(request), invalidator) { binding_.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &error_handler_called_)); + base::BindOnce(DoSetFlag, &error_handler_called_)); } ~RevocablePingServiceImpl() override {} @@ -376,7 +376,7 @@ bool error_handler_called = false; ptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &error_handler_called)); + base::BindOnce(DoSetFlag, &error_handler_called)); invalidator.reset(); impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); @@ -399,7 +399,7 @@ bool ptr_error_handler_called = false; ptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &ptr_error_handler_called)); + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); ptr->Ping(base::BindRepeating([] { FAIL(); })); base::RunLoop().RunUntilIdle(); @@ -419,7 +419,7 @@ bool ptr_error_handler_called = false; ptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &ptr_error_handler_called)); + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); bool ping_called = false; ptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); ptr->Ping(base::BindRepeating([] { FAIL(); })); @@ -435,7 +435,7 @@ mojo::test::blink::PingServicePtr ptr; auto invalidator = std::make_unique<InterfaceInvalidator>(); RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); - ptr.set_connection_error_handler(base::BindRepeating([] { FAIL(); })); + ptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); PingServiceImpl impl2(impl.binding()->Unbind()); invalidator.reset(); @@ -454,7 +454,7 @@ bool ptr_error_handler_called = false; ptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &ptr_error_handler_called)); + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); invalidator.reset(); base::RunLoop().RunUntilIdle(); @@ -475,7 +475,7 @@ bool ptr_error_handler_called = false; ptr.set_connection_error_handler( - base::BindRepeating(DoSetFlag, &ptr_error_handler_called)); + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); invalidator.reset(); PingServiceImpl impl2(impl.binding()->Unbind()); @@ -599,7 +599,7 @@ auto impl_ptr = MakeRevocableStrongBinding(std::make_unique<PingServiceImplBase>(), MakeRequest(&ptr), invalidator.get()); - ptr.set_connection_error_handler(base::BindRepeating([] { FAIL(); })); + ptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); ptr.reset(); base::RunLoop().RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/mojo/RevocableStrongBinding.h b/third_party/WebKit/Source/platform/mojo/RevocableStrongBinding.h index d760e94..aa898d3 100644 --- a/third_party/WebKit/Source/platform/mojo/RevocableStrongBinding.h +++ b/third_party/WebKit/Source/platform/mojo/RevocableStrongBinding.h
@@ -100,7 +100,7 @@ : impl_(std::move(impl)), binding_(impl_.get(), std::move(request), invalidator), weak_factory_(this) { - binding_.set_connection_error_handler(base::BindRepeating( + binding_.set_connection_error_handler(base::BindOnce( &RevocableStrongBinding::OnConnectionError, base::Unretained(this))); }
diff --git a/third_party/WebKit/Source/platform/network/HTTPParsers.cpp b/third_party/WebKit/Source/platform/network/HTTPParsers.cpp index 92128f1f..a583f5de 100644 --- a/third_party/WebKit/Source/platform/network/HTTPParsers.cpp +++ b/third_party/WebKit/Source/platform/network/HTTPParsers.cpp
@@ -86,45 +86,6 @@ return pos < len; } -// Returns true if the function can match the whole token (case insensitive) -// incrementing pos on match, otherwise leaving pos unchanged. -// Note: Might return pos == str.length() -inline bool SkipToken(const String& str, unsigned& pos, const char* token) { - unsigned len = str.length(); - unsigned current = pos; - - while (current < len && *token) { - if (ToASCIILower(str[current]) != *token++) - return false; - ++current; - } - - if (*token) - return false; - - pos = current; - return true; -} - -// True if the expected equals sign is seen and there is more to follow. -inline bool SkipEquals(const String& str, unsigned& pos) { - return SkipWhiteSpace(str, pos) && str[pos++] == '=' && - SkipWhiteSpace(str, pos); -} - -// True if a value present, incrementing pos to next space or semicolon, if any. -// Note: might return pos == str.length(). -inline bool SkipValue(const String& str, unsigned& pos) { - unsigned start = pos; - unsigned len = str.length(); - while (pos < len) { - if (str[pos] == ' ' || str[pos] == '\t' || str[pos] == ';') - break; - ++pos; - } - return pos != start; -} - template <typename CharType> inline bool IsASCIILowerAlphaOrDigit(CharType c) { return IsASCIILower(c) || IsASCIIDigit(c); @@ -302,7 +263,7 @@ unsigned& failure_position, String& report_url) { DEFINE_STATIC_LOCAL(String, failure_reason_invalid_toggle, - ("expected 0 or 1")); + ("expected token to be 0 or 1")); DEFINE_STATIC_LOCAL(String, failure_reason_invalid_separator, ("expected semicolon")); DEFINE_STATIC_LOCAL(String, failure_reason_invalid_equals, @@ -318,84 +279,98 @@ DEFINE_STATIC_LOCAL(String, failure_reason_invalid_directive, ("unrecognized directive")); - unsigned pos = 0; + HeaderFieldTokenizer tokenizer(header); - if (!SkipWhiteSpace(header, pos)) - return kReflectedXSSUnset; + StringView toggle; + if (!tokenizer.ConsumeToken(Mode::kNormal, toggle)) { + if (tokenizer.IsConsumed()) + return kReflectedXSSUnset; + } - if (header[pos] == '0') - return kAllowReflectedXSS; - - if (header[pos++] != '1') { + if (toggle.length() != 1 || (toggle[0] != '0' && toggle[0] != '1')) { failure_reason = failure_reason_invalid_toggle; return kReflectedXSSInvalid; } + if (toggle[0] == '0') + return kAllowReflectedXSS; + ReflectedXSSDisposition result = kFilterReflectedXSS; bool mode_directive_seen = false; bool report_directive_seen = false; - while (1) { + while (!tokenizer.IsConsumed()) { // At end of previous directive: consume whitespace, semicolon, and // whitespace. - if (!SkipWhiteSpace(header, pos)) - return result; - - if (header[pos++] != ';') { + if (!tokenizer.Consume(';')) { failure_reason = failure_reason_invalid_separator; - failure_position = pos; + failure_position = tokenizer.Index(); return kReflectedXSSInvalid; } - if (!SkipWhiteSpace(header, pos)) + // Give a pass to a trailing semicolon. + if (tokenizer.IsConsumed()) return result; // At start of next directive. - if (SkipToken(header, pos, "mode")) { + StringView token; + unsigned token_start = tokenizer.Index(); + if (!tokenizer.ConsumeToken(Mode::kNormal, token)) { + failure_reason = failure_reason_invalid_directive; + failure_position = token_start; + return kReflectedXSSInvalid; + } + if (EqualIgnoringASCIICase(token, "mode")) { if (mode_directive_seen) { failure_reason = failure_reason_duplicate_mode; - failure_position = pos; + failure_position = token_start; return kReflectedXSSInvalid; } mode_directive_seen = true; - if (!SkipEquals(header, pos)) { + if (!tokenizer.Consume('=')) { failure_reason = failure_reason_invalid_equals; - failure_position = pos; + failure_position = tokenizer.Index(); return kReflectedXSSInvalid; } - if (!SkipToken(header, pos, "block")) { + String value; + unsigned value_start = tokenizer.Index(); + if (!tokenizer.ConsumeTokenOrQuotedString(Mode::kNormal, value) || + !EqualIgnoringASCIICase(value, "block")) { failure_reason = failure_reason_invalid_mode; - failure_position = pos; + failure_position = value_start; return kReflectedXSSInvalid; } result = kBlockReflectedXSS; - } else if (SkipToken(header, pos, "report")) { + } else if (EqualIgnoringASCIICase(token, "report")) { if (report_directive_seen) { failure_reason = failure_reason_duplicate_report; - failure_position = pos; + failure_position = token_start; return kReflectedXSSInvalid; } report_directive_seen = true; - if (!SkipEquals(header, pos)) { + if (!tokenizer.Consume('=')) { failure_reason = failure_reason_invalid_equals; - failure_position = pos; + failure_position = tokenizer.Index(); return kReflectedXSSInvalid; } - size_t start_pos = pos; - if (!SkipValue(header, pos)) { + // Set, just in case later semantic check deems unacceptable. + failure_position = tokenizer.Index(); + String value; + // Relaxed mode - unquoted URLs contain colons and such. + if (!tokenizer.ConsumeTokenOrQuotedString(Mode::kRelaxed, value)) { failure_reason = failure_reason_invalid_report; - failure_position = pos; return kReflectedXSSInvalid; } - report_url = header.Substring(start_pos, pos - start_pos); - failure_position = - start_pos; // If later semantic check deems unacceptable. + report_url = value; } else { + // Unrecognized directive failure_reason = failure_reason_invalid_directive; - failure_position = pos; + failure_position = token_start; return kReflectedXSSInvalid; } } + + return result; } ContentTypeOptionsDisposition ParseContentTypeOptionsHeader(
diff --git a/third_party/WebKit/Source/platform/network/HTTPParsersTest.cpp b/third_party/WebKit/Source/platform/network/HTTPParsersTest.cpp index 10d75865..661673b 100644 --- a/third_party/WebKit/Source/platform/network/HTTPParsersTest.cpp +++ b/third_party/WebKit/Source/platform/network/HTTPParsersTest.cpp
@@ -613,34 +613,34 @@ SUCC__("1", kFilterReflectedXSS, 0, nullptr), SUCC__(" 1 ", kFilterReflectedXSS, 0, nullptr), SUCC__(" 1 ;", kFilterReflectedXSS, 0, nullptr), - FAIL__(";", "expected 0 or 1", 0), - FAIL__(";;", "expected 0 or 1", 0), - FAIL__(";;;", "expected 0 or 1", 0), - FAIL__(" ; ", "expected 0 or 1", 0), - FAIL__(" ; ; ", "expected 0 or 1", 0), - FAIL__("; ; ;", "expected 0 or 1", 0), - FAIL__("2", "expected 0 or 1", 0), - FAIL__(" 2 ", "expected 0 or 1", 0), - FAIL__("-1", "expected 0 or 1", 0), - FAIL__(" -1 ", "expected 0 or 1", 0), - FAIL__("red", "expected 0 or 1", 0), - FAIL__("12345678901234567", "expected semicolon", 2), - FAIL__("1:", "expected semicolon", 2), - FAIL__("1 2", "expected semicolon", 3), + FAIL__(";", "expected token to be 0 or 1", 0), + FAIL__(";;", "expected token to be 0 or 1", 0), + FAIL__(";;;", "expected token to be 0 or 1", 0), + FAIL__(" ; ", "expected token to be 0 or 1", 0), + FAIL__(" ; ; ", "expected token to be 0 or 1", 0), + FAIL__("; ; ;", "expected token to be 0 or 1", 0), + FAIL__("2", "expected token to be 0 or 1", 0), + FAIL__(" 2 ", "expected token to be 0 or 1", 0), + FAIL__("-1", "expected token to be 0 or 1", 0), + FAIL__(" -1 ", "expected token to be 0 or 1", 0), + FAIL__("red", "expected token to be 0 or 1", 0), + FAIL__("12345678901234567", "expected token to be 0 or 1", 0), + FAIL__("1:", "expected semicolon", 1), + FAIL__("1 2", "expected semicolon", 2), FAIL__("1; red", "unrecognized directive", 3), // Don't allow quoted strings here. - FAIL__("\"", "expected 0 or 1", 0), - FAIL__("\"0", "expected 0 or 1", 0), - FAIL__("\"0\"", "expected 0 or 1", 0), - FAIL__("\" 0 \"", "expected 0 or 1", 0), - FAIL__("\" 0\";", "expected 0 or 1", 0), - FAIL__("\" 0;\"", "expected 0 or 1", 0), - FAIL__("\"1", "expected 0 or 1", 0), - FAIL__("\"1\"", "expected 0 or 1", 0), - FAIL__("\" 1 \"", "expected 0 or 1", 0), - FAIL__("\" 1\";", "expected 0 or 1", 0), - FAIL__("\" 1;\"", "expected 0 or 1", 0), + FAIL__("\"", "expected token to be 0 or 1", 0), + FAIL__("\"0", "expected token to be 0 or 1", 0), + FAIL__("\"0\"", "expected token to be 0 or 1", 0), + FAIL__("\" 0 \"", "expected token to be 0 or 1", 0), + FAIL__("\" 0\";", "expected token to be 0 or 1", 0), + FAIL__("\" 0;\"", "expected token to be 0 or 1", 0), + FAIL__("\"1", "expected token to be 0 or 1", 0), + FAIL__("\"1\"", "expected token to be 0 or 1", 0), + FAIL__("\" 1 \"", "expected token to be 0 or 1", 0), + FAIL__("\" 1\";", "expected token to be 0 or 1", 0), + FAIL__("\" 1;\"", "expected token to be 0 or 1", 0), // No other parameters unless enabled. SUCC__("0; mode=block; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag", @@ -656,18 +656,18 @@ SUCC__("1; mode= block;", kBlockReflectedXSS, 0, nullptr), SUCC__("1; mode =block;", kBlockReflectedXSS, 0, nullptr), FAIL__("1; mode", "expected equals sign", 7), - FAIL__("1; mode=", "expected equals sign", 8), - FAIL__("1; mode =", "expected equals sign", 9), + FAIL__("1; mode=", "invalid mode directive", 8), + FAIL__("1; mode =", "invalid mode directive", 9), FAIL__("1; mode=purple", "invalid mode directive", 8), - FAIL__("1; mode=block-a-block-block", "expected semicolon", 14), - FAIL__("1; mode=block=a-block-block", "expected semicolon", 14), - FAIL__("1; mode=block; mode=block", "duplicate mode directive", 19), + FAIL__("1; mode=block-a-block-block", "invalid mode directive", 8), + FAIL__("1; mode=block=a-block-block", "expected semicolon", 13), + FAIL__("1; mode=block; mode=block", "duplicate mode directive", 15), FAIL__("1; mode=block; report=foo; mode=block;", - "duplicate mode directive", 31), + "duplicate mode directive", 27), - // TODO(tsepez): allow quoted strings here. - FAIL__("1; mode=\"block\"", "invalid mode directive", 8), - FAIL__("1; mode=\"block\";", "invalid mode directive", 8), + // Quoted strings allowed here. + SUCC__("1; mode=\"block\"", kBlockReflectedXSS, 0, nullptr), + SUCC__("1; mode=\"block\";", kBlockReflectedXSS, 0, nullptr), FAIL__("1; mode=\"block;\"", "invalid mode directive", 8), FAIL__("1; mode=\"red\"", "invalid mode directive", 8), @@ -689,24 +689,23 @@ SUCC__("1; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag; mode=block", kBlockReflectedXSS, 10, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"), FAIL__("1; report", "expected equals sign", 9), - FAIL__("1; report=", "expected equals sign", 10), + FAIL__("1; report=", "invalid report directive", 10), FAIL__("1; report= ;", "invalid report directive", 11), FAIL__("1; report=http://foo.com; mode=block; report=http://foo.com;", - "duplicate report directive", 44), + "duplicate report directive", 38), FAIL__("1; report=http://foo.com;SEQUID=7", "unrecognized directive", 25), FAIL__("1; mode=block; report=http://foo.com;SEQUID=7", "unrecognized directive", 37), - // TODO(tsepez): See https://crbug.com/825557 - SUCC__("1; report=\"", kFilterReflectedXSS, 10, "\""), - SUCC__("1; report=\"http://foo.com", kFilterReflectedXSS, 10, - "\"http://foo.com"), + // Quoted strings allowed per https://crbug.com/825557 SUCC__("1; report=\"http://foo.com\"", kFilterReflectedXSS, 10, - "\"http://foo.com\""), - FAIL__("1; report=\"http://foo.com;SEQUID=7\"", "unrecognized directive", - 26), - FAIL__("1; report=\"http://foo.com\";SEQUID=7", "unrecognized directive", - 27), + "http://foo.com"), + SUCC__("1; report=\"http://foo.com;SEQUID=7\"", kFilterReflectedXSS, 10, + "http://foo.com;SEQUID=7"), + FAIL__("1; report=\"", "invalid report directive", 10), + FAIL__("1; report=\"http://foo.com", "invalid report directive", 10), + FAIL__("1; report=\"http://foo.com\";SEQUID=7", + "unrecognized directive", 27), #undef SUCC__ #undef FAIL__
diff --git a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h index 6af2d9a..e6678275 100644 --- a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h +++ b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h
@@ -124,7 +124,8 @@ WebEffectiveConnectionType EffectiveType() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; - DCHECK(state.on_line_initialized); + // TODO (tbansal): Add a DCHECK to check that |state.on_line_initialized| is + // true once https://crbug.com/728771 is fixed. return state.effective_type; } @@ -133,7 +134,8 @@ Optional<TimeDelta> HttpRtt() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; - DCHECK(state.on_line_initialized); + // TODO (tbansal): Add a DCHECK to check that |state.on_line_initialized| is + // true once https://crbug.com/728771 is fixed. return state.http_rtt; } @@ -151,7 +153,8 @@ Optional<double> DownlinkThroughputMbps() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; - DCHECK(state.on_line_initialized); + // TODO (tbansal): Add a DCHECK to check that |state.on_line_initialized| is + // true once https://crbug.com/728771 is fixed. return state.downlink_throughput_mbps; }
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5 index 9126b1c..e5983d4 100644 --- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 +++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -748,6 +748,10 @@ status: "stable", }, { + name: "NetInfoDownlinkHeader", + status: "experimental", + }, + { name: "NetInfoDownlinkMax", status: "stable", }, @@ -756,10 +760,18 @@ status: "stable", }, { + name: "NetInfoEffectiveTypeHeader", + status: "experimental", + }, + { name: "NetInfoRtt", status: "stable", }, { + name: "NetInfoRttHeader", + status: "experimental", + }, + { name: "NetInfoSaveData", status: "stable", },
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc index 4411b92e..dfd5d227 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -535,7 +535,7 @@ } void FrameSchedulerImpl::SetPageFrozen(bool frozen) { - DCHECK(page_visibility_ == PageVisibilityState::kHidden); + DCHECK(!frozen || page_visibility_ == PageVisibilityState::kHidden); page_frozen_ = frozen; UpdateTaskQueues(); UpdateThrottlingState();
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc index 8fc795f..43a4e58 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -100,6 +100,7 @@ page_visibility_(kDefaultPageVisibility), disable_background_timer_throttling_(disable_background_timer_throttling), is_audio_playing_(false), + is_frozen_(false), reported_background_throttling_since_navigation_(false), has_active_connection_(false), nested_runloop_(false), @@ -134,9 +135,16 @@ page_visibility_ = page_visibility; UpdateBackgroundThrottlingState(); + + // Visible pages should not be frozen. + if (page_visibility_ == PageVisibilityState::kVisible && is_frozen_) + SetPageFrozen(false); } void PageSchedulerImpl::SetPageFrozen(bool frozen) { + if (is_frozen_ == frozen) + return; + is_frozen_ = frozen; for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) frame_scheduler->SetPageFrozen(frozen); if (delegate_) @@ -248,6 +256,10 @@ return is_audio_playing_; } +bool PageSchedulerImpl::IsFrozen() const { + return is_frozen_; +} + void PageSchedulerImpl::OnConnectionUpdated() { bool has_active_connection = false; for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) { @@ -274,6 +286,7 @@ state->SetBoolean("disable_background_timer_throttling", disable_background_timer_throttling_); state->SetBoolean("is_audio_playing", is_audio_playing_); + state->SetBoolean("is_frozen", is_frozen_); state->SetBoolean("reported_background_throttling_since_navigation", reported_background_throttling_since_navigation_);
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h index 50cdf63..0f6f6a9 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -73,6 +73,8 @@ // Virtual for testing. virtual void ReportIntervention(const std::string& message); + bool IsFrozen() const; + std::unique_ptr<FrameSchedulerImpl> CreateFrameSchedulerImpl( base::trace_event::BlameContext*, FrameScheduler::FrameType); @@ -117,6 +119,7 @@ PageVisibilityState page_visibility_; bool disable_background_timer_throttling_; bool is_audio_playing_; + bool is_frozen_; bool reported_background_throttling_since_navigation_; bool has_active_connection_; bool nested_runloop_;
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc index 09dd147..64e402de 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -80,6 +80,18 @@ return frame_scheduler_->LoadingTaskQueue(); } + scoped_refptr<TaskQueue> DeferrableTaskQueue() { + return frame_scheduler_->DeferrableTaskQueue(); + } + + scoped_refptr<TaskQueue> PausableTaskQueue() { + return frame_scheduler_->PausableTaskQueue(); + } + + scoped_refptr<TaskQueue> UnpausableTaskQueue() { + return frame_scheduler_->UnpausableTaskQueue(); + } + base::SimpleTestTickClock clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; std::unique_ptr<RendererSchedulerImpl> scheduler_; @@ -1099,6 +1111,63 @@ base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); } +namespace { +void IncrementCounter(int* counter) { + ++*counter; +} +} // namespace + +TEST_F(PageSchedulerImplTest, PageFreeze) { + ScopedStopLoadingInBackgroundForTest stop_loading_enabler(true); + ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(true); + + int counter = 0; + LoadingTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + ThrottleableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + DeferrableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + PausableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + UnpausableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + + page_scheduler_->SetPageVisible(false); + EXPECT_EQ(false, page_scheduler_->IsFrozen()); + + // In a backgrounded active page, all queues should run. + mock_task_runner_->RunUntilIdle(); + EXPECT_EQ(5, counter); + + LoadingTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + ThrottleableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + DeferrableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + PausableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + UnpausableTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + counter = 0; + + page_scheduler_->SetPageFrozen(true); + EXPECT_EQ(true, page_scheduler_->IsFrozen()); + + // In a backgrounded frozen page, only Unpausable queue should run. + mock_task_runner_->RunUntilIdle(); + EXPECT_EQ(1, counter); + + // A visible page should not be frozen. + page_scheduler_->SetPageVisible(true); + EXPECT_EQ(false, page_scheduler_->IsFrozen()); + + // Once the page is unfrozen, the rest of the queues should run. + mock_task_runner_->RunUntilIdle(); + EXPECT_EQ(5, counter); +} + } // namespace page_scheduler_impl_unittest } // namespace scheduler } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/WebScrollIntoViewParams.cpp b/third_party/WebKit/Source/platform/scroll/WebScrollIntoViewParams.cpp index d6e50ef7..e3ad05d 100644 --- a/third_party/WebKit/Source/platform/scroll/WebScrollIntoViewParams.cpp +++ b/third_party/WebKit/Source/platform/scroll/WebScrollIntoViewParams.cpp
@@ -93,13 +93,15 @@ ScrollType scroll_type, bool make_visible_in_visual_viewport, ScrollBehavior scroll_behavior, - bool is_for_scroll_sequence) + bool is_for_scroll_sequence, + bool zoom_into_rect) : align_x(scroll_alignment_x), align_y(scroll_alignment_y), type(FromScrollType(scroll_type)), make_visible_in_visual_viewport(make_visible_in_visual_viewport), behavior(FromScrollBehavior(scroll_behavior)), - is_for_scroll_sequence(is_for_scroll_sequence) {} + is_for_scroll_sequence(is_for_scroll_sequence), + zoom_into_rect(zoom_into_rect) {} ScrollAlignment WebScrollIntoViewParams::GetScrollAlignmentX() const { return ToScrollAlignment(align_x);
diff --git a/third_party/WebKit/Source/platform/testing/RunAllTests.cpp b/third_party/WebKit/Source/platform/testing/RunAllTests.cpp index a327939..839d910 100644 --- a/third_party/WebKit/Source/platform/testing/RunAllTests.cpp +++ b/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
@@ -60,7 +60,7 @@ testIoThread.task_runner(), mojo::edk::ScopedIPCSupport::ShutdownPolicy::CLEAN); result = base::LaunchUnitTests( - argc, argv, base::Bind(runTestSuite, base::Unretained(&testSuite))); + argc, argv, base::BindOnce(runTestSuite, base::Unretained(&testSuite))); } return result; }
diff --git a/third_party/WebKit/Source/platform/wtf/HashTable.h b/third_party/WebKit/Source/platform/wtf/HashTable.h index dfd1595..107bb53 100644 --- a/third_party/WebKit/Source/platform/wtf/HashTable.h +++ b/third_party/WebKit/Source/platform/wtf/HashTable.h
@@ -2023,8 +2023,14 @@ // Used for purely weak and for weak-and-strong tables (ephemerons). static void Process(typename Allocator::Visitor* visitor, void* closure) { HashTableType* table = reinterpret_cast<HashTableType*>(closure); + // During incremental marking, the table may be freed after the callback has + // been registered. if (!table->table_) return; + + // Only trace the backing store. Its fields will be processed below. + Allocator::template TraceHashTableBackingOnly<ValueType, HashTableType>( + visitor, table->table_, &(table->table_)); // Now perform weak processing (this is a no-op if the backing was // accessible through an iterator and was already marked strongly). for (ValueType* element = table->table_ + table->table_size_ - 1; @@ -2091,18 +2097,15 @@ // Weak HashTable. The HashTable may be held alive strongly from somewhere // else, e.g., an iterator. - // Marking of the table is delayed because the backing store is potentially - // held alive strongly by other objects. Delayed marking happens after - // regular marking. + // Trace the table weakly. For marking this will result in delaying the + // processing until the end of the atomic pause. It is safe to trace + // weakly multiple times. Allocator::template TraceHashTableBackingWeakly<ValueType, HashTable>( - visitor, table_, &table_); - - // It is safe to register the table multiple times. - Allocator::RegisterWeakMembers( - visitor, this, + visitor, table_, &table_, WeakProcessingHashTableHelper<Traits::kWeakHandlingFlag, Key, Value, Extractor, HashFunctions, Traits, - KeyTraits, Allocator>::Process); + KeyTraits, Allocator>::Process, + this); if (IsTraceableInCollectionTrait<Traits>::value) { // Mix of strong and weak fields. We use an approach similar to ephemeron
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_multipart.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_multipart.py index 6b50247f..c546fd0c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_multipart.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_multipart.py
@@ -175,7 +175,7 @@ """Linux breakpad dump reader.""" def _binaries_to_symbolize(self): - return ['content_shell', 'libtest_netscape_plugin.so', 'libosmesa.so'] + return ['content_shell', 'libosmesa.so'] def _file_extension(self): return 'dmp'
diff --git a/third_party/WebKit/common/client_hints/client_hints.cc b/third_party/WebKit/common/client_hints/client_hints.cc index 32c3286e..98de374 100644 --- a/third_party/WebKit/common/client_hints/client_hints.cc +++ b/third_party/WebKit/common/client_hints/client_hints.cc
@@ -8,8 +8,9 @@ namespace blink { -const char* const kClientHintsHeaderMapping[] = {"device-memory", "dpr", - "width", "viewport-width"}; +const char* const kClientHintsHeaderMapping[] = { + "device-memory", "dpr", "width", "viewport-width", + "rtt", "downlink", "ect"}; const size_t kClientHintsHeaderMappingCount = arraysize(kClientHintsHeaderMapping);
diff --git a/third_party/WebKit/common/test/run_all_unittests.cc b/third_party/WebKit/common/test/run_all_unittests.cc index dd9a20e..305f0521 100644 --- a/third_party/WebKit/common/test/run_all_unittests.cc +++ b/third_party/WebKit/common/test/run_all_unittests.cc
@@ -15,5 +15,5 @@ return base::LaunchUnitTests( argc, argv, - base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); + base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/third_party/WebKit/public/platform/WebScrollIntoViewParams.h b/third_party/WebKit/public/platform/WebScrollIntoViewParams.h index 6ce0779a..289d1dca 100644 --- a/third_party/WebKit/public/platform/WebScrollIntoViewParams.h +++ b/third_party/WebKit/public/platform/WebScrollIntoViewParams.h
@@ -6,8 +6,10 @@ #define WebScrollIntoViewParams_h #include "public/platform/WebCommon.h" +#include "public/platform/WebFloatRect.h" #if INSIDE_BLINK +#include "platform/geometry/FloatRect.h" #include "platform/scroll/ScrollAlignment.h" #include "platform/scroll/ScrollTypes.h" #endif @@ -36,7 +38,7 @@ struct Alignment { Alignment() = default; #if INSIDE_BLINK - Alignment(const ScrollAlignment&); + BLINK_PLATFORM_EXPORT Alignment(const ScrollAlignment&); #endif AlignmentBehavior rect_visible = kNoScroll; AlignmentBehavior rect_hidden = kCenter; @@ -69,6 +71,17 @@ Behavior behavior = kAuto; bool is_for_scroll_sequence = false; + // If true, once the root frame scrolls into view it will zoom into the scroll + // rect. + bool zoom_into_rect = false; + + // The following bounds are normalized to the scrolling rect, i.e., to + // retrieve the approximate bounds in root layer's document, the relative + // bounds should be scaled by the width and height of the scrolling rect in x + // and y coordinates respectively (and then offset by the rect's location). + WebFloatRect relative_element_bounds = WebFloatRect(); + WebFloatRect relative_caret_bounds = WebFloatRect(); + WebScrollIntoViewParams() = default; #if INSIDE_BLINK BLINK_PLATFORM_EXPORT WebScrollIntoViewParams( @@ -77,7 +90,8 @@ ScrollType scroll_type = kProgrammaticScroll, bool make_visible_in_visual_viewport = true, ScrollBehavior scroll_behavior = kScrollBehaviorAuto, - bool is_for_scroll_sequence = false); + bool is_for_scroll_sequence = false, + bool zoom_into_rect = false); BLINK_PLATFORM_EXPORT ScrollAlignment GetScrollAlignmentX() const;
diff --git a/third_party/WebKit/public/platform/web_client_hints_types.mojom b/third_party/WebKit/public/platform/web_client_hints_types.mojom index 652b829..734aa14 100644 --- a/third_party/WebKit/public/platform/web_client_hints_types.mojom +++ b/third_party/WebKit/public/platform/web_client_hints_types.mojom
@@ -17,6 +17,9 @@ kDpr = 1, kResourceWidth = 2, kViewportWidth = 3, + kRtt = 4, + kDownlink = 5, + kEct = 6, // Warning: Before adding a new client hint, read the warning at the top. };
diff --git a/third_party/WebKit/public/platform/web_feature.mojom b/third_party/WebKit/public/platform/web_feature.mojom index 6532617..dc60c1e 100644 --- a/third_party/WebKit/public/platform/web_feature.mojom +++ b/third_party/WebKit/public/platform/web_feature.mojom
@@ -1893,6 +1893,9 @@ kTransformStreamConstructor = 2401, kNegativeBackgroundSize = 2402, kNegativeMaskSize = 2403, + kClientHintsRtt = 2404, + kClientHintsDownlink = 2405, + kClientHintsEct = 2406, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/public/web/WebFrameWidget.h b/third_party/WebKit/public/web/WebFrameWidget.h index d6762eba..15c13e4 100644 --- a/third_party/WebKit/public/web/WebFrameWidget.h +++ b/third_party/WebKit/public/web/WebFrameWidget.h
@@ -135,6 +135,11 @@ // WebFrameWidget. That is a WebLocalFrame which is focused and shares the // same LocalRoot() as this WebFrameWidget's LocalRoot(). virtual WebLocalFrame* FocusedWebLocalFrameInWidget() const = 0; + + // Scrolls the editable element which is currently focused in (a focused frame + // inside) this widget into view. The scrolling might end with a final zooming + // into the editable region which is performed in the main frame process. + virtual bool ScrollFocusedEditableElementIntoView() = 0; }; } // namespace blink
diff --git a/third_party/WebKit/public/web/WebLeakDetector.h b/third_party/WebKit/public/web/WebLeakDetector.h index bde4b9a..e3eafe9 100644 --- a/third_party/WebKit/public/web/WebLeakDetector.h +++ b/third_party/WebKit/public/web/WebLeakDetector.h
@@ -35,8 +35,6 @@ namespace blink { -class WebFrame; - class WebLeakDetectorClient { public: struct Result { @@ -83,7 +81,7 @@ // Perform initial stage of preparing for leak detection, // releasing references to resources held globally. - virtual void PrepareForLeakDetection(WebFrame*) = 0; + virtual void PrepareForLeakDetection() = 0; // Garbage collect Blink's heaps and report leak counts. // |WebLeakDetectorClient::onLeakDetectionComplete()| is called
diff --git a/third_party/WebKit/public/web/WebView.h b/third_party/WebKit/public/web/WebView.h index 4f26b87..f5d561b00 100644 --- a/third_party/WebKit/public/web/WebView.h +++ b/third_party/WebKit/public/web/WebView.h
@@ -175,10 +175,6 @@ // send it. virtual void ClearFocusedElement() = 0; - // If it is editable, scrolls the element currently in focus into view. - // Returns false if there is currently no currently focused element. - virtual bool ScrollFocusedEditableElementIntoView() { return false; } - // Smooth scroll the root layer to |targetX|, |targetY| in |durationMs|. virtual void SmoothScroll(int target_x, int target_y, long duration_ms) {}
diff --git a/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/invalidation-client-impl_test.cc b/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/invalidation-client-impl_test.cc index ab72ef2b..2020a35 100644 --- a/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/invalidation-client-impl_test.cc +++ b/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/invalidation-client-impl_test.cc
@@ -64,7 +64,7 @@ SaveArgToVector, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(vec)) { - vec->push_back(std::tr1::get<k>(args)); + vec->push_back(std::get<k>(args)); } // Given the ReadCallback of Storage::ReadKey as argument 1, invokes it with a
diff --git a/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc index 0e2e2d9..a06b36c2 100644 --- a/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc +++ b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc
@@ -19,6 +19,7 @@ #include <stdint.h> #include <set> +#include <tuple> #include "google/cacheinvalidation/impl/proto-converter.h" #include "google/cacheinvalidation/test/test-utils.h" @@ -37,7 +38,7 @@ InvokeNetworkStatusCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - std::tr1::get<k>(args)->Run(true); + std::get<k>(args)->Run(true); } const char* UnitTestBase::kClientToken = "Dummy";
diff --git a/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h index 5b62975..0371877 100644 --- a/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h +++ b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h
@@ -21,6 +21,8 @@ #include <stddef.h> +#include <tuple> + #include "google/cacheinvalidation/client_protocol.pb.h" #include "google/cacheinvalidation/include/invalidation-listener.h" #include "google/cacheinvalidation/include/types.h" @@ -313,8 +315,8 @@ InvokeAndDeleteClosure, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - std::tr1::get<k>(args)->Run(); - delete std::tr1::get<k>(args); + std::get<k>(args)->Run(); + delete std::get<k>(args); } } // namespace invalidation
diff --git a/third_party/libwebp/BUILD.gn b/third_party/libwebp/BUILD.gn index 7939ac8c..5c4fc53 100644 --- a/third_party/libwebp/BUILD.gn +++ b/third_party/libwebp/BUILD.gn
@@ -23,7 +23,8 @@ } set_opt_level = - !is_debug && is_posix && (current_cpu == "arm" || current_cpu == "arm64") + !is_debug && (is_posix || is_fuchsia) && + (current_cpu == "arm" || current_cpu == "arm64") # webp's dsp code can be built for all configurations. Skipping it when both # arm_use_neon and arm_optionally_use_neon are false will result in link errors
diff --git a/tools/checkperms/checkperms.py b/tools/checkperms/checkperms.py index f1b44b71..7388a7ef 100755 --- a/tools/checkperms/checkperms.py +++ b/tools/checkperms/checkperms.py
@@ -56,10 +56,6 @@ EXECUTABLE_PATHS = ( 'chrome/test/data/app_shim/app_shim_32_bit.app/contents/' 'macos/app_mode_loader', - 'chrome/test/data/extensions/uitest/plugins/plugin.plugin/contents/' - 'macos/testnetscapeplugin', - 'chrome/test/data/extensions/uitest/plugins_private/plugin.plugin/contents/' - 'macos/testnetscapeplugin', ) # These files must not have the executable bit set. This is mainly a performance
diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp index a9ec67a6..10575353 100644 --- a/tools/clang/plugins/ChromeClassTester.cpp +++ b/tools/clang/plugins/ChromeClassTester.cpp
@@ -88,42 +88,12 @@ if (filename == "<scratch space>") return LocationType::kThirdParty; -#if defined(LLVM_ON_UNIX) - // Resolve the symlinktastic relative path and make it absolute. - char resolvedPath[MAXPATHLEN]; - if (options_.no_realpath) { - // Same reason as windows below. - filename.insert(filename.begin(), '/'); - } else if (realpath(filename.c_str(), resolvedPath)) { - filename = resolvedPath; + // Ensure that we can search for patterns of the form "/foo/" even + // if we have a relative path like "foo/bar.cc". We don't expect + // this transformed path to exist necessarily. + if (filename.front() != '/') { + filename.insert(0, 1, '/'); } -#endif - -#if defined(LLVM_ON_WIN32) - // Make path absolute. - if (options_.no_realpath) { - // This turns e.g. "gen/dir/file.cc" to "/gen/dir/file.cc" which lets the - // "/gen/" banned_dir work. - filename.insert(filename.begin(), '/'); - } else { - // The Windows dance: Convert to UTF-16, call GetFullPathNameW, convert back - DWORD size_needed = - MultiByteToWideChar(CP_UTF8, 0, filename.data(), -1, nullptr, 0); - std::wstring utf16(size_needed, L'\0'); - MultiByteToWideChar(CP_UTF8, 0, filename.data(), -1, - &utf16[0], size_needed); - - size_needed = GetFullPathNameW(utf16.data(), 0, nullptr, nullptr); - std::wstring full_utf16(size_needed, L'\0'); - GetFullPathNameW(utf16.data(), full_utf16.size(), &full_utf16[0], nullptr); - - size_needed = WideCharToMultiByte(CP_UTF8, 0, full_utf16.data(), -1, - nullptr, 0, nullptr, nullptr); - filename.resize(size_needed); - WideCharToMultiByte(CP_UTF8, 0, full_utf16.data(), -1, &filename[0], - size_needed, nullptr, nullptr); - } -#endif // When using distributed cross compilation build tools, file paths can have // separators which differ from ones at this platform. Make them consistent.
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp index 711d6e9..23066a0b 100644 --- a/tools/clang/plugins/FindBadConstructsAction.cpp +++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -54,7 +54,8 @@ // and http://crbug.com/356816 are fixed. options_.check_enum_max_value = true; } else if (args[i] == "no-realpath") { - options_.no_realpath = true; + // Ignored. + // TODO(mostynb@vewd.com): remove this completely. } else if (args[i] == "check-ipc") { options_.check_ipc = true; } else {
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h index 64156d48..44ae6ad 100644 --- a/tools/clang/plugins/Options.h +++ b/tools/clang/plugins/Options.h
@@ -11,9 +11,6 @@ bool check_base_classes = false; bool enforce_in_thirdparty_webkit = false; // Use in Blink code itself bool check_enum_max_value = false; - // This is needed for some distributed build-sytems to respect banned - // paths. See https://crbug.com/583454 for details. - bool no_realpath = false; bool check_ipc = false; };
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc index 237aa0d..9fbf67b 100644 --- a/tools/gn/command_args.cc +++ b/tools/gn/command_args.cc
@@ -67,19 +67,22 @@ // Assumes DoesLineBeginWithComment(), this strips the # character from the // beginning and normalizes preceding whitespace. -std::string StripHashFromLine(const base::StringPiece& line) { +std::string StripHashFromLine(const base::StringPiece& line, bool pad) { // Replace the # sign and everything before it with 3 spaces, so that a // normal comment that has a space after the # will be indented 4 spaces // (which makes our formatting come out nicely). If the comment is indented // from there, we want to preserve that indenting. - return " " + line.substr(line.find('#') + 1).as_string(); + if (pad) + return " " + line.substr(line.find('#') + 1).as_string(); + return line.substr(line.find('#') + 1).as_string(); } // Tries to find the comment before the setting of the given value. void GetContextForValue(const Value& value, std::string* location_str, int* line_no, - std::string* comment) { + std::string* comment, + bool pad_comment=true) { Location location = value.origin()->GetRange().begin(); const InputFile* file = location.file(); if (!file) @@ -101,7 +104,7 @@ if (!DoesLineBeginWithComment(line)) break; - comment->insert(0, StripHashFromLine(line) + "\n"); + comment->insert(0, StripHashFromLine(line, pad_comment) + "\n"); line_off = previous_line_offset; } } @@ -171,7 +174,8 @@ if (arg.override_value.origin() && !short_only) { int line_no; std::string location, comment; - GetContextForValue(arg.override_value, &location, &line_no, &comment); + GetContextForValue(arg.override_value, &location, &line_no, &comment, + /*pad_comment=*/false); // Omit file and line if set with --args (i.e. no file) if (!location.empty()) { override_dict.SetKey("file", base::Value(location)); @@ -188,7 +192,8 @@ if (arg.default_value.origin() && !short_only) { int line_no; std::string location; - GetContextForValue(arg.default_value, &location, &line_no, &comment); + GetContextForValue(arg.default_value, &location, &line_no, &comment, + /*pad_comment=*/false); // Only emit file and line if the value is overridden. if (arg.has_override) { default_dict.SetKey("file", base::Value(location)); @@ -198,11 +203,6 @@ dict.SetKey("default", std::move(default_dict)); if (!comment.empty() && !short_only) dict.SetKey("comment", base::Value(comment)); - - std::string s; - base::JSONWriter::WriteWithOptions( - dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &s); - OutputString(s); } int ListArgs(const std::string& build_dir) {
diff --git a/tools/gn/runtime_deps.cc b/tools/gn/runtime_deps.cc index 05456178..f0a242db 100644 --- a/tools/gn/runtime_deps.cc +++ b/tools/gn/runtime_deps.cc
@@ -253,7 +253,7 @@ many actions into one logic unit, and the "data"-ness of A's dependency is lost. Solutions: - - List the outputs of the action in it's data section (if the results of + - List the outputs of the action in its data section (if the results of that action are always runtime files). - Have B list the action in data_deps (if the outputs of the actions are always runtime files).
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index f7df09e..96036a6 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -455,7 +455,7 @@ 'V8 Linux GN': 'release_bot', 'V8-Blink Linux 64': 'release_bot', 'V8-Blink Linux 64 - future': 'release_bot', - 'V8-Blink Linux 64 (dbg)': 'debug_bot', + 'V8-Blink Linux 64 (dbg)': 'release_bot_v8_debug', 'V8-Blink Mac': 'release_bot', 'V8-Blink Win': 'release_bot_x86_minimal_symbols', 'Win V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_x86_minimal_symbols', @@ -1516,6 +1516,10 @@ 'release_bot', 'mac_strip', ], + 'release_bot_v8_debug': [ + 'release_bot', 'v8_enable_debugging_features', + ], + 'release_bot_x86': [ 'release_bot', 'x86', ], @@ -2143,6 +2147,10 @@ 'gn_args': 'v8_enable_concurrent_marking=true', }, + 'v8_enable_debugging_features': { + 'gn_args': 'v8_enable_debugging_features=true', + }, + 'v8_future': { 'gn_args': 'v8_enable_future=true', },
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 0ec1a1c..9c86513c 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -5792,6 +5792,15 @@ </description> </action> +<action name="InProductHelp.NotifyEvent.IPH_ContextualSuggestions"> + <owner>twellington@chromium.org</owner> + <description> + The user triggered an event related to the contextual suggestions in-product + help. See //components/feature_engagement/README.md#Configuring-UMA for + details. + </description> +</action> + <action name="InProductHelp.NotifyEvent.IPH_DataSaverDetail"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -5989,6 +5998,15 @@ </description> </action> +<action name="InProductHelp.NotifyUsedEvent.IPH_ContextualSuggestions"> + <owner>twellington@chromium.org</owner> + <description> + The user triggered a used event related to the contextual suggestions + in-product help. See + //components/feature_engagement/README.md#Configuring-UMA for details. + </description> +</action> + <action name="InProductHelp.NotifyUsedEvent.IPH_DataSaverDetail"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -6193,6 +6211,15 @@ </description> </action> +<action name="InProductHelp.ShouldTriggerHelpUI.IPH_ContextualSuggestions"> + <owner>twellington@chromium.org</owner> + <description> + The feature engagement tracker tried to determine whether the contextual + suggestions in-product help should be shown to the user. See + //components/feature_engagement/README.md#Configuring-UMA for details. + </description> +</action> + <action name="InProductHelp.ShouldTriggerHelpUI.IPH_DataSaverDetail"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -6432,6 +6459,16 @@ </action> <action + name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_ContextualSuggestions"> + <owner>twellington@chromium.org</owner> + <description> + A user action that could have triggered the contextual suggestions + in-product help did not. See + //components/feature_engagement/README.md#Configuring-UMA for details. + </description> +</action> + +<action name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_DataSaverDetail"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -6657,6 +6694,17 @@ </action> <action + name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_ContextualSuggestions"> + <owner>donnd@chromium.org</owner> + <owner>mahmoudi@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <description> + A user action triggered the contextual suggestions in-product help. See + //components/feature_engagement/README.md#Configuring-UMA for details. + </description> +</action> + +<action name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_DataSaverDetail"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -6779,6 +6827,17 @@ </action> <action + name="InProductHelp.ShouldTriggerHelpUIResult.WouldHaveTriggered.IPH_ContextualSuggestions"> + <owner>twellington@chromium.org</owner> + <owner>mdjones@chromium.org</owner> + <description> + A user action would have triggered the contextual suggestions in-product + help, but the feature was configured for tracking only. See + //components/feature_engagement/README.md#Configuring-UMA for details. + </description> +</action> + +<action name="InProductHelp.ShouldTriggerHelpUIResult.WouldHaveTriggered.IPH_DataSaverDetail"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d7c1e28b3..970f867 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -12826,6 +12826,10 @@ <int value="432" label="TabUnderProtectionEnabled"/> <int value="433" label="UserNativePrintersAllowed"/> <int value="434" label="DefaultWebUsbGuardSetting"/> + <int value="435" label="CertificateTransparencyEnforcementDisabledForCas"/> + <int value="436" + label="CertificateTransparencyEnforcementDisabledForLegacyCas"/> + <int value="437" label="MediaRouterCastAllowAllIPs"/> </enum> <enum name="EnterprisePolicyInvalidations"> @@ -18153,6 +18157,9 @@ <int value="2401" label="TransformStreamConstructor"/> <int value="2402" label="NegativeBackgroundSize"/> <int value="2403" label="NegativeMaskSize"/> + <int value="2404" label="ClientHintsRtt"/> + <int value="2405" label="ClientHintsDownlink"/> + <int value="2406" label="ClientHintsEct"/> </enum> <enum name="FeedbackSource">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ec65cce..b270545 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -7006,6 +7006,9 @@ <summary> Time spent to create a v8::Context instance during a page loading in the main-frame window. + + Note: this histogram is emitted for all clients, both ones which have + high-resolution timer available and those which don't. </summary> </histogram> @@ -7015,6 +7018,9 @@ <summary> Time spent to create a v8::Context instance during a page loading in a non-main-frame window, e.g. iframe. + + Note: this histogram is emitted for all clients, both ones which have + high-resolution timer available and those which don't. </summary> </histogram> @@ -7024,6 +7030,9 @@ <summary> Time spent initializing LocalWindowProxy during a page loading in main windows. + + Note: this histogram is emitted for all clients, both ones which have + high-resolution timer available and those which don't. </summary> </histogram> @@ -7033,6 +7042,9 @@ <summary> Time spent initializing RemoteWindowProxy during a page loading in main frame of OOPIF. + + Note: this histogram is emitted for all clients, both ones which have + high-resolution timer available and those which don't. </summary> </histogram> @@ -7053,6 +7065,9 @@ <summary> Time spent initializing LocalWindowProxy during a page loading in non-main windows, e.g. iframe. + + Note: this histogram is emitted for all clients, both ones which have + high-resolution timer available and those which don't. </summary> </histogram> @@ -7061,6 +7076,9 @@ <owner>peria@chromium.org</owner> <summary> Time spent initializing RemoteWindowProxy during a page loading in OOPIF. + + Note: this histogram is emitted for all clients, both ones which have + high-resolution timer available and those which don't. </summary> </histogram> @@ -19671,6 +19689,9 @@ </histogram> <histogram name="EasyUnlock.AuthenticationSuccess" enum="BooleanSuccess"> + <obsolete> + Deprecated as of 03/2018. + </obsolete> <owner>joshwoodward@google.com</owner> <owner>isherman@chromium.org</owner> <summary> @@ -19976,6 +19997,9 @@ </histogram> <histogram name="EasyUnlock.SetupStateOnClose" enum="EasyUnlockSetupState"> + <obsolete> + Deprecated as of 03/2018. + </obsolete> <owner>joshwoodward@google.com</owner> <owner>tbarzic@chromium.org</owner> <summary> @@ -104679,6 +104703,15 @@ </summary> </histogram> +<histogram name="WebsiteSettings.Menu.PermissionChanged.Ask" enum="ContentType"> + <owner>miguelg@chromium.org</owner> + <owner>finnur@chromium.org</owner> + <summary> + Count of how often a specific content type (permission) is set to 'Ask' + using the content settings menu. + </summary> +</histogram> + <histogram name="WebsiteSettings.Menu.PermissionChanged.Blocked" enum="ContentType"> <owner>miguelg@chromium.org</owner> @@ -109152,6 +109185,8 @@ label="In product help for opening the contextual search panel."/> <suffix name="IPH_ContextualSearchOptIn" label="In product help for opting-in for contextual search."/> + <suffix name="IPH_ContextualSuggestions" + label="In product help for contextual suggestions."/> <suffix name="IPH_DataSaverDetail" label="In product help data saver detail."/> <suffix name="IPH_DownloadPage" label="In product help download page."/>
diff --git a/tools/perf/contrib/network_service/OWNERS b/tools/perf/contrib/network_service/OWNERS index 28361a0..7ede1223 100644 --- a/tools/perf/contrib/network_service/OWNERS +++ b/tools/perf/contrib/network_service/OWNERS
@@ -1 +1,3 @@ +chongz@chromium.org + file://services/network/OWNERS
diff --git a/tools/perf/contrib/network_service/loading.py b/tools/perf/contrib/network_service/loading.py index c2d29917..bb84100 100644 --- a/tools/perf/contrib/network_service/loading.py +++ b/tools/perf/contrib/network_service/loading.py
@@ -2,21 +2,190 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import copy +import json +import logging +import os + from benchmarks import loading from telemetry import benchmark +from telemetry.internal import story_runner +from telemetry.value.list_of_scalar_values import StandardDeviation +def _ListSubtraction(diff_list, control_list): + """Subtract |control_list|'s elements from the corresponding elements in + |diff_list|, and store the results in |diff_list|. -@benchmark.Owner(emails=['yzshen@chromium.org']) + Lists may have different length and we will align with the shorter one. + e.g. 'timeToInteractive' may be missing for some runs. + """ + + min_len = min(len(diff_list), len(control_list)) + for i in xrange(min_len): + diff_list[i] = diff_list[i] - control_list[i] + while len(diff_list) > min_len: + diff_list.pop() + +def _PointSubtraction(diff_point, control_point): + """Subtract |control_point| from |diff_point| and store the result in + |diff_point|. + + Args: + diff_point: A chart point (could either be a story point (e.g. 'FIFA') or a + 'summary' point), will hold the result. + control_point: A chart point. + """ + + if diff_point['type'] == 'scalar': + diff_point['value'] = diff_point['value'] - control_point['value'] + elif diff_point['type'] == 'list_of_scalar_values': + # Points may have None 'values' regardless their types. + if not diff_point['values'] or not control_point['values']: + diff_point['values'] = None + diff_point['std'] = None + return + _ListSubtraction(diff_point['values'], control_point['values']) + diff_point['std'] = StandardDeviation(diff_point['values']) + else: + raise NotImplementedError('invalid point type: %s' % diff_point['type']) + +def _RenameChartsAndPointsWithSuffix(charts, suffix): + """Append |suffix| to all chart names (except 'trace') and point names + (except 'summary'). + + Args: + charts: A dictionary of charts. + suffix: A string suffix, e.g. '_control'. + """ + + # First rename all points except 'summary. + for chart_name in charts: + chart = charts[chart_name] + old_point_names = chart.keys() + for point_name in old_point_names: + if point_name == 'summary': + continue + chart[point_name + suffix] = chart[point_name] + chart.pop(point_name, None) + + # Then rename all charts except 'trace'. + old_chart_names = charts.keys() + for chart_name in old_chart_names: + if chart_name == 'trace': + continue + chart = charts[chart_name] + new_chart_name = chart_name + suffix + for point_name in chart: + chart[point_name]['name'] = new_chart_name + charts[new_chart_name] = chart + charts.pop(chart_name, None) + +def _MergeCharts(dest_charts, source_charts): + """Update |dest_charts| with |source_charts| and merge 'trace'. + + Args: + dest_charts: A dictionary of charts, will hold the result. + source_charts: A dictionary of charts. + """ + + for chart_name in source_charts: + if chart_name == 'trace': + if chart_name not in dest_charts: + dest_charts[chart_name] = {} + dest_charts[chart_name].update(source_charts[chart_name]) + else: + dest_charts[chart_name] = source_charts[chart_name] + +def _MergeControlChartJsonIntoEnabled(enabled_chart_json, control_chart_json): + """Creates a diff chart_json from |enabled_chart_json| and + |control_chart_json|, then append appropriated suffix to all three chart_json + and merge them into |enabled_chart_json|. + + Args: + enabled_chart_json: A dictionary of charts, will hold the result.. + control_chart_json: A dictionary of charts. + """ + + # Leaving fields as-is other than 'charts' + enabled_charts = enabled_chart_json['charts'] + control_charts = control_chart_json['charts'] + diff_charts = copy.deepcopy(enabled_charts) + diff_charts['trace'] = {} + for chart_name in diff_charts: + for point_name in diff_charts[chart_name]: + _PointSubtraction(diff_charts[chart_name][point_name], + control_charts[chart_name][point_name]) + + _RenameChartsAndPointsWithSuffix(enabled_charts, '_enabled') + _RenameChartsAndPointsWithSuffix(control_charts, '_control') + _RenameChartsAndPointsWithSuffix(diff_charts, '_diff') + _MergeCharts(enabled_charts, control_charts) + _MergeCharts(enabled_charts, diff_charts) + +@benchmark.Owner(emails=['chongz@chromium.org']) class LoadingDesktopNetworkService(loading.LoadingDesktop): """Measures loading performance of desktop sites, with the network service enabled. + + Will run the test twice with feature on/off, and return the + difference as well as the original results. """ + + def __init__(self, max_failures=None): + super(LoadingDesktopNetworkService, self).__init__(max_failures) + self.enable_feature = False + @classmethod def Name(cls): return 'loading.desktop.network_service' + def Run(self, finder_options): + """We shouldn't be overriding this according to + telemetry.benchmark.Benchmark""" + assert 'chartjson' in finder_options.output_formats, ( + 'loading.desktop.network_service requires --output-format=chartjson. ' + 'Please contact owner to rewrite the benchmark if chartjson is going ' + 'away.') + assert finder_options.output_dir + output_dir = finder_options.output_dir + temp_file_path = os.path.join(output_dir, 'results-chart.json') + + # Run test with feature disabled. + self.enable_feature = False + control_return_code = story_runner.RunBenchmark(self, finder_options) + if control_return_code != 0: + return control_return_code + control_chart_json = json.load(open(temp_file_path)) + + # Run test again with feature enabled. + self.enable_feature = True + enabled_return_code = story_runner.RunBenchmark(self, finder_options) + if enabled_return_code != 0: + return enabled_return_code + enabled_chart_json = json.load(open(temp_file_path)) + + try: + # Merge the result and compute the difference. + _MergeControlChartJsonIntoEnabled(enabled_chart_json, control_chart_json) + except Exception as e: + logging.error('exception merging two chart json: %s', e) + with open(temp_file_path, 'w') as f: + json.dump({ + 'control_chart_json': control_chart_json, + 'enabled_chart_json': enabled_chart_json}, + f, indent=2, separators=(',', ': ')) + f.write('\n') + else: + with open(temp_file_path, 'w') as f: + json.dump(enabled_chart_json, f, indent=2, separators=(',', ': ')) + f.write('\n') + return 0 + def SetExtraBrowserOptions(self, options): + if not self.enable_feature: + return + enable_features_arg = '--enable-features=NetworkService' # If an "--enable-features" argument has been specified, append to the value @@ -27,4 +196,4 @@ enable_features_arg = arg + ',NetworkService' break - options.AppendExtraBrowserArgs([ enable_features_arg, '--incognito' ]) + options.AppendExtraBrowserArgs([enable_features_arg])
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn index 2766ffd..f4325006 100644 --- a/ui/app_list/BUILD.gn +++ b/ui/app_list/BUILD.gn
@@ -125,6 +125,7 @@ "//ui/resources", "//ui/strings", "//ui/views", + "//ui/views/mus/remote_view:remote_view_host", "//ui/wm", ]
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc index 6733e80..7ea6fd25 100644 --- a/ui/app_list/views/app_list_view_unittest.cc +++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -21,6 +21,7 @@ #include "base/test/icu_test_util.h" #include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/app_list/answer_card_contents_registry.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/pagination_model.h" #include "ui/app_list/test/app_list_test_model.h" @@ -43,6 +44,7 @@ #include "ui/app_list/views/search_result_view.h" #include "ui/app_list/views/suggestions_container_view.h" #include "ui/app_list/views/test/apps_grid_view_test_api.h" +#include "ui/aura/env.h" #include "ui/base/models/simple_menu_model.h" #include "ui/chromeos/search_box/search_box_constants.h" #include "ui/compositor/layer_animator.h" @@ -194,6 +196,19 @@ base::i18n::SetICUDefaultLocale("he"); } + // Creates AnswerCardContentsRegistry and registers a fake answer card + // view for classic ash. Otherwise, the answer card view will not be + // created. Revisit this when the test runs in mash. + if (aura::Env::GetInstanceDontCreate() && + aura::Env::GetInstanceDontCreate()->mode() == aura::Env::Mode::LOCAL) { + answer_card_contents_registry_ = + std::make_unique<AnswerCardContentsRegistry>(); + fake_answer_card_view_ = std::make_unique<views::View>(); + fake_answer_card_view_->set_owned_by_client(); + fake_answer_card_token_ = answer_card_contents_registry_->Register( + fake_answer_card_view_.get()); + } + // Initialize app list view. delegate_.reset(new AppListTestViewDelegate); view_ = new AppListView(delegate_.get()); @@ -277,6 +292,8 @@ std::make_unique<TestSearchResult>(); result->set_display_type(data.first); result->set_relevance(relevance); + if (data.first == ash::SearchResultDisplayType::kCard) + result->set_answer_card_contents_token(fake_answer_card_token_); results->Add(std::move(result)); } } @@ -461,6 +478,11 @@ std::unique_ptr<AppsGridViewTestApi> test_api_; // Restores the locale to default when destructor is called. base::test::ScopedRestoreICUDefaultLocale restore_locale_; + + std::unique_ptr<AnswerCardContentsRegistry> answer_card_contents_registry_; + std::unique_ptr<views::View> fake_answer_card_view_; + base::UnguessableToken fake_answer_card_token_; + DISALLOW_COPY_AND_ASSIGN(AppListViewFocusTest); };
diff --git a/ui/app_list/views/search_result_answer_card_view.cc b/ui/app_list/views/search_result_answer_card_view.cc index 44b4dc7..4293fa87 100644 --- a/ui/app_list/views/search_result_answer_card_view.cc +++ b/ui/app_list/views/search_result_answer_card_view.cc
@@ -8,6 +8,9 @@ #include <utility> #include <vector> +#include "base/bind.h" +#include "base/feature_list.h" +#include "services/ui/public/interfaces/window_tree.mojom.h" #include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_node_data.h" #include "ui/app_list/answer_card_contents_registry.h" @@ -15,13 +18,45 @@ #include "ui/app_list/app_list_metrics.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/views/search_result_base_view.h" +#include "ui/base/ui_base_features.h" #include "ui/gfx/canvas.h" #include "ui/views/background.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/mus/remote_view/remote_view_host.h" namespace app_list { +namespace { + +// Helper to get/create answer card view by token. +views::View* GetViewByToken(const base::UnguessableToken& token) { + // Bail for invalid token. + if (token.is_empty()) + return nullptr; + + // Use AnswerCardContentsRegistry for an in-process token-to-view map. See + // answer_card_contents_registry.h. Null check because it could be missing in + // Mash and for tests. + if (AnswerCardContentsRegistry::Get()) + return AnswerCardContentsRegistry::Get()->GetView(token); + + // Use RemoteViewHost to embed the answer card contents provided in the + // browser process in Mash. + if (base::FeatureList::IsEnabled(features::kMash)) { + views::RemoteViewHost* view = new views::RemoteViewHost(); + view->EmbedUsingToken(token, + ui::mojom::kEmbedFlagEmbedderInterceptsEvents | + ui::mojom::kEmbedFlagEmbedderControlsVisibility, + base::DoNothing()); + return view; + } + + return nullptr; +} + +} // namespace + // Container of the search answer view. class SearchResultAnswerCardView::SearchAnswerContainerView : public SearchResultBaseView { @@ -46,9 +81,8 @@ bool SetSearchResult(SearchResult* search_result) { views::View* const old_result_view = child_count() ? child_at(0) : nullptr; views::View* const new_result_view = - search_result && AnswerCardContentsRegistry::Get() - ? AnswerCardContentsRegistry::Get()->GetView( - search_result->answer_card_contents_token()) + search_result + ? GetViewByToken(search_result->answer_card_contents_token()) : nullptr; if (old_result_view != new_result_view) {
diff --git a/ui/base/material_design/material_design_controller.cc b/ui/base/material_design/material_design_controller.cc index d4dd4b1..5abb641 100644 --- a/ui/base/material_design/material_design_controller.cc +++ b/ui/base/material_design/material_design_controller.cc
@@ -120,7 +120,8 @@ // static bool MaterialDesignController::IsSecondaryUiMaterial() { - return base::FeatureList::IsEnabled(features::kSecondaryUiMd); + return base::FeatureList::IsEnabled(features::kSecondaryUiMd) || + GetMode() == MATERIAL_REFRESH; } // static
diff --git a/ui/base/win/shell.cc b/ui/base/win/shell.cc index b5afdead..e25487e 100644 --- a/ui/base/win/shell.cc +++ b/ui/base/win/shell.cc
@@ -56,13 +56,6 @@ } // namespace -bool OpenAnyViaShell(const base::string16& full_path, - const base::string16& directory, - const base::string16& args, - DWORD mask) { - return InvokeShellExecute(full_path, directory, args, base::string16(), mask); -} - bool OpenFileViaShell(const base::FilePath& full_path) { // Invoke the default verb on the file with no arguments. return InvokeShellExecute(full_path.value(), full_path.DirName().value(),
diff --git a/ui/base/win/shell.h b/ui/base/win/shell.h index c47e5ce..46b625c 100644 --- a/ui/base/win/shell.h +++ b/ui/base/win/shell.h
@@ -34,17 +34,6 @@ // Note: Must be called on a thread that allows blocking. UI_BASE_EXPORT bool OpenFileViaShell(const base::FilePath& full_path); -// Lower level function that allows opening of non-files like urls or GUIDs -// don't use it if one of the above will do. |mask| is a valid combination -// of SEE_MASK_XXX as stated in MSDN. If there is no default application -// registered for the item, it behaves the same as OpenFileViaShell. -// -// Note: Must be called on a thread that allows blocking. -UI_BASE_EXPORT bool OpenAnyViaShell(const base::string16& full_path, - const base::string16& directory, - const base::string16& args, - DWORD mask); - // Disables the ability of the specified window to be pinned to the taskbar or // the Start menu. This will remove "Pin this program to taskbar" from the // taskbar menu of the specified window.
diff --git a/ui/display/manager/BUILD.gn b/ui/display/manager/BUILD.gn index a001d48..0b7946e9 100644 --- a/ui/display/manager/BUILD.gn +++ b/ui/display/manager/BUILD.gn
@@ -36,7 +36,6 @@ "display_manager_export.h", "display_manager_utilities.cc", "display_manager_utilities.h", - "display_pref_util.h", "fake_display_delegate.cc", "fake_display_delegate.h", "fake_display_snapshot.cc",
diff --git a/ui/display/manager/chromeos/display_change_observer.cc b/ui/display/manager/chromeos/display_change_observer.cc index 68ef0da..ccfb25c 100644 --- a/ui/display/manager/chromeos/display_change_observer.cc +++ b/ui/display/manager/chromeos/display_change_observer.cc
@@ -317,10 +317,11 @@ if (snapshot->product_code() != DisplaySnapshot::kInvalidProductCode) { uint16_t manufacturer_id = 0; uint16_t product_id = 0; - SplitProductCodeInManufacturerIdAndProductId(snapshot->product_code(), - &manufacturer_id, &product_id); - new_info.set_manufacturer_id(ManufacturerIdToString(manufacturer_id)); - new_info.set_product_id(ProductIdToString(product_id)); + EdidParser::SplitProductCodeInManufacturerIdAndProductId( + snapshot->product_code(), &manufacturer_id, &product_id); + new_info.set_manufacturer_id( + EdidParser::ManufacturerIdToString(manufacturer_id)); + new_info.set_product_id(EdidParser::ProductIdToString(product_id)); } new_info.set_year_of_manufacture(snapshot->year_of_manufacture());
diff --git a/ui/display/manager/display_pref_util.h b/ui/display/manager/display_pref_util.h deleted file mode 100644 index dea15cfa..0000000 --- a/ui/display/manager/display_pref_util.h +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright (c) 2013 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_DISPLAY_MANAGER_DISPLAY_PREF_UTIL_H -#define UI_DISPLAY_MANAGER_DISPLAY_PREF_UTIL_H - -#include <map> -#include <string> - -#include "base/strings/string_piece.h" - -namespace display { - -// Utility templates to create enum to string map and -// a function to find an enum value from a string. -template <typename T> -std::map<T, std::string>* CreateToStringMap(T k1, - const std::string& v1, - T k2, - const std::string& v2, - T k3, - const std::string& v3, - T k4, - const std::string& v4) { - std::map<T, std::string>* map = new std::map<T, std::string>(); - (*map)[k1] = v1; - (*map)[k2] = v2; - (*map)[k3] = v3; - (*map)[k4] = v4; - return map; -} - -template <typename T> -std::map<T, std::string>* CreateToStringMap(T k1, - const std::string& v1, - T k2, - const std::string& v2, - T k3, - const std::string& v3) { - std::map<T, std::string>* map = new std::map<T, std::string>(); - (*map)[k1] = v1; - (*map)[k2] = v2; - (*map)[k3] = v3; - return map; -} - -template <typename T> -bool ReverseFind(const std::map<T, std::string>* map, - const base::StringPiece& value, - T* key) { - typename std::map<T, std::string>::const_iterator iter = map->begin(); - for (; iter != map->end(); ++iter) { - if (iter->second == value) { - *key = iter->first; - return true; - } - } - return false; -} - -} // namespace display - -#endif // UI_DISPLAY_MANAGER_DISPLAY_PREF_UTIL_H
diff --git a/ui/display/manager/json_converter.cc b/ui/display/manager/json_converter.cc index 1d4c0a4..363c2da 100644 --- a/ui/display/manager/json_converter.cc +++ b/ui/display/manager/json_converter.cc
@@ -11,7 +11,6 @@ #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "ui/display/display_layout.h" -#include "ui/display/manager/display_pref_util.h" namespace display {
diff --git a/ui/display/util/edid_parser.cc b/ui/display/util/edid_parser.cc index 1bb9fca1..943dd28 100644 --- a/ui/display/util/edid_parser.cc +++ b/ui/display/util/edid_parser.cc
@@ -13,182 +13,43 @@ #include "base/strings/stringprintf.h" #include "base/sys_byteorder.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "ui/display/types/display_constants.h" #include "ui/display/util/display_util.h" #include "ui/gfx/geometry/size.h" namespace display { -namespace { - -// Returns a 32-bit identifier for this model of display, using -// |manufacturer_id| and |product_id|. -uint32_t GetProductCode(uint16_t manufacturer_id, uint16_t product_id) { - return ((static_cast<uint32_t>(manufacturer_id) << 16) | - (static_cast<uint32_t>(product_id))); +EdidParser::EdidParser(const std::vector<uint8_t>& edid_blob) + : manufacturer_id_(0), + product_id_(0), + year_of_manufacture_(display::kInvalidYearOfManufacture), + gamma_(0.0), + bits_per_channel_(-1), + primaries_({0}) { + ParseEdid(edid_blob); } -} // namespace +EdidParser::~EdidParser() = default; -bool GetDisplayIdFromEDID(const std::vector<uint8_t>& edid, - uint8_t output_index, - int64_t* display_id_out, - int64_t* product_code_out) { - uint16_t manufacturer_id = 0; - uint16_t product_id = 0; - std::string product_name; +uint32_t EdidParser::GetProductCode() const { + return ((static_cast<uint32_t>(manufacturer_id_) << 16) | + (static_cast<uint32_t>(product_id_))); +} - // ParseOutputDeviceData fails if it doesn't have product_name. - ParseOutputDeviceData(edid, &manufacturer_id, &product_id, &product_name, - nullptr, nullptr); - - if (manufacturer_id == 0) - return false; - +int64_t EdidParser::GetDisplayId(uint8_t output_index) const { // Generates product specific value from product_name instead of product code. - // See crbug.com/240341 - uint32_t product_code_hash = - product_name.empty() ? 0 : base::Hash(product_name); + // See https://crbug.com/240341 + const uint32_t product_code_hash = + display_name_.empty() ? 0 : base::Hash(display_name_); // An ID based on display's index will be assigned later if this call fails. - *display_id_out = - GenerateDisplayID(manufacturer_id, product_code_hash, output_index); - // |product_code_out| is 64-bit signed so it can store -1 as kInvalidProductID - // and not match a valid product id which will all be in the lowest 32-bits. - if (product_code_out) - *product_code_out = GetProductCode(manufacturer_id, product_id); - return true; + return GenerateDisplayID(manufacturer_id_, product_code_hash, output_index); } -bool ParseOutputDeviceData(const std::vector<uint8_t>& edid, - uint16_t* manufacturer_id, - uint16_t* product_id, - std::string* human_readable_name, - gfx::Size* active_pixel_out, - gfx::Size* physical_display_size_out) { - // See http://en.wikipedia.org/wiki/Extended_display_identification_data - // for the details of EDID data format. We use the following data: - // bytes 8-9: manufacturer EISA ID, in big-endian - // bytes 10-11: manufacturer product code, in little-endian - // bytes 54-125: four descriptors (18-bytes each) which may contain - // the display name. - constexpr size_t kManufacturerOffset = 8; - constexpr size_t kManufacturerLength = 2; - constexpr size_t kProductIdOffset = 10; - constexpr size_t kProductIdLength = 2; - constexpr size_t kDescriptorOffset = 54; - constexpr size_t kNumDescriptors = 4; - constexpr size_t kDescriptorLength = 18; - // The specifier types. - constexpr uint8_t kMonitorNameDescriptor = 0xfc; - - if (manufacturer_id) { - if (edid.size() < kManufacturerOffset + kManufacturerLength) { - LOG(ERROR) << "Too short EDID data: manufacturer id"; - return false; - } - - // ICC filename is generated based on these ids. We always read this as big - // endian so that the file name matches bytes 8-11 as they appear in EDID. - *manufacturer_id = - (edid[kManufacturerOffset] << 8) + edid[kManufacturerOffset + 1]; - } - - if (product_id) { - if (edid.size() < kProductIdOffset + kProductIdLength) { - LOG(ERROR) << "Too short EDID data: product id"; - return false; - } - - *product_id = (edid[kProductIdOffset] << 8) + edid[kProductIdOffset + 1]; - } - - if (human_readable_name) - human_readable_name->clear(); - - for (size_t i = 0; i < kNumDescriptors; ++i) { - if (edid.size() < kDescriptorOffset + (i + 1) * kDescriptorLength) - break; - - size_t offset = kDescriptorOffset + i * kDescriptorLength; - - // Detailed Timing Descriptor: - if (edid[offset] != 0 && edid[offset + 1] != 0) { - constexpr int kMaxResolution = 10080; // 8k display. - - if (active_pixel_out) { - constexpr size_t kHorizontalPixelLsbOffset = 2; - constexpr size_t kHorizontalPixelMsbOffset = 4; - constexpr size_t kVerticalPixelLsbOffset = 5; - constexpr size_t kVerticalPixelMsbOffset = 7; - - const uint8_t h_lsb = edid[offset + kHorizontalPixelLsbOffset]; - const uint8_t h_msb = edid[offset + kHorizontalPixelMsbOffset]; - int h_pixel = std::min(h_lsb + ((h_msb & 0xF0) << 4), kMaxResolution); - - const uint8_t v_lsb = edid[offset + kVerticalPixelLsbOffset]; - const uint8_t v_msb = edid[offset + kVerticalPixelMsbOffset]; - int v_pixel = std::min(v_lsb + ((v_msb & 0xF0) << 4), kMaxResolution); - - active_pixel_out->SetSize(h_pixel, v_pixel); - // EDID may contain multiple DTD. Use first one that - // contains the highest resolution. - active_pixel_out = nullptr; - } - - if (physical_display_size_out) { - constexpr size_t kHorizontalSizeLsbOffset = 12; - constexpr size_t kVerticalSizeLsbOffset = 13; - constexpr size_t kSizeMsbOffset = 14; - - const uint8_t h_lsb = edid[offset + kHorizontalSizeLsbOffset]; - const uint8_t v_lsb = edid[offset + kVerticalSizeLsbOffset]; - - const uint8_t msb = edid[offset + kSizeMsbOffset]; - int h_size = h_lsb + ((msb & 0xF0) << 4); - int v_size = v_lsb + ((msb & 0x0F) << 8); - physical_display_size_out->SetSize(h_size, v_size); - physical_display_size_out = nullptr; - } - continue; - } - - // EDID Other Monitor Descriptors: - // If the descriptor contains the display name, it has the following - // structure: - // bytes 0-2, 4: \0 - // byte 3: descriptor type, defined above. - // bytes 5-17: text data, ending with \r, padding with spaces - // we should check bytes 0-2 and 4, since it may have other values in - // case that the descriptor contains other type of data. - if (edid[offset] == 0 && edid[offset + 1] == 0 && edid[offset + 2] == 0 && - edid[offset + 3] == kMonitorNameDescriptor && edid[offset + 4] == 0 && - human_readable_name) { - std::string found_name(reinterpret_cast<const char*>(&edid[offset + 5]), - kDescriptorLength - 5); - base::TrimWhitespaceASCII( - found_name, base::TRIM_TRAILING, human_readable_name); - continue; - } - } - - // Verify if the |human_readable_name| consists of printable characters only. - // TODO(oshima|muka): Consider replacing unprintable chars with white space. - if (human_readable_name) { - for (size_t i = 0; i < human_readable_name->size(); ++i) { - char c = (*human_readable_name)[i]; - if (!isascii(c) || !isprint(c)) { - human_readable_name->clear(); - LOG(ERROR) << "invalid EDID: human unreadable char in name"; - return false; - } - } - } - - return true; -} - -void SplitProductCodeInManufacturerIdAndProductId(int64_t product_code, - uint16_t* manufacturer_id, - uint16_t* product_id) { +// static +void EdidParser::SplitProductCodeInManufacturerIdAndProductId( + int64_t product_code, + uint16_t* manufacturer_id, + uint16_t* product_id) { DCHECK(manufacturer_id); DCHECK(product_id); // Undo GetProductCode() packing. @@ -196,7 +57,8 @@ *manufacturer_id = (product_code >> 16) & 0xFFFF; } -std::string ManufacturerIdToString(uint16_t manufacturer_id) { +// static +std::string EdidParser::ManufacturerIdToString(uint16_t manufacturer_id) { // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision // 2, Sep 2006, Sec 3.4.1 "ID Manufacturer Name: 2 Bytes". Essentially these // are 3 5-bit ASCII characters packed in 2 bytes, where 1 means 'A', etc. @@ -214,7 +76,8 @@ return out; } -std::string ProductIdToString(uint16_t product_id) { +// static +std::string EdidParser::ProductIdToString(uint16_t product_id) { // From "VESA Enhanced EDID Standard" Release A, Revision 2, Sep 2006, Sec // 3.4.2 "ID Product Code: 2 Bytes": "The ID product code field, [...] // contains a 2-byte manufacturer assigned product code. [...] The 2 byte @@ -224,77 +87,33 @@ return base::StringPrintf("%02X%02X", upper_char, lower_char); } -bool ParseOutputOverscanFlag(const std::vector<uint8_t>& edid, bool* flag) { +void EdidParser::ParseEdid(const std::vector<uint8_t>& edid) { // See http://en.wikipedia.org/wiki/Extended_display_identification_data - // for the extension format of EDID. Also see EIA/CEA-861 spec for - // the format of the extensions and how video capability is encoded. - // - byte 0: tag. should be 02h. - // - byte 1: revision. only cares revision 3 (03h). - // - byte 4-: data block. - constexpr size_t kExtensionBaseOffset = 128; - constexpr size_t kExtensionSize = 128; - constexpr size_t kNumExtensionsOffset = 126; - constexpr size_t kDataBlockOffset = 4; - constexpr uint8_t kCEAExtensionTag = '\x02'; - constexpr uint8_t kExpectedExtensionRevision = '\x03'; - constexpr uint8_t kExtendedTag = 7; - constexpr uint8_t kExtendedVideoCapabilityTag = 0; - constexpr uint8_t kPTOverscanFlagPosition = 4; - constexpr uint8_t kITOverscanFlagPosition = 2; - constexpr uint8_t kCEOverscanFlagPosition = 0; + // for the details of EDID data format. We use the following data: + // bytes 8-9: manufacturer EISA ID, in big-endian + // bytes 10-11: manufacturer product code, in little-endian + constexpr size_t kManufacturerOffset = 8; + constexpr size_t kManufacturerLength = 2; + constexpr size_t kProductIdOffset = 10; + constexpr size_t kProductIdLength = 2; - if (edid.size() <= kNumExtensionsOffset) - return false; - - const uint8_t num_extensions = edid[kNumExtensionsOffset]; - - for (size_t i = 0; i < num_extensions; ++i) { - // Skip parsing the whole extension if size is not enough. - if (edid.size() < kExtensionBaseOffset + (i + 1) * kExtensionSize) - break; - - const size_t extension_offset = kExtensionBaseOffset + i * kExtensionSize; - const uint8_t cea_tag = edid[extension_offset]; - const uint8_t revision = edid[extension_offset + 1]; - if (cea_tag != kCEAExtensionTag || revision != kExpectedExtensionRevision) - continue; - - const uint8_t timing_descriptors_start = std::min( - edid[extension_offset + 2], static_cast<unsigned char>(kExtensionSize)); - - for (size_t data_offset = extension_offset + kDataBlockOffset; - data_offset < extension_offset + timing_descriptors_start;) { - // A data block is encoded as: - // - byte 1 high 3 bits: tag. '07' for extended tags. - // - byte 1 remaining bits: the length of data block. - // - byte 2: the extended tag. '0' for video capability. - // - byte 3: the capability. - const uint8_t tag = edid[data_offset] >> 5; - const uint8_t payload_length = edid[data_offset] & 0x1f; - if (data_offset + payload_length + 1 > edid.size()) - break; - - if (tag != kExtendedTag || payload_length < 2 || - edid[data_offset + 1] != kExtendedVideoCapabilityTag) { - data_offset += payload_length + 1; - continue; - } - - // The difference between preferred, IT, and CE video formats - // doesn't matter. Set |flag| to true if any of these flags are true. - *flag = (edid[data_offset + 2] & (1 << kPTOverscanFlagPosition)) || - (edid[data_offset + 2] & (1 << kITOverscanFlagPosition)) || - (edid[data_offset + 2] & (1 << kCEOverscanFlagPosition)); - return true; - } + if (edid.size() < kManufacturerOffset + kManufacturerLength) { + LOG(ERROR) << "Too short EDID data: manufacturer id"; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. } + // ICC filename is generated based on these ids. We always read this as big + // endian so that the file name matches bytes 8-11 as they appear in EDID. + manufacturer_id_ = + (edid[kManufacturerOffset] << 8) + edid[kManufacturerOffset + 1]; - return false; -} + if (edid.size() < kProductIdOffset + kProductIdLength) { + LOG(ERROR) << "Too short EDID data: product id"; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. + } + product_id_ = (edid[kProductIdOffset] << 8) + edid[kProductIdOffset + 1]; -DISPLAY_UTIL_EXPORT bool ParseYearOfManufacture( - const std::vector<uint8_t>& edid, - int32_t* year) { // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision // 2, Sep 2006, Sec 3.4.4 "Week and Year of Manufacture or Model Year: 2 // Bytes". @@ -304,19 +123,54 @@ if (edid.size() < kYearOfManufactureOffset + 1) { LOG(ERROR) << "Too short EDID data: year of manufacture"; - return false; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. } const uint8_t byte_data = edid[kYearOfManufactureOffset]; - if (byte_data < kValidValueLowerBound) - return false; - DCHECK(year); - *year = byte_data + kYearOffset; - return true; -} + if (byte_data >= kValidValueLowerBound) + year_of_manufacture_ = byte_data + kYearOffset; -bool ParseChromaticityCoordinates(const std::vector<uint8_t>& edid, - SkColorSpacePrimaries* primaries) { - DCHECK(primaries); + // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision + // 1, Feb 2000, Sec 3.6 "Basic Display Parameters and Features: 5 bytes" + static constexpr int kBitsPerChannelTable[] = {0, 6, 8, 10, 12, 14, 16, 0}; + + constexpr size_t kEDIDRevisionNumberOffset = 19; + constexpr uint8_t kEDIDRevision4Value = 4; + + constexpr size_t kVideoInputDefinitionOffset = 20; + constexpr uint8_t kDigitalInfoMask = 0x80; + constexpr uint8_t kColorBitDepthMask = 0x70; + constexpr uint8_t kColorBitDepthOffset = 4; + + if (edid.size() < kVideoInputDefinitionOffset + 1) { + LOG(ERROR) << "Too short EDID data: bits per channel"; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. + } + if (edid[kEDIDRevisionNumberOffset] >= kEDIDRevision4Value && + (edid[kVideoInputDefinitionOffset] & kDigitalInfoMask)) { + // EDID needs to be revision 4 at least, and kDigitalInfoMask be set for + // the Video Input Definition entry to describe a digital interface. + bits_per_channel_ = kBitsPerChannelTable[( + (edid[kVideoInputDefinitionOffset] & kColorBitDepthMask) >> + kColorBitDepthOffset)]; + } + + // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision + // 2, Sep 2006, Sec. 3.6.3 "Display Transfer Characteristics (GAMMA ): 1 Byte" + constexpr size_t kGammaOffset = 23; + constexpr double kGammaMultiplier = 100.0; + constexpr double kGammaBias = 100.0; + + if (edid.size() < kGammaOffset + 1) { + LOG(ERROR) << "Too short EDID data: gamma"; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. + } + if (edid[kGammaOffset] != 0xFF) { + // Otherwise the byte at kGammaOffset is 0xFF, gamma is stored elsewhere. + gamma_ = (edid[kGammaOffset] + kGammaBias) / kGammaMultiplier; + } // Offsets, lengths, positions and masks are taken from [1] (or [2]). // [1] http://en.wikipedia.org/wiki/Extended_display_identification_data @@ -355,7 +209,8 @@ if (edid.size() < kChromaticityOffset + kChromaticityLength) { LOG(ERROR) << "Too short EDID data: chromaticity coordinates"; - return false; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. } const uint8_t red_green_lsbs = edid[kRedGreenLsbOffset]; @@ -363,85 +218,170 @@ // Recompose the 10b values by appropriately mixing the 8 MSBs and the 2 LSBs, // then rescale to 1024; - primaries->fRX = ((edid[kRedxMsbOffset] << 2) + + primaries_.fRX = ((edid[kRedxMsbOffset] << 2) + ((red_green_lsbs >> kRedxLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fRY = ((edid[kRedyMsbOffset] << 2) + + primaries_.fRY = ((edid[kRedyMsbOffset] << 2) + ((red_green_lsbs >> kRedyLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fGX = ((edid[kGreenxMsbOffset] << 2) + + primaries_.fGX = ((edid[kGreenxMsbOffset] << 2) + ((red_green_lsbs >> kGreenxLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fGY = ((edid[kGreenyMsbOffset] << 2) + + primaries_.fGY = ((edid[kGreenyMsbOffset] << 2) + ((red_green_lsbs >> kGreenyLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fBX = ((edid[kBluexMsbOffset] << 2) + + primaries_.fBX = ((edid[kBluexMsbOffset] << 2) + ((blue_white_lsbs >> kBluexLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fBY = ((edid[kBlueyMsbOffset] << 2) + + primaries_.fBY = ((edid[kBlueyMsbOffset] << 2) + ((blue_white_lsbs >> kBlueyLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fWX = ((edid[kWhitexMsbOffset] << 2) + + primaries_.fWX = ((edid[kWhitexMsbOffset] << 2) + ((blue_white_lsbs >> kWhitexLsbPosition) & kLsbMask)) / 1024.0f; - primaries->fWY = ((edid[kWhiteyMsbOffset] << 2) + + primaries_.fWY = ((edid[kWhiteyMsbOffset] << 2) + ((blue_white_lsbs >> kWhiteyLsbPosition) & kLsbMask)) / 1024.0f; - // TODO(mcasas): Up to two additional White Point coordinates can be provided - // in a Display Descriptor.Read them if we are not satisfied with |fWX| or - // |FWy|. https://crbug.com/771345. - return true; -} + // in a Display Descriptor. Read them if we are not satisfied with |fWX| or + // |fWy|. https://crbug.com/771345. -DISPLAY_UTIL_EXPORT bool ParseGammaValue(const std::vector<uint8_t>& edid, - double* gamma) { - // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision - // 2, Sep 2006, Sec. 3.6.3 "Display Transfer Characteristics (GAMMA ): 1 Byte" - constexpr size_t kGammaOffset = 23; - constexpr double kGammaMultiplier = 100.0; - constexpr double kGammaBias = 100.0; + // See http://en.wikipedia.org/wiki/Extended_display_identification_data + // for the details of EDID data format. We use the following data: + // bytes 54-125: four descriptors (18-bytes each) which may contain + // the display name. + constexpr size_t kDescriptorOffset = 54; + constexpr size_t kNumDescriptors = 4; + constexpr size_t kDescriptorLength = 18; + // The specifier types. + constexpr uint8_t kMonitorNameDescriptor = 0xfc; - if (edid.size() < kGammaOffset + 1) { - LOG(ERROR) << "Too short EDID data: gamma"; - return false; + display_name_.clear(); + for (size_t i = 0; i < kNumDescriptors; ++i) { + if (edid.size() < kDescriptorOffset + (i + 1) * kDescriptorLength) + break; + + size_t offset = kDescriptorOffset + i * kDescriptorLength; + + // Detailed Timing Descriptor: + if (edid[offset] != 0 && edid[offset + 1] != 0) { + constexpr int kMaxResolution = 10080; // 8k display. + + // EDID may contain multiple DTD. Use the first one, that contains the + // highest resolution. + if (active_pixel_size_.IsEmpty()) { + constexpr size_t kHorizontalPixelLsbOffset = 2; + constexpr size_t kHorizontalPixelMsbOffset = 4; + constexpr size_t kVerticalPixelLsbOffset = 5; + constexpr size_t kVerticalPixelMsbOffset = 7; + + const uint8_t h_lsb = edid[offset + kHorizontalPixelLsbOffset]; + const uint8_t h_msb = edid[offset + kHorizontalPixelMsbOffset]; + int h_pixel = std::min(h_lsb + ((h_msb & 0xF0) << 4), kMaxResolution); + + const uint8_t v_lsb = edid[offset + kVerticalPixelLsbOffset]; + const uint8_t v_msb = edid[offset + kVerticalPixelMsbOffset]; + int v_pixel = std::min(v_lsb + ((v_msb & 0xF0) << 4), kMaxResolution); + + active_pixel_size_.SetSize(h_pixel, v_pixel); + } + continue; + } + + // EDID Other Monitor Descriptors: + // If the descriptor contains the display name, it has the following + // structure: + // bytes 0-2, 4: \0 + // byte 3: descriptor type, defined above. + // bytes 5-17: text data, ending with \r, padding with spaces + // we should check bytes 0-2 and 4, since it may have other values in + // case that the descriptor contains other type of data. + if (edid[offset] == 0 && edid[offset + 1] == 0 && edid[offset + 2] == 0 && + edid[offset + 3] == kMonitorNameDescriptor && edid[offset + 4] == 0) { + std::string name(reinterpret_cast<const char*>(&edid[offset + 5]), + kDescriptorLength - 5); + base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &display_name_); + continue; + } } - if (edid[kGammaOffset] == 0xFF) // Gamma is stored elsewhere. - return false; - DCHECK(gamma); - *gamma = (edid[kGammaOffset] + kGammaBias) / kGammaMultiplier; - return true; -} -DISPLAY_UTIL_EXPORT bool ParseBitsPerChannel(const std::vector<uint8_t>& edid, - int* bits_per_channel) { - // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision - // 1, Feb 2000, Sec 3.6 "Basic Display Parameters and Features: 5 bytes" - static constexpr int kBitsPerChannelTable[] = {0, 6, 8, 10, 12, 14, 16, 0}; - - constexpr size_t kEDIDRevisionNumberOffset = 19; - constexpr uint8_t kEDIDRevision4Value = 4; - - constexpr size_t kVideoInputDefinitionOffset = 20; - constexpr uint8_t kDigitalInfoMask = 0x80; - constexpr uint8_t kColorBitDepthMask = 0x70; - constexpr uint8_t kColorBitDepthOffset = 4; - - if (edid.size() < kVideoInputDefinitionOffset + 1) { - LOG(ERROR) << "Too short EDID data: gamma"; - return false; + // Verify if the |display_name_| consists of printable characters only. + // TODO(oshima|muka): Consider replacing unprintable chars with white space. + for (const char c : display_name_) { + if (!isascii(c) || !isprint(c)) { + display_name_.clear(); + LOG(ERROR) << "invalid EDID: human unreadable char in name"; + // TODO(mcasas): add UMA, https://crbug.com/821393. + } } - // EDID needs to be revision 4 at least, and kDigitalInfoMask be set for - // the Video Input Definition entry to describe a digital interface. - if (edid[kEDIDRevisionNumberOffset] < kEDIDRevision4Value || - !(edid[kVideoInputDefinitionOffset] & kDigitalInfoMask)) { - return false; + + // See http://en.wikipedia.org/wiki/Extended_display_identification_data + // for the extension format of EDID. Also see EIA/CEA-861 spec for + // the format of the extensions and how video capability is encoded. + // - byte 0: tag. should be 02h. + // - byte 1: revision. only cares revision 3 (03h). + // - byte 4-: data block. + constexpr size_t kExtensionBaseOffset = 128; + constexpr size_t kExtensionSize = 128; + constexpr size_t kNumExtensionsOffset = 126; + constexpr size_t kDataBlockOffset = 4; + constexpr uint8_t kCEAExtensionTag = '\x02'; + constexpr uint8_t kExpectedExtensionRevision = '\x03'; + constexpr uint8_t kExtendedTag = 7; + constexpr uint8_t kExtendedVideoCapabilityTag = 0; + constexpr uint8_t kPTOverscanFlagPosition = 4; + constexpr uint8_t kITOverscanFlagPosition = 2; + constexpr uint8_t kCEOverscanFlagPosition = 0; + + if (edid.size() < kNumExtensionsOffset) { + LOG(ERROR) << "Too short EDID data: extensions"; + // TODO(mcasas): add UMA, https://crbug.com/821393. + return; // Any other fields below are beyond this edid offset. } - DCHECK(bits_per_channel); - *bits_per_channel = kBitsPerChannelTable[( - (edid[kVideoInputDefinitionOffset] & kColorBitDepthMask) >> - kColorBitDepthOffset)]; - return true; + + const uint8_t num_extensions = edid[kNumExtensionsOffset]; + + for (size_t i = 0; i < num_extensions; ++i) { + // Skip parsing the whole extension if size is not enough. + if (edid.size() < kExtensionBaseOffset + (i + 1) * kExtensionSize) + break; + + const size_t extension_offset = kExtensionBaseOffset + i * kExtensionSize; + const uint8_t cea_tag = edid[extension_offset]; + const uint8_t revision = edid[extension_offset + 1]; + if (cea_tag != kCEAExtensionTag || revision != kExpectedExtensionRevision) + continue; + + const uint8_t timing_descriptors_start = std::min( + edid[extension_offset + 2], static_cast<unsigned char>(kExtensionSize)); + + for (size_t data_offset = extension_offset + kDataBlockOffset; + data_offset < extension_offset + timing_descriptors_start;) { + // A data block is encoded as: + // - byte 1 high 3 bits: tag. '07' for extended tags. + // - byte 1 remaining bits: the length of data block. + // - byte 2: the extended tag. '0' for video capability. + // - byte 3: the capability. + const uint8_t tag = edid[data_offset] >> 5; + const uint8_t payload_length = edid[data_offset] & 0x1f; + if (data_offset + payload_length + 1 > edid.size()) + break; + + if (tag != kExtendedTag || payload_length < 2 || + edid[data_offset + 1] != kExtendedVideoCapabilityTag) { + data_offset += payload_length + 1; + continue; + } + + // The difference between preferred, IT, and CE video formats doesn't + // matter. Set the flag to true if any of these flags are true. + overscan_flag_ = + (edid[data_offset + 2] & (1 << kPTOverscanFlagPosition)) || + (edid[data_offset + 2] & (1 << kITOverscanFlagPosition)) || + (edid[data_offset + 2] & (1 << kCEOverscanFlagPosition)); + break; + } + } } } // namespace display
diff --git a/ui/display/util/edid_parser.h b/ui/display/util/edid_parser.h index dfc23fd..5323f52 100644 --- a/ui/display/util/edid_parser.h +++ b/ui/display/util/edid_parser.h
@@ -11,77 +11,68 @@ #include <vector> #include "base/compiler_specific.h" +#include "base/optional.h" +#include "third_party/skia/include/core/SkColorSpace.h" #include "ui/display/util/display_util_export.h" - -namespace gfx { -class Size; -} - -struct SkColorSpacePrimaries; - -// EDID (Extended Display Identification Data) is a format for monitor -// metadata. This provides a parser for the data. +#include "ui/gfx/geometry/size.h" namespace display { -// Generates the display id and product id for the pair of |edid| and |index|, -// and store in |display_id_out| and |product_code_out|. Returns true if the -// display id is successfully generated, or false otherwise. -DISPLAY_UTIL_EXPORT bool GetDisplayIdFromEDID(const std::vector<uint8_t>& edid, - uint8_t index, - int64_t* display_id_out, - int64_t* product_code_out); +// This class parses a EDID (Extended Display Identification Data) binary blob +// passed on constructor, and provides access to the parsed information, plus +// a few utility postprocessings. +class DISPLAY_UTIL_EXPORT EdidParser { + public: + explicit EdidParser(const std::vector<uint8_t>& edid_blob); + ~EdidParser(); -// Parses |edid| as EDID data and stores extracted data into |manufacturer_id|, -// |product_id|, |human_readable_name|, |active_pixel_out| and -// |physical_display_size_out|, then returns true. nullptr can be passed for -// unwanted output parameters. Some devices (especially internal displays) may -// not have the field for |human_readable_name|, and it will return true in -// that case. -DISPLAY_UTIL_EXPORT bool ParseOutputDeviceData( - const std::vector<uint8_t>& edid, - uint16_t* manufacturer_id, - uint16_t* product_id, - std::string* human_readable_name, - gfx::Size* active_pixel_out, - gfx::Size* physical_display_size_out); + uint16_t manufacturer_id() const { return manufacturer_id_; } + uint16_t product_id() const { return product_id_; } + const std::string& display_name() const { return display_name_; } + const gfx::Size& active_pixel_size() const { return active_pixel_size_; } + int32_t year_of_manufacture() const { return year_of_manufacture_; } + bool has_overscan_flag() const { return overscan_flag_.has_value(); } + bool overscan_flag() const { return overscan_flag_.value(); } + double gamma() const { return gamma_; } + int32_t bits_per_channel() const { return bits_per_channel_; } + const SkColorSpacePrimaries& primaries() const { return primaries_; } -// Splits the |product_code| (as returned by GetDisplayIdFromEDID()) into its -// constituents |manufacturer_id| and |product_id|. -DISPLAY_UTIL_EXPORT void SplitProductCodeInManufacturerIdAndProductId( - int64_t product_code, - uint16_t* manufacturer_id, - uint16_t* product_id); + // Returns a 32-bit identifier for this display |manufacturer_id_| and + // |product_id_|. + uint32_t GetProductCode() const; -// Extracts the three letter Manufacturer ID out of |manufacturer_id|. -DISPLAY_UTIL_EXPORT std::string ManufacturerIdToString( - uint16_t manufacturer_id); + // Generates a unique display id out of a mix of |manufacturer_id_|, hashed + // |display_name_| if available, and |output_index|. + int64_t GetDisplayId(uint8_t output_index) const; -// Extracts the 2 Byte Product ID as hex out of |product_id|. -DISPLAY_UTIL_EXPORT std::string ProductIdToString(uint16_t product_id); + // Splits the |product_code| (as returned by GetDisplayId()) into its + // constituents |manufacturer_id| and |product_id|. + static void SplitProductCodeInManufacturerIdAndProductId( + int64_t product_code, + uint16_t* manufacturer_id, + uint16_t* product_id); + // Extracts the three letter Manufacturer ID out of |manufacturer_id|. + static std::string ManufacturerIdToString(uint16_t manufacturer_id); + // Extracts the 2 Byte Product ID as hex out of |product_id|. + static std::string ProductIdToString(uint16_t product_id); -DISPLAY_UTIL_EXPORT bool ParseOutputOverscanFlag( - const std::vector<uint8_t>& edid, - bool* flag); + private: + // Parses |edid_blob|, filling up as many as possible fields below. + void ParseEdid(const std::vector<uint8_t>& edid); -DISPLAY_UTIL_EXPORT bool ParseYearOfManufacture( - const std::vector<uint8_t>& edid, - int32_t* year); + uint16_t manufacturer_id_; + uint16_t product_id_; + std::string display_name_; + // Active pixel size from the first detailed timing descriptor in the EDID. + gfx::Size active_pixel_size_; + int32_t year_of_manufacture_; + base::Optional<bool> overscan_flag_; + double gamma_; + int bits_per_channel_; + SkColorSpacePrimaries primaries_; -// Extracts from |edid| the |primaries| chromaticity coordinates (CIE xy -// coordinates for Red, Green and Blue channels and for the White Point). -DISPLAY_UTIL_EXPORT bool ParseChromaticityCoordinates( - const std::vector<uint8_t>& edid, - SkColorSpacePrimaries* primaries) WARN_UNUSED_RESULT; - -// Extracts the gamma value from |edid| and returns it, or returns 0.0. -DISPLAY_UTIL_EXPORT bool ParseGammaValue(const std::vector<uint8_t>& edid, - double* gamma) WARN_UNUSED_RESULT; - -// Extracts the bits per channel from |edid| and returns it, or returns 0. -DISPLAY_UTIL_EXPORT bool ParseBitsPerChannel(const std::vector<uint8_t>& edid, - int* bits_per_channel) - WARN_UNUSED_RESULT; + DISALLOW_COPY_AND_ASSIGN(EdidParser); +}; } // namespace display
diff --git a/ui/display/util/edid_parser_fuzzer.cc b/ui/display/util/edid_parser_fuzzer.cc index d1007e5..d3d8f0c 100644 --- a/ui/display/util/edid_parser_fuzzer.cc +++ b/ui/display/util/edid_parser_fuzzer.cc
@@ -23,17 +23,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::vector<uint8_t> edid; edid.assign(data, data + size); - uint16_t manufacturer_id, product_code; - std::string human_readable_name; - gfx::Size active_pixel_size, physical_display_size; - bool overscan; - int32_t year_of_manufacture; - - display::ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - &human_readable_name, &active_pixel_size, - &physical_display_size); - - display::ParseOutputOverscanFlag(edid, &overscan); - display::ParseYearOfManufacture(edid, &year_of_manufacture); + // Ctor already parses |edid|, which is what we want here. + display::EdidParser edid_parser(edid); return 0; }
diff --git a/ui/display/util/edid_parser_unittest.cc b/ui/display/util/edid_parser_unittest.cc index de024ae..8d30733 100644 --- a/ui/display/util/edid_parser_unittest.cc +++ b/ui/display/util/edid_parser_unittest.cc
@@ -12,21 +12,20 @@ #include "base/numerics/ranges.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "ui/display/types/display_constants.h" #include "ui/gfx/geometry/size.h" using ::testing::AssertionFailure; using ::testing::AssertionSuccess; +using ::testing::TestWithParam; +using ::testing::ValuesIn; namespace display { namespace { -// Returns the number of characters in the string literal but doesn't count its -// terminator NULL byte. -#define charsize(str) (arraysize(str) - 1) - // Sample EDID data extracted from real devices. -const unsigned char kNormalDisplay[] = +constexpr unsigned char kNormalDisplay[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01" "\x02\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25" "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" @@ -35,8 +34,9 @@ "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48" "\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\xff" "\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71"; +constexpr size_t kNormalDisplayLength = arraysize(kNormalDisplay); -const unsigned char kInternalDisplay[] = +constexpr unsigned char kInternalDisplay[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x4c\xa3\x42\x31\x00\x00\x00\x00" "\x00\x15\x01\x03\x80\x1a\x10\x78\x0a\xd3\xe5\x95\x5c\x60\x90\x27" "\x19\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" @@ -45,8 +45,9 @@ "\x00\x00\x00\x00\x00\x23\x87\x02\x64\x00\x00\x00\x00\xfe\x00\x53" "\x41\x4d\x53\x55\x4e\x47\x0a\x20\x20\x20\x20\x20\x00\x00\x00\xfe" "\x00\x31\x32\x31\x41\x54\x31\x31\x2d\x38\x30\x31\x0a\x20\x00\x45"; +constexpr size_t kInternalDisplayLength = arraysize(kInternalDisplay); -const unsigned char kOverscanDisplay[] = +constexpr unsigned char kOverscanDisplay[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x4c\x2d\xfe\x08\x00\x00\x00\x00" "\x29\x15\x01\x03\x80\x10\x09\x78\x0a\xee\x91\xa3\x54\x4c\x99\x26" "\x0f\x50\x54\xbd\xef\x80\x71\x4f\x81\xc0\x81\x00\x81\x80\x95\x00" @@ -63,9 +64,10 @@ "\x5a\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6"; +constexpr size_t kOverscanDisplayLength = arraysize(kOverscanDisplay); // The EDID info misdetecting overscan once. see crbug.com/226318 -const unsigned char kMisdetectedDisplay[] = +constexpr unsigned char kMisdetectedDisplay[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x10\xac\x64\x40\x4c\x30\x30\x32" "\x0c\x15\x01\x03\x80\x40\x28\x78\xea\x8d\x85\xad\x4f\x35\xb1\x25" "\x0e\x50\x54\xa5\x4b\x00\x71\x4f\x81\x00\x81\x80\xd1\x00\xa9\x40" @@ -82,8 +84,9 @@ "\x72\x51\xd0\x1e\x20\x6e\x28\x55\x00\x81\x91\x21\x00\x00\x1e\x8c" "\x0a\xd0\x8a\x20\xe0\x2d\x10\x10\x3e\x96\x00\x81\x91\x21\x00\x00" "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94"; +constexpr size_t kMisdetectedDisplayLength = arraysize(kMisdetectedDisplay); -const unsigned char kLP2565A[] = +constexpr unsigned char kLP2565A[] = "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x22\xF0\x76\x26\x01\x01\x01\x01" "\x02\x12\x01\x03\x80\x34\x21\x78\xEE\xEF\x95\xA3\x54\x4C\x9B\x26" "\x0F\x50\x54\xA5\x6B\x80\x81\x40\x81\x80\x81\x99\x71\x00\xA9\x00" @@ -92,8 +95,9 @@ "\x5E\x11\x00\x0A\x20\x20\x20\x20\x20\x20\x00\x00\x00\xFC\x00\x48" "\x50\x20\x4C\x50\x32\x34\x36\x35\x0A\x20\x20\x20\x00\x00\x00\xFF" "\x00\x43\x4E\x4B\x38\x30\x32\x30\x34\x48\x4D\x0A\x20\x20\x00\xA4"; +constexpr size_t kLP2565ALength = arraysize(kLP2565A); -const unsigned char kLP2565B[] = +constexpr unsigned char kLP2565B[] = "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x22\xF0\x75\x26\x01\x01\x01\x01" "\x02\x12\x01\x03\x6E\x34\x21\x78\xEE\xEF\x95\xA3\x54\x4C\x9B\x26" "\x0F\x50\x54\xA5\x6B\x80\x81\x40\x71\x00\xA9\x00\xA9\x40\xA9\x4F" @@ -102,9 +106,10 @@ "\x5E\x15\x00\x0A\x20\x20\x20\x20\x20\x20\x00\x00\x00\xFC\x00\x48" "\x50\x20\x4C\x50\x32\x34\x36\x35\x0A\x20\x20\x20\x00\x00\x00\xFF" "\x00\x43\x4E\x4B\x38\x30\x32\x30\x34\x48\x4D\x0A\x20\x20\x00\x45"; +constexpr size_t kLP2565BLength = arraysize(kLP2565B); // HP z32x monitor. -const unsigned char kHPz32x[] = +constexpr unsigned char kHPz32x[] = "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x22\xF0\x75\x32\x01\x01\x01\x01" "\x1B\x1B\x01\x04\xB5\x46\x27\x78\x3A\x8D\x15\xAC\x51\x32\xB8\x26" "\x0B\x50\x54\x21\x08\x00\xD1\xC0\xA9\xC0\x81\xC0\xD1\x00\xB3\x00" @@ -121,9 +126,10 @@ "\x00\xA0\xA0\x40\x2E\x60\x20\x30\x63\x00\xB9\x88\x21\x00\x00\x1C" "\x28\x3C\x80\xA0\x70\xB0\x23\x40\x30\x20\x36\x00\xB9\x88\x21\x00" "\x00\x1A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E"; +constexpr size_t kHPz32xLength = arraysize(kHPz32x); // Chromebook Samus internal display. -const unsigned char kSamus[] = +constexpr unsigned char kSamus[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x30\xe4\x2e\x04\x00\x00\x00\x00" "\x00\x18\x01\x04\xa5\x1b\x12\x96\x02\x4f\xd5\xa2\x59\x52\x93\x26" "\x17\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" @@ -132,9 +138,10 @@ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x4c" "\x47\x20\x44\x69\x73\x70\x6c\x61\x79\x0a\x20\x20\x00\x00\x00\xfe" "\x00\x4c\x50\x31\x32\x39\x51\x45\x32\x2d\x53\x50\x41\x31\x00\x6c"; +constexpr size_t kSamusLength = arraysize(kSamus); // Chromebook Eve internal display. -const unsigned char kEve[] = +constexpr unsigned char kEve[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x4d\x10\x8a\x14\x00\x00\x00\x00" "\x16\x1b\x01\x04\xa5\x1a\x11\x78\x06\xde\x50\xa3\x54\x4c\x99\x26" "\x0f\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" @@ -143,13 +150,29 @@ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc" "\x00\x4c\x51\x31\x32\x33\x50\x31\x4a\x58\x33\x32\x0a\x20\x00\xb6"; +constexpr size_t kEveLength = arraysize(kEve); -void Reset(gfx::Size* pixel, gfx::Size* size) { - pixel->SetSize(0, 0); - size->SetSize(0, 0); -} +constexpr SkColorSpacePrimaries kNormalDisplayPrimaries = { + 0.6777f, 0.3086f, 0.2080f, 0.6923f, 0.1465f, 0.0546f, 0.3125f, 0.3291f}; +constexpr SkColorSpacePrimaries kInternalDisplayPrimaries = { + 0.5849f, 0.3603f, 0.3769f, 0.5654f, 0.1552f, 0.0996f, 0.3125f, 0.3291f}; +constexpr SkColorSpacePrimaries kOverscanDisplayPrimaries = { + 0.6396f, 0.3291f, 0.2978f, 0.5996f, 0.1494f, 0.0595f, 0.3144f, 0.3291f}; +constexpr SkColorSpacePrimaries kMisdetectedDisplayPrimaries = { + 0.6777f, 0.3086f, 0.2080f, 0.6923f, 0.1465f, 0.0546f, 0.3125f, 0.3291f}; +constexpr SkColorSpacePrimaries kLP2565APrimaries = { + 0.6396f, 0.3291f, 0.2978f, 0.6083f, 0.1494f, 0.0595f, 0.3144f, 0.3291f}; +constexpr SkColorSpacePrimaries kLP2565BPrimaries = { + 0.6396f, 0.3291f, 0.2978f, 0.6083f, 0.1494f, 0.0595f, 0.3144f, 0.3291f}; +constexpr SkColorSpacePrimaries kHPz32xPrimaries = { + 0.6738f, 0.3164f, 0.1962f, 0.7197f, 0.1484f, 0.0439f, 0.3144f, 0.3291f}; +constexpr SkColorSpacePrimaries kSamusPrimaries = { + 0.6337f, 0.3476f, 0.3212f, 0.5771f, 0.1513f, 0.0908f, 0.3144f, 0.3291f}; +constexpr SkColorSpacePrimaries kEvePrimaries = { + 0.6396f, 0.3291f, 0.2998f, 0.5996f, 0.1494f, 0.0595f, 0.3144f, 0.3281f}; + // Chromaticity primaries in EDID are specified with 10 bits precision. -const static float kPrimariesPrecision = 0.001f; +constexpr static float kPrimariesPrecision = 0.001f; ::testing::AssertionResult SkColorSpacePrimariesEquals( const char* lhs_expr, @@ -177,353 +200,96 @@ } // namespace -TEST(EDIDParserTest, ParseOverscanFlag) { - bool flag = false; - std::vector<uint8_t> edid( - kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - EXPECT_FALSE(ParseOutputOverscanFlag(edid, &flag)); +struct TestParams { + uint16_t manufacturer_id; + uint16_t product_id; + std::string display_name; + gfx::Size active_pixel_size; + int32_t year_of_manufacture; + bool overscan_flag; + double gamma; + int bits_per_channel; + SkColorSpacePrimaries primaries; - flag = false; - edid.assign(kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - EXPECT_FALSE(ParseOutputOverscanFlag(edid, &flag)); + uint32_t product_code; + int64_t display_id_zero; - flag = false; - edid.assign(kOverscanDisplay, kOverscanDisplay + charsize(kOverscanDisplay)); - EXPECT_TRUE(ParseOutputOverscanFlag(edid, &flag)); - EXPECT_TRUE(flag); + std::string manufacturer_id_string; + std::string product_id_string; - flag = false; - edid.assign( - kMisdetectedDisplay, kMisdetectedDisplay + charsize(kMisdetectedDisplay)); - EXPECT_FALSE(ParseOutputOverscanFlag(edid, &flag)); + const unsigned char* edid_blob; + size_t edid_blob_length; +} kTestCases[] = { + {0x22f0u, 0x6c28u, "HP ZR30w", gfx::Size(2560, 1600), 2012, false, 2.2, 10, + kNormalDisplayPrimaries, 586181672, 9834734971736576, "HWP", "286C", + kNormalDisplay, kNormalDisplayLength}, + {0x4ca3u, 0x4231u, "", gfx::Size(1280, 800), 2011, false, 2.2, -1, + kInternalDisplayPrimaries, 1285767729, 21571318625337344, "SEC", "3142", + kInternalDisplay, kInternalDisplayLength}, + {0x4c2du, 0xfe08u, "SAMSUNG", gfx::Size(1920, 1080), 2011, true, 2.2, -1, + kOverscanDisplayPrimaries, 1278082568, 21442559853606400, "SAM", "08FE", + kOverscanDisplay, kOverscanDisplayLength}, + {0x10ACu, 0x6440u, "DELL U3011", gfx::Size(1920, 1200), 2011, false, 2.2, + -1, kMisdetectedDisplayPrimaries, 279733312, 4692848143772416, "DEL", + "4064", kMisdetectedDisplay, kMisdetectedDisplayLength}, + {0x22f0u, 0x7626u, "HP LP2465", gfx::Size(1920, 1200), 2008, false, 2.2, -1, + kLP2565APrimaries, 586184230, 9834630174887424, "HWP", "2676", kLP2565A, + kLP2565ALength}, + {0x22f0u, 0x7526u, "HP LP2465", gfx::Size(1920, 1200), 2008, false, 2.2, -1, + kLP2565BPrimaries, 586183974, 9834630174887424, "HWP", "2675", kLP2565B, + kLP2565BLength}, + {0x22f0u, 0x7532u, "HP Z32x", gfx::Size(3840, 2160), 2017, false, 2.2, 10, + kHPz32xPrimaries, 586183986, 9834799315992832, "HWP", "3275", kHPz32x, + kHPz32xLength}, + {0x30E4u, 0x2E04u, "", gfx::Size(2560, 1700), 2014, false, 2.5, 8, + kSamusPrimaries, 820260356, 13761487533244416, "LGD", "042E", kSamus, + kSamusLength}, + {0x4D10u, 0x8A14u, "LQ123P1JX32", gfx::Size(2400, 1600), 2017, false, 2.2, + 8, kEvePrimaries, 1292929556, 21692109949126656, "SHP", "148A", kEve, + kEveLength}, - flag = false; - // Copy |kOverscanDisplay| and set flags to false in it. The overscan flags - // are embedded at byte 150 in this specific example. Fix here too when the - // contents of kOverscanDisplay is altered. - edid.assign(kOverscanDisplay, kOverscanDisplay + charsize(kOverscanDisplay)); - edid[150] = '\0'; - EXPECT_TRUE(ParseOutputOverscanFlag(edid, &flag)); - EXPECT_FALSE(flag); + // Empty Edid, which is tantamount to error. + {0, 0, "", gfx::Size(0, 0), display::kInvalidYearOfManufacture, false, 0.0, + -1, SkColorSpacePrimaries(), 0, 0, "@@@", "0000", nullptr, 0u}, +}; + +class EDIDParserTest : public TestWithParam<TestParams> { + public: + EDIDParserTest() + : parser_(std::vector<uint8_t>( + GetParam().edid_blob, + GetParam().edid_blob + GetParam().edid_blob_length)) {} + + const EdidParser parser_; + + private: + DISALLOW_COPY_AND_ASSIGN(EDIDParserTest); +}; + +TEST_P(EDIDParserTest, ParseEdids) { + EXPECT_EQ(parser_.manufacturer_id(), GetParam().manufacturer_id); + EXPECT_EQ(parser_.product_id(), GetParam().product_id); + EXPECT_EQ(parser_.display_name(), GetParam().display_name); + EXPECT_EQ(parser_.active_pixel_size(), GetParam().active_pixel_size); + EXPECT_EQ(parser_.year_of_manufacture(), GetParam().year_of_manufacture); + EXPECT_EQ(parser_.has_overscan_flag(), GetParam().overscan_flag); + if (parser_.has_overscan_flag()) + EXPECT_EQ(parser_.overscan_flag(), GetParam().overscan_flag); + EXPECT_DOUBLE_EQ(parser_.gamma(), GetParam().gamma); + EXPECT_EQ(parser_.bits_per_channel(), GetParam().bits_per_channel); + EXPECT_PRED_FORMAT2(SkColorSpacePrimariesEquals, parser_.primaries(), + GetParam().primaries); + + EXPECT_EQ(parser_.GetProductCode(), GetParam().product_code); + EXPECT_EQ(parser_.GetDisplayId(0 /* product_index */), + GetParam().display_id_zero); + + EXPECT_EQ(EdidParser::ManufacturerIdToString(parser_.manufacturer_id()), + GetParam().manufacturer_id_string); + EXPECT_EQ(EdidParser::ProductIdToString(parser_.product_id()), + GetParam().product_id_string); } -TEST(EDIDParserTest, ParseBrokenOverscanData) { - // Do not fill valid data here because it anyway fails to parse the data. - std::vector<uint8_t> data; - bool flag = false; - EXPECT_FALSE(ParseOutputOverscanFlag(data, &flag)); - data.assign(126, '\0'); - EXPECT_FALSE(ParseOutputOverscanFlag(data, &flag)); - - // extending data because ParseOutputOverscanFlag() will access the data. - data.assign(128, '\0'); - // The number of CEA extensions is stored at byte 126. - data[126] = '\x01'; - EXPECT_FALSE(ParseOutputOverscanFlag(data, &flag)); - - data.assign(150, '\0'); - data[126] = '\x01'; - EXPECT_FALSE(ParseOutputOverscanFlag(data, &flag)); -} - -TEST(EDIDParserTest, ParseEDID) { - uint16_t manufacturer_id = 0; - uint16_t product_code = 0; - std::string human_readable_name; - std::vector<uint8_t> edid( - kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - gfx::Size pixel; - gfx::Size size; - EXPECT_TRUE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - &human_readable_name, &pixel, &size)); - EXPECT_EQ(0x22f0u, manufacturer_id); - EXPECT_EQ(0x6c28u, product_code); - EXPECT_EQ("HP ZR30w", human_readable_name); - EXPECT_EQ("2560x1600", pixel.ToString()); - EXPECT_EQ("641x400", size.ToString()); - EXPECT_EQ(ManufacturerIdToString(manufacturer_id), "HWP"); - EXPECT_EQ(ProductIdToString(product_code), "286C"); - - manufacturer_id = 0; - product_code = 0; - human_readable_name.clear(); - Reset(&pixel, &size); - edid.assign(kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - - EXPECT_TRUE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - nullptr, &pixel, &size)); - EXPECT_EQ(0x4ca3u, manufacturer_id); - EXPECT_EQ(0x4231u, product_code); - EXPECT_EQ("", human_readable_name); - EXPECT_EQ("1280x800", pixel.ToString()); - EXPECT_EQ("261x163", size.ToString()); - EXPECT_EQ(ManufacturerIdToString(manufacturer_id), "SEC"); - EXPECT_EQ(ProductIdToString(product_code), "3142"); - - // Internal display doesn't have name. - EXPECT_TRUE(ParseOutputDeviceData(edid, nullptr, nullptr, - &human_readable_name, &pixel, &size)); - EXPECT_TRUE(human_readable_name.empty()); - - manufacturer_id = 0; - product_code = 0; - human_readable_name.clear(); - Reset(&pixel, &size); - edid.assign(kOverscanDisplay, kOverscanDisplay + charsize(kOverscanDisplay)); - EXPECT_TRUE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - &human_readable_name, &pixel, &size)); - EXPECT_EQ(0x4c2du, manufacturer_id); - EXPECT_EQ(0xfe08u, product_code); - EXPECT_EQ("SAMSUNG", human_readable_name); - EXPECT_EQ("1920x1080", pixel.ToString()); - EXPECT_EQ("160x90", size.ToString()); - EXPECT_EQ(ManufacturerIdToString(manufacturer_id), "SAM"); - EXPECT_EQ(ProductIdToString(product_code), "08FE"); - - manufacturer_id = 0; - product_code = 0; - human_readable_name.clear(); - Reset(&pixel, &size); - edid.assign(kSamus, kSamus + charsize(kSamus)); - EXPECT_TRUE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - nullptr, &pixel, &size)); - EXPECT_EQ(0x30E4u, manufacturer_id); - EXPECT_EQ(0x2E04u, product_code); - EXPECT_EQ("", human_readable_name); - EXPECT_EQ("2560x1700", pixel.ToString()); - EXPECT_EQ("272x181", size.ToString()); - EXPECT_EQ(ManufacturerIdToString(manufacturer_id), "LGD"); - EXPECT_EQ(ProductIdToString(product_code), "042E"); - - manufacturer_id = 0; - product_code = 0; - human_readable_name.clear(); - Reset(&pixel, &size); - edid.assign(kEve, kEve + charsize(kEve)); - EXPECT_TRUE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - nullptr, &pixel, &size)); - EXPECT_EQ(0x4D10u, manufacturer_id); - EXPECT_EQ(0x8A14u, product_code); - EXPECT_EQ("", human_readable_name); - EXPECT_EQ("2400x1600", pixel.ToString()); - EXPECT_EQ("259x173", size.ToString()); - EXPECT_EQ(ManufacturerIdToString(manufacturer_id), "SHP"); - EXPECT_EQ(ProductIdToString(product_code), "148A"); -} - -TEST(EDIDParserTest, ParseBrokenEDID) { - uint16_t manufacturer_id = 0; - uint16_t product_code = 0; - std::string human_readable_name; - std::vector<uint8_t> edid; - - gfx::Size dummy; - - // length == 0 - EXPECT_FALSE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - &human_readable_name, &dummy, &dummy)); - - // name is broken. Copying kNormalDisplay and substitute its name data by - // some control code. - edid.assign(kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - - // display's name data is embedded in byte 95-107 in this specific example. - // Fix here too when the contents of kNormalDisplay is altered. - edid[97] = '\x1b'; - EXPECT_FALSE(ParseOutputDeviceData(edid, &manufacturer_id, nullptr, - &human_readable_name, &dummy, &dummy)); - - // If |human_readable_name| isn't specified, it skips parsing the name. - manufacturer_id = 0; - product_code = 0; - EXPECT_TRUE(ParseOutputDeviceData(edid, &manufacturer_id, &product_code, - nullptr, &dummy, &dummy)); - EXPECT_EQ(0x22f0u, manufacturer_id); - EXPECT_EQ(0x6c28u, product_code); -} - -TEST(EDIDParserTest, GetDisplayId) { - // EDID of kLP2565A and B are slightly different but actually the same device. - int64_t id1 = -1; - int64_t id2 = -1; - int64_t product_id1 = -1; - int64_t product_id2 = -1; - std::vector<uint8_t> edid(kLP2565A, kLP2565A + charsize(kLP2565A)); - EXPECT_TRUE(GetDisplayIdFromEDID(edid, 0, &id1, &product_id1)); - edid.assign(kLP2565B, kLP2565B + charsize(kLP2565B)); - EXPECT_TRUE(GetDisplayIdFromEDID(edid, 0, &id2, &product_id2)); - EXPECT_EQ(id1, id2); - // The product code in the two EDIDs varies. - EXPECT_NE(product_id1, product_id2); - EXPECT_EQ(0x22f07626, product_id1); - EXPECT_EQ(0x22f07526, product_id2); - EXPECT_NE(-1, id1); - EXPECT_NE(-1, product_id1); -} - -TEST(EDIDParserTest, GetDisplayIdFromInternal) { - int64_t id = -1; - int64_t product_id = -1; - std::vector<uint8_t> edid( - kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - EXPECT_TRUE(GetDisplayIdFromEDID(edid, 0, &id, &product_id)); - EXPECT_NE(-1, id); - EXPECT_NE(-1, product_id); -} - -TEST(EDIDParserTest, GetDisplayIdFailure) { - int64_t id = -1; - int64_t product_id = -1; - std::vector<uint8_t> edid; - EXPECT_FALSE(GetDisplayIdFromEDID(edid, 0, &id, &product_id)); - EXPECT_EQ(-1, id); - EXPECT_EQ(-1, product_id); -} - -TEST(EDIDParserTest, ParseChromaticityCoordinates) { - const std::vector<uint8_t> edid_normal_display( - kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - SkColorSpacePrimaries primaries_normal_display; - EXPECT_TRUE(ParseChromaticityCoordinates(edid_normal_display, - &primaries_normal_display)); - // Color primaries associated to |kNormalDisplay|; they don't correspond to - // any standard color gamut. - const SkColorSpacePrimaries kNormalDisplayPrimaries = { - 0.6777f, 0.3086f, 0.2080f, 0.6923f, 0.1465f, 0.0546f, 0.3125f, 0.3291f}; - EXPECT_PRED_FORMAT2(SkColorSpacePrimariesEquals, primaries_normal_display, - kNormalDisplayPrimaries); - - const std::vector<uint8_t> edid_internal_display( - kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - SkColorSpacePrimaries primaries_internal_display; - EXPECT_TRUE(ParseChromaticityCoordinates(edid_internal_display, - &primaries_internal_display)); - // Color primaries associated to |kInternalDisplay|; they don't correspond to - // any standard color gamut. - const SkColorSpacePrimaries kInternalDisplayPrimaries = { - 0.5849f, 0.3603f, 0.3769f, 0.5654f, 0.1552f, 0.0996f, 0.3125f, 0.3291f}; - EXPECT_PRED_FORMAT2(SkColorSpacePrimariesEquals, primaries_internal_display, - kInternalDisplayPrimaries); - - const std::vector<uint8_t> edid_hpz32x(kHPz32x, kHPz32x + charsize(kHPz32x)); - SkColorSpacePrimaries primaries_hpz32x; - EXPECT_TRUE(ParseChromaticityCoordinates(edid_hpz32x, &primaries_hpz32x)); - // Color primaries associated to |kHPz32x|; they don't correspond to - // any standard color gamut. - const SkColorSpacePrimaries kHPz32xPrimaries = { - 0.6738f, 0.3164f, 0.1962f, 0.7197f, 0.1484f, 0.0439f, 0.3144f, 0.3291f}; - EXPECT_PRED_FORMAT2(SkColorSpacePrimariesEquals, primaries_hpz32x, - kHPz32xPrimaries); - - const std::vector<uint8_t> edid_samus(kSamus, kSamus + charsize(kSamus)); - SkColorSpacePrimaries primaries_samus; - EXPECT_TRUE(ParseChromaticityCoordinates(edid_samus, &primaries_samus)); - // Color primaries associated to Samus Chromebook, very similar to BT.709. - const SkColorSpacePrimaries kSamusPrimaries = { - 0.6337f, 0.3476f, 0.3212f, 0.5771f, 0.1513f, 0.0908f, 0.3144f, 0.3291f}; - EXPECT_PRED_FORMAT2(SkColorSpacePrimariesEquals, primaries_samus, - kSamusPrimaries); - - const std::vector<uint8_t> edid_eve(kEve, kEve + charsize(kEve)); - SkColorSpacePrimaries primaries_eve; - EXPECT_TRUE(ParseChromaticityCoordinates(edid_eve, &primaries_eve)); - // Color primaries associated to Eve Chromebook, very similar to BT.709. - const SkColorSpacePrimaries kEvePrimaries = { - 0.6396f, 0.3291f, 0.2998f, 0.5996f, 0.1494f, 0.0595f, 0.3144f, 0.3281f}; - EXPECT_PRED_FORMAT2(SkColorSpacePrimariesEquals, primaries_eve, - kEvePrimaries); -} - -TEST(EDIDParserTest, ParseYearOfManufacture) { - const std::vector<uint8_t> edid_normal_display( - kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - int32_t edid_normal_display_year = 0; - EXPECT_TRUE( - ParseYearOfManufacture(edid_normal_display, &edid_normal_display_year)); - EXPECT_EQ(2012, edid_normal_display_year); - - const std::vector<uint8_t> edid_internal_display( - kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - int32_t edid_internal_display_year = 0; - EXPECT_TRUE(ParseYearOfManufacture(edid_internal_display, - &edid_internal_display_year)); - EXPECT_EQ(2011, edid_internal_display_year); - - const std::vector<uint8_t> edid_hpz32x(kHPz32x, kHPz32x + charsize(kHPz32x)); - int32_t edid_hpz32x_year = 0; - EXPECT_TRUE(ParseYearOfManufacture(edid_hpz32x, &edid_hpz32x_year)); - EXPECT_EQ(2017, edid_hpz32x_year); - - const std::vector<uint8_t> edid_samus(kSamus, kSamus + charsize(kSamus)); - int32_t edid_samus_year = 0; - EXPECT_TRUE(ParseYearOfManufacture(edid_samus, &edid_samus_year)); - EXPECT_EQ(2014, edid_samus_year); - - const std::vector<uint8_t> edid_eve(kEve, kEve + charsize(kEve)); - int32_t edid_eve_year = 0; - EXPECT_TRUE(ParseYearOfManufacture(edid_eve, &edid_eve_year)); - EXPECT_EQ(2017, edid_eve_year); -} - -TEST(EDIDParserTest, ParseGammaValue) { - const std::vector<uint8_t> edid_normal_display( - kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - double edid_normal_display_gamma = 0.0; - EXPECT_TRUE(ParseGammaValue(edid_normal_display, &edid_normal_display_gamma)); - EXPECT_DOUBLE_EQ(2.2, edid_normal_display_gamma); - - const std::vector<uint8_t> edid_internal_display( - kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - double edid_internal_display_gamma = 0.0; - EXPECT_TRUE( - ParseGammaValue(edid_internal_display, &edid_internal_display_gamma)); - EXPECT_DOUBLE_EQ(2.2, edid_internal_display_gamma); - - const std::vector<uint8_t> edid_hpz32x(kHPz32x, kHPz32x + charsize(kHPz32x)); - double edid_hpz32x_gamma = 0.0; - EXPECT_TRUE(ParseGammaValue(edid_hpz32x, &edid_hpz32x_gamma)); - EXPECT_DOUBLE_EQ(2.2, edid_hpz32x_gamma); - - const std::vector<uint8_t> edid_samus(kSamus, kSamus + charsize(kSamus)); - double edid_samus_gamma = 0.0; - EXPECT_TRUE(ParseGammaValue(edid_samus, &edid_samus_gamma)); - EXPECT_DOUBLE_EQ(2.5, edid_samus_gamma); - - const std::vector<uint8_t> edid_eve(kEve, kEve + charsize(kEve)); - double edid_eve_gamma = 0.0; - EXPECT_TRUE(ParseGammaValue(edid_eve, &edid_eve_gamma)); - EXPECT_DOUBLE_EQ(2.2, edid_eve_gamma); -} - -TEST(EDIDParserTest, ParseBitsPerChannel) { - const std::vector<uint8_t> edid_normal_display( - kNormalDisplay, kNormalDisplay + charsize(kNormalDisplay)); - int edid_normal_display_bits_per_channel = 0; - EXPECT_TRUE(ParseBitsPerChannel(edid_normal_display, - &edid_normal_display_bits_per_channel)); - EXPECT_EQ(10, edid_normal_display_bits_per_channel); - - const std::vector<uint8_t> edid_internal_display( - kInternalDisplay, kInternalDisplay + charsize(kInternalDisplay)); - int edid_internal_display_bits_per_channel = 0; - // |kInternalDisplay| doesn't have bits per channel information. - EXPECT_FALSE(ParseBitsPerChannel(edid_internal_display, - &edid_internal_display_bits_per_channel)); - - const std::vector<uint8_t> edid_hpz32x(kHPz32x, kHPz32x + charsize(kHPz32x)); - int edid_hpz32x_bits_per_channel = 0; - EXPECT_TRUE(ParseBitsPerChannel(edid_hpz32x, &edid_hpz32x_bits_per_channel)); - EXPECT_EQ(10, edid_hpz32x_bits_per_channel); - - const std::vector<uint8_t> edid_samus(kSamus, kSamus + charsize(kSamus)); - int edid_samus_bits_per_channel = 0; - EXPECT_TRUE(ParseBitsPerChannel(edid_samus, &edid_samus_bits_per_channel)); - EXPECT_EQ(8, edid_samus_bits_per_channel); - - const std::vector<uint8_t> edid_eve(kEve, kEve + charsize(kEve)); - int edid_eve_bits_per_channel = 0; - EXPECT_TRUE(ParseBitsPerChannel(edid_eve, &edid_eve_bits_per_channel)); - EXPECT_EQ(8, edid_eve_bits_per_channel); -} +INSTANTIATE_TEST_CASE_P(, EDIDParserTest, ValuesIn(kTestCases)); } // namespace display
diff --git a/ui/display/util/x11/edid_parser_x11.cc b/ui/display/util/x11/edid_parser_x11.cc index 06edcf8..57baee92 100644 --- a/ui/display/util/x11/edid_parser_x11.cc +++ b/ui/display/util/x11/edid_parser_x11.cc
@@ -73,33 +73,18 @@ } // namespace -EDIDParserX11::EDIDParserX11(XID output_id) - : output_id_(output_id) { +EDIDParserX11::EDIDParserX11(XID output_id) : output_id_(output_id) { GetEDIDProperty(output_id_, &edid_); } -EDIDParserX11::~EDIDParserX11() { -} +EDIDParserX11::~EDIDParserX11() {} bool EDIDParserX11::GetDisplayId(uint8_t index, int64_t* out_display_id) const { if (edid_.empty()) return false; - return GetDisplayIdFromEDID(edid_, index, out_display_id, nullptr); -} - -std::string EDIDParserX11::GetDisplayName() const { - std::string display_name; - ParseOutputDeviceData(edid_, nullptr, nullptr, &display_name, nullptr, - nullptr); - return display_name; -} - -bool EDIDParserX11::GetOutputOverscanFlag(bool* out_flag) const { - if (edid_.empty()) - return false; - - return ParseOutputOverscanFlag(edid_, out_flag); + *out_display_id = EdidParser(edid_).GetDisplayId(output_id_); + return true; } } // namespace display
diff --git a/ui/display/util/x11/edid_parser_x11.h b/ui/display/util/x11/edid_parser_x11.h index 0c49015..383d828 100644 --- a/ui/display/util/x11/edid_parser_x11.h +++ b/ui/display/util/x11/edid_parser_x11.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "ui/display/types/display_constants.h" #include "ui/display/util/display_util_export.h" +#include "ui/display/util/edid_parser.h" typedef unsigned long XID; typedef XID RROutput; @@ -31,22 +32,11 @@ // Returns true if successful, false otherwise. bool GetDisplayId(uint8_t index, int64_t* out_display_id) const; - // Generate the human readable string from EDID obtained from |output|. - // Returns an empty string upon error. - std::string GetDisplayName() const; - - // Gets the overscan flag and stores to |out_flag|. Returns true if the flag - // is found. Otherwise returns false and doesn't touch |out_flag|. The output - // will produce overscan if |out_flag| is set to true, but the output may - // still produce overscan even though it returns true and |out_flag| is set to - // false. - bool GetOutputOverscanFlag(bool* out_flag) const; - XID output_id() const { return output_id_; } const std::vector<uint8_t>& edid() const { return edid_; } private: - XID output_id_; + const XID output_id_; // This will be an empty vector upon failure to get the EDID from the // |output_id_|.
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index 90ebc4ea..bdd3d79 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc
@@ -722,6 +722,7 @@ InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; scroll_sequence_ignored_ = false; + in_inertial_scrolling_ = false; switch (scroll_status.thread) { case cc::InputHandler::SCROLL_ON_IMPL_THREAD: TRACE_EVENT_INSTANT0("input", @@ -772,6 +773,7 @@ return DID_NOT_HANDLE; cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); + in_inertial_scrolling_ = scroll_state.is_in_inertial_phase(); gfx::PointF scroll_point(gesture_event.PositionInWidget()); if (ShouldAnimate(gesture_event.data.scroll_update.delta_units != @@ -1023,9 +1025,9 @@ result = DID_HANDLE_NON_BLOCKING; } - bool is_flinging_on_impl = - fling_curve_ && !fling_may_be_active_on_main_thread_; - if (is_flinging_on_impl && is_touching_scrolling_layer) + bool is_in_inertial_scrolling_on_impl = + in_inertial_scrolling_ && gesture_scroll_on_impl_thread_; + if (is_in_inertial_scrolling_on_impl && is_touching_scrolling_layer) result = DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING; client_->SetWhiteListedTouchAction(white_listed_touch_action,
diff --git a/ui/events/blink/input_handler_proxy.h b/ui/events/blink/input_handler_proxy.h index 8ade9f53..d11b68c 100644 --- a/ui/events/blink/input_handler_proxy.h +++ b/ui/events/blink/input_handler_proxy.h
@@ -223,6 +223,7 @@ #endif bool gesture_scroll_on_impl_thread_; bool gesture_pinch_on_impl_thread_; + bool in_inertial_scrolling_ = false; bool scroll_sequence_ignored_; // This is always false when there are no flings on the main thread, but // conservative in the sense that we might not be actually flinging when it is
diff --git a/ui/gfx/color_space_unittest.cc b/ui/gfx/color_space_unittest.cc index 96dd37d..c4a95578 100644 --- a/ui/gfx/color_space_unittest.cc +++ b/ui/gfx/color_space_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <cmath> +#include <tuple> #include "base/logging.h" #include "testing/gtest/include/gtest/gtest.h" @@ -80,13 +81,13 @@ } } -typedef std::tr1::tuple<ColorSpace::TransferID, size_t> TableTestData; +typedef std::tuple<ColorSpace::TransferID, size_t> TableTestData; class ColorSpaceTableTest : public testing::TestWithParam<TableTestData> {}; TEST_P(ColorSpaceTableTest, ApproximateTransferFn) { - ColorSpace::TransferID transfer_id = std::tr1::get<0>(GetParam()); - const size_t table_size = std::tr1::get<1>(GetParam()); + ColorSpace::TransferID transfer_id = std::get<0>(GetParam()); + const size_t table_size = std::get<1>(GetParam()); gfx::ColorSpace color_space(ColorSpace::PrimaryID::BT709, transfer_id); SkColorSpaceTransferFn tr_fn;
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index c965b47d..aa5a3de 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <tuple> + #include "base/logging.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/color_space.h" @@ -586,21 +588,21 @@ ExtendedTransferTest, testing::ValuesIn(extended_transfers)); -typedef std::tr1::tuple<ColorSpace::PrimaryID, - ColorSpace::TransferID, - ColorSpace::MatrixID, - ColorSpace::RangeID, - ColorTransform::Intent> +typedef std::tuple<ColorSpace::PrimaryID, + ColorSpace::TransferID, + ColorSpace::MatrixID, + ColorSpace::RangeID, + ColorTransform::Intent> ColorSpaceTestData; class ColorSpaceTest : public testing::TestWithParam<ColorSpaceTestData> { public: ColorSpaceTest() - : color_space_(std::tr1::get<0>(GetParam()), - std::tr1::get<1>(GetParam()), - std::tr1::get<2>(GetParam()), - std::tr1::get<3>(GetParam())), - intent_(std::tr1::get<4>(GetParam())) {} + : color_space_(std::get<0>(GetParam()), + std::get<1>(GetParam()), + std::get<2>(GetParam()), + std::get<3>(GetParam())), + intent_(std::get<4>(GetParam())) {} protected: ColorSpace color_space_;
diff --git a/ui/gl/gl_surface_osmesa_x11.cc b/ui/gl/gl_surface_osmesa_x11.cc index e34c27b0..15b2bfd 100644 --- a/ui/gl/gl_surface_osmesa_x11.cc +++ b/ui/gl/gl_surface_osmesa_x11.cc
@@ -159,8 +159,6 @@ int width, int height, const PresentationCallback& callback) { - // TODO(penghuang): Provide useful presentation feedback. - // https://crbug.com/776877 gfx::Size size = GetSize(); // Move (0,0) from lower-left to upper-left @@ -182,9 +180,20 @@ XCopyArea(xdisplay_, pixmap_, window_, window_graphics_context_, x, y, width, height, x, y); + constexpr int64_t kRefreshIntervalInMicroseconds = + base::Time::kMicrosecondsPerSecond / 60; + callback.Run(gfx::PresentationFeedback( + base::TimeTicks::Now(), + base::TimeDelta::FromMicroseconds(kRefreshIntervalInMicroseconds), + 0 /* flags */)); + return gfx::SwapResult::SWAP_ACK; } +bool GLSurfaceOSMesaX11::SupportsPresentationCallback() { + return true; +} + GLSurfaceOSMesaX11::~GLSurfaceOSMesaX11() { Destroy(); }
diff --git a/ui/gl/gl_surface_osmesa_x11.h b/ui/gl/gl_surface_osmesa_x11.h index 01cdad2..415e4c91 100644 --- a/ui/gl/gl_surface_osmesa_x11.h +++ b/ui/gl/gl_surface_osmesa_x11.h
@@ -37,6 +37,7 @@ int width, int height, const PresentationCallback& callback) override; + bool SupportsPresentationCallback() override; protected: ~GLSurfaceOSMesaX11() override;
diff --git a/ui/gl/gl_switches_util.cc b/ui/gl/gl_switches_util.cc index d0bf625..4c99c44 100644 --- a/ui/gl/gl_switches_util.cc +++ b/ui/gl/gl_switches_util.cc
@@ -13,7 +13,7 @@ bool IsPresentationCallbackEnabled() { // TODO(peng): always enable once 776877 is fixed. -#if defined(OS_CHROMEOS) +#if defined(OS_CHROMEOS) || defined(OS_LINUX) return true; #else return base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/ui/native_theme/native_theme_mac.mm b/ui/native_theme/native_theme_mac.mm index ea848f8..84a2cd1 100644 --- a/ui/native_theme/native_theme_mac.mm +++ b/ui/native_theme/native_theme_mac.mm
@@ -24,20 +24,10 @@ namespace { -// Values calculated by reading pixels and solving simultaneous equations -// derived from "A over B" alpha compositing. Steps: Sample the semi-transparent -// pixel over two backgrounds; P1, P2 over backgrounds B1, B2. Use the color -// value between 0.0 and 1.0 (i.e. divide by 255.0). Then, -// alpha = (P2 - P1 + B1 - B2) / (B1 - B2) -// color = (P1 - B1 + alpha * B1) / alpha. -const SkColor kMenuPopupBackgroundColor = SkColorSetARGB(245, 255, 255, 255); -const SkColor kMenuSeparatorColor = SkColorSetARGB(255, 217, 217, 217); +const SkColor kMenuPopupBackgroundColor = SK_ColorWHITE; +const SkColor kMenuSeparatorColor = SkColorSetA(SK_ColorBLACK, 38); const SkColor kMenuBorderColor = SkColorSetARGB(60, 0, 0, 0); -const SkColor kMenuPopupBackgroundColorMavericks = - SkColorSetARGB(255, 255, 255, 255); -const SkColor kMenuSeparatorColorMavericks = SkColorSetARGB(243, 228, 228, 228); - // Hardcoded color used for some existing dialogs in Chrome's Cocoa UI. const SkColor kDialogBackgroundColor = SkColorSetRGB(251, 251, 251); @@ -139,15 +129,22 @@ case kColorId_DisabledMenuItemForegroundColor: return NSSystemColorToSkColor([NSColor disabledControlTextColor]); case kColorId_SelectedMenuItemForegroundColor: - return NSSystemColorToSkColor([NSColor selectedMenuItemTextColor]); + return SK_ColorBLACK; case kColorId_FocusedMenuItemBackgroundColor: - return ApplySystemControlTint( - NSSystemColorToSkColor([NSColor selectedMenuItemColor])); + // It's necessary to use a different alpha for Aqua mode vs Graphite mode, + // because the black used as the graphite base shows up well even at low + // alphas, but the blue used for Aqua needs a bit more alpha to show up + // properly. At the same alpha as the graphite uses, it's difficult to + // pick out clearly and looks somewhat like faint lilac instead of blue. + return ([NSColor currentControlTint] == NSGraphiteControlTint) + ? SkColorSetA(SK_ColorBLACK, 21) + : SkColorSetA( + NSSystemColorToSkColor([NSColor selectedMenuItemColor]), + 45); case kColorId_MenuBackgroundColor: return kMenuPopupBackgroundColor; case kColorId_MenuSeparatorColor: - return base::mac::IsOS10_9() ? kMenuSeparatorColorMavericks - : kMenuSeparatorColor; + return kMenuSeparatorColor; case kColorId_MenuBorderColor: return kMenuBorderColor; @@ -256,10 +253,7 @@ const MenuBackgroundExtraParams& menu_background) const { cc::PaintFlags flags; flags.setAntiAlias(true); - if (base::mac::IsOS10_9()) - flags.setColor(kMenuPopupBackgroundColorMavericks); - else - flags.setColor(kMenuPopupBackgroundColor); + flags.setColor(kMenuPopupBackgroundColor); const SkScalar radius = SkIntToScalar(menu_background.corner_radius); SkRect rect = gfx::RectToSkRect(gfx::Rect(size)); canvas->drawRoundRect(rect, radius, radius, flags);
diff --git a/ui/ozone/platform/cast/overlay_manager_cast.cc b/ui/ozone/platform/cast/overlay_manager_cast.cc index 9ce4f0a..6a34f69 100644 --- a/ui/ozone/platform/cast/overlay_manager_cast.cc +++ b/ui/ozone/platform/cast/overlay_manager_cast.cc
@@ -4,72 +4,18 @@ #include "ui/ozone/platform/cast/overlay_manager_cast.h" -#include "base/lazy_instance.h" -#include "base/memory/ptr_util.h" -#include "ui/gfx/geometry/rect_conversions.h" #include "ui/ozone/public/overlay_candidates_ozone.h" namespace ui { namespace { -base::LazyInstance<OverlayManagerCast::OverlayCompositedCallback>:: - DestructorAtExit g_overlay_composited_callback = LAZY_INSTANCE_INITIALIZER; - -// Translates a gfx::OverlayTransform into a VideoPlane::Transform. -// Could be just a lookup table once we have unit tests for this code -// to ensure it stays in sync with OverlayTransform. -chromecast::media::VideoPlane::Transform ConvertTransform( - gfx::OverlayTransform transform) { - switch (transform) { - case gfx::OVERLAY_TRANSFORM_NONE: - return chromecast::media::VideoPlane::TRANSFORM_NONE; - case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: - return chromecast::media::VideoPlane::FLIP_HORIZONTAL; - case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL: - return chromecast::media::VideoPlane::FLIP_VERTICAL; - case gfx::OVERLAY_TRANSFORM_ROTATE_90: - return chromecast::media::VideoPlane::ROTATE_90; - case gfx::OVERLAY_TRANSFORM_ROTATE_180: - return chromecast::media::VideoPlane::ROTATE_180; - case gfx::OVERLAY_TRANSFORM_ROTATE_270: - return chromecast::media::VideoPlane::ROTATE_270; - default: - NOTREACHED(); - return chromecast::media::VideoPlane::TRANSFORM_NONE; - } -} - class OverlayCandidatesCast : public OverlayCandidatesOzone { public: OverlayCandidatesCast() {} - void CheckOverlaySupport(OverlaySurfaceCandidateList* surfaces) override; + void CheckOverlaySupport(OverlaySurfaceCandidateList* surfaces) override {} }; -void OverlayCandidatesCast::CheckOverlaySupport( - OverlaySurfaceCandidateList* surfaces) { - for (auto& candidate : *surfaces) { - if (candidate.plane_z_order != -1) - continue; - - candidate.overlay_handled = true; - - // Compositor requires all overlay rectangles to have integer coords. - candidate.display_rect = - gfx::RectF(gfx::ToEnclosedRect(candidate.display_rect)); - - chromecast::RectF display_rect( - candidate.display_rect.x(), candidate.display_rect.y(), - candidate.display_rect.width(), candidate.display_rect.height()); - - // Update video plane geometry + transform to match compositor quad. - if (!g_overlay_composited_callback.Get().is_null()) - g_overlay_composited_callback.Get().Run( - display_rect, ConvertTransform(candidate.transform)); - return; - } -} - } // namespace OverlayManagerCast::OverlayManagerCast() { @@ -83,10 +29,4 @@ return std::make_unique<OverlayCandidatesCast>(); } -// static -void OverlayManagerCast::SetOverlayCompositedCallback( - const OverlayCompositedCallback& cb) { - g_overlay_composited_callback.Get() = cb; -} - } // namespace ui
diff --git a/ui/ozone/platform/cast/overlay_manager_cast.h b/ui/ozone/platform/cast/overlay_manager_cast.h index 0ddf98d6..6d9963b 100644 --- a/ui/ozone/platform/cast/overlay_manager_cast.h +++ b/ui/ozone/platform/cast/overlay_manager_cast.h
@@ -7,16 +7,12 @@ #include <memory> -#include "base/callback.h" #include "base/macros.h" -#include "chromecast/public/graphics_types.h" -#include "chromecast/public/video_plane.h" -#include "ui/ozone/ozone_export.h" #include "ui/ozone/public/overlay_manager_ozone.h" namespace ui { -class OZONE_EXPORT OverlayManagerCast : public OverlayManagerOzone { +class OverlayManagerCast : public OverlayManagerOzone { public: OverlayManagerCast(); ~OverlayManagerCast() override; @@ -25,16 +21,7 @@ std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates( gfx::AcceleratedWidget w) override; - // Callback that's made whenever an overlay quad is processed - // in the compositor. Used to allow hardware video plane to - // be positioned to match compositor hole. - using OverlayCompositedCallback = - base::Callback<void(const chromecast::RectF&, - chromecast::media::VideoPlane::Transform)>; - static void SetOverlayCompositedCallback(const OverlayCompositedCallback& cb); - private: - DISALLOW_COPY_AND_ASSIGN(OverlayManagerCast); };
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc index 91463ae..91147f0 100644 --- a/ui/ozone/platform/drm/common/drm_util.cc +++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -382,7 +382,7 @@ const base::FilePath& sys_path, size_t device_index, const gfx::Point& origin) { - int64_t display_id = ConnectorIndex(device_index, info->index()); + const uint8_t display_index = ConnectorIndex(device_index, info->index()); const gfx::Size physical_size = gfx::Size(info->connector()->mmWidth, info->connector()->mmHeight); const display::DisplayConnectionType type = GetDisplayType(info->connector()); @@ -392,33 +392,31 @@ HasColorCorrectionMatrix(fd, info->crtc()); const gfx::Size maximum_cursor_size = GetMaximumCursorSize(fd); - std::vector<uint8_t> edid; std::string display_name; + int64_t display_id = -1; int64_t product_code = display::DisplaySnapshot::kInvalidProductCode; int32_t year_of_manufacture = display::kInvalidYearOfManufacture; bool has_overscan = false; gfx::ColorSpace display_color_space; - - // This is the size of the active pixels from the first detailed timing - // descriptor in the EDID. + // Active pixels size from the first detailed timing descriptor in the EDID. gfx::Size active_pixel_size; ScopedDrmPropertyBlobPtr edid_blob( GetDrmPropertyBlob(fd, info->connector(), "EDID")); + std::vector<uint8_t> edid; if (edid_blob) { edid.assign(static_cast<uint8_t*>(edid_blob->data), static_cast<uint8_t*>(edid_blob->data) + edid_blob->length); - // TODO(mcasas): GetDisplayIdFromEDID() calls ParseOutputDeviceData(), clean - // up the code and add UMA for EDID errors, https://crbug.com/821393. Also - // handle correctly the parsing failures of the following functions. - display::GetDisplayIdFromEDID(edid, display_id, &display_id, &product_code); - display::ParseOutputDeviceData(edid, nullptr, nullptr, &display_name, - &active_pixel_size, nullptr); - display::ParseYearOfManufacture(edid, &year_of_manufacture); - display::ParseOutputOverscanFlag(edid, &has_overscan); - - display_color_space = GetColorSpaceFromEdid(edid); + display::EdidParser edid_parser(edid); + display_name = edid_parser.display_name(); + active_pixel_size = edid_parser.active_pixel_size(); + product_code = edid_parser.GetProductCode(); + display_id = edid_parser.GetDisplayId(display_index); + year_of_manufacture = edid_parser.year_of_manufacture(); + has_overscan = + edid_parser.has_overscan_flag() && edid_parser.overscan_flag(); + display_color_space = GetColorSpaceFromEdid(edid_parser); } else { VLOG(1) << "Failed to get EDID blob for connector " << info->connector()->connector_id; @@ -638,10 +636,8 @@ return params; } -gfx::ColorSpace GetColorSpaceFromEdid(const std::vector<uint8_t>& edid) { - SkColorSpacePrimaries primaries = {0}; - if (!display::ParseChromaticityCoordinates(edid, &primaries)) - return gfx::ColorSpace(); +gfx::ColorSpace GetColorSpaceFromEdid(const display::EdidParser& edid_parser) { + const SkColorSpacePrimaries primaries = edid_parser.primaries(); // Sanity check: primaries should verify By <= Ry <= Gy, Bx <= Rx and Gx <= // Rx, to guarantee that the R, G and B colors are each in the correct region. @@ -677,8 +673,8 @@ if (!primaries.toXYZD50(&color_space_as_matrix)) return gfx::ColorSpace(); - double gamma = 0.0; - if (!display::ParseGammaValue(edid, &gamma)) + const double gamma = edid_parser.gamma(); + if (gamma < 1.0) return gfx::ColorSpace(); SkColorSpaceTransferFn transfer = {gamma, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f};
diff --git a/ui/ozone/platform/drm/common/drm_util.h b/ui/ozone/platform/drm/common/drm_util.h index 9a058a7..6677fe1 100644 --- a/ui/ozone/platform/drm/common/drm_util.h +++ b/ui/ozone/platform/drm/common/drm_util.h
@@ -21,6 +21,7 @@ namespace display { class DisplayMode; +class EdidParser; } // namespace display namespace gfx { @@ -119,9 +120,9 @@ std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList( const OverlayStatusList& returns); -// Parses |edid| to extract a gfx::ColorSpace which will be IsValid() if both -// gamma and the color primaries were correctly found. -gfx::ColorSpace GetColorSpaceFromEdid(const std::vector<uint8_t>& edid); +// Uses |edid_parser| to extract a gfx::ColorSpace which will be IsValid() if +// both gamma and the color primaries were correctly found. +gfx::ColorSpace GetColorSpaceFromEdid(const display::EdidParser& edid_parser); } // namespace ui
diff --git a/ui/ozone/platform/drm/common/drm_util_unittest.cc b/ui/ozone/platform/drm/common/drm_util_unittest.cc index 6546416..ec4227e1 100644 --- a/ui/ozone/platform/drm/common/drm_util_unittest.cc +++ b/ui/ozone/platform/drm/common/drm_util_unittest.cc
@@ -11,6 +11,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/types/display_snapshot.h" +#include "ui/display/util/edid_parser.h" #include "ui/gfx/geometry/size.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" @@ -314,8 +315,8 @@ hpz32x_toXYZ50_matrix.setRowMajord(hpz32x_toXYZ50_coeffs); const gfx::ColorSpace hpz32x_color_space = gfx::ColorSpace::CreateCustom( hpz32x_toXYZ50_matrix, SkColorSpaceTransferFn({2.2, 1, 0, 0, 0, 0, 0})); - EXPECT_STREQ(hpz32x_color_space.ToString().c_str(), - GetColorSpaceFromEdid(hpz32x_edid).ToString().c_str()); + EXPECT_EQ(hpz32x_color_space.ToString(), + GetColorSpaceFromEdid(display::EdidParser(hpz32x_edid)).ToString()); const std::vector<uint8_t> samus_edid(kSamus, kSamus + arraysize(kSamus) - 1); const double samus_toXYZ50_coeffs[] = {0.41211, 0.39743, 0.15468, 0., @@ -325,8 +326,8 @@ samus_toXYZ50_matrix.setRowMajord(samus_toXYZ50_coeffs); const gfx::ColorSpace samus_color_space = gfx::ColorSpace::CreateCustom( samus_toXYZ50_matrix, SkColorSpaceTransferFn({2.5, 1, 0, 0, 0, 0, 0})); - EXPECT_STREQ(samus_color_space.ToString().c_str(), - GetColorSpaceFromEdid(samus_edid).ToString().c_str()); + EXPECT_EQ(samus_color_space.ToString(), + GetColorSpaceFromEdid(display::EdidParser(samus_edid)).ToString()); const std::vector<uint8_t> eve_edid(kEve, kEve + arraysize(kEve) - 1); const double eve_toXYZ50_coeffs[] = {0.444601, 0.377972, 0.141646, 0., @@ -336,35 +337,37 @@ eve_toXYZ50_matrix.setRowMajord(eve_toXYZ50_coeffs); const gfx::ColorSpace eve_color_space = gfx::ColorSpace::CreateCustom( eve_toXYZ50_matrix, SkColorSpaceTransferFn({2.2, 1, 0, 0, 0, 0, 0})); - EXPECT_STREQ(eve_color_space.ToString().c_str(), - GetColorSpaceFromEdid(eve_edid).ToString().c_str()); + EXPECT_EQ(eve_color_space.ToString(), + GetColorSpaceFromEdid(display::EdidParser(eve_edid)).ToString()); const std::vector<uint8_t> no_gamma_edid( kEdidWithNoGamma, kEdidWithNoGamma + arraysize(kEdidWithNoGamma) - 1); const gfx::ColorSpace no_gamma_color_space = - GetColorSpaceFromEdid(no_gamma_edid); + GetColorSpaceFromEdid(display::EdidParser(no_gamma_edid)); EXPECT_FALSE(no_gamma_color_space.IsValid()); } TEST_F(DrmUtilTest, GetInvalidColorSpaceFromEdid) { const std::vector<uint8_t> empty_edid; - EXPECT_EQ(gfx::ColorSpace(), GetColorSpaceFromEdid(empty_edid)); + EXPECT_EQ(gfx::ColorSpace(), + GetColorSpaceFromEdid(display::EdidParser(empty_edid))); const std::vector<uint8_t> invalid_edid( kInvalidEdid, kInvalidEdid + arraysize(kInvalidEdid) - 1); const gfx::ColorSpace invalid_color_space = - GetColorSpaceFromEdid(invalid_edid); + GetColorSpaceFromEdid(display::EdidParser(invalid_edid)); EXPECT_FALSE(invalid_color_space.IsValid()); const std::vector<uint8_t> sst210_edid(kSST210, kSST210 + arraysize(kSST210) - 1); - const gfx::ColorSpace sst210_color_space = GetColorSpaceFromEdid(sst210_edid); + const gfx::ColorSpace sst210_color_space = + GetColorSpaceFromEdid(display::EdidParser(sst210_edid)); EXPECT_FALSE(sst210_color_space.IsValid()) << sst210_color_space.ToString(); const std::vector<uint8_t> sst210_edid_2( kSST210Corrected, kSST210Corrected + arraysize(kSST210Corrected) - 1); const gfx::ColorSpace sst210_color_space_2 = - GetColorSpaceFromEdid(sst210_edid_2); + GetColorSpaceFromEdid(display::EdidParser(sst210_edid_2)); EXPECT_FALSE(sst210_color_space_2.IsValid()) << sst210_color_space_2.ToString(); @@ -372,7 +375,7 @@ kBrokenBluePrimaries, kBrokenBluePrimaries + arraysize(kBrokenBluePrimaries) - 1); const gfx::ColorSpace broken_blue_color_space = - GetColorSpaceFromEdid(broken_blue_edid); + GetColorSpaceFromEdid(display::EdidParser(broken_blue_edid)); EXPECT_FALSE(broken_blue_color_space.IsValid()) << broken_blue_color_space.ToString(); }
diff --git a/ui/strings/translations/ui_strings_en-GB.xtb b/ui/strings/translations/ui_strings_en-GB.xtb index 2d3ca49..8074cf7 100644 --- a/ui/strings/translations/ui_strings_en-GB.xtb +++ b/ui/strings/translations/ui_strings_en-GB.xtb
@@ -137,6 +137,7 @@ <translation id="7389409599945284130"><ph name="MESSAGE" />..</translation> <translation id="7410957453383678442">{MINUTES,plural, =1{1 minute left}other{# minutes left}}</translation> <translation id="7460907917090416791"><ph name="QUANTITY" /> TB</translation> +<translation id="7507604095951736240">Emoji</translation> <translation id="7658239707568436148">Cancel</translation> <translation id="7781829728241885113">Yesterday</translation> <translation id="7814458197256864873">&Copy</translation>
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index e79636e..050cfa5 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -126,9 +126,6 @@ using NSViewComparatorValue = __kindof NSView*; #endif -const CGFloat kYosemiteMenuOpacity = 245.0 / 255.0; -const int kYosemiteMenuBlur = 80; - // Margin at edge and corners of the window that trigger resizing. These match // actual Cocoa resize margins. const int kResizeAreaEdgeSize = 3; @@ -1455,18 +1452,6 @@ [background_layer setAutoresizingMask:kCALayerWidthSizable | kCALayerHeightSizable]; - if (widget_type_ == Widget::InitParams::TYPE_MENU) { - // Giving the canvas opacity messes up subpixel font rendering, so use a - // solid background, but make the CALayer transparent. - [background_layer setOpacity:kYosemiteMenuOpacity]; - CGSSetWindowBackgroundBlurRadius(_CGSDefaultConnection(), - [window_ windowNumber], kYosemiteMenuBlur); - // The blur effect does not occur with a fully transparent (or fully - // layer-backed) window. Setting a window background will use square - // corners, so ask the contentView to draw one instead. - [bridged_view_ setDrawMenuBackgroundForBlur:YES]; - } - // Set the layer first to create a layer-hosting view (not layer-backed). [compositor_superview_ setLayer:background_layer]; [compositor_superview_ setWantsLayer:YES];
diff --git a/ui/views/controls/menu/menu_config.cc b/ui/views/controls/menu/menu_config.cc index 529ced3..dc924136 100644 --- a/ui/views/controls/menu/menu_config.cc +++ b/ui/views/controls/menu/menu_config.cc
@@ -7,7 +7,6 @@ #include "base/macros.h" #include "ui/views/controls/menu/menu_image_util.h" #include "ui/views/round_rect_painter.h" - namespace views { MenuConfig::MenuConfig() @@ -19,6 +18,8 @@ item_bottom_margin(3), item_no_icon_top_margin(4), item_no_icon_bottom_margin(4), + fixed_text_item_height(0), + fixed_menu_width(0), item_left_margin(10), touchable_item_left_margin(16), label_to_arrow_padding(10),
diff --git a/ui/views/controls/menu/menu_config.h b/ui/views/controls/menu/menu_config.h index f5faf35e..5b9f17e3 100644 --- a/ui/views/controls/menu/menu_config.h +++ b/ui/views/controls/menu/menu_config.h
@@ -44,6 +44,13 @@ int item_no_icon_top_margin; int item_no_icon_bottom_margin; + // Fixed dimensions used for entire items. If these are nonzero, they override + // the vertical margin constants given above - the item's text and icon are + // vertically centered within these heights. + int fixed_text_item_height; + int fixed_container_item_height; + int fixed_menu_width; + // Margins between the left of the item and the icon. int item_left_margin;
diff --git a/ui/views/controls/menu/menu_config_mac.mm b/ui/views/controls/menu/menu_config_mac.mm index e941661..e950582 100644 --- a/ui/views/controls/menu/menu_config_mac.mm +++ b/ui/views/controls/menu/menu_config_mac.mm
@@ -7,29 +7,44 @@ #import <AppKit/AppKit.h> #include "base/mac/mac_util.h" +#include "ui/base/material_design/material_design_controller.h" + +namespace { + +void InitMaterialMenuConfig(views::MenuConfig* config) { + // These config parameters are from https://crbug.com/829347 and the spec + // images linked from that bug. + config->menu_vertical_border_size = 8; + config->menu_horizontal_border_size = 0; + config->submenu_horizontal_inset = 0; + config->fixed_text_item_height = 32; + config->fixed_container_item_height = 48; + config->fixed_menu_width = 320; + config->item_left_margin = 8; + config->label_to_arrow_padding = 0; + config->arrow_to_edge_padding = 16; + config->icon_to_label_padding = 8; + config->check_width = 16; + config->check_height = 16; + config->arrow_width = 8; + config->separator_height = 17; + config->separator_thickness = 1; + config->label_to_minor_text_padding = 8; + config->align_arrow_and_shortcut = true; + config->use_outer_border = false; + config->icons_in_label = true; + config->corner_radius = 8; +} + +} // namespace namespace views { void MenuConfig::Init() { font_list = gfx::FontList(gfx::Font([NSFont menuFontOfSize:0.0])); - menu_vertical_border_size = 4; - menu_horizontal_border_size = 0; - item_top_margin = item_no_icon_top_margin = 1; - item_bottom_margin = item_no_icon_bottom_margin = 1; - item_left_margin = 2; - arrow_to_edge_padding = 13; - icon_to_label_padding = 4; - check_width = 19; - check_height = 11; - separator_height = 13; - separator_upper_height = 7; - separator_lower_height = 6; - separator_thickness = 2; - align_arrow_and_shortcut = true; - icons_in_label = true; check_selected_combobox_item = true; - corner_radius = 5; - use_outer_border = false; + if (ui::MaterialDesignController::IsSecondaryUiMaterial()) + InitMaterialMenuConfig(this); } } // namespace views
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index 7154724..6aed6735 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h
@@ -138,6 +138,7 @@ base::TimeTicks closing_event_time() const { return closing_event_time_; } void set_is_combobox(bool is_combobox) { is_combobox_ = is_combobox; } + bool is_combobox() const { return is_combobox_; } // Various events, forwarded from the submenu. //
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index d9a3c92..c2d4788 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -1033,6 +1033,25 @@ return dimensions; } + const gfx::FontList& font_list = GetFontList(); + base::string16 minor_text = GetMinorText(); + if (menu_config.fixed_text_item_height && + menu_config.fixed_container_item_height && menu_config.fixed_menu_width && + GetMenuController() && !GetMenuController()->is_combobox()) { + bool has_children = NonIconChildViewsCount() > 0; + dimensions.height = has_children ? menu_config.fixed_container_item_height + : menu_config.fixed_text_item_height; + dimensions.children_width = 0; + dimensions.minor_text_width = + minor_text.empty() ? 0 : gfx::GetStringWidth(minor_text, font_list); + int leave_for_minor = dimensions.minor_text_width + ? dimensions.minor_text_width + + menu_config.label_to_minor_text_padding + : 0; + dimensions.standard_width = menu_config.fixed_menu_width - leave_for_minor; + return dimensions; + } + dimensions.height = child_size.height(); // Adjust item content height if menu has both items with and without icons. // This way all menu items will have the same height. @@ -1046,9 +1065,6 @@ if (IsContainer()) return dimensions; - // Determine the length of the label text. - const gfx::FontList& font_list = GetFontList(); - // Get Icon margin overrides for this particular item. const MenuDelegate* delegate = GetDelegate(); if (delegate) { @@ -1062,6 +1078,7 @@ } int label_start = GetLabelStartForThisItem(); + // Determine the length of the label text. int string_width = gfx::GetStringWidth(title_, font_list); if (!subtitle_.empty()) { string_width = std::max(string_width, @@ -1071,7 +1088,6 @@ dimensions.standard_width = string_width + label_start + item_right_margin_; // Determine the length of the right-side text. - base::string16 minor_text = GetMinorText(); dimensions.minor_text_width = minor_text.empty() ? 0 : gfx::GetStringWidth(minor_text, font_list);
diff --git a/ui/views/controls/menu/menu_runner_impl_cocoa.mm b/ui/views/controls/menu/menu_runner_impl_cocoa.mm index 274559a..6ea12cc 100644 --- a/ui/views/controls/menu/menu_runner_impl_cocoa.mm +++ b/ui/views/controls/menu/menu_runner_impl_cocoa.mm
@@ -20,10 +20,6 @@ namespace internal { namespace { -// The menu run types that should show a native NSMenu rather than a toolkit- -// views menu. Only supported when the menu is backed by a ui::MenuModel. -const int kNativeRunTypes = MenuRunner::CONTEXT_MENU | MenuRunner::COMBOBOX; - const CGFloat kNativeCheckmarkWidth = 18; const CGFloat kNativeMenuItemHeight = 18; @@ -118,11 +114,6 @@ ui::MenuModel* menu_model, int32_t run_types, const base::Closure& on_menu_closed_callback) { - if ((run_types & kNativeRunTypes) != 0 && - (run_types & MenuRunner::IS_NESTED) == 0) { - return new MenuRunnerImplCocoa(menu_model, on_menu_closed_callback); - } - return new MenuRunnerImplAdapter(menu_model, on_menu_closed_callback); } @@ -159,7 +150,6 @@ const gfx::Rect& bounds, MenuAnchorPosition anchor, int32_t run_types) { - DCHECK(run_types & kNativeRunTypes); DCHECK(!IsRunning()); DCHECK(parent); closing_event_time_ = base::TimeTicks();
diff --git a/ui/views/controls/progress_bar_unittest.cc b/ui/views/controls/progress_bar_unittest.cc index 6eddafe..09bb6d8 100644 --- a/ui/views/controls/progress_bar_unittest.cc +++ b/ui/views/controls/progress_bar_unittest.cc
@@ -9,10 +9,13 @@ #include "ui/accessibility/ax_node_data.h" #include "ui/gfx/color_utils.h" #include "ui/native_theme/native_theme.h" +#include "ui/views/test/views_test_base.h" namespace views { -TEST(ProgressBarTest, Accessibility) { +using ProgressBarTest = ViewsTestBase; + +TEST_F(ProgressBarTest, Accessibility) { ProgressBar bar; bar.SetValue(0.62); @@ -26,7 +29,7 @@ } // Test that default colors can be overridden. Used by Chromecast. -TEST(ProgressBarTest, OverrideDefaultColors) { +TEST_F(ProgressBarTest, OverrideDefaultColors) { ProgressBar bar; EXPECT_NE(SK_ColorRED, bar.GetForegroundColor()); EXPECT_NE(SK_ColorGREEN, bar.GetBackgroundColor());
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc index d57fbb05..16ec528c8 100644 --- a/ui/views/controls/scroll_view_unittest.cc +++ b/ui/views/controls/scroll_view_unittest.cc
@@ -134,12 +134,12 @@ DISALLOW_COPY_AND_ASSIGN(CustomView); }; -void CheckScrollbarVisibility(const ScrollView& scroll_view, +void CheckScrollbarVisibility(const ScrollView* scroll_view, ScrollBarOrientation orientation, bool should_be_visible) { const ScrollBar* scrollbar = orientation == HORIZONTAL - ? scroll_view.horizontal_scroll_bar() - : scroll_view.vertical_scroll_bar(); + ? scroll_view->horizontal_scroll_bar() + : scroll_view->vertical_scroll_bar(); if (should_be_visible) { ASSERT_TRUE(scrollbar); EXPECT_TRUE(scrollbar->visible()); @@ -179,11 +179,16 @@ public: ScrollViewTest() {} + void SetUp() override { + ViewsTestBase::SetUp(); + scroll_view_ = std::make_unique<ScrollView>(); + } + View* InstallContents() { const gfx::Rect default_outer_bounds(0, 0, 100, 100); View* contents = new View; - scroll_view_.SetContents(contents); - scroll_view_.SetBoundsRect(default_outer_bounds); + scroll_view_->SetContents(contents); + scroll_view_->SetBoundsRect(default_outer_bounds); return contents; } @@ -208,14 +213,14 @@ protected: #endif int VerticalScrollBarWidth() { - return scroll_view_.vertical_scroll_bar()->GetThickness(); + return scroll_view_->vertical_scroll_bar()->GetThickness(); } int HorizontalScrollBarHeight() { - return scroll_view_.horizontal_scroll_bar()->GetThickness(); + return scroll_view_->horizontal_scroll_bar()->GetThickness(); } - ScrollView scroll_view_; + std::unique_ptr<ScrollView> scroll_view_; private: DISALLOW_COPY_AND_ASSIGN(ScrollViewTest); @@ -332,7 +337,7 @@ // Verifies the viewport is sized to fit the available space. TEST_F(ScrollViewTest, ViewportSizedToFit) { View* contents = InstallContents(); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString()); } @@ -340,9 +345,9 @@ // bounded scroll view. TEST_F(ScrollViewTest, BoundedViewportSizedToFit) { View* contents = InstallContents(); - scroll_view_.ClipHeightTo(100, 200); - scroll_view_.SetBorder(CreateSolidBorder(2, 0)); - scroll_view_.Layout(); + scroll_view_->ClipHeightTo(100, 200); + scroll_view_->SetBorder(CreateSolidBorder(2, 0)); + scroll_view_->Layout(); EXPECT_EQ("2,2 96x96", contents->parent()->bounds().ToString()); // Make sure the width of |contents| is set properly not to overflow the @@ -355,11 +360,11 @@ TEST_F(ScrollViewTest, VerticalScrollbarDoesNotAppearUnnecessarily) { const gfx::Rect default_outer_bounds(0, 0, 100, 100); View* contents = new VerticalResizingView; - scroll_view_.SetContents(contents); - scroll_view_.SetBoundsRect(default_outer_bounds); - scroll_view_.Layout(); - EXPECT_FALSE(scroll_view_.vertical_scroll_bar()->visible()); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); + scroll_view_->SetContents(contents); + scroll_view_->SetBoundsRect(default_outer_bounds); + scroll_view_->Layout(); + EXPECT_FALSE(scroll_view_->vertical_scroll_bar()->visible()); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); } // Verifies the scrollbars are added as necessary. @@ -369,54 +374,54 @@ // Size the contents such that vertical scrollbar is needed. contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); - EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || - !scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); + EXPECT_TRUE(!scroll_view_->horizontal_scroll_bar() || + !scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); // Size the contents such that horizontal scrollbar is needed. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), contents->parent()->height()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, false); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Both horizontal and vertical. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), contents->parent()->height()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Add a border, test vertical scrollbar. const int kTopPadding = 1; const int kLeftPadding = 2; const int kBottomPadding = 3; const int kRightPadding = 4; - scroll_view_.SetBorder(CreateEmptyBorder(kTopPadding, kLeftPadding, - kBottomPadding, kRightPadding)); + scroll_view_->SetBorder(CreateEmptyBorder(kTopPadding, kLeftPadding, + kBottomPadding, kRightPadding)); contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth() - kLeftPadding - + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth() - kLeftPadding - kRightPadding, contents->parent()->width()); EXPECT_EQ(100 - kTopPadding - kBottomPadding, contents->parent()->height()); - EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || - !scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); - gfx::Rect bounds = scroll_view_.vertical_scroll_bar()->bounds(); + EXPECT_TRUE(!scroll_view_->horizontal_scroll_bar() || + !scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); + gfx::Rect bounds = scroll_view_->vertical_scroll_bar()->bounds(); EXPECT_EQ(100 - VerticalScrollBarWidth() - kRightPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(kTopPadding, bounds.y()); @@ -424,16 +429,16 @@ // Horizontal with border. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100 - kLeftPadding - kRightPadding, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - kTopPadding - + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - kTopPadding - kBottomPadding, contents->parent()->height()); - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - EXPECT_TRUE(!scroll_view_.vertical_scroll_bar() || - !scroll_view_.vertical_scroll_bar()->visible()); - bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + EXPECT_TRUE(!scroll_view_->vertical_scroll_bar() || + !scroll_view_->vertical_scroll_bar()->visible()); + bounds = scroll_view_->horizontal_scroll_bar()->bounds(); EXPECT_EQ(kLeftPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.y()); @@ -441,26 +446,26 @@ // Both horizontal and vertical with border. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth() - kLeftPadding - + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth() - kLeftPadding - kRightPadding, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - kTopPadding - + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - kTopPadding - kBottomPadding, contents->parent()->height()); - bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + bounds = scroll_view_->horizontal_scroll_bar()->bounds(); // Check horiz. - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + bounds = scroll_view_->horizontal_scroll_bar()->bounds(); EXPECT_EQ(kLeftPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding - VerticalScrollBarWidth(), bounds.right()); EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.y()); EXPECT_EQ(100 - kBottomPadding, bounds.bottom()); // Check vert. - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); - bounds = scroll_view_.vertical_scroll_bar()->bounds(); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); + bounds = scroll_view_->vertical_scroll_bar()->bounds(); EXPECT_EQ(100 - VerticalScrollBarWidth() - kRightPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(kTopPadding, bounds.y()); @@ -471,11 +476,11 @@ // Assertions around adding a header. TEST_F(ScrollViewTest, Header) { CustomView* header = new CustomView; - scroll_view_.SetHeader(header); + scroll_view_->SetHeader(header); View* header_parent = header->parent(); View* contents = InstallContents(); - scroll_view_.Layout(); + scroll_view_->Layout(); // |header|s preferred size is empty, which should result in all space going // to contents. EXPECT_EQ("0,0 100x0", header->parent()->bounds().ToString()); @@ -502,7 +507,7 @@ EXPECT_EQ("0,0 0x0", contents->bounds().ToString()); // Remove the header. - scroll_view_.SetHeader(NULL); + scroll_view_->SetHeader(NULL); // SetHeader(NULL) deletes header. header = NULL; EXPECT_EQ("0,0 100x0", header_parent->bounds().ToString()); @@ -512,111 +517,111 @@ // Verifies the scrollbars are added as necessary when a header is present. TEST_F(ScrollViewTest, ScrollBarsWithHeader) { CustomView* header = new CustomView; - scroll_view_.SetHeader(header); + scroll_view_->SetHeader(header); View* contents = InstallContents(); header->SetPreferredSize(gfx::Size(10, 20)); // Size the contents such that vertical scrollbar is needed. contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); EXPECT_EQ(80, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); - EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || - !scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); + EXPECT_TRUE(!scroll_view_->horizontal_scroll_bar() || + !scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); // Make sure the vertical scrollbar overlaps the header for traditional // scrollbars and doesn't overlap the header for overlay scrollbars. const int expected_scrollbar_y = - scroll_view_.vertical_scroll_bar()->OverlapsContent() + scroll_view_->vertical_scroll_bar()->OverlapsContent() ? header->bounds().bottom() : header->y(); - EXPECT_EQ(expected_scrollbar_y, scroll_view_.vertical_scroll_bar()->y()); + EXPECT_EQ(expected_scrollbar_y, scroll_view_->vertical_scroll_bar()->y()); EXPECT_EQ(header->y(), contents->y()); // Size the contents such that horizontal scrollbar is needed. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); EXPECT_EQ(100, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - 20, + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - 20, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); EXPECT_EQ(100, header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - EXPECT_TRUE(!scroll_view_.vertical_scroll_bar() || - !scroll_view_.vertical_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + EXPECT_TRUE(!scroll_view_->vertical_scroll_bar() || + !scroll_view_->vertical_scroll_bar()->visible()); // Both horizontal and vertical. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - 20, + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - 20, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); } // Verifies the header scrolls horizontally with the content. TEST_F(ScrollViewTest, HeaderScrollsWithContent) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 500)); CustomView* header = new CustomView; - scroll_view_.SetHeader(header); + scroll_view_->SetHeader(header); header->SetPreferredSize(gfx::Size(500, 20)); - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 100)); EXPECT_EQ("0,0", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("0,0", header->origin().ToString()); // Scroll the horizontal scrollbar. - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar()); - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 1); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar()); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 1); EXPECT_EQ("-1,0", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("-1,0", header->origin().ToString()); // Scrolling the vertical scrollbar shouldn't effect the header. - ASSERT_TRUE(scroll_view_.vertical_scroll_bar()); - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 1); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar()); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 1); EXPECT_EQ("-1,-1", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("-1,0", header->origin().ToString()); } // Verifies ScrollRectToVisible() on the child works. TEST_F(ScrollViewTest, ScrollRectToVisible) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 1000)); - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); - scroll_view_.Layout(); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view_->Layout(); EXPECT_EQ("0,0", test_api.IntegralViewOffset().ToString()); // Scroll to y=405 height=10, this should make the y position of the content @@ -625,7 +630,7 @@ const int viewport_height = test_api.contents_viewport()->height(); // Expect there to be a horizontal scrollbar, making the viewport shorter. - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), viewport_height); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height); gfx::ScrollOffset offset = test_api.CurrentOffset(); EXPECT_EQ(415 - viewport_height, offset.y()); @@ -637,17 +642,17 @@ // Verifies that child scrolls into view when it's focused. TEST_F(ScrollViewTest, ScrollChildToVisibleOnFocus) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 1000)); FixedView* child = new FixedView; child->SetPreferredSize(gfx::Size(10, 10)); child->SetPosition(gfx::Point(0, 405)); contents->AddChildView(child); - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); - scroll_view_.Layout(); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view_->Layout(); EXPECT_EQ(gfx::Point(), test_api.IntegralViewOffset()); // Set focus to the child control. This should cause the control to scroll to @@ -657,7 +662,7 @@ const int viewport_height = test_api.contents_viewport()->height(); // Expect there to be a horizontal scrollbar, making the viewport shorter. - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), viewport_height); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height); gfx::ScrollOffset offset = test_api.CurrentOffset(); EXPECT_EQ(415 - viewport_height, offset.y()); @@ -666,138 +671,138 @@ // Verifies ClipHeightTo() uses the height of the content when it is between the // minimum and maximum height values. TEST_F(ScrollViewTest, ClipHeightToNormalContentHeight) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); const int kNormalContentHeight = 75; - scroll_view_.SetContents( + scroll_view_->SetContents( new views::StaticSizedView(gfx::Size(kWidth, kNormalContentHeight))); EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), - scroll_view_.GetPreferredSize()); + scroll_view_->GetPreferredSize()); - scroll_view_.SizeToPreferredSize(); - scroll_view_.Layout(); + scroll_view_->SizeToPreferredSize(); + scroll_view_->Layout(); EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), - scroll_view_.contents()->size()); - EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), scroll_view_.size()); + scroll_view_->contents()->size()); + EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), scroll_view_->size()); } // Verifies ClipHeightTo() uses the minimum height when the content is shorter // than the minimum height value. TEST_F(ScrollViewTest, ClipHeightToShortContentHeight) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); const int kShortContentHeight = 10; View* contents = new views::StaticSizedView(gfx::Size(kWidth, kShortContentHeight)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); - EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_.GetPreferredSize()); + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_->GetPreferredSize()); - scroll_view_.SizeToPreferredSize(); - scroll_view_.Layout(); + scroll_view_->SizeToPreferredSize(); + scroll_view_->Layout(); // Layered scrolling requires the contents to fill the viewport. if (contents->layer()) { - EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_.contents()->size()); + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_->contents()->size()); } else { EXPECT_EQ(gfx::Size(kWidth, kShortContentHeight), - scroll_view_.contents()->size()); + scroll_view_->contents()->size()); } - EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_.size()); + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_->size()); } // Verifies ClipHeightTo() uses the maximum height when the content is longer // thamn the maximum height value. TEST_F(ScrollViewTest, ClipHeightToTallContentHeight) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); const int kTallContentHeight = 1000; - scroll_view_.SetContents( + scroll_view_->SetContents( new views::StaticSizedView(gfx::Size(kWidth, kTallContentHeight))); - EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.GetPreferredSize()); + EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_->GetPreferredSize()); - scroll_view_.SizeToPreferredSize(); - scroll_view_.Layout(); + scroll_view_->SizeToPreferredSize(); + scroll_view_->Layout(); // The width may be less than kWidth if the scroll bar takes up some width. - EXPECT_GE(kWidth, scroll_view_.contents()->width()); - EXPECT_EQ(kTallContentHeight, scroll_view_.contents()->height()); - EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.size()); + EXPECT_GE(kWidth, scroll_view_->contents()->width()); + EXPECT_EQ(kTallContentHeight, scroll_view_->contents()->height()); + EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_->size()); } // Verifies that when ClipHeightTo() produces a scrollbar, it reduces the width // of the inner content of the ScrollView. TEST_F(ScrollViewTest, ClipHeightToScrollbarUsesWidth) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); // Create a view that will be much taller than it is wide. - scroll_view_.SetContents(new views::ProportionallySizedView(1000)); + scroll_view_->SetContents(new views::ProportionallySizedView(1000)); // Without any width, it will default to 0,0 but be overridden by min height. - scroll_view_.SizeToPreferredSize(); - EXPECT_EQ(gfx::Size(0, kMinHeight), scroll_view_.GetPreferredSize()); + scroll_view_->SizeToPreferredSize(); + EXPECT_EQ(gfx::Size(0, kMinHeight), scroll_view_->GetPreferredSize()); - gfx::Size new_size(kWidth, scroll_view_.GetHeightForWidth(kWidth)); - scroll_view_.SetSize(new_size); - scroll_view_.Layout(); + gfx::Size new_size(kWidth, scroll_view_->GetHeightForWidth(kWidth)); + scroll_view_->SetSize(new_size); + scroll_view_->Layout(); - int expected_width = kWidth - scroll_view_.GetScrollBarLayoutWidth(); - EXPECT_EQ(scroll_view_.contents()->size().width(), expected_width); - EXPECT_EQ(scroll_view_.contents()->size().height(), 1000 * expected_width); - EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.size()); + int expected_width = kWidth - scroll_view_->GetScrollBarLayoutWidth(); + EXPECT_EQ(scroll_view_->contents()->size().width(), expected_width); + EXPECT_EQ(scroll_view_->contents()->size().height(), 1000 * expected_width); + EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_->size()); } TEST_F(ScrollViewTest, CornerViewVisibility) { View* contents = InstallContents(); - View* corner_view = ScrollViewTestApi(&scroll_view_).corner_view(); + View* corner_view = ScrollViewTestApi(scroll_view_.get()).corner_view(); contents->SetBounds(0, 0, 200, 200); - scroll_view_.Layout(); + scroll_view_->Layout(); // Corner view should not exist if using overlay scrollbars. - if (scroll_view_.vertical_scroll_bar()->OverlapsContent()) { + if (scroll_view_->vertical_scroll_bar()->OverlapsContent()) { EXPECT_FALSE(corner_view->parent()); return; } // Corner view should be visible when both scrollbars are visible. - EXPECT_EQ(&scroll_view_, corner_view->parent()); + EXPECT_EQ(scroll_view_.get(), corner_view->parent()); EXPECT_TRUE(corner_view->visible()); // Corner view should be aligned to the scrollbars. - EXPECT_EQ(scroll_view_.vertical_scroll_bar()->x(), corner_view->x()); - EXPECT_EQ(scroll_view_.horizontal_scroll_bar()->y(), corner_view->y()); - EXPECT_EQ(scroll_view_.GetScrollBarLayoutWidth(), corner_view->width()); - EXPECT_EQ(scroll_view_.GetScrollBarLayoutHeight(), corner_view->height()); + EXPECT_EQ(scroll_view_->vertical_scroll_bar()->x(), corner_view->x()); + EXPECT_EQ(scroll_view_->horizontal_scroll_bar()->y(), corner_view->y()); + EXPECT_EQ(scroll_view_->GetScrollBarLayoutWidth(), corner_view->width()); + EXPECT_EQ(scroll_view_->GetScrollBarLayoutHeight(), corner_view->height()); // Corner view should be removed when only the vertical scrollbar is visible. contents->SetBounds(0, 0, 50, 200); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_FALSE(corner_view->parent()); // ... or when only the horizontal scrollbar is visible. contents->SetBounds(0, 0, 200, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_FALSE(corner_view->parent()); // ... or when no scrollbar is visible. contents->SetBounds(0, 0, 50, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_FALSE(corner_view->parent()); // Corner view should reappear when both scrollbars reappear. contents->SetBounds(0, 0, 200, 200); - scroll_view_.Layout(); - EXPECT_EQ(&scroll_view_, corner_view->parent()); + scroll_view_->Layout(); + EXPECT_EQ(scroll_view_.get(), corner_view->parent()); EXPECT_TRUE(corner_view->visible()); } TEST_F(ScrollViewTest, ChildWithLayerTest) { View* contents = InstallContents(); - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); if (test_api.contents_viewport()->layer()) return; @@ -812,7 +817,7 @@ EXPECT_TRUE(test_api.contents_viewport()->layer()->fills_bounds_opaquely()); // Setting a transparent color should make fills opaquely false. - scroll_view_.SetBackgroundColor(SK_ColorTRANSPARENT); + scroll_view_->SetBackgroundColor(SK_ColorTRANSPARENT); EXPECT_FALSE(test_api.contents_viewport()->layer()->fills_bounds_opaquely()); child->DestroyLayer(); @@ -829,12 +834,12 @@ // is added to the ScrollView's viewport. TEST_F(ScrollViewTest, DontCreateLayerOnViewportIfLayerOnScrollViewCreated) { View* contents = InstallContents(); - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); if (test_api.contents_viewport()->layer()) return; - scroll_view_.SetPaintToLayer(); + scroll_view_->SetPaintToLayer(); View* child = new View(); contents->AddChildView(child); @@ -853,35 +858,35 @@ // Size the contents such that vertical scrollbar is needed. // Since it is overlaid, the ViewPort size should match the ScrollView. contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutWidth()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutWidth()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); // Size the contents such that horizontal scrollbar is needed. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutHeight()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, false); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutHeight()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Both horizontal and vertical scrollbars. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutWidth()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutHeight()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutWidth()); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutHeight()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Make sure the horizontal and vertical scrollbars don't overlap each other. - gfx::Rect vert_bounds = scroll_view_.vertical_scroll_bar()->bounds(); - gfx::Rect horiz_bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + gfx::Rect vert_bounds = scroll_view_->vertical_scroll_bar()->bounds(); + gfx::Rect horiz_bounds = scroll_view_->horizontal_scroll_bar()->bounds(); EXPECT_EQ(vert_bounds.x(), horiz_bounds.right()); EXPECT_EQ(horiz_bounds.y(), vert_bounds.bottom()); @@ -982,11 +987,11 @@ // Test that increasing the size of the viewport "below" scrolled content causes // the content to scroll up so that it still fills the viewport. TEST_F(ScrollViewTest, ConstrainScrollToBounds) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); View* contents = InstallContents(); contents->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(gfx::ScrollOffset(), test_api.CurrentOffset()); @@ -996,49 +1001,49 @@ EXPECT_NE(gfx::ScrollOffset(), fully_scrolled); // Making the viewport 55 pixels taller should scroll up the same amount. - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 155)); - scroll_view_.Layout(); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 155)); + scroll_view_->Layout(); EXPECT_EQ(fully_scrolled.y() - 55, test_api.CurrentOffset().y()); EXPECT_EQ(fully_scrolled.x(), test_api.CurrentOffset().x()); // And 77 pixels wider should scroll left. Also make it short again: the y- // offset from the last change should remain. - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 177, 100)); - scroll_view_.Layout(); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 177, 100)); + scroll_view_->Layout(); EXPECT_EQ(fully_scrolled.y() - 55, test_api.CurrentOffset().y()); EXPECT_EQ(fully_scrolled.x() - 77, test_api.CurrentOffset().x()); } // Calling Layout on ScrollView should not reset the scroll location. TEST_F(ScrollViewTest, ContentScrollNotResetOnLayout) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; contents->SetPreferredSize(gfx::Size(300, 300)); - scroll_view_.SetContents(contents); - scroll_view_.ClipHeightTo(0, 150); - scroll_view_.SizeToPreferredSize(); + scroll_view_->SetContents(contents); + scroll_view_->ClipHeightTo(0, 150); + scroll_view_->SizeToPreferredSize(); // ScrollView preferred width matches that of |contents|, with the height // capped at the value we clipped to. - EXPECT_EQ(gfx::Size(300, 150), scroll_view_.size()); + EXPECT_EQ(gfx::Size(300, 150), scroll_view_->size()); // Scroll down. - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 25); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 25); EXPECT_EQ(25, test_api.CurrentOffset().y()); // Call Layout; no change to scroll position. - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(25, test_api.CurrentOffset().y()); // Change contents of |contents|, call Layout; still no change to scroll // position. contents->SetPreferredSize(gfx::Size(300, 500)); contents->InvalidateLayout(); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(25, test_api.CurrentOffset().y()); // Change |contents| to be shorter than the ScrollView's clipped height. // This /will/ change the scroll location due to ConstrainScrollToBounds. contents->SetPreferredSize(gfx::Size(300, 50)); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, test_api.CurrentOffset().y()); } @@ -1046,16 +1051,16 @@ TEST_F(ScrollViewTest, VerticalOverflowIndicators) { const int kWidth = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with vertical scrollbar. FixedView* contents = new FixedView; contents->SetPreferredSize(gfx::Size(kWidth, kMaxHeight * 5)); - scroll_view_.SetContents(contents); - scroll_view_.ClipHeightTo(0, kMaxHeight); + scroll_view_->SetContents(contents); + scroll_view_->ClipHeightTo(0, kMaxHeight); // Make sure the size is set such that no horizontal scrollbar gets shown. - scroll_view_.SetSize( + scroll_view_->SetSize( gfx::Size(kWidth + test_api.GetBaseScrollBar(VERTICAL)->GetThickness(), kMaxHeight)); @@ -1064,8 +1069,8 @@ // The vertical scroll bar should be visible and the horizontal scroll bar // should not. - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); // The overflow indicator on the bottom should be visible. EXPECT_TRUE(test_api.more_content_bottom()->visible()); @@ -1079,7 +1084,7 @@ // Now scroll the view to someplace in the middle of the scrollable region. int offset = kMaxHeight * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // At this point, both overflow indicators on the top and bottom should be @@ -1093,7 +1098,7 @@ // Finally scroll the view to end of the scrollable region. offset = kMaxHeight * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // The overflow indicator on the bottom should not be visible. @@ -1111,15 +1116,15 @@ const int kWidth = 100; const int kHeight = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with horizontal scrollbar. FixedView* contents = new FixedView; contents->SetPreferredSize(gfx::Size(kWidth * 5, kHeight)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); // Make sure the size is set such that no vertical scrollbar gets shown. - scroll_view_.SetSize(gfx::Size( + scroll_view_->SetSize(gfx::Size( kWidth, kHeight + test_api.GetBaseScrollBar(HORIZONTAL)->GetThickness())); contents->SetBounds(0, 0, kWidth * 5, kHeight); @@ -1129,8 +1134,8 @@ // The horizontal scroll bar should be visible and the vertical scroll bar // should not. - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); - CheckScrollbarVisibility(scroll_view_, VERTICAL, false); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false); // The overflow indicator on the right should be visible. EXPECT_TRUE(test_api.more_content_right()->visible()); @@ -1144,7 +1149,7 @@ // Now scroll the view to someplace in the middle of the scrollable region. int offset = kWidth * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); EXPECT_EQ(gfx::ScrollOffset(offset, 0), test_api.CurrentOffset()); // At this point, both overflow indicators on the left and right should be @@ -1158,7 +1163,7 @@ // Finally scroll the view to end of the scrollable region. offset = kWidth * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); EXPECT_EQ(gfx::ScrollOffset(offset, 0), test_api.CurrentOffset()); // The overflow indicator on the right should not be visible. @@ -1176,22 +1181,22 @@ const int kWidth = 100; const int kHeight = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with both horizontal and vertical scrollbars. FixedView* contents = new FixedView; contents->SetPreferredSize(gfx::Size(kWidth * 5, kHeight * 5)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); // Make sure the size is set such that both scrollbars are shown. - scroll_view_.SetSize(gfx::Size(kWidth, kHeight)); + scroll_view_->SetSize(gfx::Size(kWidth, kHeight)); // Make sure the initial origin is 0,0 EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset()); // The horizontal and vertical scroll bars should be visible. - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); // The overflow indicators on the right and bottom should not be visible since // they are against the scrollbars. @@ -1205,8 +1210,8 @@ // Now scroll the view to someplace in the middle of the horizontal scrollable // region. int offset_x = kWidth * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), - offset_x); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), + offset_x); EXPECT_EQ(gfx::ScrollOffset(offset_x, 0), test_api.CurrentOffset()); // Since there is a vertical scrollbar only the overflow indicator on the left @@ -1220,8 +1225,8 @@ // Next, scroll the view to end of the scrollable region. offset_x = kWidth * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), - offset_x); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), + offset_x); EXPECT_EQ(gfx::ScrollOffset(offset_x, 0), test_api.CurrentOffset()); // The overflow indicator on the right should still not be visible. @@ -1237,7 +1242,7 @@ EXPECT_FALSE(test_api.more_content_bottom()->visible()); // Return the view back to the horizontal origin. - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 0); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 0); EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset()); // The overflow indicators on the right and bottom should not be visible since @@ -1253,7 +1258,7 @@ // Now scroll the view to somplace in the middle of the vertical scrollable // region. int offset_y = kHeight * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); EXPECT_EQ(gfx::ScrollOffset(0, offset_y), test_api.CurrentOffset()); // Similar to the above, since there is a horizontal scrollbar only the @@ -1268,7 +1273,7 @@ // Finally, for the vertical test scroll the region all the way to the end. offset_y = kHeight * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); EXPECT_EQ(gfx::ScrollOffset(0, offset_y), test_api.CurrentOffset()); // The overflow indicator on the bottom should still not be visible. @@ -1286,8 +1291,8 @@ // Back to the horizontal. Scroll all the way to the end in the horizontal // direction. offset_x = kWidth * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), - offset_x); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), + offset_x); EXPECT_EQ(gfx::ScrollOffset(offset_x, offset_y), test_api.CurrentOffset()); // The overflow indicator on the bottom and right should still not be visible. @@ -1302,19 +1307,19 @@ TEST_F(ScrollViewTest, VerticalWithHeaderOverflowIndicators) { const int kWidth = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with vertical scrollbar and a header. FixedView* contents = new FixedView; CustomView* header = new CustomView; contents->SetPreferredSize(gfx::Size(kWidth, kMaxHeight * 5)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); header->SetPreferredSize(gfx::Size(10, 20)); - scroll_view_.SetHeader(header); - scroll_view_.ClipHeightTo(0, kMaxHeight + header->height()); + scroll_view_->SetHeader(header); + scroll_view_->ClipHeightTo(0, kMaxHeight + header->height()); // Make sure the size is set such that no horizontal scrollbar gets shown. - scroll_view_.SetSize( + scroll_view_->SetSize( gfx::Size(kWidth + test_api.GetBaseScrollBar(VERTICAL)->GetThickness(), kMaxHeight + header->height())); @@ -1323,8 +1328,8 @@ // The vertical scroll bar should be visible and the horizontal scroll bar // should not. - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); // The overflow indicator on the bottom should be visible. EXPECT_TRUE(test_api.more_content_bottom()->visible()); @@ -1338,7 +1343,7 @@ // Now scroll the view to someplace in the middle of the scrollable region. int offset = kMaxHeight * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // At this point, only the overflow indicator on the bottom should be visible @@ -1353,7 +1358,7 @@ // Finally scroll the view to end of the scrollable region. offset = test_api.GetBaseScrollBar(VERTICAL)->GetMaxPosition(); - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // The overflow indicator on the bottom should not be visible now.
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc index 082ea64..f499e20 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -32,7 +32,10 @@ class TabbedPaneTest : public ViewsTestBase { public: - TabbedPaneTest() { + TabbedPaneTest() = default; + + void SetUp() override { + ViewsTestBase::SetUp(); tabbed_pane_ = std::make_unique<TabbedPane>(); tabbed_pane_->set_owned_by_client(); }
diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc index eb53893..9f57716 100644 --- a/ui/views/controls/textfield/textfield_model.cc +++ b/ui/views/controls/textfield/textfield_model.cc
@@ -16,6 +16,7 @@ #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/gfx/range/range.h" #include "ui/gfx/utf16_indexing.h" +#include "ui/views/style/platform_style.h" namespace views { @@ -406,10 +407,8 @@ } size_t cursor_position = GetCursorPosition(); if (cursor_position > 0) { - // Delete one code point, which may be two UTF-16 words. - size_t previous_grapheme_index = - gfx::UTF16OffsetToIndex(text(), cursor_position, -1); - gfx::Range range_to_delete(cursor_position, previous_grapheme_index); + gfx::Range range_to_delete( + PlatformStyle::RangeToDeleteBackwards(text(), cursor_position)); if (add_to_kill_buffer) SetKillBuffer(GetTextFromRange(range_to_delete)); ExecuteAndRecordDelete(range_to_delete, true);
diff --git a/ui/views/controls/textfield/textfield_model_unittest.cc b/ui/views/controls/textfield/textfield_model_unittest.cc index 4b79f54..c35b122 100644 --- a/ui/views/controls/textfield/textfield_model_unittest.cc +++ b/ui/views/controls/textfield/textfield_model_unittest.cc
@@ -233,6 +233,38 @@ EXPECT_TRUE(model.Backspace()); EXPECT_EQ(base::WideToUTF16(L"\x002C\x0020\x05D1\x05BC\x05B7\x05E9"), model.text()); + + // Halfwidth katakana ダ: + // "HALFWIDTH KATAKANA LETTER TA" + "HALFWIDTH KATAKANA VOICED SOUND MARK" + // ("ABC" prefix as sanity check that the entire string isn't deleted). + model.SetText(base::WideToUTF16(L"ABC\xFF80\xFF9E")); + MoveCursorTo(model, model.text().length()); + model.Backspace(); +#if defined(OS_MACOSX) + // On Mac, the entire cluster should be deleted to match + // NSTextField behavior. + EXPECT_EQ(base::WideToUTF16(L"ABC"), model.text()); + EXPECT_EQ(3U, model.GetCursorPosition()); +#else + EXPECT_EQ(base::WideToUTF16(L"ABC\xFF80"), model.text()); + EXPECT_EQ(4U, model.GetCursorPosition()); +#endif + + // Emoji with Fitzpatrick modifier: + // 'BOY' + 'EMOJI MODIFIER FITZPATRICK TYPE-5' + model.SetText(base::WideToUTF16(L"\U0001F466\U0001F3FE")); + MoveCursorTo(model, model.text().length()); + model.Backspace(); +#if defined(OS_MACOSX) + // On Mac, the entire emoji should be deleted to match NSTextField + // behavior. + EXPECT_EQ(base::WideToUTF16(L""), model.text()); + EXPECT_EQ(0U, model.GetCursorPosition()); +#else + // https://crbug.com/829040 + EXPECT_EQ(base::WideToUTF16(L"\U0001F466"), model.text()); + EXPECT_EQ(2U, model.GetCursorPosition()); +#endif } TEST_F(TextfieldModelTest, EmptyString) {
diff --git a/ui/views/style/platform_style.cc b/ui/views/style/platform_style.cc index 34aed2f..6717102 100644 --- a/ui/views/style/platform_style.cc +++ b/ui/views/style/platform_style.cc
@@ -8,7 +8,9 @@ #include "build/build_config.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/range/range.h" #include "ui/gfx/shadow_value.h" +#include "ui/gfx/utf16_indexing.h" #include "ui/native_theme/native_theme.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" @@ -69,6 +71,15 @@ // static void PlatformStyle::OnTextfieldEditFailed() {} +// static +gfx::Range PlatformStyle::RangeToDeleteBackwards(const base::string16& text, + size_t cursor_position) { + // Delete one code point, which may be two UTF-16 words. + size_t previous_grapheme_index = + gfx::UTF16OffsetToIndex(text, cursor_position, -1); + return gfx::Range(cursor_position, previous_grapheme_index); +} + #endif // OS_MACOSX #if !defined(DESKTOP_LINUX)
diff --git a/ui/views/style/platform_style.h b/ui/views/style/platform_style.h index 08a4627..25710b7 100644 --- a/ui/views/style/platform_style.h +++ b/ui/views/style/platform_style.h
@@ -11,6 +11,10 @@ #include "ui/views/controls/button/button.h" #include "ui/views/views_export.h" +namespace gfx { +class Range; +} // namespace gfx + namespace views { class Border; @@ -87,6 +91,14 @@ // the failed edit if platform-appropriate. static void OnTextfieldEditFailed(); + // When deleting backwards in |string| with the cursor at index + // |cursor_position|, return the range of UTF-16 words to be deleted. + // This is to support deleting entire graphemes instead of individual + // characters when necessary on Mac, and code points made from surrogate + // pairs on other platforms. + static gfx::Range RangeToDeleteBackwards(const base::string16& text, + size_t cursor_position); + private: DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformStyle); };
diff --git a/ui/views/style/platform_style_mac.mm b/ui/views/style/platform_style_mac.mm index bd09dee..4be5bae 100644 --- a/ui/views/style/platform_style_mac.mm +++ b/ui/views/style/platform_style_mac.mm
@@ -5,6 +5,7 @@ #include "ui/views/style/platform_style.h" #include "base/memory/ptr_util.h" +#include "base/strings/sys_string_conversions.h" #include "ui/base/ui_features.h" #include "ui/gfx/color_utils.h" #include "ui/views/controls/button/label_button.h" @@ -12,6 +13,24 @@ #import <Cocoa/Cocoa.h> +extern "C" { +// From CFString private headers. +typedef CF_ENUM(CFIndex, CFStringCharacterClusterType) { + kCFStringGraphemeCluster = 1, /* Unicode Grapheme Cluster */ + kCFStringComposedCharacterCluster = + 2, /* Compose all non-base (including spacing marks) */ + kCFStringCursorMovementCluster = + 3, /* Cluster suitable for cursor movements */ + kCFStringBackwardDeletionCluster = + 4 /* Cluster suitable for backward deletion */ +}; + +CFRange CFStringGetRangeOfCharacterClusterAtIndex( + CFStringRef string, + CFIndex index, + CFStringCharacterClusterType type); +} + namespace views { const int PlatformStyle::kMinLabelButtonWidth = 32; @@ -45,4 +64,23 @@ NSBeep(); } +// static +gfx::Range PlatformStyle::RangeToDeleteBackwards(const base::string16& text, + size_t cursor_position) { + if (cursor_position == 0) + return gfx::Range(); + + base::ScopedCFTypeRef<CFStringRef> cf_string( + CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, text.data(), + text.size(), kCFAllocatorNull)); + CFRange range_to_delete = CFStringGetRangeOfCharacterClusterAtIndex( + cf_string, cursor_position - 1, kCFStringBackwardDeletionCluster); + + if (range_to_delete.location == NSNotFound) + return gfx::Range(); + + // The range needs to be reversed to undo correctly. + return gfx::Range(range_to_delete.location + range_to_delete.length, + range_to_delete.location); +} } // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index 97b54ace8..2e547154 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -104,7 +104,7 @@ ui::WindowShowState show_state) { if (compositor()) { platform_window()->Show(); - compositor()->SetVisible(true); + compositor()->SetVisible(show_state != ui::SHOW_STATE_MINIMIZED); } switch (show_state) {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 31eacf5..eb10b8ff 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -198,7 +198,7 @@ void DesktopWindowTreeHostWin::ShowWindowWithState( ui::WindowShowState show_state) { if (compositor()) - compositor()->SetVisible(true); + compositor()->SetVisible(show_state != ui::SHOW_STATE_MINIMIZED); message_handler_->ShowWindowWithState(show_state); }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index e2bf9239..dc103ba7 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -515,7 +515,7 @@ void DesktopWindowTreeHostX11::ShowWindowWithState( ui::WindowShowState show_state) { if (compositor()) - SetVisible(true); + SetVisible(show_state != ui::SHOW_STATE_MINIMIZED); if (!IsVisible() || !window_mapped_in_server_) MapWindow(show_state);
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 308202a6..aee6d273 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -1118,15 +1118,17 @@ gfx::Point cursor_location(location); gfx::Point cursor_root_location(root_location); + int modifiers = ui::GetModifiersFromKeyState(); + if (IsPrecisionTouchpadNavigationGestureEnabled()) { ui::ScrollEvent event(ui::ET_SCROLL, cursor_location, ui::EventTimeForNow(), - ui::EF_NONE, scroll_x, scroll_y, scroll_x, scroll_y, - 2, momentum_phase, phase); + modifiers, scroll_x, scroll_y, scroll_x, scroll_y, 2, + momentum_phase, phase); delegate_->HandleScrollEvent(&event); } else { ui::MouseWheelEvent wheel_event( offset, cursor_location, cursor_root_location, base::TimeTicks::Now(), - ui::EF_PRECISION_SCROLLING_DELTA, ui::EF_NONE); + modifiers | ui::EF_PRECISION_SCROLLING_DELTA, ui::EF_NONE); delegate_->HandleMouseEvent(&wheel_event); } }
diff --git a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html index 16e035e..388faf5d 100644 --- a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html +++ b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.html
@@ -23,7 +23,7 @@ } </style> - <dialog is="cr-dialog" id="dialog" close-text="[[i18n('close')]]"> + <cr-dialog id="dialog" close-text="[[i18n('close')]]"> <div slot="title"> [[i18n('certificateManagerCaTrustEditDialogTitle')]] </div> @@ -51,7 +51,7 @@ [[i18n('ok')]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="ca_trust_edit_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html index fbf253c..73d8209 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.html
@@ -9,7 +9,7 @@ <dom-module id="certificate-delete-confirmation-dialog"> <template> <style include="certificate-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="[[i18n('close')]]"> + <cr-dialog id="dialog" close-text="[[i18n('close')]]"> <div slot="title"> [[getTitleText_(model, certificateType)]] </div> @@ -24,7 +24,7 @@ [[i18n('ok')]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="certificate_delete_confirmation_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html index 850da130..664a410d 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.html
@@ -10,7 +10,7 @@ <dom-module id="certificate-password-decryption-dialog"> <template> <style include="certificate-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="[[i18n('close')]]"> + <cr-dialog id="dialog" close-text="[[i18n('close')]]"> <div slot="title"> [[i18n('certificateManagerDecryptPasswordTitle')]] </div> @@ -28,7 +28,7 @@ [[i18n('ok')]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="certificate_password_decryption_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html index f17b282..a3ad6fd2 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.html
@@ -14,7 +14,7 @@ margin-bottom: 20px; } </style> - <dialog is="cr-dialog" id="dialog" close-text="[[i18n('close')]]"> + <cr-dialog id="dialog" close-text="[[i18n('close')]]"> <div slot="title"> [[i18n('certificateManagerEncryptPasswordTitle')]] </div> @@ -38,7 +38,7 @@ [[i18n('ok')]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="certificate_password_encryption_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html index 2c0bb746..ae1d5c5 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html +++ b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.html
@@ -8,7 +8,7 @@ <dom-module id="certificates-error-dialog"> <template> <style include="certificate-shared"></style> - <dialog is="cr-dialog" id="dialog" close-text="[[i18n('close')]]"> + <cr-dialog id="dialog" close-text="[[i18n('close')]]"> <div slot="title">[[model.title]]</div> <div slot="body"> <div>[[model.description]]</div> @@ -23,7 +23,7 @@ [[i18n('ok')]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="certificates_error_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html b/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html index a71d029..e42cfe1e 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html +++ b/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html
@@ -12,8 +12,8 @@ <dom-module id="bluetooth-dialog"> <template> <style include="cr-hidden-style iron-flex"> - dialog { - @apply --bluetooth-dialog-style; + cr-dialog { + --cr-dialog-native: var(--bluetooth-dialog-style); } #pairing { @@ -73,7 +73,7 @@ } </style> <!-- TODO(stevenjb/dschuyler): Find a solution to support i18n{} here --> - <dialog is="cr-dialog" id="dialog" no-cancel="[[noCancel]]" + <cr-dialog id="dialog" no-cancel="[[noCancel]]" close-text="[[i18n('close')]]" on-cancel="onDialogCanceled_" on-closed="onDialogCanceled_"> <div slot="title">[[dialogTitle]]</div> @@ -136,7 +136,7 @@ <paper-button on-tap="close">[[i18n('ok')]]</paper-button> </template> </div> - </dialog> + </cr-dialog> </template> <script src="bluetooth_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html index 50c300e56..0cff8dd8 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html
@@ -90,7 +90,7 @@ </div> <!-- Enter PIN dialog --> - <dialog is="cr-dialog" id="enterPinDialog" close-text="[[i18n('close')]]" + <cr-dialog id="enterPinDialog" close-text="[[i18n('close')]]" on-cancel="onEnterPinDialogCancel_" on-close="onEnterPinDialogClose_"> <div slot="title">[[i18n('networkSimEnterPinTitle')]]</div> @@ -109,10 +109,10 @@ [[i18n('networkSimEnter')]] </paper-button> </div> - </dialog> + </cr-dialog> <!-- Change PIN dialog --> - <dialog is="cr-dialog" id="changePinDialog" close-text="[[i18n('close')]]" + <cr-dialog id="changePinDialog" close-text="[[i18n('close')]]" on-close="onChangePinDialogClose_"> <div slot="title">[[i18n('networkSimChangePinTitle')]]</div> <div slot="body"> @@ -136,10 +136,10 @@ [[i18n('networkSimChange')]] </paper-button> </div> - </dialog> + </cr-dialog> <!-- Unlock PIN dialog --> - <dialog is="cr-dialog" id="unlockPinDialog" close-text="[[i18n('close')]]" + <cr-dialog id="unlockPinDialog" close-text="[[i18n('close')]]" on-close="onUnlockPinDialogClose_"> <div slot="title">[[i18n('networkSimLockedTitle')]]</div> <div slot="body"> @@ -157,10 +157,10 @@ [[i18n('networkSimUnlock')]] </paper-button> </div> - </dialog> + </cr-dialog> <!-- Unlock PUK dialog --> - <dialog is="cr-dialog" id="unlockPukDialog" close-text="[[i18n('close')]]" + <cr-dialog id="unlockPukDialog" close-text="[[i18n('close')]]" on-close="onUnlockPinDialogClose_"> <div slot="title">[[i18n('networkSimLockedTitle')]]</div> <div slot="body"> @@ -190,7 +190,7 @@ [[i18n('networkSimUnlock')]] </paper-button> </div> - </dialog> + </cr-dialog> </template> <script src="network_siminfo.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html index ab6bc62a..78c091b 100644 --- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html +++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -9,7 +9,7 @@ <dom-module id="cr-dialog"> <template> <style include="cr-hidden-style cr-icons"> - :host { + dialog { --scroll-border: 1px solid var(--paper-grey-300); border: 0; border-radius: 2px; @@ -21,9 +21,10 @@ padding: 0; top: 50%; width: 512px; + @apply --cr-dialog-native; } - :host([open]) #content-wrapper { + dialog[open] #content-wrapper { /* Keep max-height within viewport, and flex content accordingly. */ display: flex; flex-direction: column; @@ -39,7 +40,7 @@ flex-shrink: 0; } - :host::backdrop { + dialog::backdrop { background-color: rgba(0, 0, 0, 0.6); bottom: 0; left: 0; @@ -128,29 +129,31 @@ @apply --cr-dialog-close-image-active; } </style> - <!-- This wrapper is necessary, such that the "pulse" animation is not - erroneously played when the user clicks on the outer-most scrollbar. --> - <div id="content-wrapper"> - <div class="top-container"> - <div class="title-container" tabindex="-1"> - <slot name="title"></slot> + <dialog id="dialog"> + <!-- This wrapper is necessary, such that the "pulse" animation is not + erroneously played when the user clicks on the outer-most scrollbar. --> + <div id="content-wrapper"> + <div class="top-container"> + <div class="title-container" tabindex="-1"> + <slot name="title"></slot> + </div> + <paper-icon-button-light id="closeContainer" class="icon-clear" + hidden$="[[noCancel]]"> + <button id="close" aria-label$="[[closeText]]" + on-tap="cancel" on-keypress="onCloseKeypress_"> + </button> + </paper-icon-button-light> </div> - <paper-icon-button-light id="closeContainer" class="icon-clear" - hidden$="[[noCancel]]"> - <button id="close" aria-label$="[[closeText]]" - on-tap="cancel" on-keypress="onCloseKeypress_"> - </button> - </paper-icon-button-light> + <slot name="header"></slot> + <div class="body-container"> + <span id="bodyTopMarker"></span> + <slot name="body"></slot> + <span id="bodyBottomMarker"></span> + </div> + <slot name="button-container"></slot> + <slot name="footer"></slot> </div> - <slot name="header"></slot> - <div class="body-container"> - <span id="bodyTopMarker"></span> - <slot name="body"></slot> - <span id="bodyBottomMarker"></span> - </div> - <slot name="button-container"></slot> - <slot name="footer"></slot> - </div> + </dialog> </template> <script src="cr_dialog.js"></script> </dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js index 59ee2f6..554d8463 100644 --- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js +++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
@@ -6,16 +6,29 @@ * @fileoverview 'cr-dialog' is a component for showing a modal dialog. If the * dialog is closed via close(), a 'close' event is fired. If the dialog is * canceled via cancel(), a 'cancel' event is fired followed by a 'close' event. - * Additionally clients can inspect the dialog's |returnValue| property inside + * + * Additionally clients can get a reference to the internal native <dialog> via + * calling getNative() and inspecting the |returnValue| property inside * the 'close' event listener to determine whether it was canceled or just * closed, where a truthy value means success, and a falsy value means it was * canceled. + * + * Note that <cr-dialog> wrapper itself always has 0x0 dimensions, and + * specifying width/height on <cr-dialog> directly will have no effect on the + * internal native <dialog>. Instead use the --cr-dialog-native mixin to specify + * width/height (as well as other available mixins to style other parts of the + * dialog contents). */ Polymer({ is: 'cr-dialog', - extends: 'dialog', properties: { + open: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + /** * Alt-text for the dialog close button. */ @@ -63,7 +76,7 @@ // If the active history entry changes (i.e. user clicks back button), // all open dialogs should be cancelled. window.addEventListener('popstate', function() { - if (!this.ignorePopstate && this.open) + if (!this.ignorePopstate && this.$.dialog.open) this.cancel(); }.bind(this)); @@ -77,7 +90,7 @@ /** @override */ attached: function() { var mutationObserverCallback = function() { - if (this.open) + if (this.$.dialog.open) this.addIntersectionObserver_(); else this.removeIntersectionObserver_(); @@ -85,7 +98,7 @@ this.mutationObserver_ = new MutationObserver(mutationObserverCallback); - this.mutationObserver_.observe(this, { + this.mutationObserver_.observe(this.$.dialog, { attributes: true, attributeFilter: ['open'], }); @@ -146,17 +159,20 @@ } }, - cancel: function() { - this.fire('cancel'); - HTMLDialogElement.prototype.close.call(this, ''); + showModal: function() { + this.$.dialog.showModal(); + this.open = this.$.dialog.open; }, - /** - * @param {string=} opt_returnValue - * @override - */ - close: function(opt_returnValue) { - HTMLDialogElement.prototype.close.call(this, 'success'); + cancel: function() { + this.fire('cancel'); + this.$.dialog.close(); + this.open = this.$.dialog.open; + }, + + close: function() { + this.$.dialog.close('success'); + this.open = this.$.dialog.open; }, /** @@ -169,6 +185,16 @@ e.stopPropagation(); }, + /** + * Expose the inner native <dialog> for some rare cases where it needs to be + * directly accessed (for example to programmatically setheight/width, which + * would not work on the wrapper). + * @return {!HTMLDialogElement} + */ + getNative: function() { + return this.$.dialog; + }, + /** @return {!PaperIconButtonElement} */ getCloseButton: function() { return this.$.close; @@ -210,7 +236,7 @@ if (e.button != 0 || e.composedPath()[0].tagName !== 'DIALOG') return; - this.animate( + this.$.dialog.animate( [ {transform: 'scale(1)', offset: 0}, {transform: 'scale(1.02)', offset: 0.4},
diff --git a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html index 3738d2bb..56fccde 100644 --- a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html +++ b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html
@@ -7,6 +7,7 @@ <template> <style include="cr-icons cr-shared-style"> :host([disabled]) { + opacity: 0.65; pointer-events: none; }