diff --git a/DEPS b/DEPS index 3fe5aa5..ce2c8c2 100644 --- a/DEPS +++ b/DEPS
@@ -40,15 +40,15 @@ # 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': '111f8a9eea6980a70a300e3a8bfd758257310fe2', + 'skia_revision': '2e409009fb715400a0d64612c57187465c12790c', # 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': '711c1775d5668290aaf78a538f3dfee415851766', + 'v8_revision': '531b54ae7eeafe66dd2fc8be7e4ba0f0dedd84d3', # 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. - 'swarming_revision': 'af6b06ca68ba7a618024f28856418296a9acf375', + 'swarming_revision': 'a56c2b39ca23bdf41458421a7f825ddbf3f43f28', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -60,11 +60,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '9282c6d71f730ff604469951a1f6615baa57c056', + 'swiftshader_revision': '81aa97bd20033674ba28d779c05fbcee1539ebf7', # 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': 'd8df8d4cd419258b50413c4eb730d144824844f0', + 'pdfium_revision': '1ef2f828f71e40437d82bb039dcb087c1beb7bd6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '1e5227efcb4d551256ec2f9a5e1a8ab46529fd0f', + 'catapult_revision': 'a70ee6f1c1fbf4cf78e2de6416dde17e8277ee25', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -208,7 +208,7 @@ Var('chromium_git') + '/webm/libvpx.git' + '@' + 'ec4afbf74a4beebadee3e1b15b43c5d4e3d3bd1c', 'src/third_party/ffmpeg': - Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '06ac9ea361fa8d48916b83783bb7f36872388cc2', + Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '88c555e9e69e6f82f0674912596c1be1b30c6add', 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '2f6478eb8d40f1766a96b5b033ed26c0c2244589', @@ -235,7 +235,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '0a9e920562451b5f914e22fe88750a10e8fc0d60', # commit position 18803 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '6f863441e5b1f91ff4c0560d82656eb057024686', # commit position 18816 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), @@ -363,7 +363,7 @@ Var('chromium_git') + '/external/github.com/swisspol/GCDWebServer.git' + '@' + '43555c66627f6ed44817855a0f6d465f559d30e0', 'src/ios/third_party/material_components_ios/src': - Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'f2fbf2501a825c023f2d846aeba4a292f1053c03', + Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '3bb89d580683b81001fcfac3dc47651bd2c36bf9', 'src/ios/third_party/material_font_disk_loader_ios/src': Var('chromium_git') + '/external/github.com/material-foundation/material-font-disk-loader-ios.git' + '@' + '8e30188777b016182658fbaa0a4a020a48183224', @@ -465,7 +465,7 @@ Var('chromium_git') + '/external/android_protobuf.git' + '@' + '7fca48d8ce97f7ba3ab8eea5c472f1ad3711762f', 'src/third_party/android_tools': - Var('chromium_git') + '/android_tools.git' + '@' + '023e2f65409a2b7886b8d644d6a88542ead6cd0a', + Var('chromium_git') + '/android_tools.git' + '@' + 'e9d4018e149d50172ed462a7c21137aa915940ec', 'src/third_party/apache-portable-runtime/src': Var('chromium_git') + '/external/apache-portable-runtime.git' + '@' + 'c76a8c4277e09a82eaa229e35246edea1ee0a6a1', @@ -1201,7 +1201,7 @@ 'action': [ 'python', 'src/build/fuchsia/update_sdk.py', - '17e51e32c9a81d3f957afe533ac99ef1d565378c', + '8b1076a14d3e31dd3e569b44ddb49e49e0799baf', ], }, ],
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 895e6932..3b003c8 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -892,165 +892,6 @@ return results -def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums): - """Checks that the lines in scope occur in the right order. - - 1. C system files in alphabetical order - 2. C++ system files in alphabetical order - 3. Project's .h files - """ - - c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>') - cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>') - custom_include_pattern = input_api.re.compile(r'\s*#include ".*') - - C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3) - - state = C_SYSTEM_INCLUDES - - previous_line = '' - previous_line_num = 0 - problem_linenums = [] - out_of_order = " - line belongs before previous line" - for line_num, line in scope: - if c_system_include_pattern.match(line): - if state != C_SYSTEM_INCLUDES: - problem_linenums.append((line_num, previous_line_num, - " - C system include file in wrong block")) - elif previous_line and previous_line > line: - problem_linenums.append((line_num, previous_line_num, - out_of_order)) - elif cpp_system_include_pattern.match(line): - if state == C_SYSTEM_INCLUDES: - state = CPP_SYSTEM_INCLUDES - elif state == CUSTOM_INCLUDES: - problem_linenums.append((line_num, previous_line_num, - " - c++ system include file in wrong block")) - elif previous_line and previous_line > line: - problem_linenums.append((line_num, previous_line_num, out_of_order)) - elif custom_include_pattern.match(line): - if state != CUSTOM_INCLUDES: - state = CUSTOM_INCLUDES - elif previous_line and previous_line > line: - problem_linenums.append((line_num, previous_line_num, out_of_order)) - else: - problem_linenums.append((line_num, previous_line_num, - "Unknown include type")) - previous_line = line - previous_line_num = line_num - - warnings = [] - for (line_num, previous_line_num, failure_type) in problem_linenums: - if line_num in changed_linenums or previous_line_num in changed_linenums: - warnings.append(' %s:%d:%s' % (file_path, line_num, failure_type)) - return warnings - - -def _CheckIncludeOrderInFile(input_api, f, changed_linenums): - """Checks the #include order for the given file f.""" - - system_include_pattern = input_api.re.compile(r'\s*#include \<.*') - # Exclude the following includes from the check: - # 1) #include <.../...>, e.g., <sys/...> includes often need to appear in a - # specific order. - # 2) <atlbase.h>, "build/build_config.h" - excluded_include_pattern = input_api.re.compile( - r'\s*#include (\<.*/.*|\<atlbase\.h\>|"build/build_config.h")') - custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"') - # Match the final or penultimate token if it is xxxtest so we can ignore it - # when considering the special first include. - test_file_tag_pattern = input_api.re.compile( - r'_[a-z]+test(?=(_[a-zA-Z0-9]+)?\.)') - if_pattern = input_api.re.compile( - r'\s*#\s*(if|elif|else|endif|define|undef).*') - # Some files need specialized order of includes; exclude such files from this - # check. - uncheckable_includes_pattern = input_api.re.compile( - r'\s*#include ' - '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*') - - contents = f.NewContents() - warnings = [] - line_num = 0 - - # Handle the special first include. If the first include file is - # some/path/file.h, the corresponding including file can be some/path/file.cc, - # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h - # etc. It's also possible that no special first include exists. - # If the included file is some/path/file_platform.h the including file could - # also be some/path/file_xxxtest_platform.h. - including_file_base_name = test_file_tag_pattern.sub( - '', input_api.os_path.basename(f.LocalPath())) - - for line in contents: - line_num += 1 - if system_include_pattern.match(line): - # No special first include -> process the line again along with normal - # includes. - line_num -= 1 - break - match = custom_include_pattern.match(line) - if match: - match_dict = match.groupdict() - header_basename = test_file_tag_pattern.sub( - '', input_api.os_path.basename(match_dict['FILE'])).replace('.h', '') - - if header_basename not in including_file_base_name: - # No special first include -> process the line again along with normal - # includes. - line_num -= 1 - break - - # Split into scopes: Each region between #if and #endif is its own scope. - scopes = [] - current_scope = [] - for line in contents[line_num:]: - line_num += 1 - if uncheckable_includes_pattern.match(line): - continue - if if_pattern.match(line): - scopes.append(current_scope) - current_scope = [] - elif ((system_include_pattern.match(line) or - custom_include_pattern.match(line)) and - not excluded_include_pattern.match(line)): - current_scope.append((line_num, line)) - scopes.append(current_scope) - - for scope in scopes: - warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(), - changed_linenums)) - return warnings - - -def _CheckIncludeOrder(input_api, output_api): - """Checks that the #include order is correct. - - 1. The corresponding header for source files. - 2. C system files in alphabetical order - 3. C++ system files in alphabetical order - 4. Project's .h files in alphabetical order - - Each region separated by #if, #elif, #else, #endif, #define and #undef follows - these rules separately. - """ - def FileFilterIncludeOrder(affected_file): - black_list = (_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST) - return input_api.FilterSourceFile(affected_file, black_list=black_list) - - warnings = [] - for f in input_api.AffectedFiles(file_filter=FileFilterIncludeOrder): - if f.LocalPath().endswith(('.cc', '.h', '.mm')): - changed_linenums = set(line_num for line_num, _ in f.ChangedContents()) - warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums)) - - results = [] - if warnings: - results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING, - warnings)) - return results - - def _CheckForVersionControlConflictsInFile(input_api, f): pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$') errors = [] @@ -1423,24 +1264,6 @@ return [] -def _CheckCygwinShell(input_api, output_api): - source_file_filter = lambda x: input_api.FilterSourceFile( - x, white_list=(r'.+\.(gyp|gypi)$',)) - cygwin_shell = [] - - for f in input_api.AffectedSourceFiles(source_file_filter): - for linenum, line in f.ChangedContents(): - if 'msvs_cygwin_shell' in line: - cygwin_shell.append(f.LocalPath()) - break - - if cygwin_shell: - return [output_api.PresubmitError( - 'These files should not use msvs_cygwin_shell (the default is 0):', - items=cygwin_shell)] - return [] - - def _CheckUserActionUpdate(input_api, output_api): """Checks if any new user action has been added.""" if any('actions.xml' == input_api.os_path.basename(f) for f in @@ -2262,7 +2085,6 @@ results.extend(_CheckFilePermissions(input_api, output_api)) results.extend(_CheckTeamTags(input_api, output_api)) results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) - results.extend(_CheckIncludeOrder(input_api, output_api)) results.extend(_CheckForVersionControlConflicts(input_api, output_api)) results.extend(_CheckPatchFiles(input_api, output_api)) results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api)) @@ -2278,7 +2100,6 @@ source_file_filter=lambda x: x.LocalPath().endswith('.grd'))) results.extend(_CheckSpamLogging(input_api, output_api)) results.extend(_CheckForAnonymousVariables(input_api, output_api)) - results.extend(_CheckCygwinShell(input_api, output_api)) results.extend(_CheckUserActionUpdate(input_api, output_api)) results.extend(_CheckNoDeprecatedCss(input_api, output_api)) results.extend(_CheckNoDeprecatedJs(input_api, output_api))
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 394efb7b..eac824b 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -14,245 +14,6 @@ _TEST_DATA_DIR = 'base/test/data/presubmit' -class IncludeOrderTest(unittest.TestCase): - def testSystemHeaderOrder(self): - scope = [(1, '#include <csystem.h>'), - (2, '#include <cppsystem>'), - (3, '#include "acustom.h"')] - all_linenums = [linenum for (linenum, _) in scope] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', all_linenums) - self.assertEqual(0, len(warnings)) - - def testSystemHeaderOrderMismatch1(self): - scope = [(10, '#include <cppsystem>'), - (20, '#include <csystem.h>'), - (30, '#include "acustom.h"')] - all_linenums = [linenum for (linenum, _) in scope] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', all_linenums) - self.assertEqual(1, len(warnings)) - self.assertTrue('20' in warnings[0]) - - def testSystemHeaderOrderMismatch2(self): - scope = [(10, '#include <cppsystem>'), - (20, '#include "acustom.h"'), - (30, '#include <csystem.h>')] - all_linenums = [linenum for (linenum, _) in scope] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', all_linenums) - self.assertEqual(1, len(warnings)) - self.assertTrue('30' in warnings[0]) - - def testSystemHeaderOrderMismatch3(self): - scope = [(10, '#include "acustom.h"'), - (20, '#include <csystem.h>'), - (30, '#include <cppsystem>')] - all_linenums = [linenum for (linenum, _) in scope] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', all_linenums) - self.assertEqual(2, len(warnings)) - self.assertTrue('20' in warnings[0]) - self.assertTrue('30' in warnings[1]) - - def testAlphabeticalOrderMismatch(self): - scope = [(10, '#include <csystem.h>'), - (15, '#include <bsystem.h>'), - (20, '#include <cppsystem>'), - (25, '#include <bppsystem>'), - (30, '#include "bcustom.h"'), - (35, '#include "acustom.h"')] - all_linenums = [linenum for (linenum, _) in scope] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', all_linenums) - self.assertEqual(3, len(warnings)) - self.assertTrue('15' in warnings[0]) - self.assertTrue('25' in warnings[1]) - self.assertTrue('35' in warnings[2]) - - def testSpecialFirstInclude1(self): - mock_input_api = MockInputApi() - contents = ['#include "some/path/foo.h"', - '#include "a/header.h"'] - mock_file = MockFile('some/path/foo.cc', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testSpecialFirstInclude2(self): - mock_input_api = MockInputApi() - contents = ['#include "some/other/path/foo.h"', - '#include "a/header.h"'] - mock_file = MockFile('some/path/foo.cc', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testSpecialFirstInclude3(self): - mock_input_api = MockInputApi() - contents = ['#include "some/path/foo.h"', - '#include "a/header.h"'] - mock_file = MockFile('some/path/foo_platform.cc', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testSpecialFirstInclude4(self): - mock_input_api = MockInputApi() - contents = ['#include "some/path/bar.h"', - '#include "a/header.h"'] - mock_file = MockFile('some/path/foo_platform.cc', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(1, len(warnings)) - self.assertTrue('2' in warnings[0]) - - def testSpecialFirstInclude5(self): - mock_input_api = MockInputApi() - contents = ['#include "some/other/path/foo.h"', - '#include "a/header.h"'] - mock_file = MockFile('some/path/foo-suffix.h', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testSpecialFirstInclude6(self): - mock_input_api = MockInputApi() - contents = ['#include "some/other/path/foo_win.h"', - '#include <set>', - '#include "a/header.h"'] - mock_file = MockFile('some/path/foo_unittest_win.h', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testOrderAlreadyWrong(self): - scope = [(1, '#include "b.h"'), - (2, '#include "a.h"'), - (3, '#include "c.h"')] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', [3]) - self.assertEqual(0, len(warnings)) - - def testConflictAdded1(self): - scope = [(1, '#include "a.h"'), - (2, '#include "c.h"'), - (3, '#include "b.h"')] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', [2]) - self.assertEqual(1, len(warnings)) - self.assertTrue('3' in warnings[0]) - - def testConflictAdded2(self): - scope = [(1, '#include "c.h"'), - (2, '#include "b.h"'), - (3, '#include "d.h"')] - mock_input_api = MockInputApi() - warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api, - '', [2]) - self.assertEqual(1, len(warnings)) - self.assertTrue('2' in warnings[0]) - - def testIfElifElseEndif(self): - mock_input_api = MockInputApi() - contents = ['#include "e.h"', - '#define foo', - '#include "f.h"', - '#undef foo', - '#include "e.h"', - '#if foo', - '#include "d.h"', - '#elif bar', - '#include "c.h"', - '#else', - '#include "b.h"', - '#endif', - '#include "a.h"'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testExcludedIncludes(self): - # #include <sys/...>'s can appear in any order. - mock_input_api = MockInputApi() - contents = ['#include <sys/b.h>', - '#include <sys/a.h>'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - contents = ['#include <atlbase.h>', - '#include <aaa.h>'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - contents = ['#include "build/build_config.h"', - '#include "aaa.h"'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(0, len(warnings)) - - def testCheckOnlyCFiles(self): - mock_input_api = MockInputApi() - mock_output_api = MockOutputApi() - contents = ['#include <b.h>', - '#include <a.h>'] - mock_file_cc = MockFile('something.cc', contents) - mock_file_h = MockFile('something.h', contents) - mock_file_other = MockFile('something.py', contents) - mock_input_api.files = [mock_file_cc, mock_file_h, mock_file_other] - warnings = PRESUBMIT._CheckIncludeOrder(mock_input_api, mock_output_api) - self.assertEqual(1, len(warnings)) - self.assertEqual(2, len(warnings[0].items)) - self.assertEqual('promptOrNotify', warnings[0].type) - - def testUncheckableIncludes(self): - mock_input_api = MockInputApi() - contents = ['#include <windows.h>', - '#include "b.h"', - '#include "a.h"'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(1, len(warnings)) - - contents = ['#include "gpu/command_buffer/gles_autogen.h"', - '#include "b.h"', - '#include "a.h"'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(1, len(warnings)) - - contents = ['#include "gl_mock_autogen.h"', - '#include "b.h"', - '#include "a.h"'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(1, len(warnings)) - - contents = ['#include "ipc/some_macros.h"', - '#include "b.h"', - '#include "a.h"'] - mock_file = MockFile('', contents) - warnings = PRESUBMIT._CheckIncludeOrderInFile( - mock_input_api, mock_file, range(1, len(contents) + 1)) - self.assertEqual(1, len(warnings)) - - class VersionControlConflictsTest(unittest.TestCase): def testTypicalConflict(self): lines = ['<<<<<<< HEAD',
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java index 210215e..d78c251 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -95,8 +95,6 @@ private ContentSettingsAdapter mWebSettings; // The WebView wrapper for ContentViewCore and required browser compontents. AwContents mAwContents; - // Non-null if this webview is using the GL accelerated draw path. - private DrawGLFunctor mGLfunctor; private final WebView.HitTestResult mHitTestResult;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index a2e5d00..53bbd560 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1063,7 +1063,6 @@ assert mNativeAwContents == 0 && mCleanupReference == null && mContentViewCore == null; mNativeAwContents = newAwContentsPtr; - nativeSetAwGLFunctor(mNativeAwContents, mInitialFunctor.getNativeAwGLFunctor()); updateNativeAwGLFunctor(); // TODO(joth): when the native and java counterparts of AwBrowserContext are hooked up to // each other, we should update |mBrowserContext| according to the newly received native
diff --git a/android_webview/test/embedded_test_server/BUILD.gn b/android_webview/test/embedded_test_server/BUILD.gn index e9b2f3af..f9d6dbf9 100644 --- a/android_webview/test/embedded_test_server/BUILD.gn +++ b/android_webview/test/embedded_test_server/BUILD.gn
@@ -57,6 +57,8 @@ ":aw_java_test_native_support", "//net:test_support", ] + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + configs += [ "//build/config/android:hide_all_but_jni" ] } android_apk("aw_net_test_support_apk") {
diff --git a/ash/ime/ime_controller.cc b/ash/ime/ime_controller.cc index 496c1e0..85527abc 100644 --- a/ash/ime/ime_controller.cc +++ b/ash/ime/ime_controller.cc
@@ -43,6 +43,17 @@ client_->SwitchToPreviousIme(); } +void ImeController::SwitchImeById(const std::string& ime_id, + bool show_message) { + if (client_) + client_->SwitchImeById(ime_id, show_message); +} + +void ImeController::ActivateImeMenuItem(const std::string& key) { + if (client_) + client_->ActivateImeMenuItem(key); +} + bool ImeController::CanSwitchImeWithAccelerator( const ui::Accelerator& accelerator) const { // If none of the input methods associated with |accelerator| are active, we @@ -67,7 +78,7 @@ ++it; if (it == candidate_ids.end()) it = candidate_ids.begin(); - client_->SwitchImeById(*it); + client_->SwitchImeById(*it, true /* show_message */); } // mojom::ImeController:
diff --git a/ash/ime/ime_controller.h b/ash/ime/ime_controller.h index a9652b8..80c9412 100644 --- a/ash/ime/ime_controller.h +++ b/ash/ime/ime_controller.h
@@ -42,9 +42,14 @@ // Binds the mojo interface to this object. void BindRequest(mojom::ImeControllerRequest request); + // Returns true if switching to next/previous IME is allowed. bool CanSwitchIme() const; + + // Wrappers for mojom::ImeControllerClient methods. void SwitchToNextIme(); void SwitchToPreviousIme(); + void SwitchImeById(const std::string& ime_id, bool show_message); + void ActivateImeMenuItem(const std::string& key); // Returns true if the switch is allowed and the keystroke should be // consumed.
diff --git a/ash/ime/ime_controller_unittest.cc b/ash/ime/ime_controller_unittest.cc index d454d86..9c3e38d 100644 --- a/ash/ime/ime_controller_unittest.cc +++ b/ash/ime/ime_controller_unittest.cc
@@ -74,16 +74,18 @@ // mojom::ImeControllerClient: void SwitchToNextIme() override { ++next_ime_count_; } void SwitchToPreviousIme() override { ++previous_ime_count_; } - void SwitchImeById(const std::string& id) override { + void SwitchImeById(const std::string& id, bool show_message) override { ++switch_ime_count_; last_switch_ime_id_ = id; + last_show_message_ = show_message; } - void ActivateImeProperty(const std::string& key) override {} + void ActivateImeMenuItem(const std::string& key) override {} int next_ime_count_ = 0; int previous_ime_count_ = 0; int switch_ime_count_ = 0; std::string last_switch_ime_id_; + bool last_show_message_ = false; private: mojo::Binding<mojom::ImeControllerClient> binding_; @@ -175,6 +177,9 @@ controller->SwitchToPreviousIme(); EXPECT_EQ(0, client.previous_ime_count_); + controller->SwitchImeById("ime1", true /* show_message */); + EXPECT_EQ(0, client.switch_ime_count_); + // After setting the client the requests are forwarded. controller->SetClient(client.CreateInterfacePtr()); controller->SwitchToNextIme(); @@ -184,6 +189,18 @@ controller->SwitchToPreviousIme(); controller->FlushMojoForTesting(); EXPECT_EQ(1, client.previous_ime_count_); + + controller->SwitchImeById("ime1", true /* show_message */); + controller->FlushMojoForTesting(); + EXPECT_EQ(1, client.switch_ime_count_); + EXPECT_EQ("ime1", client.last_switch_ime_id_); + EXPECT_TRUE(client.last_show_message_); + + controller->SwitchImeById("ime2", false /* show_message */); + controller->FlushMojoForTesting(); + EXPECT_EQ(2, client.switch_ime_count_); + EXPECT_EQ("ime2", client.last_switch_ime_id_); + EXPECT_FALSE(client.last_show_message_); } TEST_F(ImeControllerTest, SwitchImeWithAccelerator) {
diff --git a/ash/public/interfaces/ime_controller.mojom b/ash/public/interfaces/ime_controller.mojom index d66f415..8bccdf5f 100644 --- a/ash/public/interfaces/ime_controller.mojom +++ b/ash/public/interfaces/ime_controller.mojom
@@ -41,11 +41,11 @@ // Switches to an input method by |id|. Does nothing if the input method is // not installed. The ID is usually the output of a call like // chromeos::extension_ime_util::GetInputMethodIDByEngineID("xkb:jp::jpn"), - // see that function for details. - SwitchImeById(string id); + // see that function for details. Shows a bubble with the input method short + // name when |show_message| is true. + SwitchImeById(string id, bool show_message); - // Activates an input method property. These are settings that are provided by - // IME extensions that appear in the IME menu. Does nothing if the |key| does - // not exist. - ActivateImeProperty(string key); + // Activates an input method menu item. The |key| must be a value from the + // ImeMenuItems provided via RefreshIme. Does nothing if the |key| is invalid. + ActivateImeMenuItem(string key); };
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index e1ce3ff..f1dbd573 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -230,6 +230,8 @@ "touch_calibration_complete_check.1x.icon", "touch_calibration_complete_check.icon", "touch_calibration_hand.icon", + "tray_action_new_lock_screen_note.1x.icon", + "tray_action_new_lock_screen_note.icon", "window_control_back.1x.icon", "window_control_back.icon", "window_control_close.1x.icon",
diff --git a/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon b/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon new file mode 100644 index 0000000..f482c465 --- /dev/null +++ b/ash/resources/vector_icons/tray_action_new_lock_screen_note.1x.icon
@@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 9.33f, 1.33f, +LINE_TO, 4, 1.33f, +CUBIC_TO, 3.26f, 1.33f, 2.67f, 1.93f, 2.67f, 2.67f, +LINE_TO, 2.67f, 13.33f, +CUBIC_TO, 2.67f, 14.07f, 3.26f, 14.67f, 3.99f, 14.67f, +LINE_TO, 12, 14.67f, +CUBIC_TO, 12.74f, 14.67f, 13.33f, 14.07f, 13.33f, 13.33f, +LINE_TO, 13.33f, 5.33f, +LINE_TO, 9.33f, 1.33f, +CLOSE, +MOVE_TO, 10.67f, 10.67f, +LINE_TO, 8.67f, 10.67f, +LINE_TO, 8.67f, 12.67f, +LINE_TO, 7.33f, 12.67f, +LINE_TO, 7.33f, 10.67f, +LINE_TO, 5.33f, 10.67f, +LINE_TO, 5.33f, 9.33f, +LINE_TO, 7.33f, 9.33f, +LINE_TO, 7.33f, 7.33f, +LINE_TO, 8.67f, 7.33f, +LINE_TO, 8.67f, 9.33f, +LINE_TO, 10.67f, 9.33f, +LINE_TO, 10.67f, 10.67f, +CLOSE, +MOVE_TO, 8.67f, 6, +LINE_TO, 8.67f, 2.33f, +LINE_TO, 12.33f, 6, +LINE_TO, 8.67f, 6, +CLOSE, +END
diff --git a/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon b/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon new file mode 100644 index 0000000..e7c8c23 --- /dev/null +++ b/ash/resources/vector_icons/tray_action_new_lock_screen_note.icon
@@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 32, +MOVE_TO, 18.67f, 2.67f, +LINE_TO, 8, 2.67f, +CUBIC_TO, 6.53f, 2.67f, 5.35f, 3.86f, 5.35f, 5.33f, +LINE_TO, 5.33f, 26.67f, +CUBIC_TO, 5.33f, 28.14f, 6.51f, 29.33f, 7.99f, 29.33f, +LINE_TO, 24, 29.33f, +CUBIC_TO, 25.47f, 29.33f, 26.67f, 28.14f, 26.67f, 26.67f, +LINE_TO, 26.67f, 10.67f, +LINE_TO, 18.67f, 2.67f, +CLOSE, +MOVE_TO, 21.33f, 21.33f, +LINE_TO, 17.33f, 21.33f, +LINE_TO, 17.33f, 25.33f, +LINE_TO, 14.67f, 25.33f, +LINE_TO, 14.67f, 21.33f, +LINE_TO, 10.67f, 21.33f, +LINE_TO, 10.67f, 18.67f, +LINE_TO, 14.67f, 18.67f, +LINE_TO, 14.67f, 14.67f, +LINE_TO, 17.33f, 14.67f, +LINE_TO, 17.33f, 18.67f, +LINE_TO, 21.33f, 18.67f, +LINE_TO, 21.33f, 21.33f, +CLOSE, +MOVE_TO, 17.33f, 12, +LINE_TO, 17.33f, 4.67f, +LINE_TO, 24.67f, 12, +LINE_TO, 17.33f, 12, +CLOSE, +END
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc index 6c8f6e7..82948a84 100644 --- a/ash/shelf/app_list_button.cc +++ b/ash/shelf/app_list_button.cc
@@ -21,6 +21,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" +#include "base/timer/timer.h" #include "chromeos/chromeos_switches.h" #include "ui/accessibility/ax_node_data.h" #include "ui/app_list/presenter/app_list.h" @@ -42,6 +43,9 @@ #include "ui/views/painter.h" namespace ash { +namespace { +constexpr int kVoiceInteractionAnimationDelayMs = 200; +} // namespace constexpr uint8_t kVoiceInteractionRunningAlpha = 255; // 100% alpha constexpr uint8_t kVoiceInteractionNotRunningAlpha = 138; // 54% alpha @@ -72,6 +76,7 @@ voice_interaction_overlay_ = new VoiceInteractionOverlay(this); AddChildView(voice_interaction_overlay_); voice_interaction_overlay_->SetVisible(false); + voice_interaction_animation_delay_timer_.reset(new base::OneShotTimer()); } else { voice_interaction_overlay_ = nullptr; } @@ -79,6 +84,8 @@ AppListButton::~AppListButton() { Shell::Get()->RemoveShellObserver(this); + if (voice_interaction_animation_delay_timer_) + voice_interaction_animation_delay_timer_->Stop(); } void AppListButton::OnAppListShown() { @@ -116,13 +123,21 @@ return; case ui::ET_GESTURE_TAP: case ui::ET_GESTURE_TAP_CANCEL: - if (voice_interaction_overlay_) + if (voice_interaction_overlay_) { voice_interaction_overlay_->EndAnimation(); + voice_interaction_animation_delay_timer_->Stop(); + } ImageButton::OnGestureEvent(event); return; case ui::ET_GESTURE_TAP_DOWN: - if (voice_interaction_overlay_) - voice_interaction_overlay_->StartAnimation(); + if (voice_interaction_overlay_) { + voice_interaction_animation_delay_timer_->Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds( + kVoiceInteractionAnimationDelayMs), + base::Bind(&VoiceInteractionOverlay::StartAnimation, + base::Unretained(voice_interaction_overlay_))); + } if (!Shell::Get()->IsAppListVisible()) AnimateInkDrop(views::InkDropState::ACTION_PENDING, event); ImageButton::OnGestureEvent(event);
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h index 987fe19..6ad53960 100644 --- a/ash/shelf/app_list_button.h +++ b/ash/shelf/app_list_button.h
@@ -13,6 +13,10 @@ #include "third_party/skia/include/core/SkColor.h" #include "ui/views/controls/button/image_button.h" +namespace base { +class OneShotTimer; +} // namespace base + namespace ash { class InkDropButtonListener; class Shelf; @@ -75,6 +79,7 @@ Shelf* shelf_; VoiceInteractionOverlay* voice_interaction_overlay_; + std::unique_ptr<base::OneShotTimer> voice_interaction_animation_delay_timer_; bool voice_interaction_running_ = false;
diff --git a/ash/shelf/voice_interaction_overlay.cc b/ash/shelf/voice_interaction_overlay.cc index ad9447d..e50c738 100644 --- a/ash/shelf/voice_interaction_overlay.cc +++ b/ash/shelf/voice_interaction_overlay.cc
@@ -48,7 +48,7 @@ namespace ash { namespace { -constexpr int kFullExpandDurationMs = 650; +constexpr int kFullExpandDurationMs = 450; constexpr int kFullRetractDurationMs = 300; constexpr int kFullBurstDurationMs = 200; @@ -72,7 +72,6 @@ constexpr float kBackgroundInitSizeDip = 48.f; constexpr float kBackgroundStartSizeDip = 10.f; constexpr float kBackgroundSizeDip = 48.f; -constexpr int kBackgroundStartDelayMs = 100; constexpr int kBackgroundOpacityDurationMs = 200; constexpr float kBackgroundShadowElevationDip = 24.f; @@ -116,8 +115,9 @@ flags.setStyle(cc::PaintFlags::kFill_Style); flags.setLooper(gfx::CreateShadowDrawLooper(shadow_values_)); gfx::Rect shadow_bounds = shadow_layer_->bounds(); - canvas->DrawCircle({radius - shadow_bounds.x(), radius - shadow_bounds.y()}, - radius, flags); + canvas->DrawCircle( + gfx::PointF(radius - shadow_bounds.x(), radius - shadow_bounds.y()), + radius, flags); } void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} @@ -210,7 +210,7 @@ ui::ScopedLayerAnimationSettings settings(ripple_layer_->GetAnimator()); settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kRippleExpandDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2); ripple_layer_->SetTransform(transform); @@ -255,14 +255,13 @@ ui::ScopedLayerAnimationSettings settings(icon_layer_->GetAnimator()); settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kFullExpandDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2); icon_layer_->SetTransform(transform); icon_layer_->SetOpacity(kIconOpacity); } // Setup background initial state. - background_layer_->SetVisible(false); background_layer_->SetOpacity(0); transform.MakeIdentity(); @@ -294,7 +293,7 @@ ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator()); settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kFullExpandDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2); background_layer_->SetTransform(transform); } @@ -302,14 +301,9 @@ { ui::ScopedLayerAnimationSettings settings(background_layer_->GetAnimator()); settings.SetTransitionDuration( - base::TimeDelta::FromMilliseconds(kBackgroundStartDelayMs)); - background_layer_->SetVisible(true); - - settings.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kBackgroundOpacityDurationMs)); - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); - settings.SetPreemptionStrategy( - ui::LayerAnimator::PreemptionStrategy::ENQUEUE_NEW_ANIMATION); + settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_2); + background_layer_->SetOpacity(1); } }
diff --git a/ash/system/ime/tray_ime_chromeos_unittest.cc b/ash/system/ime/tray_ime_chromeos_unittest.cc index 7b65293..533c3e5 100644 --- a/ash/system/ime/tray_ime_chromeos_unittest.cc +++ b/ash/system/ime/tray_ime_chromeos_unittest.cc
@@ -228,10 +228,6 @@ // Tests that if no IMEs are present the default view is hidden when a11y is // enabled. TEST_F(TrayIMETest, HidesOnA11yEnabled) { - // TODO: investigate failure in mash. http://crbug.com/695561. - if (Shell::GetAshConfig() == Config::MASH) - return; - SetActiveImeCount(0); SuppressKeyboard(); EXPECT_TRUE(default_view()->visible()); @@ -246,10 +242,6 @@ // Tests that clicking on the keyboard toggle causes the virtual keyboard // to toggle between enabled and disabled. TEST_F(TrayIMETest, PerformActionOnDetailedView) { - // TODO: investigate failure in mash. http://crbug.com/695561. - if (Shell::GetAshConfig() == Config::MASH) - return; - SetActiveImeCount(0); SuppressKeyboard(); EXPECT_FALSE(keyboard::IsKeyboardEnabled());
diff --git a/ash/system/ime_menu/ime_list_view.cc b/ash/system/ime_menu/ime_list_view.cc index 282e734f..10fcbb3 100644 --- a/ash/system/ime_menu/ime_list_view.cc +++ b/ash/system/ime_menu/ime_list_view.cc
@@ -22,7 +22,6 @@ #include "ash/system/tray/tri_view.h" #include "base/metrics/histogram_macros.h" #include "ui/accessibility/ax_node_data.h" -#include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_palette.h" @@ -38,8 +37,6 @@ #include "ui/views/view.h" #include "ui/views/widget/widget.h" -using chromeos::input_method::InputMethodManager; - namespace ash { namespace { @@ -296,14 +293,14 @@ } void ImeListView::HandleViewClicked(views::View* view) { + ImeController* ime_controller = Shell::Get()->ime_controller(); std::map<views::View*, std::string>::const_iterator ime = ime_map_.find(view); if (ime != ime_map_.end()) { Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_IME_SWITCH_MODE); std::string ime_id = ime->second; last_selected_item_id_ = ime_id; - InputMethodManager::Get()->GetActiveIMEState()->ChangeInputMethod( - ime_id, false /* show_message */); + ime_controller->SwitchImeById(ime_id, false /* show_message */); UMA_HISTOGRAM_ENUMERATION("InputMethod.ImeSwitch", ImeSwitchType::kTray, ImeSwitchType::kCount); @@ -314,7 +311,7 @@ return; const std::string key = property->second; last_selected_item_id_ = key; - InputMethodManager::Get()->ActivateInputMethodMenuItem(key); + ime_controller->ActivateImeMenuItem(key); } if (!should_focus_ime_after_selection_with_keyboard_ ||
diff --git a/ash/system/lock_screen_action/lock_screen_action_tray.cc b/ash/system/lock_screen_action/lock_screen_action_tray.cc index bc475b65..92a7f51 100644 --- a/ash/system/lock_screen_action/lock_screen_action_tray.cc +++ b/ash/system/lock_screen_action/lock_screen_action_tray.cc
@@ -21,47 +21,19 @@ namespace ash { -namespace { - -// The preferred size for the tray item view. -const int kItemViewPreferredSize = 32; - -} // namespace - -// View for the tray item for the lock screen note creation action. -class LockScreenActionTray::NewNoteActionView : public views::View { - public: - NewNoteActionView() { - SetLayoutManager(new views::FillLayout); - icon_ = new views::ImageView(); - icon_->SetImage(CreateVectorIcon(kPaletteActionCreateNoteIcon, - kTrayIconSize, kShelfIconColor)); - icon_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_CREATE_NOTE_ACTION)); - AddChildView(icon_); - } - - ~NewNoteActionView() override {} - - gfx::Size CalculatePreferredSize() const override { - return gfx::Size(kItemViewPreferredSize, kItemViewPreferredSize); - } - - const gfx::ImageSkia& GetImage() const { return icon_->GetImage(); } - - private: - views::ImageView* icon_; - - DISALLOW_COPY_AND_ASSIGN(NewNoteActionView); -}; - LockScreenActionTray::LockScreenActionTray(Shelf* shelf) : TrayBackgroundView(shelf), session_observer_(this), tray_action_observer_(this) { SetInkDropMode(InkDropMode::ON); SetVisible(false); - new_note_action_view_ = new NewNoteActionView(); + new_note_action_view_ = new views::ImageView(); + new_note_action_view_->SetImage( + CreateVectorIcon(kTrayActionNewLockScreenNoteIcon, kShelfIconColor)); + new_note_action_view_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_CREATE_NOTE_ACTION)); + new_note_action_view_->SetPreferredSize( + gfx::Size(kTrayItemSize, kTrayItemSize)); tray_container()->AddChildView(new_note_action_view_); }
diff --git a/ash/system/lock_screen_action/lock_screen_action_tray.h b/ash/system/lock_screen_action/lock_screen_action_tray.h index 857ecb8..e4afed77 100644 --- a/ash/system/lock_screen_action/lock_screen_action_tray.h +++ b/ash/system/lock_screen_action/lock_screen_action_tray.h
@@ -17,6 +17,10 @@ class ImageSkia; } +namespace views { +class ImageView; +} + namespace ash { class SessionController; @@ -57,8 +61,6 @@ const gfx::ImageSkia& GetImageForTesting() const; private: - class NewNoteActionView; - // Whether the tray item should be visible in its current state. bool IsStateVisible() const; @@ -66,7 +68,7 @@ void UpdateNewNoteIcon(); // The view for the tray item - it's a wrapper around a ImageView. - NewNoteActionView* new_note_action_view_; + views::ImageView* new_note_action_view_; mojom::TrayActionState new_note_state_ = mojom::TrayActionState::kNotAvailable;
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc index ea786f10..1d75f99 100644 --- a/ash/system/network/network_list.cc +++ b/ash/system/network/network_list.cc
@@ -318,16 +318,6 @@ NetworkStateHandler::NetworkStateList network_list; handler->GetVisibleNetworkList(&network_list); UpdateNetworks(network_list); - - // Add Tether networks. - NetworkStateHandler::NetworkStateList tether_network_list; - handler->GetVisibleNetworkListByType(NetworkTypePattern::Tether(), - &tether_network_list); - for (const auto* tether_network : tether_network_list) { - network_list_.push_back( - base::MakeUnique<NetworkInfo>(tether_network->guid())); - } - UpdateNetworkIcons(); UpdateNetworkListInternal(); } @@ -355,12 +345,6 @@ for (const auto* network : networks) { if (!NetworkTypePattern::NonVirtual().MatchesType(network->type())) continue; - - // Do not add Wi-Fi networks that are associated with a Tether network. - if (NetworkTypePattern::WiFi().MatchesType(network->type()) && - !network->tether_guid().empty()) - continue; - network_list_.push_back(base::MakeUnique<NetworkInfo>(network->guid())); } }
diff --git a/ash/system/overview/overview_button_tray.cc b/ash/system/overview/overview_button_tray.cc index cf3d55b..9af0ea5 100644 --- a/ash/system/overview/overview_button_tray.cc +++ b/ash/system/overview/overview_button_tray.cc
@@ -15,11 +15,11 @@ #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/window_selector_controller.h" +#include "ash/wm/window_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/border.h" #include "ui/views/controls/image_view.h" -#include "ui/wm/core/window_util.h" namespace ash { @@ -69,7 +69,7 @@ // current window), if it exists. if (mru_window_list.size() > 1) { AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); - ::wm::ActivateWindow(mru_window_list[1]); + wm::GetWindowState(mru_window_list[1])->Activate(); return true; } }
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc index e378071..97f2a72 100644 --- a/ash/system/overview/overview_button_tray_unittest.cc +++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -19,6 +19,7 @@ #include "ash/test/status_area_widget_test_helper.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "ash/wm/overview/window_selector_controller.h" +#include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "base/command_line.h" #include "base/test/user_action_tester.h" @@ -157,6 +158,13 @@ PerformDoubleTap(); EXPECT_TRUE(wm::IsActiveWindow(window1.get())); EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting()); + + // Verify that if we minimize a window, double tapping the overlay tray button + // will bring up the window. + wm::GetWindowState(window2.get())->Minimize(); + ASSERT_EQ(window2->layer()->GetTargetOpacity(), 0.0); + PerformDoubleTap(); + EXPECT_EQ(window2->layer()->GetTargetOpacity(), 1.0); } // Tests that tapping on the control will record the user action Tray_Overview.
diff --git a/ash/wm/overview/scoped_transform_overview_window.cc b/ash/wm/overview/scoped_transform_overview_window.cc index 37ef65d..9e5cbde 100644 --- a/ash/wm/overview/scoped_transform_overview_window.cc +++ b/ash/wm/overview/scoped_transform_overview_window.cc
@@ -405,6 +405,9 @@ if (!minimized_widget_) CreateMirrorWindowForMinimizedState(); } else { + // If the original window is no longer minimized, make sure it will be + // visible when we restore it when selection mode ends. + EnsureVisible(); minimized_widget_->CloseNow(); minimized_widget_.reset(); }
diff --git a/ash/wm/panels/attached_panel_window_targeter.cc b/ash/wm/panels/attached_panel_window_targeter.cc index 0f365d5..7c151164 100644 --- a/ash/wm/panels/attached_panel_window_targeter.cc +++ b/ash/wm/panels/attached_panel_window_targeter.cc
@@ -70,6 +70,8 @@ default_touch_extend_.left(), default_touch_extend_.bottom(), 0); } + NOTREACHED(); + return gfx::Insets(); } } // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn index 91a18fa..9e1e77a 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -199,6 +199,8 @@ "android/throw_uncaught_exception.h", "android/time_utils.cc", "android/time_utils.h", + "android/timezone_utils.cc", + "android/timezone_utils.h", "android/trace_event_binding.cc", "android/trace_event_binding.h", "android/unguessable_token_android.cc", @@ -703,8 +705,6 @@ "profiler/scoped_tracker.h", "profiler/stack_sampling_profiler.cc", "profiler/stack_sampling_profiler.h", - "profiler/tracked_time.cc", - "profiler/tracked_time.h", "rand_util.cc", "rand_util.h", "rand_util_nacl.cc", @@ -2145,7 +2145,6 @@ "process/process_unittest.cc", "process/process_util_unittest.cc", "profiler/stack_sampling_profiler_unittest.cc", - "profiler/tracked_time_unittest.cc", "rand_util_unittest.cc", "run_loop_unittest.cc", "scoped_clear_errno_unittest.cc", @@ -2527,6 +2526,7 @@ "android/java/src/org/chromium/base/ThreadUtils.java", "android/java/src/org/chromium/base/ThrowUncaughtException.java", "android/java/src/org/chromium/base/TimeUtils.java", + "android/java/src/org/chromium/base/TimezoneUtils.java", "android/java/src/org/chromium/base/TraceEvent.java", "android/java/src/org/chromium/base/UnguessableToken.java", "android/java/src/org/chromium/base/library_loader/LibraryLoader.java", @@ -2605,6 +2605,7 @@ "android/java/src/org/chromium/base/ThreadUtils.java", "android/java/src/org/chromium/base/ThrowUncaughtException.java", "android/java/src/org/chromium/base/TimeUtils.java", + "android/java/src/org/chromium/base/TimezoneUtils.java", "android/java/src/org/chromium/base/TraceEvent.java", "android/java/src/org/chromium/base/UnguessableToken.java", "android/java/src/org/chromium/base/VisibleForTesting.java",
diff --git a/base/android/java/src/org/chromium/base/TimezoneUtils.java b/base/android/java/src/org/chromium/base/TimezoneUtils.java new file mode 100644 index 0000000..cddd3d9d --- /dev/null +++ b/base/android/java/src/org/chromium/base/TimezoneUtils.java
@@ -0,0 +1,36 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.base; + +import android.os.StrictMode; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.MainDex; + +import java.util.TimeZone; + +@JNINamespace("base::android") +@MainDex +class TimezoneUtils { + /** + * Guards this class from being instantiated. + */ + + private TimezoneUtils() {} + + /** + * @return the Olson timezone ID of the current system time zone. + */ + @CalledByNative + private static String getDefaultTimeZoneId() { + // On Android N or earlier, getting the default timezone requires the disk + // access when a device set up is skipped. + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + String timezoneID = TimeZone.getDefault().getID(); + StrictMode.setThreadPolicy(oldPolicy); + return timezoneID; + } +}
diff --git a/base/android/jni_generator/SampleForTests_jni.golden b/base/android/jni_generator/SampleForTests_jni.golden index 7b384252..e50583ab 100644 --- a/base/android/jni_generator/SampleForTests_jni.golden +++ b/base/android/jni_generator/SampleForTests_jni.golden
@@ -482,24 +482,35 @@ }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} - const int kMethodsInnerClassSize = arraysize(kMethodsInnerClass); +} // namespace android +} // namespace base + +JNI_REGISTRATION_EXPORT bool + RegisterNative_org_chromium_example_jni_1generator_SampleForTests(JNIEnv* + env) { + + const int kMethodsInnerClassSize = + arraysize(base::android::kMethodsInnerClass); if (env->RegisterNatives(InnerClass_clazz(env), - kMethodsInnerClass, + base::android::kMethodsInnerClass, kMethodsInnerClassSize) < 0) { jni_generator::HandleRegistrationError( env, InnerClass_clazz(env), __FILE__); return false; } - const int kMethodsSampleForTestsSize = arraysize(kMethodsSampleForTests); + const int kMethodsSampleForTestsSize = + arraysize(base::android::kMethodsSampleForTests); if (env->RegisterNatives(SampleForTests_clazz(env), - kMethodsSampleForTests, + base::android::kMethodsSampleForTests, kMethodsSampleForTestsSize) < 0) { jni_generator::HandleRegistrationError( env, SampleForTests_clazz(env), __FILE__); @@ -509,7 +520,4 @@ return true; } -} // namespace android -} // namespace base - #endif // org_chromium_example_jni_generator_SampleForTests_JNI
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index 3818009..8249fc9e 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py
@@ -401,7 +401,7 @@ def IsMainDexJavaClass(contents): - """Returns "true" if the class is annotated with "@MainDex", "false" if not. + """Returns True if the class is annotated with "@MainDex", False if not. JNI registration doesn't always need to be completed for non-browser processes since most Java code is only used by the browser process. Classes that are @@ -409,8 +409,17 @@ to force JNI registration. """ re_maindex = re.compile(r'@MainDex[\s\S]*class({|[\s\S]*{)') - found = re.search(re_maindex, contents) - return 'true' if found else 'false' + return bool(re.search(re_maindex, contents)) + + +def GetBinaryClassName(fully_qualified_class): + """Returns a string concatenating the Java package and class.""" + return fully_qualified_class.replace('_', '_1').replace('/', '_') + + +def GetRegistrationFunctionName(fully_qualified_class): + """Returns the register name with a given class.""" + return 'RegisterNative_' + GetBinaryClassName(fully_qualified_class) def GetStaticCastForReturnType(return_type): @@ -620,7 +629,6 @@ is_constructor=True)] self.called_by_natives = MangleCalledByNatives(self.jni_params, self.called_by_natives) - self.constant_fields = [] re_constant_field = re.compile('.*?public static final int (?P<name>.*?);') re_constant_field_value = re.compile( @@ -673,13 +681,12 @@ jni_namespace = ExtractJNINamespace(contents) or options.namespace natives = ExtractNatives(contents, options.ptr_type) called_by_natives = ExtractCalledByNatives(self.jni_params, contents) - maindex = IsMainDexJavaClass(contents) if len(natives) == 0 and len(called_by_natives) == 0: raise SyntaxError('Unable to find any JNI methods for %s.' % fully_qualified_class) inl_header_file_generator = InlHeaderFileGenerator( jni_namespace, fully_qualified_class, natives, called_by_natives, [], - self.jni_params, options, maindex) + self.jni_params, options) self.content = inl_header_file_generator.GetContent() @classmethod @@ -715,8 +722,7 @@ """Generates an inline header file for JNI integration.""" def __init__(self, namespace, fully_qualified_class, natives, - called_by_natives, constant_fields, jni_params, options, - maindex='false'): + called_by_natives, constant_fields, jni_params, options): self.namespace = namespace self.fully_qualified_class = fully_qualified_class self.class_name = self.fully_qualified_class.split('/')[-1] @@ -724,7 +730,6 @@ self.called_by_natives = called_by_natives self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' self.constant_fields = constant_fields - self.maindex = maindex self.jni_params = jni_params self.options = options @@ -766,8 +771,9 @@ // Step 3: RegisterNatives. $JNI_NATIVE_METHODS -$REGISTER_NATIVES +$REGISTER_NATIVES_EMPTY $CLOSE_NAMESPACE +$REGISTER_NATIVES #endif // ${HEADER_GUARD} """) @@ -779,8 +785,9 @@ 'METHOD_STUBS': self.GetMethodStubsString(), 'OPEN_NAMESPACE': self.GetOpenNamespaceString(), 'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(), - 'REGISTER_NATIVES': self.GetRegisterNativesString(), + 'REGISTER_NATIVES_EMPTY': self.GetOriginalRegisterNativesString(), 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(), + 'REGISTER_NATIVES': self.GetRegisterNativesString(), 'HEADER_GUARD': self.header_guard, 'INCLUDES': self.GetIncludesString(), } @@ -829,14 +836,19 @@ return '\n'.join(ret) def SubstituteNativeMethods(self, template): - """Substitutes JAVA_CLASS and KMETHODS in the provided template.""" + """Substitutes NAMESPACE, JAVA_CLASS and KMETHODS in the provided + template.""" ret = [] all_classes = self.GetUniqueClasses(self.natives) all_classes[self.class_name] = self.fully_qualified_class for clazz in all_classes: kmethods = self.GetKMethodsString(clazz) + namespace_str = '' + if self.namespace: + namespace_str = self.namespace + '::' if kmethods: - values = {'JAVA_CLASS': clazz, + values = {'NAMESPACE': namespace_str, + 'JAVA_CLASS': clazz, 'KMETHODS': kmethods} ret += [template.substitute(values)] if not ret: return '' @@ -853,32 +865,38 @@ """) return self.SubstituteNativeMethods(template) + # TODO(agrieve): Remove this function when deleting original registers. + # https://crbug.com/683256. + def GetOriginalRegisterNativesString(self): + """Return the code for original RegisterNatives""" + natives = self.GetRegisterNativesImplString() + if not natives: + return '' + + return """ +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. +static bool RegisterNativesImpl(JNIEnv* env) { + return true; +} +""" + def GetRegisterNativesString(self): """Returns the code for RegisterNatives.""" natives = self.GetRegisterNativesImplString() if not natives: return '' - template = Template("""\ -${REGISTER_NATIVES_SIGNATURE} { -${EARLY_EXIT} +JNI_REGISTRATION_EXPORT bool ${REGISTER_NAME}(JNIEnv* env) { ${NATIVES} return true; } """) - signature = 'static bool RegisterNativesImpl(JNIEnv* env)' - early_exit = '' - if self.options.native_exports_optional: - early_exit = """\ - if (jni_generator::ShouldSkipJniRegistration(%s)) - return true; -""" % self.maindex - - values = {'REGISTER_NATIVES_SIGNATURE': signature, - 'EARLY_EXIT': early_exit, - 'NATIVES': natives, - } - + values = { + 'REGISTER_NAME': + GetRegistrationFunctionName(self.fully_qualified_class), + 'NATIVES': natives + } return template.substitute(values) def GetRegisterNativesImplString(self): @@ -887,10 +905,11 @@ return '' template = Template("""\ - const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); + const int kMethods${JAVA_CLASS}Size = + arraysize(${NAMESPACE}kMethods${JAVA_CLASS}); if (env->RegisterNatives(${JAVA_CLASS}_clazz(env), - kMethods${JAVA_CLASS}, + ${NAMESPACE}kMethods${JAVA_CLASS}, kMethods${JAVA_CLASS}Size) < 0) { jni_generator::HandleRegistrationError( env, ${JAVA_CLASS}_clazz(env), __FILE__); @@ -974,7 +993,7 @@ """ template = Template("Java_${JAVA_NAME}_native${NAME}") - java_name = self.fully_qualified_class.replace('_', '_1').replace('/', '_') + java_name = GetBinaryClassName(self.fully_qualified_class) if native.java_class_name: java_name += '_00024' + native.java_class_name @@ -1314,19 +1333,21 @@ print e sys.exit(1) if output_file: - if not os.path.exists(os.path.dirname(os.path.abspath(output_file))): - os.makedirs(os.path.dirname(os.path.abspath(output_file))) - if options.optimize_generation and os.path.exists(output_file): - with file(output_file, 'r') as f: - existing_content = f.read() - if existing_content == content: - return - with file(output_file, 'w') as f: - f.write(content) + WriteOutput(output_file, content) else: print content +def WriteOutput(output_file, content): + if os.path.exists(output_file): + with open(output_file) as f: + existing_content = f.read() + if existing_content == content: + return + with open(output_file, 'w') as f: + f.write(content) + + def GetScriptName(): script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) base_index = 0 @@ -1363,10 +1384,6 @@ option_parser.add_option('--output_dir', help='The output directory. Must be used with ' '--input') - option_parser.add_option('--optimize_generation', type="int", - default=0, help='Whether we should optimize JNI ' - 'generation by not regenerating files if they have ' - 'not changed.') option_parser.add_option('--script_name', default=GetScriptName(), help='The name of this script in the generated ' 'header.')
diff --git a/base/android/jni_generator/jni_generator_helper.h b/base/android/jni_generator/jni_generator_helper.h index 3062806..53629a657 100644 --- a/base/android/jni_generator/jni_generator_helper.h +++ b/base/android/jni_generator/jni_generator_helper.h
@@ -30,6 +30,13 @@ #define JNI_GENERATOR_EXPORT extern "C" __attribute__((visibility("default"))) #endif +// Used to export JNI registration functions. +#if defined(COMPONENT_BUILD) +#define JNI_REGISTRATION_EXPORT __attribute__((visibility("default"))) +#else +#define JNI_REGISTRATION_EXPORT +#endif + namespace jni_generator { inline void HandleRegistrationError(JNIEnv* env, @@ -42,12 +49,14 @@ base::android::CheckException(env); } +// TODO(estevenson): Remove this function since all natives are registered +// together. Currently gvr-android-sdk stil calls it. +// https://crbug.com/664306. inline bool ShouldSkipJniRegistration(bool is_maindex_class) { switch (base::android::GetJniRegistrationType()) { case base::android::ALL_JNI_REGISTRATION: return false; case base::android::NO_JNI_REGISTRATION: - // TODO(estevenson): Change this to a DCHECK. return true; case base::android::SELECTIVE_JNI_REGISTRATION: return !is_maindex_class;
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py index d667a47..41e617f 100755 --- a/base/android/jni_generator/jni_generator_tests.py +++ b/base/android/jni_generator/jni_generator_tests.py
@@ -967,33 +967,6 @@ test_options) self.assertGoldenTextEquals(h.GetContent()) - def testMainDexFile(self): - test_data = """ - package org.chromium.example.jni_generator; - - @MainDex - class Test { - private static native int nativeStaticMethod(long nativeTest, int arg1); - } - """ - options = TestOptions() - jni_from_java = jni_generator.JNIFromJavaSource( - test_data, 'org/chromium/foo/Bar', options) - self.assertGoldenTextEquals(jni_from_java.GetContent()) - - def testNonMainDexFile(self): - test_data = """ - package org.chromium.example.jni_generator; - - class Test { - private static native int nativeStaticMethod(long nativeTest, int arg1); - } - """ - options = TestOptions() - jni_from_java = jni_generator.JNIFromJavaSource( - test_data, 'org/chromium/foo/Bar', options) - self.assertGoldenTextEquals(jni_from_java.GetContent()) - def testMainDexAnnotation(self): mainDexEntries = [ '@MainDex public class Test {', @@ -1021,7 +994,7 @@ '@MainDex public class Test extends Testable<java.io.Serializable> {', ] for entry in mainDexEntries: - self.assertEquals("true", IsMainDexJavaClass(entry)) + self.assertEquals(True, IsMainDexJavaClass(entry)) def testNoMainDexAnnotation(self): noMainDexEntries = [ @@ -1031,7 +1004,7 @@ 'public class Test extends BaseTest {' ] for entry in noMainDexEntries: - self.assertEquals("false", IsMainDexJavaClass(entry)) + self.assertEquals(False, IsMainDexJavaClass(entry)) def testNativeExportsOnlyOption(self): test_data = """
diff --git a/base/android/jni_generator/jni_registration_generator.py b/base/android/jni_generator/jni_registration_generator.py new file mode 100755 index 0000000..febb5b7 --- /dev/null +++ b/base/android/jni_generator/jni_registration_generator.py
@@ -0,0 +1,179 @@ +#!/usr/bin/env python +# 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. + +"""Generate JNI registration entry points + +Creates a header file with two static functions: RegisterMainDexNatives() and +RegisterNonMainDexNatives(). Together, these will use manual JNI registration +to register all native methods that exist within an application.""" + +import argparse +import jni_generator +import os +import string +import sys +from util import build_utils + + +def GenerateJNIHeader(java_file_paths, output_file, args): + """Generate a header file including two registration functions. + + Forward declares all JNI registration functions created by jni_generator.py. + Calls the functions in RegisterMainDexNatives() if they are main dex. And + calls them in RegisterNonMainDexNatives() if they are non-main dex. + + Args: + java_file_paths: A list of java file paths. + output_file: A relative path to output file. + args: All input arguments. + """ + registration_dict = { + 'FORWARD_DECLARATIONS': '', + 'REGISTER_MAIN_DEX_NATIVES': '', + 'REGISTER_NON_MAIN_DEX_NATIVES': '' + } + # Sort the file list to make sure the order is deterministic. + java_file_paths.sort() + for path in java_file_paths: + if path in args.no_register_java: + continue + with open(path) as f: + contents = f.read() + natives = jni_generator.ExtractNatives(contents, 'long') + if len(natives) == 0: + continue + fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName( + path, contents) + main_dex = jni_generator.IsMainDexJavaClass(contents) + header_generator = HeaderGenerator( + fully_qualified_class, registration_dict, main_dex) + registration_dict = header_generator.GetContent() + + header_content = CreateFromDict(registration_dict) + if output_file: + jni_generator.WriteOutput(output_file, header_content) + else: + print header_content + + +def CreateFromDict(registration_dict): + """Returns the content of the header file.""" + + template = string.Template("""\ +// 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. + + +// This file is autogenerated by +// base/android/jni_generator/jni_registration_generator.py +// Please do not change its content. + +#ifndef HEADER_GUARD +#define HEADER_GUARD + +#include <jni.h> + +#include "base/android/jni_generator/jni_generator_helper.h" +#include "base/android/jni_int_wrapper.h" + +// Step 1: Forward declaration. +${FORWARD_DECLARATIONS} + +// Step 2: Main dex and non-main dex registration functions. + +bool RegisterMainDexNatives(JNIEnv* env) { +${REGISTER_MAIN_DEX_NATIVES} + + return true; +} + +bool RegisterNonMainDexNatives(JNIEnv* env) { +${REGISTER_NON_MAIN_DEX_NATIVES} + + return true; +} + +#endif // HEADER_GUARD +""") + if len(registration_dict['FORWARD_DECLARATIONS']) == 0: + return '' + return jni_generator.WrapOutput(template.substitute(registration_dict)) + + +class HeaderGenerator(object): + """Generates an inline header file for JNI registration.""" + + def __init__(self, fully_qualified_class, registration_dict, main_dex): + self.fully_qualified_class = fully_qualified_class + self.class_name = self.fully_qualified_class.split('/')[-1] + self.registration_dict = registration_dict + self.main_dex = main_dex + + def GetContent(self): + self._AddForwardDeclaration() + self._AddRegisterNatives() + return self.registration_dict + + def _AddForwardDeclaration(self): + """Add the content of the forward declaration to the dictionary.""" + template = string.Template('JNI_REGISTRATION_EXPORT bool ${METHOD_NAME}(' + 'JNIEnv* env);\n') + value = { + 'METHOD_NAME': + jni_generator.GetRegistrationFunctionName( + self.fully_qualified_class) + } + self.registration_dict['FORWARD_DECLARATIONS'] += template.substitute(value) + + def _AddRegisterNatives(self): + """Add the body of the RegisterNativesImpl method to the dictionary.""" + template = string.Template(""" +if (!${REGISTER_NAME}(env)) + return false; +""") + value = { + 'REGISTER_NAME': + jni_generator.GetRegistrationFunctionName( + self.fully_qualified_class) + } + register_body = template.substitute(value) + if self.main_dex: + self.registration_dict['REGISTER_MAIN_DEX_NATIVES'] += register_body + else: + self.registration_dict['REGISTER_NON_MAIN_DEX_NATIVES'] += register_body + + +def main(argv): + arg_parser = argparse.ArgumentParser() + build_utils.AddDepfileOption(arg_parser) + + arg_parser.add_argument('--sources_files', + help='A list of .sources files which contain Java ' + 'file paths. Must be used with --output.') + arg_parser.add_argument('--output', + help='The output file path.') + arg_parser.add_argument('--no_register_java', + help='A list of Java files which should be ignored ' + 'by the parser.') + args = arg_parser.parse_args(build_utils.ExpandFileArgs(argv[1:])) + args.sources_files = build_utils.ParseGnList(args.sources_files) + + if args.sources_files: + java_file_paths = [] + for f in args.sources_files: + # java_file_paths stores each Java file path as a string. + java_file_paths += build_utils.ReadSourcesList(f) + else: + print '\nError: Must specify --sources_files.' + return 1 + output_file = args.output + GenerateJNIHeader(java_file_paths, output_file, args) + + if args.depfile: + build_utils.WriteDepfile(args.depfile, output_file) + +if __name__ == '__main__': + sys.exit(main(sys.argv))
diff --git a/base/android/jni_generator/testInnerClassNatives.golden b/base/android/jni_generator/testInnerClassNatives.golden index 20b8830..363f916 100644 --- a/base/android/jni_generator/testInnerClassNatives.golden +++ b/base/android/jni_generator/testInnerClassNatives.golden
@@ -51,11 +51,16 @@ }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} - const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass); +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) { + + const int kMethodsMyInnerClassSize = + arraysize(kMethodsMyInnerClass); if (env->RegisterNatives(MyInnerClass_clazz(env), kMethodsMyInnerClass,
diff --git a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden index 67352e7..6c07b58 100644 --- a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden +++ b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
@@ -67,9 +67,13 @@ "I", reinterpret_cast<void*>(Java_org_chromium_TestJni_nativeInit) }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} + +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) { const int kMethodsMyOtherInnerClassSize = arraysize(kMethodsMyOtherInnerClass); @@ -82,7 +86,8 @@ return false; } - const int kMethodsTestJniSize = arraysize(kMethodsTestJni); + const int kMethodsTestJniSize = + arraysize(kMethodsTestJni); if (env->RegisterNatives(TestJni_clazz(env), kMethodsTestJni,
diff --git a/base/android/jni_generator/testInnerClassNativesMultiple.golden b/base/android/jni_generator/testInnerClassNativesMultiple.golden index 7807efa..add5ac9 100644 --- a/base/android/jni_generator/testInnerClassNativesMultiple.golden +++ b/base/android/jni_generator/testInnerClassNativesMultiple.golden
@@ -74,9 +74,13 @@ }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} + +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) { const int kMethodsMyOtherInnerClassSize = arraysize(kMethodsMyOtherInnerClass); @@ -89,7 +93,8 @@ return false; } - const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass); + const int kMethodsMyInnerClassSize = + arraysize(kMethodsMyInnerClass); if (env->RegisterNatives(MyInnerClass_clazz(env), kMethodsMyInnerClass,
diff --git a/base/android/jni_generator/testMainDexFile.golden b/base/android/jni_generator/testMainDexFile.golden deleted file mode 100644 index cbb2a7d..0000000 --- a/base/android/jni_generator/testMainDexFile.golden +++ /dev/null
@@ -1,67 +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. - -// This file is autogenerated by -// base/android/jni_generator/jni_generator.py -// For -// org/chromium/foo/Bar - -#ifndef org_chromium_foo_Bar_JNI -#define org_chromium_foo_Bar_JNI - -#include <jni.h> - -#include "base/android/jni_generator/jni_generator_helper.h" - -#include "base/android/jni_int_wrapper.h" - -// Step 1: forward declarations. -namespace { -const char kBarClassPath[] = "org/chromium/foo/Bar"; -// Leaking this jclass as we cannot use LazyInstance from some threads. -base::subtle::AtomicWord g_Bar_clazz __attribute__((unused)) = 0; -#define Bar_clazz(env) base::android::LazyGetClass(env, kBarClassPath, &g_Bar_clazz) - -} // namespace - -// Step 2: method stubs. -JNI_GENERATOR_EXPORT jint Java_org_chromium_foo_Bar_nativeStaticMethod(JNIEnv* - env, jobject jcaller, - jlong nativeTest, - jint arg1) { - Test* native = reinterpret_cast<Test*>(nativeTest); - CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0); - return native->StaticMethod(env, base::android::JavaParamRef<jobject>(env, - jcaller), arg1); -} - -// Step 3: RegisterNatives. - -static const JNINativeMethod kMethodsBar[] = { - { "nativeStaticMethod", -"(" -"J" -"I" -")" -"I", reinterpret_cast<void*>(Java_org_chromium_foo_Bar_nativeStaticMethod) }, -}; - -static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(true)) - return true; - - const int kMethodsBarSize = arraysize(kMethodsBar); - - if (env->RegisterNatives(Bar_clazz(env), - kMethodsBar, - kMethodsBarSize) < 0) { - jni_generator::HandleRegistrationError( - env, Bar_clazz(env), __FILE__); - return false; - } - - return true; -} - -#endif // org_chromium_foo_Bar_JNI
diff --git a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden index 0eecb5a..03aac48e 100644 --- a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden +++ b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
@@ -75,11 +75,16 @@ "V", reinterpret_cast<void*>(Java_org_chromium_foo_Foo_nativeDoSomething) }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} - const int kMethodsFooSize = arraysize(kMethodsFoo); +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_foo_Foo(JNIEnv* env) { + + const int kMethodsFooSize = + arraysize(kMethodsFoo); if (env->RegisterNatives(Foo_clazz(env), kMethodsFoo,
diff --git a/base/android/jni_generator/testNatives.golden b/base/android/jni_generator/testNatives.golden index 3362c928..0bfbe04 100644 --- a/base/android/jni_generator/testNatives.golden +++ b/base/android/jni_generator/testNatives.golden
@@ -320,11 +320,16 @@ }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} - const int kMethodsTestJniSize = arraysize(kMethodsTestJni); +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) { + + const int kMethodsTestJniSize = + arraysize(kMethodsTestJni); if (env->RegisterNatives(TestJni_clazz(env), kMethodsTestJni,
diff --git a/base/android/jni_generator/testNativesLong.golden b/base/android/jni_generator/testNativesLong.golden index ec029ce3..201a066 100644 --- a/base/android/jni_generator/testNativesLong.golden +++ b/base/android/jni_generator/testNativesLong.golden
@@ -46,11 +46,16 @@ "V", reinterpret_cast<void*>(Java_org_chromium_TestJni_nativeDestroy) }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} - const int kMethodsTestJniSize = arraysize(kMethodsTestJni); +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) { + + const int kMethodsTestJniSize = + arraysize(kMethodsTestJni); if (env->RegisterNatives(TestJni_clazz(env), kMethodsTestJni,
diff --git a/base/android/jni_generator/testNonMainDexFile.golden b/base/android/jni_generator/testNonMainDexFile.golden deleted file mode 100644 index 533241e..0000000 --- a/base/android/jni_generator/testNonMainDexFile.golden +++ /dev/null
@@ -1,67 +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. - -// This file is autogenerated by -// base/android/jni_generator/jni_generator.py -// For -// org/chromium/foo/Bar - -#ifndef org_chromium_foo_Bar_JNI -#define org_chromium_foo_Bar_JNI - -#include <jni.h> - -#include "base/android/jni_generator/jni_generator_helper.h" - -#include "base/android/jni_int_wrapper.h" - -// Step 1: forward declarations. -namespace { -const char kBarClassPath[] = "org/chromium/foo/Bar"; -// Leaking this jclass as we cannot use LazyInstance from some threads. -base::subtle::AtomicWord g_Bar_clazz __attribute__((unused)) = 0; -#define Bar_clazz(env) base::android::LazyGetClass(env, kBarClassPath, &g_Bar_clazz) - -} // namespace - -// Step 2: method stubs. -JNI_GENERATOR_EXPORT jint Java_org_chromium_foo_Bar_nativeStaticMethod(JNIEnv* - env, jobject jcaller, - jlong nativeTest, - jint arg1) { - Test* native = reinterpret_cast<Test*>(nativeTest); - CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0); - return native->StaticMethod(env, base::android::JavaParamRef<jobject>(env, - jcaller), arg1); -} - -// Step 3: RegisterNatives. - -static const JNINativeMethod kMethodsBar[] = { - { "nativeStaticMethod", -"(" -"J" -"I" -")" -"I", reinterpret_cast<void*>(Java_org_chromium_foo_Bar_nativeStaticMethod) }, -}; - -static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; - - const int kMethodsBarSize = arraysize(kMethodsBar); - - if (env->RegisterNatives(Bar_clazz(env), - kMethodsBar, - kMethodsBarSize) < 0) { - jni_generator::HandleRegistrationError( - env, Bar_clazz(env), __FILE__); - return false; - } - - return true; -} - -#endif // org_chromium_foo_Bar_JNI
diff --git a/base/android/jni_generator/testSingleJNIAdditionalImport.golden b/base/android/jni_generator/testSingleJNIAdditionalImport.golden index ef618da8..a367ae7 100644 --- a/base/android/jni_generator/testSingleJNIAdditionalImport.golden +++ b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
@@ -69,11 +69,16 @@ "V", reinterpret_cast<void*>(Java_org_chromium_foo_Foo_nativeDoSomething) }, }; +// TODO(agrieve): Remove these empty registration functions and functions +// calling them. https://crbug.com/683256. static bool RegisterNativesImpl(JNIEnv* env) { - if (jni_generator::ShouldSkipJniRegistration(false)) - return true; + return true; +} - const int kMethodsFooSize = arraysize(kMethodsFoo); +JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_foo_Foo(JNIEnv* env) { + + const int kMethodsFooSize = + arraysize(kMethodsFoo); if (env->RegisterNatives(Foo_clazz(env), kMethodsFoo,
diff --git a/base/android/timezone_utils.cc b/base/android/timezone_utils.cc new file mode 100644 index 0000000..5243cdc --- /dev/null +++ b/base/android/timezone_utils.cc
@@ -0,0 +1,23 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/android/timezone_utils.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/strings/string16.h" +#include "jni/TimezoneUtils_jni.h" + +namespace base { +namespace android { + +base::string16 GetDefaultTimeZoneId() { + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jstring> timezone_id = + Java_TimezoneUtils_getDefaultTimeZoneId(env); + return ConvertJavaStringToUTF16(timezone_id); +} + +} // namespace android +} // namespace base
diff --git a/base/android/timezone_utils.h b/base/android/timezone_utils.h new file mode 100644 index 0000000..f78ef85d --- /dev/null +++ b/base/android/timezone_utils.h
@@ -0,0 +1,22 @@ +// 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 BASE_ANDROID_TIMEZONE_UTILS_H_ +#define BASE_ANDROID_TIMEZONE_UTILS_H_ + +#include <jni.h> + +#include "base/base_export.h" +#include "base/strings/string16.h" + +namespace base { +namespace android { + +// Return an ICU timezone created from the host timezone. +BASE_EXPORT base::string16 GetDefaultTimeZoneId(); + +} // namespace android +} // namespace base + +#endif // BASE_ANDROID_TIMEZONE_UTILS_H_
diff --git a/base/atomic_ref_count.h b/base/atomic_ref_count.h index 93c1f0d..cc56f5d 100644 --- a/base/atomic_ref_count.h +++ b/base/atomic_ref_count.h
@@ -8,38 +8,77 @@ #ifndef BASE_ATOMIC_REF_COUNT_H_ #define BASE_ATOMIC_REF_COUNT_H_ -#include "base/atomicops.h" +#include <atomic> namespace base { -typedef subtle::AtomicWord AtomicRefCount; +class AtomicRefCount { + public: + constexpr AtomicRefCount() : ref_count_(0) {} + explicit constexpr AtomicRefCount(int initial_value) + : ref_count_(initial_value) {} + + // Increment a reference count. + void Increment() { Increment(1); } + + // Increment a reference count by "increment", which must exceed 0. + void Increment(int increment) { + ref_count_.fetch_add(increment, std::memory_order_relaxed); + } + + // Decrement a reference count, and return whether the result is non-zero. + // Insert barriers to ensure that state written before the reference count + // became zero will be visible to a thread that has just made the count zero. + bool Decrement() { + // TODO(jbroman): Technically this doesn't need to be an acquire operation + // unless the result is 1 (i.e., the ref count did indeed reach zero). + // However, there are toolchain issues that make that not work as well at + // present (notably TSAN doesn't like it). + return ref_count_.fetch_sub(1, std::memory_order_acq_rel) != 1; + } + + // Return whether the reference count is one. If the reference count is used + // in the conventional way, a refrerence count of 1 implies that the current + // thread owns the reference and no other thread shares it. This call + // performs the test for a reference count of one, and performs the memory + // barrier needed for the owning thread to act on the object, knowing that it + // has exclusive access to the object. + bool IsOne() const { return ref_count_.load(std::memory_order_acquire) == 1; } + + // Return whether the reference count is zero. With conventional object + // referencing counting, the object will be destroyed, so the reference count + // should never be zero. Hence this is generally used for a debug check. + bool IsZero() const { + return ref_count_.load(std::memory_order_acquire) == 0; + } + + // Returns the current reference count (with no barriers). This is subtle, and + // should be used only for debugging. + int SubtleRefCountForDebug() const { + return ref_count_.load(std::memory_order_relaxed); + } + + private: + std::atomic_int ref_count_; +}; + +// TODO(jbroman): Inline these functions once the above changes stick. // Increment a reference count by "increment", which must exceed 0. -inline void AtomicRefCountIncN(volatile AtomicRefCount *ptr, - AtomicRefCount increment) { - subtle::NoBarrier_AtomicIncrement(ptr, increment); -} - -// Decrement a reference count by "decrement", which must exceed 0, -// and return whether the result is non-zero. -// Insert barriers to ensure that state written before the reference count -// became zero will be visible to a thread that has just made the count zero. -inline bool AtomicRefCountDecN(volatile AtomicRefCount *ptr, - AtomicRefCount decrement) { - bool res = (subtle::Barrier_AtomicIncrement(ptr, -decrement) != 0); - return res; +inline void AtomicRefCountIncN(volatile AtomicRefCount* ptr, int increment) { + const_cast<AtomicRefCount*>(ptr)->Increment(increment); } // Increment a reference count by 1. inline void AtomicRefCountInc(volatile AtomicRefCount *ptr) { - base::AtomicRefCountIncN(ptr, 1); + const_cast<AtomicRefCount*>(ptr)->Increment(); } // Decrement a reference count by 1 and return whether the result is non-zero. // Insert barriers to ensure that state written before the reference count // became zero will be visible to a thread that has just made the count zero. inline bool AtomicRefCountDec(volatile AtomicRefCount *ptr) { - return base::AtomicRefCountDecN(ptr, 1); + return const_cast<AtomicRefCount*>(ptr)->Decrement(); } // Return whether the reference count is one. If the reference count is used @@ -49,16 +88,14 @@ // needed for the owning thread to act on the object, knowing that it has // exclusive access to the object. inline bool AtomicRefCountIsOne(volatile AtomicRefCount *ptr) { - bool res = (subtle::Acquire_Load(ptr) == 1); - return res; + return const_cast<AtomicRefCount*>(ptr)->IsOne(); } // Return whether the reference count is zero. With conventional object // referencing counting, the object will be destroyed, so the reference count // should never be zero. Hence this is generally used for a debug check. inline bool AtomicRefCountIsZero(volatile AtomicRefCount *ptr) { - bool res = (subtle::Acquire_Load(ptr) == 0); - return res; + return const_cast<AtomicRefCount*>(ptr)->IsZero(); } } // namespace base
diff --git a/base/debug/task_annotator.cc b/base/debug/task_annotator.cc index 46969f2..10c5636 100644 --- a/base/debug/task_annotator.cc +++ b/base/debug/task_annotator.cc
@@ -35,7 +35,7 @@ tracked_objects::TaskStopwatch stopwatch; stopwatch.Start(); - tracked_objects::Duration queue_duration = + base::TimeDelta queue_duration = stopwatch.StartTime() - pending_task->EffectiveTimePosted(); TRACE_EVENT_WITH_FLOW1(
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc index 124336b..4a1327b 100644 --- a/base/i18n/icu_util.cc +++ b/base/i18n/icu_util.cc
@@ -20,12 +20,13 @@ #include "build/build_config.h" #include "third_party/icu/source/common/unicode/putil.h" #include "third_party/icu/source/common/unicode/udata.h" -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#if (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_ANDROID) #include "third_party/icu/source/i18n/unicode/timezone.h" #endif #if defined(OS_ANDROID) #include "base/android/apk_assets.h" +#include "base/android/timezone_utils.h" #endif #if defined(OS_IOS) @@ -188,6 +189,19 @@ g_debug_icu_load = 3; // To debug http://crbug.com/445616. g_debug_icu_last_error = err; } +#if defined(OS_ANDROID) + else { + // On Android, we can't leave it up to ICU to set the default timezone + // because ICU's timezone detection does not work in many timezones (e.g. + // Australia/Sydney, Asia/Seoul, Europe/Paris ). Use JNI to detect the host + // timezone and set the ICU default timezone accordingly in advance of + // actual use. See crbug.com/722821 and + // https://ssl.icu-project.org/trac/ticket/13208 . + base::string16 timezone_id = base::android::GetDefaultTimeZoneId(); + icu::TimeZone::adoptDefault(icu::TimeZone::createTimeZone( + icu::UnicodeString(FALSE, timezone_id.data(), timezone_id.length()))); + } +#endif return err == U_ZERO_ERROR; } #endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
diff --git a/base/memory/ref_counted.cc b/base/memory/ref_counted.cc index bc8bd5f..ec082ba 100644 --- a/base/memory/ref_counted.cc +++ b/base/memory/ref_counted.cc
@@ -10,7 +10,7 @@ namespace { #if DCHECK_IS_ON() -AtomicRefCount g_cross_thread_ref_count_access_allow_count = 0; +AtomicRefCount g_cross_thread_ref_count_access_allow_count(0); #endif } // namespace
diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h index 56bd4025..743dbabd 100644 --- a/base/memory/ref_counted.h +++ b/base/memory/ref_counted.h
@@ -179,7 +179,7 @@ #endif } - mutable AtomicRefCount ref_count_ = 0; + mutable AtomicRefCount ref_count_{0}; #if DCHECK_IS_ON() mutable bool needs_adopt_ref_ = false; mutable bool in_dtor_ = false;
diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc index c179b80..b6e997b 100644 --- a/base/memory/weak_ptr.cc +++ b/base/memory/weak_ptr.cc
@@ -77,5 +77,11 @@ WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) { } +WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {} + +WeakPtrFactoryBase::~WeakPtrFactoryBase() { + ptr_ = 0; +} + } // namespace internal } // namespace base
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h index 3544439..d7d590b 100644 --- a/base/memory/weak_ptr.h +++ b/base/memory/weak_ptr.h
@@ -275,22 +275,33 @@ return weak_ptr == nullptr; } +namespace internal { +class BASE_EXPORT WeakPtrFactoryBase { + protected: + WeakPtrFactoryBase(uintptr_t ptr); + ~WeakPtrFactoryBase(); + internal::WeakReferenceOwner weak_reference_owner_; + uintptr_t ptr_; +}; +} // namespace internal + // A class may be composed of a WeakPtrFactory and thereby // control how it exposes weak pointers to itself. This is helpful if you only // need weak pointers within the implementation of a class. This class is also // useful when working with primitive types. For example, you could have a // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. template <class T> -class WeakPtrFactory { +class WeakPtrFactory : public internal::WeakPtrFactoryBase { public: - explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { - } + explicit WeakPtrFactory(T* ptr) + : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {} - ~WeakPtrFactory() { ptr_ = nullptr; } + ~WeakPtrFactory() {} WeakPtr<T> GetWeakPtr() { DCHECK(ptr_); - return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); + return WeakPtr<T>(weak_reference_owner_.GetRef(), + reinterpret_cast<T*>(ptr_)); } // Call this method to invalidate all existing weak pointers. @@ -306,8 +317,6 @@ } private: - internal::WeakReferenceOwner weak_reference_owner_; - T* ptr_; DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); };
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc index 4f67794..f3c16d2 100644 --- a/base/metrics/field_trial.cc +++ b/base/metrics/field_trial.cc
@@ -1116,6 +1116,8 @@ // Tell the child process the name of the inherited HANDLE. uintptr_t uintptr_handle = reinterpret_cast<uintptr_t>(shm.GetHandle()); ss << uintptr_handle << ","; +#elif defined(OS_FUCHSIA) + ss << shm.GetHandle() << ","; #elif !defined(OS_POSIX) #error Unsupported OS #endif
diff --git a/base/profiler/scoped_profile.h b/base/profiler/scoped_profile.h index 4df6a1b..b862bbc2 100644 --- a/base/profiler/scoped_profile.h +++ b/base/profiler/scoped_profile.h
@@ -15,7 +15,6 @@ #include "base/base_export.h" #include "base/location.h" #include "base/macros.h" -#include "base/profiler/tracked_time.h" #include "base/trace_event/heap_profiler.h" #include "base/tracked_objects.h"
diff --git a/base/profiler/tracked_time.cc b/base/profiler/tracked_time.cc deleted file mode 100644 index 7e0040c..0000000 --- a/base/profiler/tracked_time.cc +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/profiler/tracked_time.h" - -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <mmsystem.h> // Declare timeGetTime()... after including build_config. -#endif - -namespace tracked_objects { - -Duration::Duration() : ms_(0) {} -Duration::Duration(int32_t duration) : ms_(duration) {} - -Duration& Duration::operator+=(const Duration& other) { - ms_ += other.ms_; - return *this; -} - -Duration Duration::operator+(const Duration& other) const { - return Duration(ms_ + other.ms_); -} - -bool Duration::operator==(const Duration& other) const { - return ms_ == other.ms_; -} - -bool Duration::operator!=(const Duration& other) const { - return ms_ != other.ms_; -} - -bool Duration::operator>(const Duration& other) const { - return ms_ > other.ms_; -} - -// static -Duration Duration::FromMilliseconds(int ms) { return Duration(ms); } - -int32_t Duration::InMilliseconds() const { - return ms_; -} - -//------------------------------------------------------------------------------ - -TrackedTime::TrackedTime() : ms_(0) {} -TrackedTime::TrackedTime(int32_t ms) : ms_(ms) {} -TrackedTime::TrackedTime(const base::TimeTicks& time) - : ms_(static_cast<int32_t>((time - base::TimeTicks()).InMilliseconds())) {} - -// static -TrackedTime TrackedTime::Now() { - return TrackedTime(base::TimeTicks::Now()); -} - -Duration TrackedTime::operator-(const TrackedTime& other) const { - return Duration(ms_ - other.ms_); -} - -TrackedTime TrackedTime::operator+(const Duration& other) const { - return TrackedTime(ms_ + other.ms_); -} - -bool TrackedTime::is_null() const { return ms_ == 0; } - -} // namespace tracked_objects
diff --git a/base/profiler/tracked_time.h b/base/profiler/tracked_time.h deleted file mode 100644 index b32f41b..0000000 --- a/base/profiler/tracked_time.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_PROFILER_TRACKED_TIME_H_ -#define BASE_PROFILER_TRACKED_TIME_H_ - -#include <stdint.h> - -#include "base/base_export.h" -#include "base/time/time.h" - -namespace tracked_objects { - -//------------------------------------------------------------------------------ - -// TimeTicks maintains a wasteful 64 bits of data (we need less than 32), and on -// windows, a 64 bit timer is expensive to even obtain. We use a simple -// millisecond counter for most of our time values, as well as millisecond units -// of duration between those values. This means we can only handle durations -// up to 49 days (range), or 24 days (non-negative time durations). -// We only define enough methods to service the needs of the tracking classes, -// and our interfaces are modeled after what TimeTicks and TimeDelta use (so we -// can swap them into place if we want to use the "real" classes). - -class BASE_EXPORT Duration { // Similar to base::TimeDelta. - public: - Duration(); - - Duration& operator+=(const Duration& other); - Duration operator+(const Duration& other) const; - - bool operator==(const Duration& other) const; - bool operator!=(const Duration& other) const; - bool operator>(const Duration& other) const; - - static Duration FromMilliseconds(int ms); - - int32_t InMilliseconds() const; - - private: - friend class TrackedTime; - explicit Duration(int32_t duration); - - // Internal time is stored directly in milliseconds. - int32_t ms_; -}; - -class BASE_EXPORT TrackedTime { // Similar to base::TimeTicks. - public: - TrackedTime(); - explicit TrackedTime(const base::TimeTicks& time); - - static TrackedTime Now(); - Duration operator-(const TrackedTime& other) const; - TrackedTime operator+(const Duration& other) const; - bool is_null() const; - - static TrackedTime FromMilliseconds(int32_t ms) { return TrackedTime(ms); } - - private: - friend class Duration; - explicit TrackedTime(int32_t ms); - - // Internal duration is stored directly in milliseconds. - uint32_t ms_; -}; - -} // namespace tracked_objects - -#endif // BASE_PROFILER_TRACKED_TIME_H_
diff --git a/base/profiler/tracked_time_unittest.cc b/base/profiler/tracked_time_unittest.cc deleted file mode 100644 index f6d35ba..0000000 --- a/base/profiler/tracked_time_unittest.cc +++ /dev/null
@@ -1,105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Test of classes in tracked_time.cc - -#include <stdint.h> - -#include "base/profiler/tracked_time.h" -#include "base/time/time.h" -#include "base/tracked_objects.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace tracked_objects { - -TEST(TrackedTimeTest, TrackedTimerMilliseconds) { - // First make sure we basicallly transfer simple milliseconds values as - // expected. Most critically, things should not become null. - int32_t kSomeMilliseconds = 243; // Some example times. - int64_t kReallyBigMilliseconds = (1LL << 35) + kSomeMilliseconds; - - TrackedTime some = TrackedTime() + - Duration::FromMilliseconds(kSomeMilliseconds); - EXPECT_EQ(kSomeMilliseconds, (some - TrackedTime()).InMilliseconds()); - EXPECT_FALSE(some.is_null()); - - // Now create a big time, to check that it is wrapped modulo 2^32. - base::TimeTicks big = base::TimeTicks() + - base::TimeDelta::FromMilliseconds(kReallyBigMilliseconds); - EXPECT_EQ(kReallyBigMilliseconds, (big - base::TimeTicks()).InMilliseconds()); - - TrackedTime wrapped_big(big); - // Expect wrapping at 32 bits. - EXPECT_EQ(kSomeMilliseconds, (wrapped_big - TrackedTime()).InMilliseconds()); -} - -TEST(TrackedTimeTest, TrackedTimerDuration) { - int kFirstMilliseconds = 793; - int kSecondMilliseconds = 14889; - - Duration first = Duration::FromMilliseconds(kFirstMilliseconds); - Duration second = Duration::FromMilliseconds(kSecondMilliseconds); - - EXPECT_EQ(kFirstMilliseconds, first.InMilliseconds()); - EXPECT_EQ(kSecondMilliseconds, second.InMilliseconds()); - - Duration sum = first + second; - EXPECT_EQ(kFirstMilliseconds + kSecondMilliseconds, sum.InMilliseconds()); -} - -TEST(TrackedTimeTest, TrackedTimerVsTimeTicks) { - // Make sure that our 32 bit timer is aligned with the TimeTicks() timer. - - // First get a 64 bit timer (which should not be null). - base::TimeTicks ticks_before = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_before.is_null()); - - // Then get a 32 bit timer that can be be null when it wraps. - TrackedTime now = TrackedTime::Now(); - - // Then get a bracketing time. - base::TimeTicks ticks_after = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_after.is_null()); - - // Now make sure that we bracketed our tracked time nicely. - Duration before = now - TrackedTime(ticks_before); - EXPECT_LE(0, before.InMilliseconds()); - Duration after = now - TrackedTime(ticks_after); - EXPECT_GE(0, after.InMilliseconds()); -} - -TEST(TrackedTimeTest, TrackedTimerDisabled) { - // Check to be sure disabling the collection of data induces a null time - // (which we know will return much faster). - ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED); - // Since we disabled tracking, we should get a null response. - TrackedTime track_now = ThreadData::Now(); - EXPECT_TRUE(track_now.is_null()); -} - -TEST(TrackedTimeTest, TrackedTimerEnabled) { - ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE); - // Make sure that when we enable tracking, we get a real timer result. - - // First get a 64 bit timer (which should not be null). - base::TimeTicks ticks_before = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_before.is_null()); - - // Then get a 32 bit timer that can be null when it wraps. - // Crtical difference from the TrackedTimerVsTimeTicks test, is that we use - // ThreadData::Now(). It can sometimes return the null time. - TrackedTime now = ThreadData::Now(); - - // Then get a bracketing time. - base::TimeTicks ticks_after = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_after.is_null()); - - // Now make sure that we bracketed our tracked time nicely. - Duration before = now - TrackedTime(ticks_before); - EXPECT_LE(0, before.InMilliseconds()); - Duration after = now - TrackedTime(ticks_after); - EXPECT_GE(0, after.InMilliseconds()); -} - -} // namespace tracked_objects
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h index 1e35639..f9af1b5 100644 --- a/base/task_scheduler/task_scheduler_impl.h +++ b/base/task_scheduler/task_scheduler_impl.h
@@ -30,6 +30,10 @@ #include "base/task_scheduler/task_tracker_posix.h" #endif +#if defined(OS_WIN) +#include "base/win/com_init_check_hook.h" +#endif + namespace base { class HistogramBase; @@ -99,6 +103,11 @@ AtomicFlag join_for_testing_returned_; #endif +#if defined(OS_WIN) && defined(COM_INIT_CHECK_HOOK_ENABLED) + // Provides COM initialization verification for supported builds. + base::win::ComInitCheckHook com_init_check_hook_; +#endif + DISALLOW_COPY_AND_ASSIGN(TaskSchedulerImpl); };
diff --git a/base/threading/worker_pool_posix.cc b/base/threading/worker_pool_posix.cc index e7aca86..3c50db48 100644 --- a/base/threading/worker_pool_posix.cc +++ b/base/threading/worker_pool_posix.cc
@@ -21,8 +21,6 @@ #include "base/trace_event/trace_event.h" #include "base/tracked_objects.h" -using tracked_objects::TrackedTime; - namespace base { namespace {
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc index f8dbdbc..ad93225f 100644 --- a/base/tracked_objects.cc +++ b/base/tracked_objects.cc
@@ -168,8 +168,8 @@ #define CONDITIONAL_ASSIGN(assign_it, target, source) \ ((target) ^= ((target) ^ (source)) & -static_cast<int32_t>(assign_it)) -void DeathData::RecordDurations(const int32_t queue_duration, - const int32_t run_duration, +void DeathData::RecordDurations(const base::TimeDelta queue_duration, + const base::TimeDelta run_duration, const uint32_t random_number) { // We'll just clamp at INT_MAX, but we should note this in the UI as such. if (count_ < INT_MAX) @@ -182,15 +182,18 @@ base::subtle::NoBarrier_Store(&sample_probability_count_, sample_probability_count); - base::subtle::NoBarrier_Store(&queue_duration_sum_, - queue_duration_sum_ + queue_duration); - base::subtle::NoBarrier_Store(&run_duration_sum_, - run_duration_sum_ + run_duration); + base::subtle::NoBarrier_Store( + &queue_duration_sum_, + queue_duration_sum_ + queue_duration.InMilliseconds()); + base::subtle::NoBarrier_Store( + &run_duration_sum_, run_duration_sum_ + run_duration.InMilliseconds()); - if (queue_duration_max() < queue_duration) - base::subtle::NoBarrier_Store(&queue_duration_max_, queue_duration); - if (run_duration_max() < run_duration) - base::subtle::NoBarrier_Store(&run_duration_max_, run_duration); + if (queue_duration_max() < queue_duration.InMilliseconds()) + base::subtle::NoBarrier_Store(&queue_duration_max_, + queue_duration.InMilliseconds()); + if (run_duration_max() < run_duration.InMilliseconds()) + base::subtle::NoBarrier_Store(&run_duration_max_, + run_duration.InMilliseconds()); // Take a uniformly distributed sample over all durations ever supplied during // the current profiling phase. @@ -202,8 +205,10 @@ // used them to generate random_number). CHECK_GT(sample_probability_count, 0); if (0 == (random_number % sample_probability_count)) { - base::subtle::NoBarrier_Store(&queue_duration_sample_, queue_duration); - base::subtle::NoBarrier_Store(&run_duration_sample_, run_duration); + base::subtle::NoBarrier_Store(&queue_duration_sample_, + queue_duration.InMilliseconds()); + base::subtle::NoBarrier_Store(&run_duration_sample_, + run_duration.InMilliseconds()); } } @@ -533,7 +538,8 @@ sizeof(random_number_)); MSAN_UNPOISON(&random_number_, sizeof(random_number_)); random_number_ += static_cast<uint32_t>(this - static_cast<ThreadData*>(0)); - random_number_ ^= (Now() - TrackedTime()).InMilliseconds(); + random_number_ ^= + static_cast<uint32_t>((Now() - base::TimeTicks()).InMilliseconds()); DCHECK(!next_); base::AutoLock lock(*list_lock_.Pointer()); @@ -678,13 +684,14 @@ } void ThreadData::TallyADeath(const Births& births, - int32_t queue_duration, + const base::TimeDelta queue_duration, const TaskStopwatch& stopwatch) { - int32_t run_duration = stopwatch.RunDurationMs(); + base::TimeDelta run_duration = stopwatch.RunDuration(); // Stir in some randomness, plus add constant in case durations are zero. const uint32_t kSomePrimeNumber = 2147483647; - random_number_ += queue_duration + run_duration + kSomePrimeNumber; + random_number_ += queue_duration.InMilliseconds() + + run_duration.InMilliseconds() + kSomePrimeNumber; // An address is going to have some randomness to it as well ;-). random_number_ ^= static_cast<uint32_t>(&births - reinterpret_cast<Births*>(0)); @@ -743,11 +750,10 @@ // get a time value since we "weren't tracking" and we were trying to be // efficient by not calling for a genuine time value. For simplicity, we'll // use a default zero duration when we can't calculate a true value. - TrackedTime start_of_run = stopwatch.StartTime(); - int32_t queue_duration = 0; + base::TimeTicks start_of_run = stopwatch.StartTime(); + base::TimeDelta queue_duration; if (!start_of_run.is_null()) { - queue_duration = (start_of_run - completed_task.EffectiveTimePosted()) - .InMilliseconds(); + queue_duration = start_of_run - completed_task.EffectiveTimePosted(); } current_thread_data->TallyADeath(*births, queue_duration, stopwatch); } @@ -755,7 +761,7 @@ // static void ThreadData::TallyRunOnWorkerThreadIfTracking( const Births* births, - const TrackedTime& time_posted, + const base::TimeTicks& time_posted, const TaskStopwatch& stopwatch) { // Even if we have been DEACTIVATED, we will process any pending births so // that our data structures (which counted the outstanding births) remain @@ -776,10 +782,10 @@ if (!current_thread_data) return; - TrackedTime start_of_run = stopwatch.StartTime(); - int32_t queue_duration = 0; + base::TimeTicks start_of_run = stopwatch.StartTime(); + base::TimeDelta queue_duration; if (!start_of_run.is_null()) { - queue_duration = (start_of_run - time_posted).InMilliseconds(); + queue_duration = start_of_run - time_posted; } current_thread_data->TallyADeath(*births, queue_duration, stopwatch); } @@ -798,7 +804,7 @@ if (!current_thread_data) return; - int32_t queue_duration = 0; + base::TimeDelta queue_duration; current_thread_data->TallyADeath(*births, queue_duration, stopwatch); } @@ -927,12 +933,13 @@ } // static -TrackedTime ThreadData::Now() { +base::TimeTicks ThreadData::Now() { if (now_function_for_testing_) - return TrackedTime::FromMilliseconds((*now_function_for_testing_)()); + return base::TimeTicks() + + base::TimeDelta::FromMilliseconds((*now_function_for_testing_)()); if (IsProfilerTimingEnabled() && TrackingStatus()) - return TrackedTime::Now(); - return TrackedTime(); // Super fast when disabled, or not compiled. + return base::TimeTicks::Now(); + return base::TimeTicks(); // Super fast when disabled, or not compiled. } // static @@ -1036,9 +1043,9 @@ //------------------------------------------------------------------------------ TaskStopwatch::TaskStopwatch() - : wallclock_duration_ms_(0), + : wallclock_duration_(), current_thread_data_(NULL), - excluded_duration_ms_(0), + excluded_duration_(), parent_(NULL) { #if DCHECK_IS_ON() state_ = CREATED; @@ -1085,7 +1092,7 @@ } void TaskStopwatch::Stop() { - const TrackedTime end_time = ThreadData::Now(); + const base::TimeTicks end_time = ThreadData::Now(); #if DCHECK_IS_ON() DCHECK(state_ == RUNNING); state_ = STOPPED; @@ -1097,7 +1104,7 @@ #endif if (!start_time_.is_null() && !end_time.is_null()) { - wallclock_duration_ms_ = (end_time - start_time_).InMilliseconds(); + wallclock_duration_ = end_time - start_time_; } if (!current_thread_data_) @@ -1113,11 +1120,11 @@ DCHECK(parent_->child_ == this); parent_->child_ = NULL; #endif - parent_->excluded_duration_ms_ += wallclock_duration_ms_; + parent_->excluded_duration_ += wallclock_duration_; parent_ = NULL; } -TrackedTime TaskStopwatch::StartTime() const { +base::TimeTicks TaskStopwatch::StartTime() const { #if DCHECK_IS_ON() DCHECK(state_ != CREATED); #endif @@ -1125,12 +1132,12 @@ return start_time_; } -int32_t TaskStopwatch::RunDurationMs() const { +base::TimeDelta TaskStopwatch::RunDuration() const { #if DCHECK_IS_ON() DCHECK(state_ == STOPPED); #endif - return wallclock_duration_ms_ - excluded_duration_ms_; + return wallclock_duration_ - excluded_duration_; } ThreadData* TaskStopwatch::GetThreadData() const {
diff --git a/base/tracked_objects.h b/base/tracked_objects.h index b1355d52..b3aed63 100644 --- a/base/tracked_objects.h +++ b/base/tracked_objects.h
@@ -26,7 +26,6 @@ #include "base/location.h" #include "base/macros.h" #include "base/process/process_handle.h" -#include "base/profiler/tracked_time.h" #include "base/synchronization/lock.h" #include "base/threading/thread_local_storage.h" @@ -346,8 +345,8 @@ // Update stats for a task destruction (death) that had a Run() time of // |duration|, and has had a queueing delay of |queue_duration|. - void RecordDurations(const int32_t queue_duration, - const int32_t run_duration, + void RecordDurations(const base::TimeDelta queue_duration, + const base::TimeDelta run_duration, const uint32_t random_number); // Update stats for a task destruction that performed |alloc_ops| @@ -609,9 +608,10 @@ // the task. // The |end_of_run| was just obtained by a call to Now() (just after the task // finished). - static void TallyRunOnWorkerThreadIfTracking(const Births* births, - const TrackedTime& time_posted, - const TaskStopwatch& stopwatch); + static void TallyRunOnWorkerThreadIfTracking( + const Births* births, + const base::TimeTicks& time_posted, + const TaskStopwatch& stopwatch); // Record the end of execution in region, generally corresponding to a scope // being exited. @@ -644,7 +644,7 @@ // the profiler enabled. It will generally be optimized away when it is // ifdef'ed to be small enough (allowing the profiler to be "compiled out" of // the code). - static TrackedTime Now(); + static base::TimeTicks Now(); // This function can be called at process termination to validate that thread // cleanup routines have been called for at least some number of named @@ -689,7 +689,7 @@ // Find a place to record a death on this thread. void TallyADeath(const Births& births, - int32_t queue_duration, + base::TimeDelta queue_duration, const TaskStopwatch& stopwatch); // Snapshots (under a lock) the profiled data for the tasks for this thread @@ -845,13 +845,13 @@ void Stop(); // Returns the start time. - TrackedTime StartTime() const; + base::TimeTicks StartTime() const; // Task's duration is calculated as the wallclock duration between starting // and stopping this stopwatch, minus the wallclock durations of any other // instances that are immediately nested in this one, started and stopped on // this thread during that period. - int32_t RunDurationMs() const; + base::TimeDelta RunDuration() const; #if BUILDFLAG(USE_ALLOCATOR_SHIM) const base::debug::ThreadHeapUsageTracker& heap_usage() const { @@ -865,7 +865,7 @@ private: // Time when the stopwatch was started. - TrackedTime start_time_; + base::TimeTicks start_time_; #if BUILDFLAG(USE_ALLOCATOR_SHIM) base::debug::ThreadHeapUsageTracker heap_usage_; @@ -873,14 +873,14 @@ #endif // Wallclock duration of the task. - int32_t wallclock_duration_ms_; + base::TimeDelta wallclock_duration_; // Tracking info for the current thread. ThreadData* current_thread_data_; // Sum of wallclock durations of all stopwatches that were directly nested in // this one. - int32_t excluded_duration_ms_; + base::TimeDelta excluded_duration_; // Stopwatch which was running on our thread when this stopwatch was started. // That preexisting stopwatch must be adjusted to the exclude the wallclock
diff --git a/base/tracked_objects_unittest.cc b/base/tracked_objects_unittest.cc index 1eb4199..e3f1ff1a 100644 --- a/base/tracked_objects_unittest.cc +++ b/base/tracked_objects_unittest.cc
@@ -80,8 +80,8 @@ const std::string& birth_thread, const std::string& death_thread, int count, - int run_ms, - int queue_ms) { + int run_duration, + int queue_duration) { ASSERT_EQ(1u, process_data.phased_snapshots.size()); auto it = process_data.phased_snapshots.find(0); ASSERT_TRUE(it != process_data.phased_snapshots.end()); @@ -99,16 +99,17 @@ process_data_phase.tasks[0].birth.sanitized_thread_name); EXPECT_EQ(count, process_data_phase.tasks[0].death_data.count); - EXPECT_EQ(count * run_ms, + EXPECT_EQ(count * run_duration, process_data_phase.tasks[0].death_data.run_duration_sum); - EXPECT_EQ(run_ms, process_data_phase.tasks[0].death_data.run_duration_max); - EXPECT_EQ(run_ms, + EXPECT_EQ(run_duration, + process_data_phase.tasks[0].death_data.run_duration_max); + EXPECT_EQ(run_duration, process_data_phase.tasks[0].death_data.run_duration_sample); - EXPECT_EQ(count * queue_ms, + EXPECT_EQ(count * queue_duration, process_data_phase.tasks[0].death_data.queue_duration_sum); - EXPECT_EQ(queue_ms, + EXPECT_EQ(queue_duration, process_data_phase.tasks[0].death_data.queue_duration_max); - EXPECT_EQ(queue_ms, + EXPECT_EQ(queue_duration, process_data_phase.tasks[0].death_data.queue_duration_sample); EXPECT_EQ(death_thread, @@ -275,27 +276,29 @@ EXPECT_EQ(data->count(), 0); EXPECT_EQ(nullptr, data->last_phase_snapshot()); - int32_t run_ms = 42; - int32_t queue_ms = 8; + base::TimeDelta run_duration = base::TimeDelta::FromMilliseconds(42); + base::TimeDelta queue_duration = base::TimeDelta::FromMilliseconds(8); const int kUnrandomInt = 0; // Fake random int that ensure we sample data. - data->RecordDurations(queue_ms, run_ms, kUnrandomInt); - EXPECT_EQ(data->run_duration_sum(), run_ms); - EXPECT_EQ(data->run_duration_max(), run_ms); - EXPECT_EQ(data->run_duration_sample(), run_ms); - EXPECT_EQ(data->queue_duration_sum(), queue_ms); - EXPECT_EQ(data->queue_duration_max(), queue_ms); - EXPECT_EQ(data->queue_duration_sample(), queue_ms); + data->RecordDurations(queue_duration, run_duration, kUnrandomInt); + EXPECT_EQ(data->run_duration_sum(), run_duration.InMilliseconds()); + EXPECT_EQ(data->run_duration_max(), run_duration.InMilliseconds()); + EXPECT_EQ(data->run_duration_sample(), run_duration.InMilliseconds()); + EXPECT_EQ(data->queue_duration_sum(), queue_duration.InMilliseconds()); + EXPECT_EQ(data->queue_duration_max(), queue_duration.InMilliseconds()); + EXPECT_EQ(data->queue_duration_sample(), queue_duration.InMilliseconds()); EXPECT_EQ(data->count(), 1); EXPECT_EQ(nullptr, data->last_phase_snapshot()); - data->RecordDurations(queue_ms, run_ms, kUnrandomInt); - EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); - EXPECT_EQ(data->run_duration_max(), run_ms); - EXPECT_EQ(data->run_duration_sample(), run_ms); - EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); - EXPECT_EQ(data->queue_duration_max(), queue_ms); - EXPECT_EQ(data->queue_duration_sample(), queue_ms); + data->RecordDurations(queue_duration, run_duration, kUnrandomInt); + EXPECT_EQ(data->run_duration_sum(), + (run_duration + run_duration).InMilliseconds()); + EXPECT_EQ(data->run_duration_max(), run_duration.InMilliseconds()); + EXPECT_EQ(data->run_duration_sample(), run_duration.InMilliseconds()); + EXPECT_EQ(data->queue_duration_sum(), + (queue_duration + queue_duration).InMilliseconds()); + EXPECT_EQ(data->queue_duration_max(), queue_duration.InMilliseconds()); + EXPECT_EQ(data->queue_duration_sample(), queue_duration.InMilliseconds()); EXPECT_EQ(data->count(), 2); EXPECT_EQ(nullptr, data->last_phase_snapshot()); } @@ -383,23 +386,25 @@ std::unique_ptr<DeathData> data(new DeathData()); ASSERT_NE(data, nullptr); - const int32_t run_ms = 42; - const int32_t queue_ms = 8; + const base::TimeDelta run_duration = base::TimeDelta::FromMilliseconds(42); + const base::TimeDelta queue_duration = base::TimeDelta::FromMilliseconds(8); const int kUnrandomInt = 0; // Fake random int that ensure we sample data. - data->RecordDurations(queue_ms, run_ms, kUnrandomInt); - data->RecordDurations(queue_ms, run_ms, kUnrandomInt); + data->RecordDurations(queue_duration, run_duration, kUnrandomInt); + data->RecordDurations(queue_duration, run_duration, kUnrandomInt); data->RecordAllocations(kAllocOps, kFreeOps, kAllocatedBytes, kFreedBytes, kAllocOverheadBytes, kMaxAllocatedBytes); data->OnProfilingPhaseCompleted(123); - EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); + EXPECT_EQ(data->run_duration_sum(), + (run_duration + run_duration).InMilliseconds()); EXPECT_EQ(data->run_duration_max(), 0); - EXPECT_EQ(data->run_duration_sample(), run_ms); - EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); + EXPECT_EQ(data->run_duration_sample(), run_duration.InMilliseconds()); + EXPECT_EQ(data->queue_duration_sum(), + (queue_duration + queue_duration).InMilliseconds()); EXPECT_EQ(data->queue_duration_max(), 0); - EXPECT_EQ(data->queue_duration_sample(), queue_ms); + EXPECT_EQ(data->queue_duration_sample(), queue_duration.InMilliseconds()); EXPECT_EQ(data->count(), 2); EXPECT_EQ(data->alloc_ops(), kAllocOps); @@ -412,16 +417,17 @@ ASSERT_NE(nullptr, data->last_phase_snapshot()); EXPECT_EQ(123, data->last_phase_snapshot()->profiling_phase); EXPECT_EQ(2, data->last_phase_snapshot()->death_data.count); - EXPECT_EQ(2 * run_ms, + EXPECT_EQ(2 * run_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.run_duration_sum); - EXPECT_EQ(run_ms, data->last_phase_snapshot()->death_data.run_duration_max); - EXPECT_EQ(run_ms, + EXPECT_EQ(run_duration.InMilliseconds(), + data->last_phase_snapshot()->death_data.run_duration_max); + EXPECT_EQ(run_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.run_duration_sample); - EXPECT_EQ(2 * queue_ms, + EXPECT_EQ(2 * queue_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.queue_duration_sum); - EXPECT_EQ(queue_ms, + EXPECT_EQ(queue_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.queue_duration_max); - EXPECT_EQ(queue_ms, + EXPECT_EQ(queue_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.queue_duration_sample); EXPECT_EQ(kAllocOps, data->last_phase_snapshot()->death_data.alloc_ops); @@ -436,19 +442,22 @@ EXPECT_EQ(nullptr, data->last_phase_snapshot()->prev); - const int32_t run_ms1 = 21; - const int32_t queue_ms1 = 4; + const base::TimeDelta run_duration1 = base::TimeDelta::FromMilliseconds(21); + const base::TimeDelta queue_duration1 = base::TimeDelta::FromMilliseconds(4); - data->RecordDurations(queue_ms1, run_ms1, kUnrandomInt); + data->RecordDurations(queue_duration1, run_duration1, kUnrandomInt); data->RecordAllocations(kAllocOps, kFreeOps, kAllocatedBytes, kFreedBytes, kAllocOverheadBytes, kMaxAllocatedBytes); - EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms + run_ms1); - EXPECT_EQ(data->run_duration_max(), run_ms1); - EXPECT_EQ(data->run_duration_sample(), run_ms1); - EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms + queue_ms1); - EXPECT_EQ(data->queue_duration_max(), queue_ms1); - EXPECT_EQ(data->queue_duration_sample(), queue_ms1); + EXPECT_EQ(data->run_duration_sum(), + (run_duration + run_duration + run_duration1).InMilliseconds()); + EXPECT_EQ(data->run_duration_max(), run_duration1.InMilliseconds()); + EXPECT_EQ(data->run_duration_sample(), run_duration1.InMilliseconds()); + EXPECT_EQ( + data->queue_duration_sum(), + (queue_duration + queue_duration + queue_duration1).InMilliseconds()); + EXPECT_EQ(data->queue_duration_max(), queue_duration1.InMilliseconds()); + EXPECT_EQ(data->queue_duration_sample(), queue_duration1.InMilliseconds()); EXPECT_EQ(data->count(), 3); EXPECT_EQ(data->alloc_ops(), 2 * kAllocOps); @@ -461,16 +470,17 @@ ASSERT_NE(nullptr, data->last_phase_snapshot()); EXPECT_EQ(123, data->last_phase_snapshot()->profiling_phase); EXPECT_EQ(2, data->last_phase_snapshot()->death_data.count); - EXPECT_EQ(2 * run_ms, + EXPECT_EQ(2 * run_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.run_duration_sum); - EXPECT_EQ(run_ms, data->last_phase_snapshot()->death_data.run_duration_max); - EXPECT_EQ(run_ms, + EXPECT_EQ(run_duration.InMilliseconds(), + data->last_phase_snapshot()->death_data.run_duration_max); + EXPECT_EQ(run_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.run_duration_sample); - EXPECT_EQ(2 * queue_ms, + EXPECT_EQ(2 * queue_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.queue_duration_sum); - EXPECT_EQ(queue_ms, + EXPECT_EQ(queue_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.queue_duration_max); - EXPECT_EQ(queue_ms, + EXPECT_EQ(queue_duration.InMilliseconds(), data->last_phase_snapshot()->death_data.queue_duration_sample); EXPECT_EQ(kAllocOps, data->last_phase_snapshot()->death_data.alloc_ops); @@ -615,7 +625,7 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = base::TimeTicks::FromInternalValue(1000); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -644,7 +654,7 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = base::TimeTicks::FromInternalValue(1000); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -664,7 +674,7 @@ TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted1 = TrackedTime::FromMilliseconds(9); + const base::TimeTicks kTimePosted1 = base::TimeTicks::FromInternalValue(9000); const base::TimeTicks kDelayedStartTime1 = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task1(location, kDelayedStartTime1); @@ -894,7 +904,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); ThreadData::InitializeThreadContext(kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -961,7 +972,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); ThreadData::InitializeThreadContext(kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1022,7 +1034,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1057,7 +1070,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1094,7 +1108,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1135,7 +1150,8 @@ const char kFunction[] = "DifferentLives"; Location location(kFunction, kFile, kLineNumber, NULL); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1210,7 +1226,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1244,7 +1261,8 @@ Location location(kFunction, kFile, kLineNumber, NULL); TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1287,7 +1305,8 @@ TallyABirth(location, kMainThreadName); - const TrackedTime kTimePosted = TrackedTime::FromMilliseconds(1); + const base::TimeTicks kTimePosted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(1); const base::TimeTicks kDelayedStartTime = base::TimeTicks(); // TrackingInfo will call TallyABirth() during construction. base::TrackingInfo pending_task(location, kDelayedStartTime); @@ -1304,7 +1323,8 @@ Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); base::TrackingInfo nested_task(second_location, kDelayedStartTime); // Overwrite implied Now(). - nested_task.time_posted = TrackedTime::FromMilliseconds(8); + nested_task.time_posted = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(8); SetTestTime(9); TaskStopwatch nested_task_stopwatch; nested_task_stopwatch.Start();
diff --git a/base/tracking_info.h b/base/tracking_info.h index 6c3bcd1..6a13a39 100644 --- a/base/tracking_info.h +++ b/base/tracking_info.h
@@ -12,7 +12,6 @@ #define BASE_TRACKING_INFO_H_ #include "base/base_export.h" -#include "base/profiler/tracked_time.h" #include "base/time/time.h" namespace tracked_objects { @@ -35,10 +34,8 @@ // means that queuing delay for such tasks will show how long they went // unserviced, after they *could* be serviced. This is the same stat as we // have for non-delayed tasks, and we consistently call it queuing delay. - tracked_objects::TrackedTime EffectiveTimePosted() const { - return delayed_run_time.is_null() - ? time_posted - : tracked_objects::TrackedTime(delayed_run_time); + base::TimeTicks EffectiveTimePosted() const { + return delayed_run_time.is_null() ? time_posted : delayed_run_time; } // Record of location and thread that the task came from. @@ -47,7 +44,7 @@ // Time when the related task was posted. Note that this value may be empty // if task profiling is disabled, and should only be used in conjunction with // profiling-related reporting. - tracked_objects::TrackedTime time_posted; + base::TimeTicks time_posted; // The time when the task should be run. base::TimeTicks delayed_run_time;
diff --git a/base/win/com_init_check_hook.cc b/base/win/com_init_check_hook.cc index 1e654484..bec03d7 100644 --- a/base/win/com_init_check_hook.cc +++ b/base/win/com_init_check_hook.cc
@@ -116,6 +116,8 @@ INT3, // The hotpatch placeholder used nop's in the sled. NOP, + // This function has already been patched by a different component. + EXTERNALLY_PATCHED, }; HookManager() = default; @@ -142,15 +144,16 @@ HotpatchPlaceholderFormat format = GetHotpatchPlaceholderFormat( reinterpret_cast<const void*>(co_create_instance_padded_address_)); if (format == HotpatchPlaceholderFormat::UNKNOWN) { - const unsigned char* hotpatch_bytes = - reinterpret_cast<const unsigned char*>( - co_create_instance_padded_address_); NOTREACHED() << "Unrecognized hotpatch function format: " - << base::StringPrintf("%02x %02x %02x %02x %02x %02x %02x", - hotpatch_bytes[0], hotpatch_bytes[1], - hotpatch_bytes[2], hotpatch_bytes[3], - hotpatch_bytes[4], hotpatch_bytes[5], - hotpatch_bytes[6]); + << FirstSevenBytesToString( + co_create_instance_padded_address_); + return; + } else if (format == HotpatchPlaceholderFormat::EXTERNALLY_PATCHED) { + // TODO(robliao): Make this crash after resolving http://crbug.com/737090. + hotpatch_placeholder_format_ = format; + DLOG(WARNING) + << "CoCreateInstance appears to be previously patched. Skipping. (" + << FirstSevenBytesToString(co_create_instance_padded_address_) << ")"; return; } @@ -185,6 +188,7 @@ reinterpret_cast<const void*>(&g_hotpatch_placeholder_nop), sizeof(g_hotpatch_placeholder_nop)); break; + case HotpatchPlaceholderFormat::EXTERNALLY_PATCHED: case HotpatchPlaceholderFormat::UNKNOWN: break; } @@ -213,6 +217,16 @@ return HotpatchPlaceholderFormat::NOP; } + const unsigned char* instruction_bytes = + reinterpret_cast<const unsigned char*>( + co_create_instance_padded_address_); + const unsigned char entry_point_byte = instruction_bytes[5]; + // Check for all of the common jmp opcodes. + if (entry_point_byte == 0xeb || entry_point_byte == 0xe9 || + entry_point_byte == 0xff || entry_point_byte == 0xea) { + return HotpatchPlaceholderFormat::EXTERNALLY_PATCHED; + } + return HotpatchPlaceholderFormat::UNKNOWN; } @@ -235,6 +249,15 @@ dwClsContext, riid, ppv); } + // Returns the first 7 bytes in hex as a string at |address|. + static std::string FirstSevenBytesToString(uint32_t address) { + const unsigned char* bytes = + reinterpret_cast<const unsigned char*>(address); + return base::StringPrintf("%02x %02x %02x %02x %02x %02x %02x", bytes[0], + bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], + bytes[6]); + } + // Synchronizes everything in this class. base::Lock lock_; size_t init_count_ = 0;
diff --git a/base/win/com_init_check_hook_unittest.cc b/base/win/com_init_check_hook_unittest.cc index dcb0a3d3..00677a7d 100644 --- a/base/win/com_init_check_hook_unittest.cc +++ b/base/win/com_init_check_hook_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/gtest_util.h" #include "base/win/com_init_util.h" +#include "base/win/patch_util.h" #include "base/win/scoped_com_initializer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -64,5 +65,71 @@ #endif } +TEST(ComInitCheckHook, UnexpectedHook) { +#if defined(COM_INIT_CHECK_HOOK_ENABLED) + HMODULE ole32_library = ::LoadLibrary(L"ole32.dll"); + ASSERT_TRUE(ole32_library); + + uint32_t co_create_instance_padded_address = + reinterpret_cast<uint32_t>( + GetProcAddress(ole32_library, "CoCreateInstance")) - 5; + const unsigned char* co_create_instance_bytes = + reinterpret_cast<const unsigned char*>(co_create_instance_padded_address); + const unsigned char original_byte = co_create_instance_bytes[0]; + const unsigned char unexpected_byte = 0xdb; + ASSERT_EQ(static_cast<DWORD>(NO_ERROR), + internal::ModifyCode( + reinterpret_cast<void*>(co_create_instance_padded_address), + reinterpret_cast<const void*>(&unexpected_byte), + sizeof(unexpected_byte))); + + EXPECT_DCHECK_DEATH({ ComInitCheckHook com_check_hook; }); + + // If this call fails, really bad things are going to happen to other tests + // so CHECK here. + CHECK_EQ(static_cast<DWORD>(NO_ERROR), + internal::ModifyCode( + reinterpret_cast<void*>(co_create_instance_padded_address), + reinterpret_cast<const void*>(&original_byte), + sizeof(original_byte))); + + ::FreeLibrary(ole32_library); + ole32_library = nullptr; +#endif +} + +TEST(ComInitCheckHook, ExternallyHooked) { +#if defined(COM_INIT_CHECK_HOOK_ENABLED) + HMODULE ole32_library = ::LoadLibrary(L"ole32.dll"); + ASSERT_TRUE(ole32_library); + + uint32_t co_create_instance_address = reinterpret_cast<uint32_t>( + GetProcAddress(ole32_library, "CoCreateInstance")); + const unsigned char* co_create_instance_bytes = + reinterpret_cast<const unsigned char*>(co_create_instance_address); + const unsigned char original_byte = co_create_instance_bytes[0]; + const unsigned char jmp_byte = 0xe9; + ASSERT_EQ(static_cast<DWORD>(NO_ERROR), + internal::ModifyCode( + reinterpret_cast<void*>(co_create_instance_address), + reinterpret_cast<const void*>(&jmp_byte), sizeof(jmp_byte))); + + // This line shouldn't crash if a hook is already in place. + // TODO(robliao): Make it crash after resolving http://crbug.com/737090. + { ComInitCheckHook com_check_hook; } + + // If this call fails, really bad things are going to happen to other tests + // so CHECK here. + CHECK_EQ( + static_cast<DWORD>(NO_ERROR), + internal::ModifyCode(reinterpret_cast<void*>(co_create_instance_address), + reinterpret_cast<const void*>(&original_byte), + sizeof(original_byte))); + + ::FreeLibrary(ole32_library); + ole32_library = nullptr; +#endif +} + } // namespace win } // namespace base
diff --git a/base/win/patch_util.h b/base/win/patch_util.h index 920ac63..035fb83 100644 --- a/base/win/patch_util.h +++ b/base/win/patch_util.h
@@ -7,6 +7,8 @@ #include <windows.h> +#include "base/base_export.h" + namespace base { namespace win { namespace internal { @@ -14,7 +16,7 @@ // Copies |length| bytes from |source| to |destination|, temporarily setting // |destination| to writable. Returns a Windows error code or NO_ERROR if // successful. -DWORD ModifyCode(void* destination, const void* source, int length); +BASE_EXPORT DWORD ModifyCode(void* destination, const void* source, int length); } // namespace internal } // namespace win
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py index e7bf827..ba2311a 100755 --- a/build/android/gradle/generate_gradle.py +++ b/build/android/gradle/generate_gradle.py
@@ -211,7 +211,7 @@ def JavaFiles(self): if self._java_files is None: - java_sources_file = self.Gradle().get('java_sources_file') + java_sources_file = self.DepsInfo().get('java_sources_file') java_files = [] if java_sources_file: java_sources_file = _RebasePath(java_sources_file)
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index c085176..6eab4b2 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -413,7 +413,7 @@ gradle['android_manifest'] = options.android_manifest if options.type in ('java_binary', 'java_library', 'android_apk'): if options.java_sources_file: - gradle['java_sources_file'] = options.java_sources_file + deps_info['java_sources_file'] = options.java_sources_file if options.bundled_srcjars: gradle['bundled_srcjars'] = ( build_utils.ParseGnList(options.bundled_srcjars)) @@ -436,6 +436,14 @@ gradle['dependent_java_projects'].append(c['path']) + if options.type == 'android_apk': + config['jni'] = {} + all_java_sources = [c['java_sources_file'] for c in all_library_deps + if 'java_sources_file' in c] + if options.java_sources_file: + all_java_sources.append(options.java_sources_file) + config['jni']['all_source'] = all_java_sources + if (options.type in ('java_binary', 'java_library')): deps_info['requires_android'] = options.requires_android deps_info['supports_android'] = options.supports_android
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py index ea7687f..f68b73b 100644 --- a/build/android/pylib/constants/__init__.py +++ b/build/android/pylib/constants/__init__.py
@@ -96,7 +96,7 @@ SCREENSHOTS_DIR = os.path.join(DIR_SOURCE_ROOT, 'out_screenshots') ANDROID_SDK_VERSION = version_codes.MARSHMALLOW -ANDROID_SDK_BUILD_TOOLS_VERSION = '25.0.2' +ANDROID_SDK_BUILD_TOOLS_VERSION = '26.0.0' ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'android_tools', 'sdk') ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT,
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index 73d34cd7..909fa75 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -43,8 +43,8 @@ if (!defined(default_android_sdk_root)) { default_android_sdk_root = "//third_party/android_tools/sdk" - default_android_sdk_version = "25" - default_android_sdk_build_tools_version = "25.0.2" + default_android_sdk_version = "26" + default_android_sdk_build_tools_version = "26.0.0" } if (!defined(default_lint_android_sdk_root)) {
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 38032b768..ceffd063 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -192,7 +192,6 @@ "--depfile", rebase_path(depfile, root_build_dir), "--input_file={{source}}", - "--optimize_generation=1", "--ptr_type=long", "--output_dir", rebase_path(jni_output_dir, root_build_dir), @@ -302,7 +301,6 @@ rebase_path(jar_file, root_build_dir), "--input_file", class, - "--optimize_generation=1", "--ptr_type=long", "--output_dir", rebase_path(jni_output_dir, root_build_dir), @@ -334,6 +332,61 @@ } } + # Declare a jni registration target. + # + # This target generates a header file calling JNI registration functions + # created by generate_jni and generate_jar_jni. + # + # See base/android/jni_generator/jni_registration_generator.py for more info + # about the format of the header file. + # + # Variables + # target: The Apk target to generate registrations for. + # output: Path to the generated .h file. + # exception_files: List of .java files that should be ignored when searching + # for native methods. (optional) + # + # Example + # generate_jni_registration("chrome_jni_registration") { + # target = ":chrome_public_apk" + # output = "$root_gen_dir/chrome/browser/android/${target_name}.h" + # exception_files = [ + # "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + # "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + # "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + # ] + # } + template("generate_jni_registration") { + action(target_name) { + forward_variables_from(invoker, [ "testonly" ]) + _build_config = get_label_info(invoker.target, "target_gen_dir") + "/" + + get_label_info(invoker.target, "name") + ".build_config" + _rebased_build_config = rebase_path(_build_config, root_build_dir) + + _rebase_exception_java_files = + rebase_path(invoker.exception_files, root_build_dir) + + script = "//base/android/jni_generator/jni_registration_generator.py" + deps = [ + "${invoker.target}__build_config", + ] + inputs = [ + _build_config, + ] + outputs = [ + invoker.output, + ] + + args = [ + # This is a list of .sources files. + "--sources_files=@FileArg($_rebased_build_config:jni:all_source)", + "--output", + rebase_path(invoker.output, root_build_dir), + "--no_register_java=$_rebase_exception_java_files", + ] + } + } + # Declare a target for c-preprocessor-generated java files # # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index ac12aed..c1d63a8 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -982,6 +982,11 @@ # TODO(brucedawson): fix warnings, crbug.com/554200 "/wd4312", + # C4324 warns when padding is added to fulfill alignas requirements, + # but can trigger in benign cases that are difficult to individually + # suppress. + "/wd4324", + # C4351: new behavior: elements of array 'array' will be default # initialized # This is a silly "warning" that basically just alerts you that the
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py index 63a3c581..a46ccba1 100755 --- a/build/fuchsia/test_runner.py +++ b/build/fuchsia/test_runner.py
@@ -215,6 +215,8 @@ help='GTest repeat value to use') parser.add_argument('--test-launcher-filter-file', help='Pass filter file through to target process') + parser.add_argument('--test_launcher_summary_output', + help='Currently ignored for 2-sided roll.') args = parser.parse_args() bootfs = BuildBootfs(args.output_directory, args.runtime_deps_path,
diff --git a/build/linux/sysroot_scripts/build_and_upload.py b/build/linux/sysroot_scripts/build_and_upload.py index bdbd73dd..78eaa631 100755 --- a/build/linux/sysroot_scripts/build_and_upload.py +++ b/build/linux/sysroot_scripts/build_and_upload.py
@@ -44,10 +44,10 @@ run_script([script_path, 'BuildSysroot%s' % arch]) run_script([script_path, 'UploadSysroot%s' % arch, revision]) - tarball = '%s_%s_%s_sysroot.tgz' % (distro, release, arch.lower()) - tgz_path = os.path.join(script_dir, "..", "..", "..", "out", "sysroot-build", - release, tarball) - sha1sum = sha1sumfile(tgz_path) + tarball = '%s_%s_%s_sysroot.tar.xz' % (distro, release, arch.lower()) + tarxz_path = os.path.join(script_dir, "..", "..", "..", "out", + "sysroot-build", release, tarball) + sha1sum = sha1sumfile(tarxz_path) sysroot_dir = '%s_%s_%s-sysroot' % (distro, release, arch.lower()) sysroot_metadata = {
diff --git a/build/linux/sysroot_scripts/sysroot-creator.sh b/build/linux/sysroot_scripts/sysroot-creator.sh index bc8bc7a..59ddaa2f 100644 --- a/build/linux/sysroot_scripts/sysroot-creator.sh +++ b/build/linux/sysroot_scripts/sysroot-creator.sh
@@ -155,7 +155,7 @@ # This is where the staging sysroot is. INSTALL_ROOT="${BUILD_DIR}/${DIST}_${ARCH_LOWER}_staging" - TARBALL="${BUILD_DIR}/${DISTRO}_${DIST}_${ARCH_LOWER}_sysroot.tgz" + TARBALL="${BUILD_DIR}/${DISTRO}_${DIST}_${ARCH_LOWER}_sysroot.tar.xz" if ! mkdir -p "${INSTALL_ROOT}" ; then echo "ERROR: ${INSTALL_ROOT} can't be created." @@ -178,7 +178,7 @@ CreateTarBall() { Banner "Creating tarball ${TARBALL}" - tar zcf ${TARBALL} -C ${INSTALL_ROOT} . + tar Jcf ${TARBALL} -C ${INSTALL_ROOT} . } ExtractPackageGz() {
diff --git a/cc/base/switches.cc b/cc/base/switches.cc index f4aff0cf..0d0e13b1 100644 --- a/cc/base/switches.cc +++ b/cc/base/switches.cc
@@ -27,6 +27,9 @@ // Enables defering image decodes to the image decode service. const char kEnableCheckerImaging[] = "enable-checker-imaging"; +// Disabled defering image decodes to the image decode service. +const char kDisableCheckerImaging[] = "disable-checker-imaging"; + // Percentage of the browser controls need to be hidden before they will auto // hide. const char kBrowserControlsHideThreshold[] = "top-controls-hide-threshold";
diff --git a/cc/base/switches.h b/cc/base/switches.h index 3f58249..3ac951e 100644 --- a/cc/base/switches.h +++ b/cc/base/switches.h
@@ -21,6 +21,7 @@ CC_BASE_EXPORT extern const char kDisableMainFrameBeforeActivation[]; CC_BASE_EXPORT extern const char kEnableMainFrameBeforeActivation[]; CC_BASE_EXPORT extern const char kEnableCheckerImaging[]; +CC_BASE_EXPORT extern const char kDisableCheckerImaging[]; CC_BASE_EXPORT extern const char kBrowserControlsHideThreshold[]; CC_BASE_EXPORT extern const char kBrowserControlsShowThreshold[]; CC_BASE_EXPORT extern const char kSlowDownRasterScaleFactor[];
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn index 59fb1ec4..c5f2406 100644 --- a/cc/ipc/BUILD.gn +++ b/cc/ipc/BUILD.gn
@@ -54,7 +54,7 @@ "render_pass.mojom", "returned_resource.mojom", "selection.mojom", - "shared_bitmap_manager.mojom", + "shared_bitmap_allocation_notifier.mojom", "shared_quad_state.mojom", "surface_id.mojom", "surface_info.mojom",
diff --git a/cc/ipc/shared_bitmap_allocation_notifier.mojom b/cc/ipc/shared_bitmap_allocation_notifier.mojom new file mode 100644 index 0000000..1648625 --- /dev/null +++ b/cc/ipc/shared_bitmap_allocation_notifier.mojom
@@ -0,0 +1,21 @@ +// 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. + +module cc.mojom; + +import "gpu/ipc/common/mailbox.mojom"; + +// This interface is used when allocating shared bitmaps to be shared with a +// display compositor. +// This interface needs to be associated with the channel used to submit +// CompositorFrames, to prevent running into message ordering issues (the +// display compositor trying to access shared memory before the registration +// message below made it to the display compositor). +interface SharedBitmapAllocationNotifier { + // Informs the display compositor that the child allocated a shared bitmap. + DidAllocateSharedBitmap(handle<shared_buffer> buffer, gpu.mojom.Mailbox id); + + // Informs the display compositor that the child deleted a shared bitmap. + DidDeleteSharedBitmap(gpu.mojom.Mailbox id); +};
diff --git a/cc/ipc/shared_bitmap_manager.mojom b/cc/ipc/shared_bitmap_manager.mojom deleted file mode 100644 index 6b2d54dd..0000000 --- a/cc/ipc/shared_bitmap_manager.mojom +++ /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. - -module cc.mojom; - -import "gpu/ipc/common/mailbox.mojom"; - -// This interface is used when allocating shared bitmap memory to be shared -// with a display compositor. -// This interface needs to be associated with the RenderMessageFilter interface -// to prevent running into message ordering issues (CC trying to access a -// shared bitmap before the registration message below made it to the display -// compositor). -interface SharedBitmapManager { - // Informs the display compositor that the child allocated a shared bitmap. - DidAllocateSharedBitmap(handle<shared_buffer> buffer, gpu.mojom.Mailbox id); - - // Informs the display compositor that the child deleted a shared bitmap. - DidDeleteSharedBitmap(gpu.mojom.Mailbox id); -};
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 21f7f0d..7a1c775f 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -933,7 +933,7 @@ } void Layer::SetTransformTreeIndex(int index) { - DCHECK(IsPropertyChangeAllowed()); + CHECK(IsPropertyChangeAllowed()); if (transform_tree_index_ == index) return; if (index == TransformTree::kInvalidNodeId) @@ -952,7 +952,7 @@ } void Layer::SetClipTreeIndex(int index) { - DCHECK(IsPropertyChangeAllowed()); + CHECK(IsPropertyChangeAllowed()); if (clip_tree_index_ == index) return; clip_tree_index_ = index; @@ -969,7 +969,7 @@ } void Layer::SetEffectTreeIndex(int index) { - DCHECK(IsPropertyChangeAllowed()); + CHECK(IsPropertyChangeAllowed()); if (effect_tree_index_ == index) return; effect_tree_index_ = index; @@ -986,7 +986,7 @@ } void Layer::SetScrollTreeIndex(int index) { - DCHECK(IsPropertyChangeAllowed()); + CHECK(IsPropertyChangeAllowed()); if (scroll_tree_index_ == index) return; scroll_tree_index_ = index; @@ -1273,8 +1273,12 @@ return false; } -bool Layer::IsSuitableForGpuRasterization() const { - return true; +bool Layer::HasSlowPaths() const { + return false; +} + +bool Layer::HasNonAAPaint() const { + return false; } std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 1dc0735e..3f5c50e 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -308,7 +308,8 @@ // Returns true iff anything was updated that needs to be committed. virtual bool Update(); virtual void SetLayerMaskType(Layer::LayerMaskType type) {} - virtual bool IsSuitableForGpuRasterization() const; + virtual bool HasSlowPaths() const; + virtual bool HasNonAAPaint() const; virtual std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo();
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index 39f7c65a..b1035bb2 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc
@@ -15,7 +15,7 @@ #include "cc/trees/transform_node.h" #include "ui/gfx/geometry/rect_conversions.h" -static constexpr int kMaxNumberOfSlowPathsBeforeVeto = 5; +static constexpr int kMaxNumberOfSlowPathsBeforeReporting = 5; namespace cc { @@ -184,14 +184,20 @@ return raster_source->GetFlattenedPicture(); } -bool PictureLayer::IsSuitableForGpuRasterization() const { +bool PictureLayer::HasSlowPaths() const { // The display list needs to be created (see: UpdateAndExpandInvalidation) - // before checking for suitability. There are cases where an update will not - // create a display list (e.g., if the size is empty). We return true in these - // cases because the gpu suitability bit sticks false. - return !picture_layer_inputs_.display_list || - picture_layer_inputs_.display_list->NumSlowPaths() <= - kMaxNumberOfSlowPathsBeforeVeto; + // before checking for slow paths. There are cases where an update will not + // create a display list (e.g., if the size is empty). We return false in + // these cases because the slow paths bit sticks true. + return picture_layer_inputs_.display_list && + picture_layer_inputs_.display_list->NumSlowPaths() > + kMaxNumberOfSlowPathsBeforeReporting; +} + +bool PictureLayer::HasNonAAPaint() const { + // We return false by default, as this bit sticks true. + return picture_layer_inputs_.display_list && + picture_layer_inputs_.display_list->HasNonAAPaint(); } void PictureLayer::ClearClient() {
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index af63e2f3..f8bc109 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h
@@ -42,7 +42,8 @@ void SetLayerMaskType(LayerMaskType mask_type) override; sk_sp<SkPicture> GetPicture() const override; - bool IsSuitableForGpuRasterization() const override; + bool HasSlowPaths() const override; + bool HasNonAAPaint() const override; void RunMicroBenchmark(MicroBenchmark* benchmark) override;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 25b12c8..4c25f7ee 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -2328,7 +2328,6 @@ EXPECT_EQ(0u, active_layer()->release_resources_count()); // Toggling the gpu rasterization clears all tilings on both trees. host_impl()->SetHasGpuRasterizationTrigger(true); - host_impl()->SetContentIsSuitableForGpuRasterization(true); host_impl()->CommitComplete(); EXPECT_EQ(1u, pending_layer()->release_tile_resources_count()); EXPECT_EQ(1u, active_layer()->release_tile_resources_count()); @@ -2359,7 +2358,6 @@ host_impl()->NotifyReadyToActivate(); host_impl()->SetHasGpuRasterizationTrigger(true); - host_impl()->SetContentIsSuitableForGpuRasterization(false); host_impl()->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl()->gpu_rasterization_status()); @@ -2417,7 +2415,6 @@ default_tile_size.height() * 4); host_impl()->SetHasGpuRasterizationTrigger(true); - host_impl()->SetContentIsSuitableForGpuRasterization(true); host_impl()->CommitComplete(); SetupDefaultTrees(layer_bounds); @@ -2431,7 +2428,6 @@ TEST_F(PictureLayerImplTest, RequiredTilesWithGpuRasterization) { host_impl()->SetHasGpuRasterizationTrigger(true); - host_impl()->SetContentIsSuitableForGpuRasterization(true); host_impl()->CommitComplete(); gfx::Size viewport_size(1000, 1000); @@ -4740,7 +4736,6 @@ host_impl()->SetViewportSize(gfx::Size(1000, 1000)); gfx::Size result; - host_impl()->SetContentIsSuitableForGpuRasterization(true); host_impl()->SetHasGpuRasterizationTrigger(false); host_impl()->CommitComplete(); EXPECT_EQ(host_impl()->gpu_rasterization_status(),
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 82cd0be..1735f0e3 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc
@@ -233,13 +233,17 @@ host_impl.active_tree()->root_layer_for_testing()->DidDraw(nullptr); } -TEST(PictureLayerTest, SuitableForGpuRasterization) { +TEST(PictureLayerTest, HasSlowPaths) { std::unique_ptr<FakeRecordingSource> recording_source_owned( new FakeRecordingSource); FakeRecordingSource* recording_source = recording_source_owned.get(); + gfx::Size layer_bounds(200, 200); + gfx::Rect layer_rect(layer_bounds); + Region invalidation(layer_rect); + FakeContentLayerClient client; - client.set_bounds(gfx::Size()); + client.set_bounds(layer_bounds); scoped_refptr<FakePictureLayer> layer = FakePictureLayer::CreateWithRecordingSource( &client, std::move(recording_source_owned)); @@ -251,28 +255,52 @@ &host_client, &task_graph_runner, animation_host.get()); host->SetRootLayer(layer); - // Update layers to initialize the recording source. + recording_source->SetNeedsDisplayRect(layer_rect); + layer->Update(); + + // Layer does not have slow paths by default. + EXPECT_FALSE(layer->HasSlowPaths()); + + // Add slow-path content to the client. + client.set_contains_slow_paths(true); + recording_source->SetNeedsDisplayRect(layer_rect); + layer->Update(); + EXPECT_TRUE(layer->HasSlowPaths()); +} + +TEST(PictureLayerTest, HasNonAAPaint) { + std::unique_ptr<FakeRecordingSource> recording_source_owned( + new FakeRecordingSource); + FakeRecordingSource* recording_source = recording_source_owned.get(); + gfx::Size layer_bounds(200, 200); gfx::Rect layer_rect(layer_bounds); Region invalidation(layer_rect); - gfx::Rect new_recorded_viewport = client.PaintableRegion(); - scoped_refptr<DisplayItemList> display_list = - client.PaintContentsToDisplayList( - ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); - size_t painter_reported_memory_usage = - client.GetApproximateUnsharedMemoryUsage(); - recording_source->UpdateAndExpandInvalidation(&invalidation, layer_bounds, - new_recorded_viewport); - recording_source->UpdateDisplayItemList(display_list, - painter_reported_memory_usage); + FakeContentLayerClient client; + client.set_bounds(layer_bounds); + scoped_refptr<FakePictureLayer> layer = + FakePictureLayer::CreateWithRecordingSource( + &client, std::move(recording_source_owned)); - // Layer is suitable for gpu rasterization by default. - EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); + FakeLayerTreeHostClient host_client; + TestTaskGraphRunner task_graph_runner; + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); + host->SetRootLayer(layer); - // Veto gpu rasterization. - layer->set_force_unsuitable_for_gpu_rasterization(true); - EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); + recording_source->SetNeedsDisplayRect(layer_rect); + layer->Update(); + + // Layer does not have non-aa paint by default. + EXPECT_FALSE(layer->HasNonAAPaint()); + + // Add non-aa content to the client. + client.add_draw_rect(layer_rect, PaintFlags()); + recording_source->SetNeedsDisplayRect(layer_rect); + layer->Update(); + EXPECT_TRUE(layer->HasNonAAPaint()); } // PicturePile uses the source frame number as a unit for measuring invalidation
diff --git a/cc/layers/texture_layer_impl_unittest.cc b/cc/layers/texture_layer_impl_unittest.cc index aa44f93..5dd7dc90 100644 --- a/cc/layers/texture_layer_impl_unittest.cc +++ b/cc/layers/texture_layer_impl_unittest.cc
@@ -186,7 +186,6 @@ EXPECT_FALSE(released); // Toggling the gpu rasterization clears all tilings on both trees. impl.host_impl()->SetHasGpuRasterizationTrigger(true); - impl.host_impl()->SetContentIsSuitableForGpuRasterization(true); impl.host_impl()->CommitComplete(); EXPECT_TRUE(impl.host_impl()->use_gpu_rasterization()); EXPECT_FALSE(released);
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 7c39886..f42dfdb 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc
@@ -678,6 +678,9 @@ return nullptr; } + // Big filters can sometimes fallback to CPU. Therefore, we need + // to disable subnormal floats for performance and security reasons. + ScopedSubnormalFloatDisabler disabler; SkMatrix local_matrix; local_matrix.setTranslate(origin.x(), origin.y()); local_matrix.postScale(scale.x(), scale.y()); @@ -950,6 +953,9 @@ return nullptr; } + // Big filters can sometimes fallback to CPU. Therefore, we need + // to disable subnormal floats for performance and security reasons. + ScopedSubnormalFloatDisabler disabler; SkMatrix local_matrix; local_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y());
diff --git a/cc/paint/display_item_list.h b/cc/paint/display_item_list.h index e419e04..1381336 100644 --- a/cc/paint/display_item_list.h +++ b/cc/paint/display_item_list.h
@@ -108,6 +108,7 @@ void Finalize(); int NumSlowPaths() const { return paint_op_buffer_.numSlowPaths(); } + bool HasNonAAPaint() const { return paint_op_buffer_.HasNonAAPaint(); } // This gives the total number of PaintOps. size_t op_count() const { return paint_op_buffer_.size(); }
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 834869b8..981622d 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -559,6 +559,10 @@ return record->numSlowPaths(); } +bool DrawRecordOp::HasNonAAPaint() const { + return record->HasNonAAPaint(); +} + AnnotateOp::AnnotateOp(PaintCanvas::AnnotationType annotation_type, const SkRect& rect, sk_sp<SkData> data)
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h index b7b115f..6a899c2 100644 --- a/cc/paint/paint_op_buffer.h +++ b/cc/paint/paint_op_buffer.h
@@ -97,6 +97,8 @@ int CountSlowPaths() const { return 0; } int CountSlowPathsFromFlags() const { return 0; } + bool HasNonAAPaint() const { return false; } + bool HasDiscardableImages() const { return false; } bool HasDiscardableImagesFromFlags() const { return false; } @@ -115,6 +117,7 @@ explicit PaintOpWithFlags(const PaintFlags& flags) : flags(flags) {} int CountSlowPathsFromFlags() const { return flags.getPathEffect() ? 1 : 0; } + bool HasNonAAPaint() const { return !flags.isAntiAlias(); } bool HasDiscardableImagesFromFlags() const { if (!IsDrawOp()) return false; @@ -258,6 +261,7 @@ SkCanvas* canvas, const SkMatrix& original_ctm); int CountSlowPaths() const; + bool HasNonAAPaint() const { return !antialias; } ThreadsafePath path; SkClipOp op; @@ -284,6 +288,7 @@ static void Raster(const PaintOp* op, SkCanvas* canvas, const SkMatrix& original_ctm); + bool HasNonAAPaint() const { return !antialias; } SkRRect rrect; SkClipOp op; @@ -407,6 +412,7 @@ SkCanvas* canvas, const SkMatrix& original_ctm); bool HasDiscardableImages() const; + bool HasNonAAPaint() const { return false; } PaintImage image; SkScalar left; @@ -455,6 +461,7 @@ const PaintFlags* flags, SkCanvas* canvas, const SkMatrix& original_ctm); + bool HasNonAAPaint() const { return false; } SkIRect rect; }; @@ -559,6 +566,7 @@ size_t AdditionalBytesUsed() const; bool HasDiscardableImages() const; int CountSlowPaths() const; + bool HasNonAAPaint() const; sk_sp<const PaintRecord> record; }; @@ -694,6 +702,7 @@ const PaintFlags* flags, SkCanvas* canvas, const SkMatrix& original_ctm); + bool HasNonAAPaint() const { return false; } SkRect bounds; }; @@ -785,6 +794,7 @@ return sizeof(*this) + reserved_ + subrecord_bytes_used_; } int numSlowPaths() const { return num_slow_paths_; } + bool HasNonAAPaint() const { return has_non_aa_paint_; } bool HasDiscardableImages() const { return has_discardable_images_; } // Resize the PaintOpBuffer to exactly fit the current amount of used space. @@ -947,6 +957,8 @@ num_slow_paths_ += op->CountSlowPathsFromFlags(); num_slow_paths_ += op->CountSlowPaths(); + has_non_aa_paint_ |= op->HasNonAAPaint(); + has_discardable_images_ |= op->HasDiscardableImages(); has_discardable_images_ |= op->HasDiscardableImagesFromFlags(); @@ -960,6 +972,7 @@ // Record paths for veto-to-msaa for gpu raster. int num_slow_paths_ = 0; + bool has_non_aa_paint_ = false; // Record additional bytes used by referenced sub-records and display lists. size_t subrecord_bytes_used_ = 0; bool has_discardable_images_ = false;
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 5d9c122..913db86 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -490,6 +490,119 @@ EXPECT_EQ(4, buffer2->numSlowPaths()); } +TEST(PaintOpBufferTest, NonAAPaint) { + // PaintOpWithFlags + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + // Add a PaintOpWithFlags (in this case a line) with AA. + PaintFlags line_effect; + line_effect.setAntiAlias(true); + buffer->push<DrawLineOp>(1.f, 2.f, 3.f, 4.f, line_effect); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + // Add a PaintOpWithFlags (in this case a line) without AA. + PaintFlags line_effect_no_aa; + line_effect_no_aa.setAntiAlias(false); + buffer->push<DrawLineOp>(1.f, 2.f, 3.f, 4.f, line_effect_no_aa); + EXPECT_TRUE(buffer->HasNonAAPaint()); + } + + // ClipPathOp + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + SkPath path; + path.addCircle(2, 2, 5); + + // ClipPathOp with AA + buffer->push<ClipPathOp>(path, SkClipOp::kIntersect, true /* antialias */); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + // ClipPathOp without AA + buffer->push<ClipPathOp>(path, SkClipOp::kIntersect, false /* antialias */); + EXPECT_TRUE(buffer->HasNonAAPaint()); + } + + // ClipRRectOp + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + // ClipRRectOp with AA + buffer->push<ClipRRectOp>(SkRRect::MakeEmpty(), SkClipOp::kIntersect, + true /* antialias */); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + // ClipRRectOp without AA + buffer->push<ClipRRectOp>(SkRRect::MakeEmpty(), SkClipOp::kIntersect, + false /* antialias */); + EXPECT_TRUE(buffer->HasNonAAPaint()); + } + + // Drawing a record with non-aa paths into another propogates the value. + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + auto sub_buffer = sk_make_sp<PaintOpBuffer>(); + SkPath path; + path.addCircle(2, 2, 5); + sub_buffer->push<ClipPathOp>(path, SkClipOp::kIntersect, + false /* antialias */); + EXPECT_TRUE(sub_buffer->HasNonAAPaint()); + + buffer->push<DrawRecordOp>(sub_buffer); + EXPECT_TRUE(buffer->HasNonAAPaint()); + } + + // The following PaintOpWithFlags types are overridden to *not* ever have + // non-AA paint. AA is hard to notice, and these kick us out of MSAA in too + // many cases. + + // DrawImageOp + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + PaintImage image = PaintImage(PaintImage::GetNextId(), + CreateDiscardableImage(gfx::Size(100, 100))); + PaintFlags non_aa_flags; + non_aa_flags.setAntiAlias(true); + buffer->push<DrawImageOp>(image, SkIntToScalar(0), SkIntToScalar(0), + &non_aa_flags); + + EXPECT_FALSE(buffer->HasNonAAPaint()); + } + + // DrawIRectOp + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + PaintFlags non_aa_flags; + non_aa_flags.setAntiAlias(true); + buffer->push<DrawIRectOp>(SkIRect::MakeWH(1, 1), non_aa_flags); + + EXPECT_FALSE(buffer->HasNonAAPaint()); + } + + // SaveLayerOp + { + auto buffer = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer->HasNonAAPaint()); + + PaintFlags non_aa_flags; + non_aa_flags.setAntiAlias(true); + auto bounds = SkRect::MakeWH(1, 1); + buffer->push<SaveLayerOp>(&bounds, &non_aa_flags); + + EXPECT_FALSE(buffer->HasNonAAPaint()); + } +} + TEST(PaintOpBufferTest, ContiguousIndices) { PaintOpBuffer buffer; MockCanvas canvas;
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 9ca1f97..bf8046f 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -2190,8 +2190,10 @@ case RESOURCE_TYPE_BITMAP: DCHECK(resource.has_shared_bitmap_id); guid = GetSharedBitmapGUIDForTracing(resource.shared_bitmap_id); - shared_memory_guid = - resource.shared_bitmap->GetSharedMemoryHandle().GetGUID(); + if (resource.shared_bitmap) { + shared_memory_guid = + resource.shared_bitmap->GetSharedMemoryHandle().GetGUID(); + } break; }
diff --git a/cc/resources/shared_bitmap.h b/cc/resources/shared_bitmap.h index ac91c35..6a67cf8 100644 --- a/cc/resources/shared_bitmap.h +++ b/cc/resources/shared_bitmap.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> +#include "base/hash.h" #include "base/macros.h" #include "base/trace_event/memory_allocator_dump.h" #include "cc/cc_export.h" @@ -19,7 +20,13 @@ } namespace cc { -typedef gpu::Mailbox SharedBitmapId; +using SharedBitmapId = gpu::Mailbox; + +struct SharedBitmapIdHash { + size_t operator()(const SharedBitmapId& id) const { + return base::Hash(reinterpret_cast<const char*>(id.name), sizeof(id.name)); + } +}; CC_EXPORT base::trace_event::MemoryAllocatorDumpGuid GetSharedBitmapGUIDForTracing(const SharedBitmapId& bitmap_id);
diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc index 89c41bbbf..962c023 100644 --- a/cc/surfaces/compositor_frame_sink_support.cc +++ b/cc/surfaces/compositor_frame_sink_support.cc
@@ -77,9 +77,11 @@ } void CompositorFrameSinkSupport::EvictCurrentSurface() { - if (!current_surface_) + if (!current_surface_id_.is_valid()) return; - DestroyCurrentSurface(); + SurfaceId to_destroy_surface_id = current_surface_id_; + current_surface_id_ = SurfaceId(); + surface_manager_->DestroySurface(to_destroy_surface_id); } void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { @@ -96,8 +98,9 @@ // |has_damage| is not transmitted, but false by default. DCHECK(!ack.has_damage); - if (current_surface_) - surface_manager_->SurfaceModified(current_surface_->surface_id(), ack); + if (current_surface_id_.is_valid()) + surface_manager_->SurfaceModified(current_surface_id_, ack); + if (begin_frame_source_) begin_frame_source_->DidFinishFrame(this); } @@ -127,12 +130,12 @@ } } - std::unique_ptr<Surface> surface; - bool create_new_surface = - (!current_surface_ || - local_surface_id != current_surface_->surface_id().local_surface_id()); - if (!create_new_surface) { - surface = std::move(current_surface_); + Surface* prev_surface = + surface_manager_->GetSurfaceForId(current_surface_id_); + Surface* current_surface = nullptr; + if (prev_surface && + local_surface_id == current_surface_id_.local_surface_id()) { + current_surface = prev_surface; } else { SurfaceId surface_id(frame_sink_id_, local_surface_id); gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size(); @@ -142,8 +145,7 @@ if (!surface_info.is_valid()) { TRACE_EVENT_INSTANT0("cc", "Invalid SurfaceInfo", TRACE_EVENT_SCOPE_THREAD); - if (current_surface_) - DestroyCurrentSurface(); + EvictCurrentSurface(); ReturnedResourceArray resources; TransferableResource::ReturnResources(frame.resource_list, &resources); ReturnResources(resources); @@ -151,12 +153,13 @@ return true; } - surface = CreateSurface(surface_info); - surface_manager_->SurfaceDamageExpected(surface->surface_id(), + current_surface = CreateSurface(surface_info); + current_surface_id_ = SurfaceId(frame_sink_id_, local_surface_id); + surface_manager_->SurfaceDamageExpected(current_surface->surface_id(), last_begin_frame_args_); } - bool result = surface->QueueFrame( + bool result = current_surface->QueueFrame( std::move(frame), base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, weak_factory_.GetWeakPtr()), @@ -164,15 +167,14 @@ weak_factory_.GetWeakPtr())); if (!result) { - surface_manager_->DestroySurface(std::move(surface)); + EvictCurrentSurface(); return false; } - if (current_surface_) { - surface->SetPreviousFrameSurface(current_surface_.get()); - DestroyCurrentSurface(); + if (prev_surface && prev_surface != current_surface) { + current_surface->SetPreviousFrameSurface(prev_surface); + surface_manager_->DestroySurface(prev_surface->surface_id()); } - current_surface_ = std::move(surface); if (begin_frame_source_) begin_frame_source_->DidFinishFrame(this); @@ -288,9 +290,8 @@ void CompositorFrameSinkSupport::OnBeginFrame(const BeginFrameArgs& args) { UpdateNeedsBeginFramesInternal(); - if (current_surface_) { - surface_manager_->SurfaceDamageExpected(current_surface_->surface_id(), - args); + if (current_surface_id_.is_valid()) { + surface_manager_->SurfaceDamageExpected(current_surface_id_, args); } last_begin_frame_args_ = args; if (client_) @@ -342,28 +343,29 @@ begin_frame_source_->RemoveObserver(this); } -std::unique_ptr<Surface> CompositorFrameSinkSupport::CreateSurface( +Surface* CompositorFrameSinkSupport::CreateSurface( const SurfaceInfo& surface_info) { seen_first_frame_activation_ = false; return surface_manager_->CreateSurface(weak_factory_.GetWeakPtr(), surface_info); } -void CompositorFrameSinkSupport::DestroyCurrentSurface() { - surface_manager_->DestroySurface(std::move(current_surface_)); -} - void CompositorFrameSinkSupport::RequestCopyOfSurface( std::unique_ptr<CopyOutputRequest> copy_request) { - if (!current_surface_) + if (!current_surface_id_.is_valid()) return; - - DCHECK(current_surface_->compositor_frame_sink_support().get() == this); - current_surface_->RequestCopyOfOutput(std::move(copy_request)); + Surface* current_surface = + surface_manager_->GetSurfaceForId(current_surface_id_); + DCHECK_EQ(this, current_surface->compositor_frame_sink_support().get()); + current_surface->RequestCopyOfOutput(std::move(copy_request)); BeginFrameAck ack; ack.has_damage = true; - if (current_surface_->HasActiveFrame()) - surface_manager_->SurfaceModified(current_surface_->surface_id(), ack); + if (current_surface->HasActiveFrame()) + surface_manager_->SurfaceModified(current_surface->surface_id(), ack); +} + +Surface* CompositorFrameSinkSupport::GetCurrentSurfaceForTesting() { + return surface_manager_->GetSurfaceForId(current_surface_id_); } } // namespace cc
diff --git a/cc/surfaces/compositor_frame_sink_support.h b/cc/surfaces/compositor_frame_sink_support.h index 4397a1409..808cb29 100644 --- a/cc/surfaces/compositor_frame_sink_support.h +++ b/cc/surfaces/compositor_frame_sink_support.h
@@ -43,7 +43,6 @@ const FrameSinkId& frame_sink_id() const { return frame_sink_id_; } - Surface* current_surface_for_testing() { return current_surface_.get(); } SurfaceManager* surface_manager() { return surface_manager_; } bool needs_sync_points() { return needs_sync_points_; } @@ -68,6 +67,8 @@ void OnSurfaceActivated(Surface* surface); + Surface* GetCurrentSurfaceForTesting(); + protected: CompositorFrameSinkSupport(CompositorFrameSinkSupportClient* client, const FrameSinkId& frame_sink_id, @@ -99,14 +100,14 @@ void OnBeginFrameSourcePausedChanged(bool paused) override; void UpdateNeedsBeginFramesInternal(); - std::unique_ptr<Surface> CreateSurface(const SurfaceInfo& surface_info); - void DestroyCurrentSurface(); + Surface* CreateSurface(const SurfaceInfo& surface_info); CompositorFrameSinkSupportClient* const client_; SurfaceManager* surface_manager_ = nullptr; const FrameSinkId frame_sink_id_; + SurfaceId current_surface_id_; // If this contains a value then a surface reference from the top-level root // to SurfaceId(frame_sink_id_, referenced_local_surface_id_.value()) was @@ -115,7 +116,6 @@ SurfaceResourceHolder surface_resource_holder_; - std::unique_ptr<Surface> current_surface_; // Counts the number of CompositorFrames that have been submitted and have not // yet received an ACK. int ack_pending_count_ = 0;
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index 9be53ad..19c54082 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc
@@ -29,8 +29,7 @@ previous_frame_surface_id_(surface_info.id()), compositor_frame_sink_support_(std::move(compositor_frame_sink_support)), surface_manager_(compositor_frame_sink_support_->surface_manager()), - frame_index_(kFrameIndexStart), - destroyed_(false) {} + frame_index_(kFrameIndexStart) {} Surface::~Surface() { ClearCopyRequests();
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h index 1dc71b7..6f4495b 100644 --- a/cc/surfaces/surface.h +++ b/cc/surfaces/surface.h
@@ -127,9 +127,6 @@ return HasActiveFrame() && active_frame_data_->draw_callback; } - bool destroyed() const { return destroyed_; } - void set_destroyed(bool destroyed) { destroyed_ = destroyed; } - private: struct FrameData { FrameData(CompositorFrame&& frame, @@ -172,7 +169,6 @@ base::Optional<FrameData> active_frame_data_; int frame_index_; bool closed_ = false; - bool destroyed_; std::vector<SurfaceSequence> destruction_dependencies_; base::flat_set<SurfaceId> blocking_surfaces_;
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc index c26dda8..bfcde56af 100644 --- a/cc/surfaces/surface_manager.cc +++ b/cc/surfaces/surface_manager.cc
@@ -44,20 +44,9 @@ } SurfaceManager::~SurfaceManager() { - DCHECK(thread_checker_.CalledOnValidThread()); - - // Remove all temporary references on shutdown. - temporary_references_.clear(); - temporary_reference_ranges_.clear(); - - GarbageCollectSurfaces(); - - for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); - it != surfaces_to_destroy_.end(); - ++it) { - UnregisterSurface((*it)->surface_id()); - } - surfaces_to_destroy_.clear(); + // All CompositorFrameSinkSupports and their surfaces are supposed to be + // destroyed before SurfaceManager. + DCHECK_EQ(surfaces_to_destroy_.size(), surface_map_.size()); } #if DCHECK_IS_ON() @@ -82,7 +71,7 @@ dependency_tracker_->RequestSurfaceResolution(pending_surface); } -std::unique_ptr<Surface> SurfaceManager::CreateSurface( +Surface* SurfaceManager::CreateSurface( base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support, const SurfaceInfo& surface_info) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -93,42 +82,30 @@ // If no surface with this SurfaceId exists, simply create the surface and // return. - auto surface_iter = surface_map_.find(surface_info.id()); - if (surface_iter == surface_map_.end()) { - auto surface = + auto it = surface_map_.find(surface_info.id()); + if (it == surface_map_.end()) { + surface_map_[surface_info.id()] = base::MakeUnique<Surface>(surface_info, compositor_frame_sink_support); - surface_map_[surface->surface_id()] = surface.get(); - return surface; + return surface_map_[surface_info.id()].get(); } - // If a surface with this SurfaceId exists and it's not marked as destroyed, - // we should not receive a request to create a new surface with the same - // SurfaceId. - DCHECK(surface_iter->second->destroyed()); - - // If a surface with this SurfaceId exists and it's marked as destroyed, - // it means it's in the garbage collector's queue. We simply take it out of - // the queue and reuse it. - auto it = - std::find_if(surfaces_to_destroy_.begin(), surfaces_to_destroy_.end(), - [&surface_info](const std::unique_ptr<Surface>& surface) { - return surface->surface_id() == surface_info.id(); - }); - DCHECK(it != surfaces_to_destroy_.end()); - std::unique_ptr<Surface> surface = std::move(*it); - surfaces_to_destroy_.erase(it); - surface->set_destroyed(false); + // If a surface with this SurfaceId exists, it must be marked as destroyed. + // Otherwise, we wouldn't receive a request to reuse the same SurfaceId. + // Remove the surface out of the garbage collector's queue and reuse it. + Surface* surface = it->second.get(); + DCHECK(IsMarkedForDestruction(surface_info.id())); + surfaces_to_destroy_.erase(surface_info.id()); DCHECK_EQ(compositor_frame_sink_support.get(), surface->compositor_frame_sink_support().get()); return surface; } -void SurfaceManager::DestroySurface(std::unique_ptr<Surface> surface) { +void SurfaceManager::DestroySurface(const SurfaceId& surface_id) { DCHECK(thread_checker_.CalledOnValidThread()); - surface->set_destroyed(true); + DCHECK(surface_map_.count(surface_id)); for (auto& observer : observer_list_) - observer.OnSurfaceDestroyed(surface->surface_id()); - surfaces_to_destroy_.push_back(std::move(surface)); + observer.OnSurfaceDestroyed(surface_id); + surfaces_to_destroy_.insert(surface_id); GarbageCollectSurfaces(); } @@ -243,15 +220,13 @@ ? GetLiveSurfacesForReferences() : GetLiveSurfacesForSequences(); - std::vector<std::unique_ptr<Surface>> surfaces_to_delete; + std::vector<SurfaceId> surfaces_to_delete; // Delete all destroyed and unreachable surfaces. for (auto iter = surfaces_to_destroy_.begin(); iter != surfaces_to_destroy_.end();) { - SurfaceId surface_id = (*iter)->surface_id(); - if (reachable_surfaces.count(surface_id) == 0) { - UnregisterSurface(surface_id); - surfaces_to_delete.push_back(std::move(*iter)); + if (reachable_surfaces.count(*iter) == 0) { + surfaces_to_delete.push_back(*iter); iter = surfaces_to_destroy_.erase(iter); } else { ++iter; @@ -259,7 +234,8 @@ } // ~Surface() draw callback could modify |surfaces_to_destroy_|. - surfaces_to_delete.clear(); + for (const SurfaceId& surface_id : surfaces_to_delete) + DestroySurfaceInternal(surface_id); } SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { @@ -303,11 +279,12 @@ // their destruction dependencies satisfied. for (auto& map_entry : surface_map_) { const SurfaceId& surface_id = map_entry.first; - Surface* surface = map_entry.second; + Surface* surface = map_entry.second.get(); surface->SatisfyDestructionDependencies(&satisfied_sequences_, framesink_manager_.GetValidFrameSinkIds()); - if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0) { + if (!IsMarkedForDestruction(surface_id) || + surface->GetDestructionDependencyCount() > 0) { live_surfaces_set.insert(surface_id); live_surfaces.push_back(surface_id); } @@ -316,7 +293,7 @@ // Mark all surfaces reachable from live surfaces by adding them to // live_surfaces and live_surfaces_set. for (size_t i = 0; i < live_surfaces.size(); i++) { - Surface* surf = surface_map_[live_surfaces[i]]; + Surface* surf = surface_map_[live_surfaces[i]].get(); DCHECK(surf); const auto& children = GetSurfacesReferencedByParent(surf->surface_id()); @@ -470,10 +447,10 @@ Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) { DCHECK(thread_checker_.CalledOnValidThread()); - SurfaceMap::iterator it = surface_map_.find(surface_id); + auto it = surface_map_.find(surface_id); if (it == surface_map_.end()) return nullptr; - return it->second; + return it->second.get(); } bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id, @@ -531,10 +508,15 @@ observer.OnSurfaceDamageExpected(surface_id, args); } -void SurfaceManager::UnregisterSurface(const SurfaceId& surface_id) { +void SurfaceManager::DestroySurfaceInternal(const SurfaceId& surface_id) { DCHECK(thread_checker_.CalledOnValidThread()); - SurfaceMap::iterator it = surface_map_.find(surface_id); + auto it = surface_map_.find(surface_id); DCHECK(it != surface_map_.end()); + // Make sure that the surface is removed from the map before being actually + // destroyed. An ack could be sent during the destruction of a surface which + // could trigger a synchronous frame submission to a half-destroyed surface + // and that's not desirable. + std::unique_ptr<Surface> doomed = std::move(it->second); surface_map_.erase(it); RemoveAllSurfaceReferences(surface_id); } @@ -549,7 +531,7 @@ Surface* surface = GetSurfaceForId(surface_id); if (surface) { *str << surface->surface_id().ToString(); - *str << (surface->destroyed() ? " destroyed" : " live"); + *str << (IsMarkedForDestruction(surface_id) ? " destroyed" : " live"); if (surface->HasPendingFrame()) { // This provides the surface size from the root render pass. @@ -576,4 +558,8 @@ } #endif // DCHECK_IS_ON() +bool SurfaceManager::IsMarkedForDestruction(const SurfaceId& surface_id) { + return surfaces_to_destroy_.count(surface_id) != 0; +} + } // namespace cc
diff --git a/cc/surfaces/surface_manager.h b/cc/surfaces/surface_manager.h index 6cca042..872faec 100644 --- a/cc/surfaces/surface_manager.h +++ b/cc/surfaces/surface_manager.h
@@ -7,12 +7,12 @@ #include <stdint.h> -#include <list> #include <memory> #include <unordered_map> #include <unordered_set> #include <vector> +#include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/logging.h" #include "base/macros.h" @@ -67,12 +67,15 @@ void RequestSurfaceResolution(Surface* pending_surface); - std::unique_ptr<Surface> CreateSurface( + // Creates a Surface for the given CompositorFrameSinkSupport. The surface + // will be destroyed when DestroySurface is called, all of its destruction + // dependencies are satisfied, and it is not reachable from the root surface. + Surface* CreateSurface( base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support, const SurfaceInfo& surface_info); // Destroy the Surface once a set of sequence numbers has been satisfied. - void DestroySurface(std::unique_ptr<Surface> surface); + void DestroySurface(const SurfaceId& surface_id); // Called when a surface has been added to the aggregated CompositorFrame // and will notify observers with SurfaceObserver::OnSurfaceWillDraw. @@ -261,9 +264,8 @@ // |surface_id| that were added before |surface_id| will also be removed. void RemoveTemporaryReference(const SurfaceId& surface_id, bool remove_range); - // Called when a surface is destroyed and it needs to be removed from the - // surface map. - void UnregisterSurface(const SurfaceId& surface_id); + // Removes the surface from the surface map and destroys it. + void DestroySurfaceInternal(const SurfaceId& surface_id); #if DCHECK_IS_ON() // Recursively prints surface references starting at |surface_id| to |str|. @@ -272,20 +274,19 @@ std::stringstream* str); #endif + // Returns true if |surface_id| is in the garbage collector's queue. + bool IsMarkedForDestruction(const SurfaceId& surface_id); + // Use reference or sequence based lifetime management. LifetimeType lifetime_type_; FrameSinkManager framesink_manager_; - using SurfaceMap = std::unordered_map<SurfaceId, Surface*, SurfaceIdHash>; - SurfaceMap surface_map_; + base::flat_map<SurfaceId, std::unique_ptr<Surface>> surface_map_; base::ObserverList<SurfaceObserver> observer_list_; base::ThreadChecker thread_checker_; - // List of surfaces to be destroyed, along with what sequences they're still - // waiting on. - using SurfaceDestroyList = std::list<std::unique_ptr<Surface>>; - SurfaceDestroyList surfaces_to_destroy_; + base::flat_set<SurfaceId> surfaces_to_destroy_; // Set of SurfaceSequences that have been satisfied by a frame but not yet // waited on.
diff --git a/cc/surfaces/surface_synchronization_unittest.cc b/cc/surfaces/surface_synchronization_unittest.cc index c9983d75..6fc69e6e 100644 --- a/cc/surfaces/surface_synchronization_unittest.cc +++ b/cc/surfaces/surface_synchronization_unittest.cc
@@ -76,27 +76,27 @@ CompositorFrameSinkSupport& display_support() { return *supports_[0]; } Surface* display_surface() { - return display_support().current_surface_for_testing(); + return display_support().GetCurrentSurfaceForTesting(); } CompositorFrameSinkSupport& parent_support() { return *supports_[1]; } Surface* parent_surface() { - return parent_support().current_surface_for_testing(); + return parent_support().GetCurrentSurfaceForTesting(); } CompositorFrameSinkSupport& child_support1() { return *supports_[2]; } Surface* child_surface1() { - return child_support1().current_surface_for_testing(); + return child_support1().GetCurrentSurfaceForTesting(); } CompositorFrameSinkSupport& child_support2() { return *supports_[3]; } Surface* child_surface2() { - return child_support2().current_surface_for_testing(); + return child_support2().GetCurrentSurfaceForTesting(); } CompositorFrameSinkSupport& support(int index) { return *supports_[index]; } Surface* surface(int index) { - return support(index).current_surface_for_testing(); + return support(index).GetCurrentSurfaceForTesting(); } SurfaceManager& surface_manager() { return surface_manager_; } @@ -177,6 +177,10 @@ surface_observer_.Reset(); } + bool IsMarkedForDestruction(const SurfaceId& surface_id) { + return surface_manager_.IsMarkedForDestruction(surface_id); + } + protected: testing::NiceMock<MockCompositorFrameSinkSupportClient> support_client_; @@ -1041,7 +1045,7 @@ child_support1().EvictCurrentSurface(); surface = surface_manager().GetSurfaceForId(child_id); EXPECT_NE(nullptr, surface); - EXPECT_TRUE(surface->destroyed()); + EXPECT_TRUE(IsMarkedForDestruction(child_id)); // Child submits another frame to the same local surface id that is marked // destroyed. @@ -1052,7 +1056,7 @@ // used again. Surface* surface2 = surface_manager().GetSurfaceForId(child_id); EXPECT_EQ(surface, surface2); - EXPECT_FALSE(surface2->destroyed()); + EXPECT_FALSE(IsMarkedForDestruction(child_id)); } // Verifies that if a LocalSurfaceId belonged to a surface that doesn't exist
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc index a384a53..8bbb086 100644 --- a/cc/test/fake_content_layer_client.cc +++ b/cc/test/fake_content_layer_client.cc
@@ -31,7 +31,8 @@ last_canvas_(nullptr), last_painting_control_(PAINTING_BEHAVIOR_NORMAL), reported_memory_usage_(0), - bounds_set_(false) {} + bounds_set_(false), + contains_slow_paths_(false) {} FakeContentLayerClient::~FakeContentLayerClient() { } @@ -81,6 +82,18 @@ } } + if (contains_slow_paths_) { + // Add 6 slow paths, passing the reporting threshold. + SkPath path; + path.addCircle(2, 2, 5); + path.addCircle(3, 4, 2); + PaintOpBuffer* buffer = display_list->StartPaint(); + for (int i = 0; i < 6; ++i) { + buffer->push<ClipPathOp>(path, SkClipOp::kIntersect, true); + } + display_list->EndPaintOfUnpaired(PaintableRegion()); + } + if (fill_with_nonsolid_color_) { gfx::Rect draw_rect = PaintableRegion(); PaintFlags flags;
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h index 5849cb1..ce5c32f2 100644 --- a/cc/test/fake_content_layer_client.h +++ b/cc/test/fake_content_layer_client.h
@@ -51,6 +51,10 @@ fill_with_nonsolid_color_ = nonsolid; } + void set_contains_slow_paths(bool contains_slow_paths) { + contains_slow_paths_ = contains_slow_paths; + } + void add_draw_rect(const gfx::Rect& rect, const PaintFlags& flags) { draw_rects_.push_back(std::make_pair(gfx::RectF(rect), flags)); } @@ -107,6 +111,7 @@ size_t reported_memory_usage_; gfx::Size bounds_; bool bounds_set_; + bool contains_slow_paths_; }; } // namespace cc
diff --git a/cc/test/fake_picture_layer.cc b/cc/test/fake_picture_layer.cc index 5e71a79..ef473ec2 100644 --- a/cc/test/fake_picture_layer.cc +++ b/cc/test/fake_picture_layer.cc
@@ -9,20 +9,14 @@ namespace cc { FakePictureLayer::FakePictureLayer(ContentLayerClient* client) - : PictureLayer(client), - update_count_(0), - always_update_resources_(false), - force_unsuitable_for_gpu_rasterization_(false) { + : PictureLayer(client) { SetBounds(gfx::Size(1, 1)); SetIsDrawable(true); } FakePictureLayer::FakePictureLayer(ContentLayerClient* client, std::unique_ptr<RecordingSource> source) - : PictureLayer(client, std::move(source)), - update_count_(0), - always_update_resources_(false), - force_unsuitable_for_gpu_rasterization_(false) { + : PictureLayer(client, std::move(source)) { SetBounds(gfx::Size(1, 1)); SetIsDrawable(true); } @@ -60,10 +54,16 @@ return updated || always_update_resources_; } -bool FakePictureLayer::IsSuitableForGpuRasterization() const { - if (force_unsuitable_for_gpu_rasterization_) - return false; - return PictureLayer::IsSuitableForGpuRasterization(); +bool FakePictureLayer::HasSlowPaths() const { + if (force_content_has_slow_paths_) + return true; + return PictureLayer::HasSlowPaths(); +} + +bool FakePictureLayer::HasNonAAPaint() const { + if (force_content_has_non_aa_paint_) + return true; + return PictureLayer::HasNonAAPaint(); } } // namespace cc
diff --git a/cc/test/fake_picture_layer.h b/cc/test/fake_picture_layer.h index 1ae27b71..fbedca1 100644 --- a/cc/test/fake_picture_layer.h +++ b/cc/test/fake_picture_layer.h
@@ -29,7 +29,8 @@ // Layer implementation. std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool Update() override; - bool IsSuitableForGpuRasterization() const override; + bool HasSlowPaths() const override; + bool HasNonAAPaint() const override; int update_count() const { return update_count_; } void reset_update_count() { update_count_ = 0; } @@ -38,8 +39,12 @@ always_update_resources_ = always_update_resources; } - void set_force_unsuitable_for_gpu_rasterization(bool flag) { - force_unsuitable_for_gpu_rasterization_ = flag; + void set_force_content_has_slow_paths(bool flag) { + force_content_has_slow_paths_ = flag; + } + + void set_force_content_has_non_aa_paint(bool flag) { + force_content_has_non_aa_paint_ = flag; } void set_fixed_tile_size(gfx::Size fixed_tile_size) { @@ -52,10 +57,11 @@ std::unique_ptr<RecordingSource> source); ~FakePictureLayer() override; - int update_count_; - bool always_update_resources_; + int update_count_ = 0; + bool always_update_resources_ = false; - bool force_unsuitable_for_gpu_rasterization_; + bool force_content_has_slow_paths_ = false; + bool force_content_has_non_aa_paint_ = false; gfx::Size fixed_tile_size_; };
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h index 617d09f..b7ae1c2 100644 --- a/cc/test/test_web_graphics_context_3d.h +++ b/cc/test/test_web_graphics_context_3d.h
@@ -353,6 +353,9 @@ void set_enable_dc_layers(bool support) { test_capabilities_.dc_layers = support; } + void set_support_multisample_compatibility(bool support) { + test_capabilities_.multisample_compatibility = support; + } // When this context is lost, all contexts in its share group are also lost. void add_share_group_context(TestWebGraphicsContext3D* context3d) {
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 7e1e56ae..3ab29fa 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -497,8 +497,8 @@ rendering_stats_instrumentation_.get(), task_graph_runner_, std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_)); host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); - host_impl->SetContentIsSuitableForGpuRasterization( - content_is_suitable_for_gpu_rasterization_); + host_impl->SetContentHasSlowPaths(content_has_slow_paths_); + host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); task_graph_runner_ = NULL; input_handler_weak_ptr_ = host_impl->AsWeakPtr(); return host_impl; @@ -579,7 +579,8 @@ } void LayerTreeHost::ResetGpuRasterizationTracking() { - content_is_suitable_for_gpu_rasterization_ = true; + content_has_slow_paths_ = false; + content_has_non_aa_paint_ = false; gpu_rasterization_histogram_recorded_ = false; } @@ -702,11 +703,13 @@ UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered", has_gpu_rasterization_trigger_); UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent", - content_is_suitable_for_gpu_rasterization_); + !content_has_slow_paths_); + UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSlowPathsWithNonAAPaint", + content_has_slow_paths_ && content_has_non_aa_paint_); // Record how many pages actually get gpu rasterization when enabled. - UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed", - (has_gpu_rasterization_trigger_ && - content_is_suitable_for_gpu_rasterization_)); + UMA_HISTOGRAM_BOOLEAN( + "Renderer4.GpuRasterizationUsed", + (has_gpu_rasterization_trigger_ && !content_has_slow_paths_)); } gpu_rasterization_histogram_recorded_ = true; @@ -777,20 +780,28 @@ EnsureValidPropertyTreeState(this); - bool content_is_suitable_for_gpu = true; - bool did_paint_content = - PaintContent(update_layer_list, &content_is_suitable_for_gpu); + bool content_has_slow_paths = false; + bool content_has_non_aa_paint = false; + bool did_paint_content = PaintContent( + update_layer_list, &content_has_slow_paths, &content_has_non_aa_paint); - if (content_is_suitable_for_gpu) { - ++num_consecutive_frames_suitable_for_gpu_; - if (num_consecutive_frames_suitable_for_gpu_ >= - kNumFramesToConsiderBeforeGpuRasterization) { - content_is_suitable_for_gpu_rasterization_ = true; + // |content_has_non_aa_paint| is a correctness (not performance) modifier, if + // it changes we immediately update. To prevent churn, this flag is sticky. + content_has_non_aa_paint_ |= content_has_non_aa_paint; + + // If no slow-path content has appeared for a required number of frames, + // update the flag. + if (!content_has_slow_paths) { + ++num_consecutive_frames_without_slow_paths_; + if (num_consecutive_frames_without_slow_paths_ >= + kNumFramesToConsiderBeforeRemovingSlowPathFlag) { + content_has_slow_paths_ = false; } } else { - num_consecutive_frames_suitable_for_gpu_ = 0; - content_is_suitable_for_gpu_rasterization_ = false; + num_consecutive_frames_without_slow_paths_ = 0; + content_has_slow_paths_ = true; } + return did_paint_content; } @@ -1138,12 +1149,14 @@ } bool LayerTreeHost::PaintContent(const LayerList& update_layer_list, - bool* content_is_suitable_for_gpu) { + bool* content_has_slow_paths, + bool* content_has_non_aa_paint) { base::AutoReset<bool> painting(&in_paint_layer_contents_, true); bool did_paint_content = false; for (const auto& layer : update_layer_list) { did_paint_content |= layer->Update(); - *content_is_suitable_for_gpu &= layer->IsSuitableForGpuRasterization(); + *content_has_slow_paths |= layer->HasSlowPaths(); + *content_has_non_aa_paint |= layer->HasNonAAPaint(); } return did_paint_content; } @@ -1314,8 +1327,8 @@ void LayerTreeHost::PushLayerTreeHostPropertiesTo( LayerTreeHostImpl* host_impl) { host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); - host_impl->SetContentIsSuitableForGpuRasterization( - content_is_suitable_for_gpu_rasterization_); + host_impl->SetContentHasSlowPaths(content_has_slow_paths_); + host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); RecordGpuRasterizationHistogram(host_impl); host_impl->SetViewportSize(device_viewport_size_);
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 7aa95ec9..6b742a01 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -349,7 +349,8 @@ bool in_update_property_trees() const { return in_update_property_trees_; } bool PaintContent(const LayerList& update_layer_list, - bool* content_is_suitable_for_gpu); + bool* content_has_slow_paths, + bool* content_has_non_aa_paint); bool in_paint_layer_contents() const { return in_paint_layer_contents_; } void SetHasCopyRequest(bool has_copy_request); @@ -525,8 +526,8 @@ friend class LayerTreeHostSerializationTest; // This is the number of consecutive frames in which we want the content to be - // suitable for GPU rasterization before re-enabling it. - enum { kNumFramesToConsiderBeforeGpuRasterization = 60 }; + // free of slow-paths before toggling the flag. + enum { kNumFramesToConsiderBeforeRemovingSlowPathFlag = 60 }; void ApplyViewportDeltas(ScrollAndScaleSet* info); void RecordWheelAndTouchScrollingCount(ScrollAndScaleSet* info); @@ -565,7 +566,8 @@ bool visible_ = false; bool has_gpu_rasterization_trigger_ = false; - bool content_is_suitable_for_gpu_rasterization_ = true; + bool content_has_slow_paths_ = false; + bool content_has_non_aa_paint_ = false; bool gpu_rasterization_histogram_recorded_ = false; // If set, then page scale animation has completed, but the client hasn't been @@ -582,7 +584,7 @@ TaskGraphRunner* task_graph_runner_; SurfaceSequenceGenerator surface_sequence_generator_; - uint32_t num_consecutive_frames_suitable_for_gpu_ = 0; + uint32_t num_consecutive_frames_without_slow_paths_ = 0; scoped_refptr<Layer> root_layer_;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 3e781b3..5f62cb6 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -200,7 +200,8 @@ current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), layer_tree_frame_sink_(nullptr), need_update_gpu_rasterization_status_(false), - content_is_suitable_for_gpu_rasterization_(true), + content_has_slow_paths_(false), + content_has_non_aa_paint_(false), has_gpu_rasterization_trigger_(false), use_gpu_rasterization_(false), use_msaa_(false), @@ -1813,9 +1814,16 @@ } } -void LayerTreeHostImpl::SetContentIsSuitableForGpuRasterization(bool flag) { - if (content_is_suitable_for_gpu_rasterization_ != flag) { - content_is_suitable_for_gpu_rasterization_ = flag; +void LayerTreeHostImpl::SetContentHasSlowPaths(bool flag) { + if (content_has_slow_paths_ != flag) { + content_has_slow_paths_ = flag; + need_update_gpu_rasterization_status_ = true; + } +} + +void LayerTreeHostImpl::SetContentHasNonAAPaint(bool flag) { + if (content_has_non_aa_paint_ != flag) { + content_has_non_aa_paint_ = flag; need_update_gpu_rasterization_status_ = true; } } @@ -1847,22 +1855,25 @@ ContextProvider* compositor_context_provider = layer_tree_frame_sink_->context_provider(); bool gpu_rasterization_enabled = false; + bool supports_disable_msaa = false; if (compositor_context_provider) { const auto& caps = compositor_context_provider->ContextCapabilities(); gpu_rasterization_enabled = caps.gpu_rasterization; + supports_disable_msaa = caps.multisample_compatibility; if (!caps.msaa_is_slow) max_msaa_samples = caps.max_samples; } bool use_gpu = false; bool use_msaa = false; - bool using_msaa_for_complex_content = - requested_msaa_samples > 0 && max_msaa_samples >= requested_msaa_samples; + bool using_msaa_for_slow_paths = + requested_msaa_samples > 0 && + max_msaa_samples >= requested_msaa_samples && + (!content_has_non_aa_paint_ || supports_disable_msaa); if (settings_.gpu_rasterization_forced) { use_gpu = true; gpu_rasterization_status_ = GpuRasterizationStatus::ON_FORCED; - use_msaa = !content_is_suitable_for_gpu_rasterization_ && - using_msaa_for_complex_content; + use_msaa = content_has_slow_paths_ && using_msaa_for_slow_paths; if (use_msaa) { gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; } @@ -1870,8 +1881,7 @@ gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE; } else if (!has_gpu_rasterization_trigger_) { gpu_rasterization_status_ = GpuRasterizationStatus::OFF_VIEWPORT; - } else if (!content_is_suitable_for_gpu_rasterization_ && - using_msaa_for_complex_content) { + } else if (content_has_slow_paths_ && using_msaa_for_slow_paths) { use_gpu = use_msaa = true; gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; } else {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index b5510a6..8fba6e2 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -403,7 +403,8 @@ TileManager* tile_manager() { return &tile_manager_; } void SetHasGpuRasterizationTrigger(bool flag); - void SetContentIsSuitableForGpuRasterization(bool flag); + void SetContentHasSlowPaths(bool flag); + void SetContentHasNonAAPaint(bool flag); bool CanUseGpuRasterization(); bool use_gpu_rasterization() const { return use_gpu_rasterization_; } bool use_msaa() const { return use_msaa_; } @@ -756,7 +757,8 @@ std::unique_ptr<ResourceProvider> resource_provider_; bool need_update_gpu_rasterization_status_; - bool content_is_suitable_for_gpu_rasterization_; + bool content_has_slow_paths_; + bool content_has_non_aa_paint_; bool has_gpu_rasterization_trigger_; bool use_gpu_rasterization_; bool use_msaa_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 9f362a34..50d4aee 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -8656,7 +8656,7 @@ host_impl_->ResetRequiresHighResToDraw(); - host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->SetContentHasSlowPaths(false); host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->CommitComplete(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); @@ -11763,7 +11763,7 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { // Set initial state, before varying GPU rasterization trigger. host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, host_impl_->gpu_rasterization_status()); @@ -11786,8 +11786,8 @@ host_impl_->NotifyReadyToActivate(); } -// Tests that SetContentIsSuitableForGpuRasterization behaves as expected. -TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSuitability) { +// Tests that SetContentHasSlowPaths behaves as expected. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) { std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa = TestWebGraphicsContext3D::Create(); context_with_msaa->SetMaxSamples(4); @@ -11797,25 +11797,25 @@ EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeLayerTreeFrameSink::Create3d( std::move(context_with_msaa)))); - // Set initial state, before varying GPU rasterization suitability. + // Set initial state, with slow paths on. host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_msaa()); host_impl_->NotifyReadyToActivate(); - // Toggle suitability on. - host_impl_->SetContentIsSuitableForGpuRasterization(true); + // Toggle slow paths off. + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); host_impl_->NotifyReadyToActivate(); - // And off. - host_impl_->SetContentIsSuitableForGpuRasterization(false); + // And on. + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); @@ -11838,7 +11838,7 @@ // Set initial state, before varying scale factor. host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); @@ -11876,7 +11876,7 @@ std::move(context_with_msaa)))); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); @@ -11899,7 +11899,7 @@ LayerTreeSettings settings = DefaultSettings(); EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, host_impl_->gpu_rasterization_status()); @@ -11910,7 +11910,7 @@ EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, host_impl_->gpu_rasterization_status()); @@ -11934,27 +11934,92 @@ }; TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { - // Ensure that without the msaa_is_slow cap we raster unsuitable content with + // Ensure that without the msaa_is_slow cap we raster slow paths with // msaa. CreateHostImplWithMsaaIsSlow(false); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); - // Ensure that with the msaa_is_slow cap we don't raster unsuitable content + // Ensure that with the msaa_is_slow cap we don't raster slow paths // with msaa (we'll still use GPU raster, though). CreateHostImplWithMsaaIsSlow(true); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); } +class MsaaCompatibilityLayerTreeHostImplTest : public LayerTreeHostImplTest { + public: + void CreateHostImplWithMultisampleCompatibility( + bool support_multisample_compatibility) { + LayerTreeSettings settings = DefaultSettings(); + settings.gpu_rasterization_msaa_sample_count = 4; + auto context_provider = TestContextProvider::Create(); + context_provider->UnboundTestContext3d()->SetMaxSamples(4); + context_provider->UnboundTestContext3d() + ->set_support_multisample_compatibility( + support_multisample_compatibility); + context_provider->UnboundTestContext3d()->set_gpu_rasterization(true); + auto msaa_is_normal_layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(context_provider); + EXPECT_TRUE(CreateHostImpl( + settings, std::move(msaa_is_normal_layer_tree_frame_sink))); + } +}; + +TEST_F(MsaaCompatibilityLayerTreeHostImplTest, + GpuRasterizationStatusNonAAPaint) { + // Ensure that without non-aa paint and without multisample compatibility, we + // raster slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(false); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(false); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Ensure that without non-aa paint and with multisample compatibility, we + // raster slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(true); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(false); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Ensure that with non-aa paint and without multisample compatibility, we do + // not raster slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(false); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Ensure that with non-aa paint and with multisample compatibility, we raster + // slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(true); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); +} + TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { // Check page scale factor update in property trees when an update is made // on the active tree.
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 46bf072..4cce2ce0 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -5459,14 +5459,14 @@ } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); @@ -5510,14 +5510,14 @@ } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); @@ -5541,17 +5541,14 @@ scoped_refptr<ContextProvider> compositor_context_provider, scoped_refptr<ContextProvider> worker_context_provider) override { auto context = TestWebGraphicsContext3D::Create(); + context->SetMaxSamples(4); + context->set_support_multisample_compatibility(false); context->set_gpu_rasterization(true); auto context_provider = TestContextProvider::Create(std::move(context)); return LayerTreeHostTest::CreateLayerTreeFrameSink( renderer_settings, refresh_rate, std::move(context_provider), std::move(worker_context_provider)); } -}; - -class LayerTreeHostTestGpuRasterizationEnabled - : public LayerTreeHostWithGpuRasterizationTest { - protected: void SetupTree() override { LayerTreeHostTest::SetupTree(); @@ -5569,6 +5566,14 @@ layer_client_.set_bounds(layer_->bounds()); } + FakeContentLayerClient layer_client_; + FakePictureLayer* layer_; + FakeRecordingSource* recording_source_; +}; + +class LayerTreeHostTestGpuRasterizationEnabled + : public LayerTreeHostWithGpuRasterizationTest { + protected: void BeginTest() override { // Verify default value. EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); @@ -5578,26 +5583,26 @@ EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is relevant as well. - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. // The results will be verified after commit is completed below. - // Since we are manually marking the source as unsuitable, + // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. layer_->SetNeedsDisplay(); PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - // Ensure the suitability bit sticks. - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + // Ensure the slow path bit sticks. + EXPECT_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + EXPECT_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); @@ -5605,10 +5610,6 @@ } void AfterTest() override {} - - FakeContentLayerClient layer_client_; - FakePictureLayer* layer_; - FakeRecordingSource* recording_source_; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); @@ -5620,39 +5621,6 @@ settings->gpu_rasterization_msaa_sample_count = 4; } - std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink( - const RendererSettings& renderer_settings, - double refresh_rate, - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { - std::unique_ptr<TestWebGraphicsContext3D> context = - TestWebGraphicsContext3D::Create(); - context->SetMaxSamples(4); - context->set_gpu_rasterization(true); - compositor_context_provider = - TestContextProvider::Create(std::move(context)); - return LayerTreeTest::CreateLayerTreeFrameSink( - renderer_settings, refresh_rate, compositor_context_provider, - worker_context_provider); - } - - void SetupTree() override { - LayerTreeHostTest::SetupTree(); - - std::unique_ptr<FakeRecordingSource> recording_source( - new FakeRecordingSource); - recording_source_ = recording_source.get(); - - scoped_refptr<FakePictureLayer> layer = - FakePictureLayer::CreateWithRecordingSource( - &layer_client_, std::move(recording_source)); - layer_ = layer.get(); - layer->SetBounds(gfx::Size(10, 10)); - layer->SetIsDrawable(true); - layer_tree_host()->root_layer()->AddChild(layer); - layer_client_.set_bounds(layer_->bounds()); - } - void BeginTest() override { // Verify default value. EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); @@ -5662,11 +5630,11 @@ EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is relevant as well. - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. // The results will be verified after commit is completed below. - // Since we are manually marking the source as unsuitable, + // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. layer_->SetNeedsDisplay(); PostSetNeedsCommitToMainThread(); @@ -5683,13 +5651,13 @@ ++num_commits_; switch (num_commits_) { case 1: - layer_->set_force_unsuitable_for_gpu_rasterization(false); + layer_->set_force_content_has_slow_paths(false); break; case 30: - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); break; case 31: - layer_->set_force_unsuitable_for_gpu_rasterization(false); + layer_->set_force_content_has_slow_paths(false); break; case 90: expected_use_msaa_ = false; @@ -5702,15 +5670,67 @@ void AfterTest() override {} - FakeContentLayerClient layer_client_; - FakePictureLayer* layer_; - FakeRecordingSource* recording_source_; int num_commits_ = 0; bool expected_use_msaa_ = true; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationReenabled); +class LayerTreeHostTestGpuRasterizationNonAASticky + : public LayerTreeHostWithGpuRasterizationTest { + protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_msaa_sample_count = 4; + } + + void BeginTest() override { + // Verify default value. + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + + // Gpu rasterization trigger is relevant. + layer_tree_host()->SetHasGpuRasterizationTrigger(true); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); + + // Start without slow paths, but no non-aa paint. + layer_->set_force_content_has_slow_paths(true); + layer_->set_force_content_has_non_aa_paint(false); + + // The results will be verified after commit is completed below. + layer_->SetNeedsDisplay(); + PostSetNeedsCommitToMainThread(); + } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_)); + if (expected_use_msaa_) { + EXPECT_TRUE(host_impl->use_msaa()); + } else { + EXPECT_FALSE(host_impl->use_msaa()); + } + + ++num_commits_; + switch (num_commits_) { + case 30: + layer_->set_force_content_has_non_aa_paint(true); + expected_use_msaa_ = false; + break; + case 31: + layer_->set_force_content_has_non_aa_paint(false); + break; + } + PostSetNeedsCommitToMainThread(); + if (num_commits_ > 100) + EndTest(); + } + + void AfterTest() override {} + + int num_commits_ = 0; + bool expected_use_msaa_ = true; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationNonAASticky); + class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { @@ -5745,26 +5765,26 @@ EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is irrelevant as well. - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. // The results will be verified after commit is completed below. - // Since we are manually marking the source as unsuitable, + // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. layer_->SetNeedsDisplay(); PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - // Ensure the suitability bit sticks. - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + // Ensure the slow-paths bit sticks. + EXPECT_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + EXPECT_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization());
diff --git a/chrome/VERSION b/chrome/VERSION index d3f4347..1701a9d 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=61 MINOR=0 -BUILD=3144 +BUILD=3145 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 1bb7d1ce..caf727c 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -444,15 +444,6 @@ # From java_sources.gni. java_files = chrome_test_java_sources - # TODO(crbug/716236): Remove this exclusion and update these two test files, - # after the O SDK is rolled. - if (android_sdk_version == "O") { - java_files -= [ - "javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java", - "javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java", - ] - } - deps = [ ":partner_location_descriptor_proto_java", "//base:base_java", @@ -681,6 +672,7 @@ "../browser/android/chrome_entry_point.cc", ] deps = [ + ":chrome_jni_registration($default_toolchain)", "//build/config:exe_and_shlib_deps", "//chrome:chrome_android_core", ] @@ -705,8 +697,30 @@ } # Ensure that .pak files are built only once (build them in the default -# toolchain). +# toolchain). The central header file calling JNI registration functions +# is generated from Java code so it just needs to be generated once. if (current_toolchain == default_toolchain) { + generate_jni_registration("chrome_jni_registration") { + target = ":chrome_public_apk" + output = "$root_gen_dir/chrome/browser/android/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] + } + + generate_jni_registration("chrome_sync_shell_jni_registration") { + testonly = true + target = ":chrome_sync_shell_apk" + output = "$root_gen_dir/chrome/browser/android/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] + } + if (enable_resource_whitelist_generation) { generate_resource_whitelist("monochrome_resource_whitelist") { # Always use the 32-bit library's whitelist since the 64-bit one is @@ -802,12 +816,13 @@ shared_library("chrome_sync_shell") { testonly = true sources = [ - "../browser/android/chrome_entry_point.cc", + "../browser/android/chrome_sync_shell_entry_point.cc", "../browser/android/chrome_sync_shell_main_delegate.cc", "../browser/android/chrome_sync_shell_main_delegate.h", "../browser/android/chrome_sync_shell_main_delegate_initializer.cc", ] deps = [ + ":chrome_sync_shell_jni_registration($default_toolchain)", "//build/config:exe_and_shlib_deps", "//chrome:chrome_android_core", "//components/sync", @@ -888,6 +903,9 @@ apk_name = "ChromeSyncShell" shared_libraries = [ ":chrome_sync_shell" ] + # This exists here rather than in chrome_sync_shell_test_apk for JNI + # registration to be able to find the native side functions. + java_files = [ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java" ] deps = [ ":chrome_sync_shell_apk_template_resources", @@ -895,6 +913,7 @@ # but that code is stripped out via proguard. Adding this deps adds # usages and prevents removal of the proto code. "//components/sync:test_support_proto_java", + "//third_party/android_protobuf:protobuf_nano_javalib", ] } @@ -988,11 +1007,23 @@ } } -android_library("chrome_sync_shell_test_apk_java") { - testonly = true - - # From java_sources.jni. - java_files = sync_shell_test_java_sources +instrumentation_test_apk("chrome_sync_shell_test_apk") { + apk_name = "ChromeSyncShellTest" + apk_under_test = ":chrome_sync_shell_apk" + android_manifest = chrome_sync_shell_test_apk_manifest + android_manifest_dep = ":chrome_sync_shell_test_apk_manifest" + java_files = [ + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java", + "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java", + ] deps = [ "//base:base_java", @@ -1008,21 +1039,9 @@ "//components/sync/android:sync_java", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", - "//third_party/android_protobuf:protobuf_nano_javalib", "//third_party/android_support_test_runner:runner_java", "//third_party/android_tools:android_support_v7_appcompat_java", "//ui/android:ui_java", ] -} - -instrumentation_test_apk("chrome_sync_shell_test_apk") { - apk_name = "ChromeSyncShellTest" - apk_under_test = ":chrome_sync_shell_apk" - android_manifest = chrome_sync_shell_test_apk_manifest - android_manifest_dep = ":chrome_sync_shell_test_apk_manifest" - deps = [ - ":chrome_sync_shell_test_apk_java", - "//third_party/android_support_test_runner:runner_java", - ] proguard_enabled = !is_java_debug }
diff --git a/chrome/android/OWNERS b/chrome/android/OWNERS index bf63cb9..e7413ef 100644 --- a/chrome/android/OWNERS +++ b/chrome/android/OWNERS
@@ -1,5 +1,4 @@ bauerb@chromium.org -dfalcantara@chromium.org dtrainor@chromium.org mariakhomenko@chromium.org nyquist@chromium.org
diff --git a/chrome/android/java/res/OWNERS b/chrome/android/java/res/OWNERS index a2a58dc..56e129f9 100644 --- a/chrome/android/java/res/OWNERS +++ b/chrome/android/java/res/OWNERS
@@ -1,5 +1,4 @@ set noparent -dfalcantara@chromium.org dtrainor@chromium.org tedchoc@chromium.org twellington@chromium.org
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 11be9f5..965d1ec8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -93,7 +93,6 @@ import org.chromium.chrome.browser.metrics.LaunchMetrics; import org.chromium.chrome.browser.metrics.StartupMetrics; import org.chromium.chrome.browser.metrics.UmaSessionStats; -import org.chromium.chrome.browser.metrics.UmaUtils; import org.chromium.chrome.browser.metrics.WebApkUma; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; @@ -939,6 +938,9 @@ * super depending on whether the tasks should run before or after these ones. */ protected void onDeferredStartup() { + if (mDeferredStartupPosted) return; + + mDeferredStartupPosted = true; initDeferredStartupForActivity(); ProcessInitializationHandler.getInstance().initializeDeferredStartupTasks(); DeferredStartupHandler.getInstance().queueDeferredTasksOnIdleHandler(); @@ -2065,15 +2067,7 @@ return; } mDeferredStartupQueued = false; - - if (!mDeferredStartupPosted) { - mDeferredStartupPosted = true; - RecordHistogram.recordLongTimesHistogram( - "UMA.Debug.EnableCrashUpload.PostDeferredStartUptime2", - SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), - TimeUnit.MILLISECONDS); - onDeferredStartup(); - } + onDeferredStartup(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index df517a6..63010bdf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -488,7 +488,10 @@ // Data reduction promo should be temporarily suppressed if the sign in promo is // shown to avoid nagging users too much. if (!SigninPromoUtil.launchSigninPromoIfNeeded(this)) { - DataReductionPromoScreen.launchDataReductionPromo(this); + if (!DataReductionPromoScreen.launchDataReductionPromo(this) + && getBottomSheet() != null) { + getBottomSheet().showHelpBubbleIfNecessary(); + } } } else { preferenceManager.setPromosSkippedOnFirstStart(true); @@ -941,9 +944,15 @@ } mIntentWithEffect = false; + boolean activeTabBeingRestored = false; if ((mIsOnFirstRun || getSavedInstanceState() == null) && intent != null) { if (!mIntentHandler.shouldIgnoreIntent(intent)) { mIntentWithEffect = mIntentHandler.onNewIntent(intent); + + // Allow the active tab to be restored so that the correct tab is selected when + // the bottom sheet NTP UI is closed. + activeTabBeingRestored |= (getBottomSheet() != null + && NewTabPage.isNTPUrl(IntentHandler.getUrlFromIntent(intent))); } if (isMainIntentFromLauncher(intent)) { @@ -963,7 +972,8 @@ // We always need to try to restore tabs. The set of tabs might be empty, but at least // it will trigger the notification that tab restore is complete which is needed by // other parts of Chrome such as sync. - boolean activeTabBeingRestored = !mIntentWithEffect; + activeTabBeingRestored |= !mIntentWithEffect; + mMainIntentMetrics.setIgnoreEvents(true); mTabModelSelectorImpl.restoreTabs(activeTabBeingRestored); mMainIntentMetrics.setIgnoreEvents(false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java index a2b3aed..bbb08b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -95,10 +95,12 @@ RecordHistogram.recordLongTimesHistogram( "UMA.Debug.EnableCrashUpload.DeferredStartUpMaxTaskDuration", mMaxTaskDuration, TimeUnit.MILLISECONDS); - RecordHistogram.recordLongTimesHistogram( - "UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime", - SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), - TimeUnit.MILLISECONDS); + if (UmaUtils.hasComeToForeground()) { + RecordHistogram.recordLongTimesHistogram( + "UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime", + SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), + TimeUnit.MILLISECONDS); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java index 9dd8de1..f13034aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java
@@ -27,6 +27,7 @@ private final AppMenuHandler mMenuHandler; private Runnable mOnAppMenuShownListener; private boolean mIsTouchEventsBeingProcessed; + private boolean mShowMenuOnUp; /** * @param menuHandler MenuHandler implementation that can show and get the app menu. @@ -43,6 +44,14 @@ } /** + * @param showMenuOnUp Whether app menu should show on the up action. + * If false, the app menu will be shown on the down action. + */ + public void setShowMenuOnUp(boolean showMenuOnUp) { + mShowMenuOnUp = showMenuOnUp; + } + + /** * Shows the app menu if it is not already shown. * @param view View that initiated showing this menu. Normally it is a menu button. * @param startDragging Whether dragging is started. @@ -81,6 +90,16 @@ return showAppMenu(view, false); } + /** + * Set whether touch event is being processed and view is pressed on touch event. + * @param view View that received a touch event. + * @param isActionDown Whether the touch event is a down action. + */ + private void updateTouchEvent(View view, boolean isActionDown) { + mIsTouchEventsBeingProcessed = isActionDown; + view.setPressed(isActionDown); + } + @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View view, MotionEvent event) { @@ -88,16 +107,20 @@ switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - mIsTouchEventsBeingProcessed = true; - isTouchEventConsumed |= true; - view.setPressed(true); - showAppMenu(view, true); + if (!mShowMenuOnUp) { + isTouchEventConsumed |= true; + updateTouchEvent(view, true); + showAppMenu(view, true); + } break; case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mIsTouchEventsBeingProcessed = false; isTouchEventConsumed |= true; - view.setPressed(false); + updateTouchEvent(view, false); + if (mShowMenuOnUp) showAppMenu(view, false); + break; + case MotionEvent.ACTION_CANCEL: + isTouchEventConsumed |= true; + updateTouchEvent(view, false); break; default: }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/banners/OWNERS index 453dc77..d6d1a1da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/OWNERS
@@ -1,2 +1 @@ -dfalcantara@chromium.org dominickn@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index a38c28e..81fea9a7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -22,7 +22,6 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.share.ShareParams; -import org.chromium.content.browser.ContentViewCore; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid.OnCloseContextMenuListener; @@ -32,11 +31,12 @@ import javax.annotation.Nullable; /** - * A helper class that handles generating context menus for {@link ContentViewCore}s. + * A helper class that handles generating context menus for {@link WebContents}s. */ public class ContextMenuHelper implements OnCreateContextMenuListener { private static final int MAX_SHARE_DIMEN_PX = 2048; + private final WebContents mWebContents; private long mNativeContextMenuHelper; private ContextMenuPopulator mPopulator; @@ -46,13 +46,14 @@ private Runnable mOnMenuShown; private Runnable mOnMenuClosed; - private ContextMenuHelper(long nativeContextMenuHelper) { + private ContextMenuHelper(long nativeContextMenuHelper, WebContents webContents) { mNativeContextMenuHelper = nativeContextMenuHelper; + mWebContents = webContents; } @CalledByNative - private static ContextMenuHelper create(long nativeContextMenuHelper) { - return new ContextMenuHelper(nativeContextMenuHelper); + private static ContextMenuHelper create(long nativeContextMenuHelper, WebContents webContents) { + return new ContextMenuHelper(nativeContextMenuHelper, webContents); } @CalledByNative @@ -80,15 +81,15 @@ /** * Starts showing a context menu for {@code view} based on {@code params}. - * @param contentViewCore The {@link ContentViewCore} to show the menu to. - * @param params The {@link ContextMenuParams} that indicate what menu items to show. + * @param params The {@link ContextMenuParams} that indicate what menu items to show. + * @param view container view for the menu. + * @param topContentOffsetPx the offset of the content from the top. */ @CalledByNative private void showContextMenu( - final ContentViewCore contentViewCore, final ContextMenuParams params) { + final ContextMenuParams params, View view, float topContentOffsetPx) { if (params.isFile()) return; - View view = contentViewCore.getContainerView(); - final WindowAndroid windowAndroid = contentViewCore.getWindowAndroid(); + final WindowAndroid windowAndroid = mWebContents.getTopLevelNativeWindow(); if (view == null || view.getVisibility() != View.VISIBLE || view.getParent() == null || windowAndroid == null || windowAndroid.getActivity().get() == null @@ -108,8 +109,7 @@ mOnMenuShown = new Runnable() { @Override public void run() { - WebContents webContents = contentViewCore.getWebContents(); - RecordHistogram.recordBooleanHistogram("ContextMenu.Shown", webContents != null); + RecordHistogram.recordBooleanHistogram("ContextMenu.Shown", mWebContents != null); } }; mOnMenuClosed = new Runnable() { @@ -143,7 +143,7 @@ } } }); - menuUi.setRenderCoordinates(contentViewCore.getRenderCoordinates()); + menuUi.setTopContentOffsetY(topContentOffsetPx); menuUi.displayMenu(mActivity, mCurrentContextMenuParams, items, mCallback, mOnMenuShown, mOnMenuClosed); if (mCurrentContextMenuParams.isImage()) { @@ -206,8 +206,7 @@ Callback<byte[]> callback = new Callback<byte[]>() { @Override public void onResult(byte[] result) { - WebContents webContents = nativeGetJavaWebContents(mNativeContextMenuHelper); - WindowAndroid windowAndroid = webContents.getTopLevelNativeWindow(); + WindowAndroid windowAndroid = mWebContents.getTopLevelNativeWindow(); Activity activity = windowAndroid.getActivity().get(); if (activity == null) return; @@ -257,7 +256,6 @@ return mPopulator; } - private native WebContents nativeGetJavaWebContents(long nativeContextMenuHelper); private native void nativeOnStartDownload( long nativeContextMenuHelper, boolean isLink, boolean isDataReductionProxyEnabled); private native void nativeSearchForImage(long nativeContextMenuHelper);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java index f965262..b2f6c02 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java
@@ -30,7 +30,6 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.ContextMenuDialog; -import org.chromium.content.browser.RenderCoordinates; import java.util.ArrayList; import java.util.List; @@ -45,7 +44,7 @@ private ImageView mHeaderImageView; private Callback<Boolean> mOnShareItemClicked; private View mPagerView; - private RenderCoordinates mRenderCoordinates; + private float mTopContentOffsetPx; public TabularContextMenuUi(Callback<Boolean> onShareItemClicked) { mOnShareItemClicked = onShareItemClicked; @@ -101,7 +100,7 @@ (TabularContextMenuViewPager) view.findViewById(R.id.custom_pager)); final ContextMenuDialog dialog = new ContextMenuDialog(activity, R.style.DialogWhenLarge, - touchPointXPx, touchPointYPx, mPagerView, mRenderCoordinates); + touchPointXPx, touchPointYPx, mTopContentOffsetPx, mPagerView); dialog.setContentView(view); return dialog; @@ -288,10 +287,14 @@ } /** - * Gives this class access to the render coordinates to allow access to the total size of the - * toolbar and tab strip. + * Set the content offset. + * + * This should be set separately ahead of calling {@link displayMenu()} + * since it cannot be passed to the method. + * @param topContentOffsetPx y content offset from the top. */ - public void setRenderCoordinates(RenderCoordinates renderCoordinates) { - mRenderCoordinates = renderCoordinates; + public void setTopContentOffsetY(float topContentOffsetPx) { + assert mContextMenuDialog != null; + mTopContentOffsetPx = topContentOffsetPx; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java index edae544..6060aeaf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java
@@ -58,6 +58,7 @@ private ContextualSearchTapState mLastTapState; private boolean mIsWaitingForInvalidTapDetection; private boolean mShouldHandleSelectionModification; + // Whether the selection was automatically expanded due to an adjustment (e.g. Resolve). private boolean mDidExpandSelection; // Position of the selection. @@ -70,10 +71,6 @@ // When the last tap gesture happened. private long mTapTimeNanoseconds; - // Tracks whether a Context Menu has just been shown and the UX has been dismissed. - // The selection may be unreliable until the next reset. See crbug.com/628436. - private boolean mIsContextMenuShown; - private class ContextualSearchGestureStateListener extends GestureStateListener { @Override public void onScrollStarted(int scrollOffsetY, int scrollExtentY) { @@ -125,12 +122,10 @@ /** * Notifies that a Context Menu has been shown. - * Future controller events may be unreliable until the next reset. */ void onContextMenuShown() { // Hide the UX. mHandler.handleSelectionDismissal(); - mIsContextMenuShown = true; } /** @@ -252,11 +247,11 @@ boolean shouldHandleSelection = false; switch (eventType) { case SelectionEventType.SELECTION_HANDLES_SHOWN: - if (!mIsContextMenuShown) { - mWasTapGestureDetected = false; - mSelectionType = SelectionType.LONG_PRESS; - shouldHandleSelection = true; - } + mWasTapGestureDetected = false; + mSelectionType = SelectionType.LONG_PRESS; + shouldHandleSelection = true; + ContentViewCore baseContentView = getBaseContentView(); + if (baseContentView != null) mSelectedText = baseContentView.getSelectedText(); break; case SelectionEventType.SELECTION_HANDLES_CLEARED: mHandler.handleSelectionDismissal(); @@ -269,15 +264,10 @@ } if (shouldHandleSelection) { - ContentViewCore baseContentView = getBaseContentView(); - if (baseContentView != null) { - String selection = baseContentView.getSelectedText(); - if (selection != null) { - mX = posXPix; - mY = posYPix; - mSelectedText = selection; - handleSelection(selection, SelectionType.LONG_PRESS); - } + if (mSelectedText != null) { + mX = posXPix; + mY = posYPix; + handleSelection(mSelectedText, SelectionType.LONG_PRESS); } } } @@ -301,7 +291,6 @@ resetSelectionStates(); mLastTapState = null; mLastScrollTimeNs = 0; - mIsContextMenuShown = false; mTapTimeNanoseconds = 0; mDidExpandSelection = false; } @@ -410,10 +399,7 @@ Tab currentTab = mActivity.getActivityTab(); if (currentTab == null) return null; - ContentViewCore contentViewCore = currentTab.getContentViewCore(); - if (contentViewCore == null) return null; - - return contentViewCore.getWebContents(); + return currentTab.getWebContents(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS index 345ead2..2b5bfcd8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS
@@ -1,3 +1,2 @@ -dfalcantara@chromium.org mariakhomenko@chromium.org yusufo@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/download/OWNERS index efafd02..c86b971 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/OWNERS
@@ -1,4 +1,3 @@ qinmin@chromium.org -per-file DownloadActivity.java=dfalcantara@chromium.org per-file DownloadActivity.java=twellington@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS index a5ae8db..14074130 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS
@@ -1,4 +1,3 @@ set noparent -dfalcantara@chromium.org twellington@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/favicon/LargeIconBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/favicon/LargeIconBridge.java index d8f4089..15e9ffc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/favicon/LargeIconBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/favicon/LargeIconBridge.java
@@ -8,6 +8,7 @@ import android.support.annotation.Nullable; import android.util.LruCache; +import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.browser.profiles.Profile; @@ -19,8 +20,8 @@ public class LargeIconBridge { private static final int CACHE_ENTRY_MIN_SIZE_BYTES = 1024; + private final Profile mProfile; private long mNativeLargeIconBridge; - private Profile mProfile; private LruCache<String, CachedFavicon> mFaviconCache; private static class CachedFavicon { @@ -60,6 +61,17 @@ } /** + * Constructor that leaves the bridge independent from the native side. + * Note: {@link #getLargeIconForUrl(String, int, LargeIconCallback)} will crash with the default + * implementation, it should then be overridden. + */ + @VisibleForTesting + public LargeIconBridge() { + mNativeLargeIconBridge = 0; + mProfile = null; + } + + /** * Create an internal cache. * @param cacheSizeBytes The maximum size of the cache in bytes. Must be greater than 0. Note * that this will be an approximate as there is no easy way to measure @@ -81,9 +93,10 @@ * Deletes the C++ side of this class. This must be called when this object is no longer needed. */ public void destroy() { - assert mNativeLargeIconBridge != 0; - nativeDestroy(mNativeLargeIconBridge); - mNativeLargeIconBridge = 0; + if (mNativeLargeIconBridge != 0) { + nativeDestroy(mNativeLargeIconBridge); + mNativeLargeIconBridge = 0; + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/infobar/OWNERS index 99e44ca..abb2e3f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/OWNERS
@@ -1,5 +1,4 @@ set noparent -dfalcantara@chromium.org mdjones@chromium.org per-file GeneratedPasswordSavedInfoBar*=rouslan@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java index 9dfdb56..6feb385e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -50,7 +50,6 @@ import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.media.MediaCaptureNotificationService; import org.chromium.chrome.browser.metrics.LaunchMetrics; -import org.chromium.chrome.browser.metrics.UmaUtils; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.notifications.channels.ChannelsUpdater; @@ -253,10 +252,6 @@ if (mInitializedDeferredStartupTasks) return; mInitializedDeferredStartupTasks = true; - RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.DeferredStartUptime2", - SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), - TimeUnit.MILLISECONDS); - handleDeferredStartupTasksInitialization(); } @@ -493,10 +488,6 @@ * minidump storage directory. */ private void initCrashReporting() { - RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.Uptime3", - mAsyncTaskStartTime - UmaUtils.getForegroundStartTime(), - TimeUnit.MILLISECONDS); - // Crash reports can be uploaded as part of a background service even while the main // Chrome activity is not running, and hence regular metrics reporting is not // possible. Instead, metrics are temporarily written to prefs; export those prefs
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS index c806110..f017f94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS
@@ -1,7 +1,6 @@ set noparent -dfalcantara@chromium.org tedchoc@chromium.org yusufo@chromium.org -# COMPONENT: UI>Browser>Mobile>SearchWidget \ No newline at end of file +# COMPONENT: UI>Browser>Mobile>SearchWidget
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java index 3eca3e9..b2f440de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -870,11 +870,12 @@ clearNotification(); } - @Nullable + @NonNull private MediaMetadataCompat createMetadata() { - if (mMediaNotificationInfo.isPrivate) return null; - + // Can't return null as {@link MediaSessionCompat#setMetadata()} will crash in some versions + // of the Android compat library. MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder(); + if (mMediaNotificationInfo.isPrivate) return metadataBuilder.build(); metadataBuilder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMediaNotificationInfo.metadata.getTitle());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java index 3704fb21..5f22e8e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java
@@ -52,14 +52,10 @@ } /** - * Whether the application is in the early stage since the browser process start. The - * "application start" ends right after the last histogram related to browser startup is - * recorded. Currently, the very first navigation commit in the lifetime of the process ends the - * "application start". - * Must only be called on the UI thread. + * Determines if Chrome was brought to foreground. */ - public static boolean isRunningApplicationStart() { - return sRunningApplicationStart; + public static boolean hasComeToForeground() { + return sForegroundStartTimeMs != 0; } /**
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 4838a28..e4e552fa 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
@@ -34,13 +34,12 @@ import org.chromium.chrome.browser.download.DownloadManagerService; import org.chromium.chrome.browser.metrics.StartupMetrics; import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; -import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrlServiceObserver; +import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory; import org.chromium.chrome.browser.suggestions.SuggestionsEventReporter; -import org.chromium.chrome.browser.suggestions.SuggestionsEventReporterBridge; import org.chromium.chrome.browser.suggestions.SuggestionsMetrics; import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegateImpl; @@ -76,8 +75,6 @@ // Key for the scroll position data that may be stored in a navigation entry. private static final String NAVIGATION_ENTRY_SCROLL_POSITION_KEY = "NewTabPageScrollPosition"; - private static SuggestionsSource sSuggestionsSourceForTests; - private final Tab mTab; private final TabModelSelector mTabModelSelector; @@ -92,7 +89,6 @@ private boolean mSearchProviderHasLogo; private FakeboxDelegate mFakeboxDelegate; - private SnippetsBridge mSnippetsBridge; // The timestamp at which the constructor was called. private final long mConstructedTimeNs; @@ -170,11 +166,6 @@ return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_OFFLINE_PAGES_FEATURE_NAME); } - @VisibleForTesting - public static void setSuggestionsSourceForTests(SuggestionsSource suggestionsSource) { - sSuggestionsSourceForTests = suggestionsSource; - } - private class NewTabPageManagerImpl extends SuggestionsUiDelegateImpl implements NewTabPageManager { public NewTabPageManagerImpl(SuggestionsSource suggestionsSource, @@ -238,12 +229,6 @@ } @Override - public SuggestionsSource getSuggestionsSource() { - if (sSuggestionsSourceForTests != null) return sSuggestionsSourceForTests; - return mSnippetsBridge; - } - - @Override public boolean isCurrentPage() { if (mIsDestroyed) return false; if (mFakeboxDelegate == null) return false; @@ -318,13 +303,14 @@ mTabModelSelector = tabModelSelector; Profile profile = mTab.getProfile(); - mSnippetsBridge = new SnippetsBridge(profile); - SuggestionsEventReporter eventReporter = new SuggestionsEventReporterBridge(); + SuggestionsDependencyFactory depsFactory = SuggestionsDependencyFactory.getInstance(); + SuggestionsSource suggestionsSource = depsFactory.createSuggestionSource(profile); + SuggestionsEventReporter eventReporter = depsFactory.createEventReporter(); SuggestionsNavigationDelegateImpl navigationDelegate = new SuggestionsNavigationDelegateImpl( activity, profile, nativePageHost, tabModelSelector); - mNewTabPageManager = new NewTabPageManagerImpl(mSnippetsBridge, eventReporter, + mNewTabPageManager = new NewTabPageManagerImpl(suggestionsSource, eventReporter, navigationDelegate, profile, nativePageHost, activity.getReferencePool()); mTileGroupDelegate = new NewTabPageTileGroupDelegate( activity, profile, tabModelSelector, navigationDelegate); @@ -556,10 +542,6 @@ .isAttachedToWindow(getView()) : "Destroy called before removed from window"; if (mIsLoaded && !mTab.isHidden()) recordNTPHidden(); - if (mSnippetsBridge != null) { - mSnippetsBridge.onDestroy(); - mSnippetsBridge = null; - } mNewTabPageManager.onDestroy(); mTileGroupDelegate.destroy(); TemplateUrlService.getInstance().removeObserver(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java index 2629312..7ea63ca72 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java
@@ -11,7 +11,6 @@ import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.ContentSuggestionsAdditionalAction; -import org.chromium.chrome.browser.suggestions.DestructionObserver; import java.util.ArrayList; import java.util.List; @@ -19,7 +18,7 @@ /** * Provides access to the snippets to display on the NTP using the C++ ContentSuggestionsService. */ -public class SnippetsBridge implements SuggestionsSource, DestructionObserver { +public class SnippetsBridge implements SuggestionsSource { private static final String TAG = "SnippetsBridge"; private long mNativeSnippetsBridge;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java index fa22a7e..e71bd86 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java
@@ -8,13 +8,14 @@ import org.chromium.base.Callback; import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo; +import org.chromium.chrome.browser.suggestions.DestructionObserver; import java.util.List; /** * An interface for classes that provide content suggestions. */ -public interface SuggestionsSource { +public interface SuggestionsSource extends DestructionObserver { /** * An observer for events in the content suggestions service. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS index 79becd2..047e38a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS
@@ -1 +1 @@ -dfalcantara@chromium.org +nyquist@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoScreen.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoScreen.java index 34ed542..514e231 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoScreen.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoScreen.java
@@ -22,20 +22,23 @@ /** * Launch the data reduction promo, if it needs to be displayed. + * @return Whether the data reduction promo was displayed. */ - public static void launchDataReductionPromo(Activity parentActivity) { + public static boolean launchDataReductionPromo(Activity parentActivity) { // The promo is displayed if Chrome is launched directly (i.e., not with the intent to // navigate to and view a URL on startup), the instance is part of the field trial, // and the promo has not been displayed before. - if (!DataReductionPromoUtils.canShowPromos()) return; - if (DataReductionPromoUtils.getDisplayedFreOrSecondRunPromo()) return; + if (!DataReductionPromoUtils.canShowPromos()) return false; + if (DataReductionPromoUtils.getDisplayedFreOrSecondRunPromo()) return false; // Showing the promo dialog in multiwindow mode is broken on Galaxy Note devices: // http://crbug.com/354696. If we're in multiwindow mode, save the dialog for later. - if (MultiWindowUtils.getInstance().isLegacyMultiWindow(parentActivity)) return; + if (MultiWindowUtils.getInstance().isLegacyMultiWindow(parentActivity)) return false; DataReductionPromoScreen promoScreen = new DataReductionPromoScreen(parentActivity); promoScreen.setOnDismissListener(promoScreen); promoScreen.show(); + + return true; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionSiteBreakdownView.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionSiteBreakdownView.java index 8450c91e..4b17908 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionSiteBreakdownView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionSiteBreakdownView.java
@@ -30,6 +30,13 @@ */ public class DataReductionSiteBreakdownView extends LinearLayout { private static final int NUM_DATA_USE_ITEMS_TO_ADD = 10; + + /** + * Hostname used for the other bucket which consists of chrome-services traffic. + * This should be in sync with the same in DataReductionProxyDataUseObserver. + */ + private static final String OTHER_HOST_NAME = "Other"; + private int mNumDataUseItemsToDisplay = 10; private TableLayout mTableLayout; @@ -89,7 +96,7 @@ mDataUseItems = items; setTextViewUnsortedAttributes(mDataUsedTitle); setTextViewSortedAttributes(mDataSavedTitle); - Collections.sort(items, new DataSavedComparator()); + Collections.sort(mDataUseItems, new DataSavedComparator()); if (mDataUseItems.size() == 0) { setVisibility(GONE); } else { @@ -130,7 +137,12 @@ implements Comparator<DataReductionDataUseItem>, Serializable { @Override public int compare(DataReductionDataUseItem lhs, DataReductionDataUseItem rhs) { - if (lhs.getDataUsed() < rhs.getDataUsed()) { + // Force the 'Other' category to the bottom of the list. + if (OTHER_HOST_NAME.equals(lhs.getHostname())) { + return 1; + } else if (OTHER_HOST_NAME.equals(rhs.getHostname())) { + return -1; + } else if (lhs.getDataUsed() < rhs.getDataUsed()) { return 1; } else if (lhs.getDataUsed() > rhs.getDataUsed()) { return -1; @@ -147,7 +159,12 @@ implements Comparator<DataReductionDataUseItem>, Serializable { @Override public int compare(DataReductionDataUseItem lhs, DataReductionDataUseItem rhs) { - if (lhs.getDataSaved() < rhs.getDataSaved()) { + // Force the 'Other' category to the bottom of the list. + if (OTHER_HOST_NAME.equals(lhs.getHostname())) { + return 1; + } else if (OTHER_HOST_NAME.equals(rhs.getHostname())) { + return -1; + } else if (lhs.getDataSaved() < rhs.getDataSaved()) { return 1; } else if (lhs.getDataSaved() > rhs.getDataSaved()) { return -1; @@ -180,7 +197,12 @@ TextView dataUsedView = (TextView) row.findViewById(R.id.site_data_used); TextView dataSavedView = (TextView) row.findViewById(R.id.site_data_saved); - hostnameView.setText(mDataUseItems.get(i).getHostname()); + String hostName = mDataUseItems.get(i).getHostname(); + if (OTHER_HOST_NAME.equals(hostName)) { + hostName = getResources().getString( + R.string.data_reduction_breakdown_other_host_name); + } + hostnameView.setText(hostName); dataUsedView.setText(mDataUseItems.get(i).getFormattedDataUsed(getContext())); dataSavedView.setText(mDataUseItems.get(i).getFormattedDataSaved(getContext())); @@ -228,4 +250,4 @@ mTableLayout.requestLayout(); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS index c806110..f017f94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS
@@ -1,7 +1,6 @@ set noparent -dfalcantara@chromium.org tedchoc@chromium.org yusufo@chromium.org -# COMPONENT: UI>Browser>Mobile>SearchWidget \ No newline at end of file +# COMPONENT: UI>Browser>Mobile>SearchWidget
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java index d85eacbd..f519276f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java
@@ -13,6 +13,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.chrome.browser.infobar.InfoBar; +import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.util.AccessibilityUtil; /** @@ -24,8 +26,7 @@ * during {@link #DEFAULT_SNACKBAR_DURATION_MS} milliseconds, it will call * {@link SnackbarController#onDismissNoAction(Object)}. */ -public class SnackbarManager implements OnClickListener { - +public class SnackbarManager implements OnClickListener, InfoBarContainer.InfoBarContainerObserver { /** * Interface that shows the ability to provide a snackbar manager. Activities implementing this * interface must call {@link SnackbarManager#onStart()} and {@link SnackbarManager#onStop()} in @@ -159,6 +160,21 @@ updateView(); } + // InfoBarContainerObserver implementation. + @Override + public void onAddInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isFirst) { + // Bring Snackbars to the foreground so that it's not blocked by infobars. + if (isShowing()) { + mView.bringToFront(); + } + } + + @Override + public void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isLast) {} + + @Override + public void onInfoBarContainerAttachedToWindow(boolean hasInfobars) {} + /** * Temporarily changes the parent {@link ViewGroup} of the snackbar. If a snackbar is currently * showing, this method removes the snackbar from its original parent, and attaches it to the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java index 5fb75d9..d4c3d6fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java
@@ -175,6 +175,10 @@ return mView.isShown(); } + void bringToFront() { + mView.bringToFront(); + } + /** * Sends an accessibility event to mMessageView announcing that this window was added so that * the mMessageView content description is read aloud if accessibility is enabled.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSites.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSites.java index cac588939..645bbca3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSites.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSites.java
@@ -11,7 +11,7 @@ /** * Methods to provide most recent urls, titles and thumbnails. */ -interface MostVisitedSites { +public interface MostVisitedSites { /** * An interface for handling events in {@link MostVisitedSites}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetContent.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetContent.java index fec31e58..b53bb9f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetContent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetContent.java
@@ -13,17 +13,13 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; -import org.chromium.base.DiscardableReferencePool; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.NativePageHost; import org.chromium.chrome.browser.ntp.ContextMenuManager; import org.chromium.chrome.browser.ntp.ContextMenuManager.TouchEnabledDelegate; import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; -import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.profiles.Profile; @@ -43,9 +39,6 @@ * Provides content to be displayed inside of the Home tab of bottom sheet. */ public class SuggestionsBottomSheetContent implements BottomSheet.BottomSheetContent { - private static SuggestionsSource sSuggestionsSourceForTesting; - private static SuggestionsEventReporter sEventReporterForTesting; - private final View mView; private final FadingShadowView mShadowView; private final SuggestionsRecyclerView mRecyclerView; @@ -56,13 +49,15 @@ public SuggestionsBottomSheetContent(final ChromeActivity activity, final BottomSheet sheet, TabModelSelector tabModelSelector, SnackbarManager snackbarManager) { + SuggestionsDependencyFactory depsFactory = SuggestionsDependencyFactory.getInstance(); Profile profile = Profile.getLastUsedProfile(); SuggestionsNavigationDelegate navigationDelegate = new SuggestionsNavigationDelegateImpl(activity, profile, sheet, tabModelSelector); mTileGroupDelegate = new TileGroupDelegateImpl( activity, profile, tabModelSelector, navigationDelegate, snackbarManager); - mSuggestionsUiDelegate = createSuggestionsDelegate( - profile, navigationDelegate, sheet, activity.getReferencePool()); + mSuggestionsUiDelegate = new SuggestionsUiDelegateImpl( + depsFactory.createSuggestionSource(profile), depsFactory.createEventReporter(), + navigationDelegate, profile, sheet, activity.getReferencePool()); mView = LayoutInflater.from(activity).inflate( R.layout.suggestions_bottom_sheet_content, null); @@ -204,39 +199,4 @@ } }); } - - public static void setSuggestionsSourceForTesting(SuggestionsSource suggestionsSource) { - sSuggestionsSourceForTesting = suggestionsSource; - } - - public static void setEventReporterForTesting(SuggestionsEventReporter eventReporter) { - sEventReporterForTesting = eventReporter; - } - - private static SuggestionsUiDelegateImpl createSuggestionsDelegate(Profile profile, - SuggestionsNavigationDelegate navigationDelegate, NativePageHost host, - DiscardableReferencePool referencePool) { - SnippetsBridge snippetsBridge = null; - SuggestionsSource suggestionsSource; - SuggestionsEventReporter eventReporter; - - if (sSuggestionsSourceForTesting == null) { - snippetsBridge = new SnippetsBridge(profile); - suggestionsSource = snippetsBridge; - } else { - suggestionsSource = sSuggestionsSourceForTesting; - } - - if (sEventReporterForTesting == null) { - eventReporter = new SuggestionsEventReporterBridge(); - } else { - eventReporter = sEventReporterForTesting; - } - - SuggestionsUiDelegateImpl delegate = new SuggestionsUiDelegateImpl( - suggestionsSource, eventReporter, navigationDelegate, profile, host, referencePool); - if (snippetsBridge != null) delegate.addDestructionObserver(snippetsBridge); - - return delegate; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsDependencyFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsDependencyFactory.java new file mode 100644 index 0000000..a7d66e9 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsDependencyFactory.java
@@ -0,0 +1,52 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.suggestions; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.favicon.LargeIconBridge; +import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; +import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; +import org.chromium.chrome.browser.profiles.Profile; + +/** + * Provides an injection mechanisms for dependencies of the suggestions package. + * + * This class is intended to handle creating the instances of the various classes that interact with + * native code, so that they can be easily swapped out during tests. + */ +public class SuggestionsDependencyFactory { + private static SuggestionsDependencyFactory sInstance; + + public static SuggestionsDependencyFactory getInstance() { + ThreadUtils.assertOnUiThread(); + if (sInstance == null) sInstance = new SuggestionsDependencyFactory(); + return sInstance; + } + + @VisibleForTesting + public static void setInstanceForTesting(SuggestionsDependencyFactory testInstance) { + if (sInstance != null && testInstance != null) { + throw new IllegalStateException("A real instance already exists."); + } + sInstance = testInstance; + } + + public SuggestionsSource createSuggestionSource(Profile profile) { + return new SnippetsBridge(profile); + } + + public SuggestionsEventReporter createEventReporter() { + return new SuggestionsEventReporterBridge(); + } + + public MostVisitedSites createMostVisitedSites(Profile profile) { + return new MostVisitedSitesBridge(profile); + } + + public LargeIconBridge createLargeIconBridge(Profile profile) { + return new LargeIconBridge(profile); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java index b739ddef..2595e9a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsUiDelegateImpl.java
@@ -57,6 +57,8 @@ mProfile = profile; mHost = host; mReferencePool = referencePool; + + addDestructionObserver(mSuggestionsSource); } @Override @@ -158,7 +160,10 @@ */ private LargeIconBridge getLargeIconBridge() { assert !mIsDestroyed; - if (mLargeIconBridge == null) mLargeIconBridge = new LargeIconBridge(mProfile); + if (mLargeIconBridge == null) { + mLargeIconBridge = + SuggestionsDependencyFactory.getInstance().createLargeIconBridge(mProfile); + } return mLargeIconBridge; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroupDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroupDelegateImpl.java index 568dc875..0f49fc3e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroupDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroupDelegateImpl.java
@@ -10,7 +10,6 @@ import org.chromium.base.Callback; import org.chromium.base.CommandLine; -import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; @@ -33,7 +32,6 @@ * the {@link TileGroup} should not know about. */ public class TileGroupDelegateImpl implements TileGroup.Delegate { - private static MostVisitedSites sMostVisitedSitesForTests; private final Context mContext; private final SnackbarManager mSnackbarManager; @@ -51,7 +49,8 @@ mSnackbarManager = snackbarManager; mTabModelSelector = tabModelSelector; mNavigationDelegate = navigationDelegate; - mMostVisitedSites = buildMostVisitedSites(profile); + mMostVisitedSites = + SuggestionsDependencyFactory.getInstance().createMostVisitedSites(profile); } @Override @@ -111,19 +110,6 @@ mMostVisitedSites.destroy(); } - private static MostVisitedSites buildMostVisitedSites(Profile profile) { - if (sMostVisitedSitesForTests != null) { - return sMostVisitedSitesForTests; - } else { - return new MostVisitedSitesBridge(profile); - } - } - - @VisibleForTesting - public static void setMostVisitedSitesForTests(MostVisitedSites mostVisitedSitesForTests) { - sMostVisitedSitesForTests = mostVisitedSitesForTests; - } - private void showTileRemovedSnackbar(String url, final Callback<String> removalUndoneCallback) { if (mTileRemovedSnackbarController == null) { mTileRemovedSnackbarController = new SnackbarController() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java index efea41c..0573d850 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -210,19 +210,19 @@ } if (!hasCommitted) return; - if (isInMainFrame && UmaUtils.isRunningApplicationStart()) { + if (isInMainFrame && UmaUtils.hasComeToForeground()) { // Current median is 550ms, and long tail is very long. ZoomedIn gives good view of the // median and ZoomedOut gives a good overview. RecordHistogram.recordCustomTimesHistogram( - "Startup.FirstCommitNavigationTime2.ZoomedIn", - SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), - 200, 1000, TimeUnit.MILLISECONDS, 100); + "Startup.FirstCommitNavigationTime3.ZoomedIn", + SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), 200, 1000, + TimeUnit.MILLISECONDS, 100); // For ZoomedOut very rarely is it under 50ms and this range matches // CustomTabs.IntentToFirstCommitNavigationTime2.ZoomedOut. RecordHistogram.recordCustomTimesHistogram( - "Startup.FirstCommitNavigationTime2.ZoomedOut", - SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), - 50, TimeUnit.MINUTES.toMillis(10), TimeUnit.MILLISECONDS, 50); + "Startup.FirstCommitNavigationTime3.ZoomedOut", + SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), 50, + TimeUnit.MINUTES.toMillis(10), TimeUnit.MILLISECONDS, 50); UmaUtils.setRunningApplicationStart(false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/OWNERS deleted file mode 100644 index 79becd2..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -dfalcantara@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/OWNERS deleted file mode 100644 index 79becd2..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -dfalcantara@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java index 9e75482..54ebfe9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
@@ -22,6 +22,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; +import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.util.ColorUtils; @@ -215,6 +216,11 @@ return mBottomSheet.isSheetOpen() || super.shouldDrawShadow(); } + @Override + public boolean isReadyForTextureCapture() { + return super.isReadyForTextureCapture() && !mBottomSheet.isShowingNewTab(); + } + /** Shows the tab switcher toolbar. */ public void showTabSwitcherToolbar() { setTabSwitcherMode(true, true, false); @@ -412,6 +418,13 @@ updateToolbarTopMargin(); } + @Override + public void initialize(ToolbarDataProvider toolbarDataProvider, + ToolbarTabController tabController, AppMenuButtonHelper appMenuButtonHelper) { + super.initialize(toolbarDataProvider, tabController, appMenuButtonHelper); + mAppMenuButtonHelper.setShowMenuOnUp(true); + } + /** * Update the top margin of all the components inside the toolbar. If the toolbar handle is * being used, extra margin is added. @@ -457,8 +470,6 @@ setContentDescription( getResources().getString(R.string.bottom_sheet_accessibility_toolbar)); } - - mBottomSheet.showHelpBubbleIfNecessary(); } /**
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 a044205..9fb0ac9 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
@@ -60,7 +60,7 @@ protected TintedImageButton mMenuButton; protected ImageView mMenuBadge; protected View mMenuButtonWrapper; - private AppMenuButtonHelper mAppMenuButtonHelper; + protected AppMenuButtonHelper mAppMenuButtonHelper; protected final ColorStateList mDarkModeTint; protected final ColorStateList mLightModeTint;
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 b072e2d..a99c7ca6 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
@@ -178,7 +178,6 @@ getInstance(activity); assert sInstance != null; if (sInstance == null) return; - assert !sInstance.mInVr; sInstance.mDonSucceeded = true; if (sInstance.mPaused) { if (sInstance.mInVrAtChromeLaunch == null) sInstance.mInVrAtChromeLaunch = false; @@ -852,7 +851,7 @@ private void handleDonFlowSuccess() { mDonSucceeded = false; // If we fail to enter VR when we should have entered VR, return to the home screen. - if (!enterVrAfterDon()) { + if (!mInVr && !enterVrAfterDon()) { cancelPendingVrEntry(); maybeSetPresentResult(false); mVrDaydreamApi.launchVrHomescreen();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 2c400dd..fe861316 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -282,20 +282,13 @@ }; // We need a parent for the RenderToSurfaceLayout because we want screen taps to only be // routed to the GvrUiLayout, and not propagate through to the NativePage. So screen taps - // are handled by the RenderToSurfaceLayoutParent, while touch events generated from the VR - // controller are injected directly into the RenderToSurfaceLayout, bypassing the parent. + // fall through the RenderToSurfaceLayoutParent, onto the GvrUiLayout, while touch events + // generated from the VR controller are injected directly into the RenderToSurfaceLayout, + // bypassing the parent. mRenderToSurfaceLayoutParent = new FrameLayout(mActivity) { @Override public boolean dispatchTouchEvent(MotionEvent event) { - // We only want to target touch events to the actual screen to the GvrUiLayout, - // which is dynamically loaded and attached to the GvrLayoutImpl. - for (int i = 0; i < getContainer().getChildCount(); ++i) { - View child = getContainer().getChildAt(i); - if (child.getClass().getSimpleName().equals("GvrLayoutImpl")) { - child.dispatchTouchEvent(event); - } - } - return true; + return false; } }; mRenderToSurfaceLayoutParent.setVisibility(View.INVISIBLE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS index fe55c0f2..6a60ce47 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org dominickn@chromium.org mlamouri@chromium.org changwan@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java index c4d55b5..51158cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java
@@ -11,6 +11,7 @@ import android.os.SystemClock; import org.chromium.base.ActivityState; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; import org.chromium.base.library_loader.LibraryProcessType; @@ -25,6 +26,8 @@ import org.chromium.chrome.browser.tab.TabRedirectHandler; import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.components.navigation_interception.NavigationParams; +import org.chromium.net.NetError; +import org.chromium.net.NetworkChangeNotifier; import org.chromium.webapk.lib.client.WebApkServiceConnectionManager; import java.util.concurrent.TimeUnit; @@ -49,6 +52,93 @@ /** Records whether we're currently showing a disclosure notification. */ private boolean mNotificationShowing; + private static final String TAG = "cr_WebApkActivity"; + + /** A {@link WebappSplashScreenController} that also handles WebAPK logic. */ + private class WebApkSplashScreenController extends WebappSplashScreenController { + /** The error code of the navigation. */ + private int mErrorCode; + + private WebApkOfflineDialog mOfflineDialog; + + /** Indicates whether reloading is allowed. */ + private boolean mAllowReloads; + + @Override + public void onDidFinishNavigation(final Tab tab, final String url, boolean isInMainFrame, + boolean isErrorPage, boolean hasCommitted, boolean isSameDocument, + boolean isFragmentNavigation, Integer pageTransition, int errorCode, + int httpStatusCode) { + super.onDidFinishNavigation(tab, url, isInMainFrame, isErrorPage, hasCommitted, + isSameDocument, isFragmentNavigation, pageTransition, errorCode, + httpStatusCode); + mErrorCode = errorCode; + + switch (mErrorCode) { + case NetError.ERR_NETWORK_CHANGED: + onNetworkChanged(tab); + break; + case NetError.ERR_INTERNET_DISCONNECTED: + onNetworkDisconnected(tab); + break; + default: + if (mOfflineDialog != null) { + mOfflineDialog.cancel(); + mOfflineDialog = null; + } + break; + } + } + + @Override + protected boolean canHideSplashScreen() { + return mErrorCode != NetError.ERR_INTERNET_DISCONNECTED + && mErrorCode != NetError.ERR_NETWORK_CHANGED; + } + + private void onNetworkChanged(Tab tab) { + if (!mAllowReloads) return; + + // It is possible that we get {@link NetError.ERR_NETWORK_CHANGED} during the first + // reload after the device is online. The navigation will fail until the next auto + // reload fired by {@link NetErrorHelperCore}. We call reload explicitly to reduce the + // waiting time. + tab.reloadIgnoringCache(); + mAllowReloads = false; + } + + private void onNetworkDisconnected(final Tab tab) { + if (mOfflineDialog != null) return; + + final NetworkChangeNotifier.ConnectionTypeObserver observer = + new NetworkChangeNotifier.ConnectionTypeObserver() { + @Override + public void onConnectionTypeChanged(int connectionType) { + if (!NetworkChangeNotifier.isOnline()) return; + + NetworkChangeNotifier.removeConnectionTypeObserver(this); + tab.reloadIgnoringCache(); + // One more reload is allowed after the network connection is back. + mAllowReloads = true; + } + }; + + NetworkChangeNotifier.addConnectionTypeObserver(observer); + mOfflineDialog = new WebApkOfflineDialog(); + mOfflineDialog.show(WebApkActivity.this, new WebApkOfflineDialog.DialogListener() { + @Override + public void onQuit() { + ApiCompatibilityUtils.finishAndRemoveTask(WebApkActivity.this); + } + }, mWebappInfo.name()); + } + } + + @Override + protected WebappSplashScreenController createWebappSplashScreenController() { + return new WebApkSplashScreenController(); + } + @Override protected WebappInfo createWebappInfo(Intent intent) { return (intent == null) ? WebApkInfo.createEmpty() : WebApkInfo.create(intent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java new file mode 100644 index 0000000..5509fa6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java
@@ -0,0 +1,53 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.webapps; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.view.ContextThemeWrapper; + +import org.chromium.chrome.R; + +/** + * A dialog to notify users that WebAPKs need a network connection to launch. + */ + +public class WebApkOfflineDialog { + /** A listener which is notified when user quits the dialog. */ + public interface DialogListener { void onQuit(); } + + private Dialog mDialog; + + /** + * Shows the dialog that notifies users that the WebAPK is offline. + * @param context The current context. + * @param listener The listener for the dialog. + * @param appName The name of the WebAPK for which the dialog is shown. + */ + public void show(Context context, final DialogListener listener, String appName) { + // The context theme wrapper is needed for pre-L. + AlertDialog.Builder builder = new AlertDialog.Builder( + new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light_Dialog)); + builder.setMessage(context.getString(R.string.webapk_offline_dialog, appName)) + .setNegativeButton(R.string.webapk_offline_dialog_quit_button, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + listener.onQuit(); + } + }); + + mDialog = builder.create(); + mDialog.setCanceledOnTouchOutside(false); + mDialog.show(); + }; + + /** Closes the dialog. */ + public void cancel() { + mDialog.cancel(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 6acfaacd..aacdbf8a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -86,7 +86,11 @@ public WebappActivity() { mWebappInfo = createWebappInfo(null); mDirectoryManager = new WebappDirectoryManager(); - mSplashController = new WebappSplashScreenController(); + mSplashController = createWebappSplashScreenController(); + } + + protected WebappSplashScreenController createWebappSplashScreenController() { + return new WebappSplashScreenController(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java index f9dd9aa..3ba88d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
@@ -91,17 +91,23 @@ @Override public void didFirstVisuallyNonEmptyPaint(Tab tab) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT); + if (canHideSplashScreen()) { + hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT); + } } @Override public void onPageLoadFinished(Tab tab) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED); + if (canHideSplashScreen()) { + hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED); + } } @Override public void onPageLoadFailed(Tab tab, int errorCode) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED); + if (canHideSplashScreen()) { + hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED); + } } @Override @@ -109,6 +115,10 @@ hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_CRASH); } + protected boolean canHideSplashScreen() { + return true; + } + /** Sets the splash screen layout and sets the splash screen's title and icon. */ private void initializeLayout(WebappInfo webappInfo, int backgroundColor, Bitmap splashImage) { mInitializedLayout = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ContextMenuDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ContextMenuDialog.java index 4521649..196c9a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ContextMenuDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ContextMenuDialog.java
@@ -20,9 +20,6 @@ import android.view.animation.ScaleAnimation; import org.chromium.chrome.browser.contextmenu.TabularContextMenuViewPager; -import org.chromium.content.browser.RenderCoordinates; - -import javax.annotation.Nullable; /** * ContextMenuDialog is a subclass of AlwaysDismissedDialog that ensures that the proper scale @@ -37,7 +34,7 @@ private final View mContentView; private final float mTouchPointXPx; private final float mTouchPointYPx; - private final RenderCoordinates mRenderCoordinates; + private final float mTopContentOffsetPx; private float mContextMenuSourceXPx; private float mContextMenuSourceYPx; @@ -50,18 +47,17 @@ * the default dialog theme * @param touchPointXPx The x-coordinate of the touch that triggered the context menu. * @param touchPointYPx The y-coordinate of the touch that triggered the context menu. + * @param topContentOffsetPx The offset of the content from the top. * @param contentView The The {@link TabularContextMenuViewPager} to display on the dialog. - * @param renderCoordinates The render coordinates to get the y offset of the window. This could - * be null if ContentViewCore is not available. */ public ContextMenuDialog(Activity ownerActivity, int theme, float touchPointXPx, - float touchPointYPx, View contentView, @Nullable RenderCoordinates renderCoordinates) { + float touchPointYPx, float topContentOffsetPx, View contentView) { super(ownerActivity, theme); mActivity = ownerActivity; mTouchPointXPx = touchPointXPx; mTouchPointYPx = touchPointYPx; + mTopContentOffsetPx = topContentOffsetPx; mContentView = contentView; - mRenderCoordinates = renderCoordinates; } @Override @@ -98,9 +94,7 @@ window.getDecorView().getWindowVisibleDisplayFrame(rectangle); float xOffsetPx = rectangle.left; - float contentOffsetYPx = - mRenderCoordinates != null ? mRenderCoordinates.getContentOffsetYPix() : 0; - float yOffsetPx = rectangle.top + contentOffsetYPx; + float yOffsetPx = rectangle.top + mTopContentOffsetPx; int[] currentLocationOnScreenPx = new int[2]; mContentView.getLocationOnScreen(currentLocationOnScreenPx);
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 ec1f118..570a7ae 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
@@ -40,6 +40,7 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; +import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; import org.chromium.chrome.browser.ntp.NativePageFactory; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -152,10 +153,7 @@ /** The {@link BottomSheetMetrics} used to record user actions and histograms. */ private final BottomSheetMetrics mMetrics; - /** - * The {@link BottomSheetNewTabController} used to present the new tab UI when - * {@link ChromeFeatureList#CHROME_HOME_NTP_REDESIGN} is enabled. - */ + /** The {@link BottomSheetNewTabController} used to present the new tab UI. */ private BottomSheetNewTabController mNtpController; /** For detecting scroll and fling events on the bottom sheet. */ @@ -235,6 +233,12 @@ /** A delegate for when the action bar starts showing. */ private ViewShiftingActionBarDelegate mActionBarDelegate; + /** The {@link LayoutManagerChrome} used to show and hide overview mode. **/ + private LayoutManagerChrome mLayoutManager; + + /** Whether the help bubble has been shown. **/ + private boolean mHasShownTextBubble; + /** * An interface defining content that can be displayed inside of the bottom sheet for Chrome * Home. @@ -593,6 +597,7 @@ * @param layoutManager The {@link LayoutManagerChrome} used to show and hide overview mode. */ public void setLayoutManagerChrome(LayoutManagerChrome layoutManager) { + mLayoutManager = layoutManager; mNtpController.setLayoutManagerChrome(layoutManager); } @@ -711,6 +716,23 @@ mDefaultToolbarView = (BottomToolbarPhone) mControlContainer.findViewById(R.id.toolbar); mNtpController = new BottomSheetNewTabController(this, mDefaultToolbarView); + + mActivity.getFullscreenManager().addListener(new FullscreenListener() { + @Override + public void onToggleOverlayVideoMode(boolean enabled) { + if (isSheetOpen()) setSheetState(SHEET_STATE_PEEK, false); + } + + @Override + public void onControlsOffsetChanged( + float topOffset, float bottomOffset, boolean needsAnimate) {} + + @Override + public void onContentOffsetChanged(float offset) {} + + @Override + public void onBottomControlsHeightChanged(int bottomControlsHeight) {} + }); } /** @@ -947,6 +969,8 @@ announceForAccessibility(getResources().getString(R.string.bottom_sheet_closed)); clearFocus(); mActivity.removeViewObscuringAllTabs(this); + + showHelpBubbleIfNecessary(); } /** @@ -1367,11 +1391,19 @@ */ public void showHelpBubbleIfNecessary() { // If FRE is not complete, the FRE screen is likely covering ChromeTabbedActivity so the - // help bubble should not be shown. Also skip showing if the bottom sheet is already open. - if (!FirstRunStatus.getFirstRunFlowComplete() || mCurrentState != SHEET_STATE_PEEK) return; + // help bubble should not be shown. Also skip showing if the bottom sheet is already open, + // the UI has not been initialized (indicated by mLayoutManager == null), or the tab + // switcher is showing. + if (mHasShownTextBubble || isSheetOpen() || mLayoutManager == null + || mLayoutManager.overviewVisible() || !FirstRunStatus.getFirstRunFlowComplete()) { + return; + } SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); - if (preferences.getBoolean(BOTTOM_SHEET_HELP_BUBBLE_SHOWN, false)) return; + if (preferences.getBoolean(BOTTOM_SHEET_HELP_BUBBLE_SHOWN, false)) { + mHasShownTextBubble = true; + return; + } boolean showExpandButtonHelpBubble = ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME_EXPAND_BUTTON); @@ -1390,6 +1422,7 @@ helpBubble.setInsetPx(0, inset, 0, inset); helpBubble.setDismissOnTouchInteraction(true); helpBubble.show(); + mHasShownTextBubble = true; preferences.edit().putBoolean(BOTTOM_SHEET_HELP_BUBBLE_SHOWN, true).apply(); }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index d56817e..70e4e9ca 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1055,6 +1055,9 @@ <message name="IDS_DATA_REDUCTION_BREAKDOWN_REMAINING_SITES_LABEL" desc="Title for the the remaining sites on the Data Reduction statistics page. The breakdown lists the top ten sites with the greatest amount of data usage or mobile data that was saved and then groups the remaining sites together."> Remaining sites (<ph name="NUMBER_OF_SITES">%1$d<ex>35</ex></ph>) </message> + <message name="IDS_DATA_REDUCTION_BREAKDOWN_OTHER_HOST_NAME" desc="Appears in a table that has a Site column and a Used column. URLs of sites the user has visited appear in the Site column, and the amount of data the site has used appears under Used. The “Other” entry appears at the bottom of the Site column, and is a grouping for sites and services where the URL is unavailable."> + Other + </message> <message name="IDS_DATA_REDUCTION_USAGE_RESET_STATISTICS_BUTTON" desc="Text to be displayed on the button to reset the Data Reduction statistics."> Reset Statistics </message> @@ -2942,6 +2945,12 @@ <message name="IDS_WEBAPK_RUNNING_IN_CHROME_DISCLOSURE" desc="Message on the notification that indicates a WebApk may use Chrome data."> This app is running in Chrome. </message> + <message name="IDS_WEBAPK_OFFLINE_DIALOG" desc="The message on the dialog shown when launching a WebAPK needs network connection."> + To use <ph name="APP_NAME">%1$s<ex>PWA List</ex></ph> for the first time, please connect to the internet + </message> + <message name="IDS_WEBAPK_OFFLINE_DIALOG_QUIT_BUTTON" desc="The text on the quit button on the dialog shown when launching a WebAPK needs network connection."> + OK + </message> <!-- Keyboard shortcuts in Android N--> <message name="IDS_KEYBOARD_SHORTCUT_OPEN_NEW_TAB" desc="A text label that appears next to the keyboard shortcut to open a new tab in Chrome. The shortcut description is shown in a system dialog along with all other supported shortcuts. [CHAR-LIMIT=55]">
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 158ce1e..0f18e3e 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1033,6 +1033,7 @@ "java/src/org/chromium/chrome/browser/suggestions/TileGroupDelegateImpl.java", "java/src/org/chromium/chrome/browser/suggestions/TileView.java", "java/src/org/chromium/chrome/browser/suggestions/NavigationRecorder.java", + "java/src/org/chromium/chrome/browser/suggestions/SuggestionsDependencyFactory.java", "java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegate.java", "java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java", "java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java", @@ -1187,6 +1188,7 @@ "java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java", "java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java", "java/src/org/chromium/chrome/browser/webapps/WebApkManagedActivity.java", + "java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java", "java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java", "java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java", "java/src/org/chromium/chrome/browser/webapps/WebApkVersionManager.java", @@ -1652,6 +1654,7 @@ "javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java", "javatests/src/org/chromium/chrome/browser/tabmodel/document/MockDocumentTabModel.java", "javatests/src/org/chromium/chrome/browser/test/ChromeBrowserTestRule.java", + "javatests/src/org/chromium/chrome/browser/test/ClearAppDataTestRule.java", "javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java", "javatests/src/org/chromium/chrome/browser/toolbar/ToolbarModelTest.java", "javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java", @@ -1809,20 +1812,6 @@ "junit/src/org/chromium/chrome/browser/widget/selection/SelectionDelegateTest.java", ] -sync_shell_test_java_sources = [ - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java", - "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java", -] - # Only used for testing, should not be shipped to end users. if (enable_offline_pages_harness) { chrome_java_sources += [ "java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
diff --git a/chrome/android/javatests/OWNERS b/chrome/android/javatests/OWNERS index 64b3bac..2913950e 100644 --- a/chrome/android/javatests/OWNERS +++ b/chrome/android/javatests/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org dtrainor@chromium.org nyquist@chromium.org skyostil@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java index 8d3e8ac..22990c6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
@@ -254,6 +254,35 @@ } /** + * Test 'Request Desktop Site' option is preserved after navigation to a new entry + * through a click on a link. + */ + @Test + @MediumTest + @Feature({"Navigation"}) + @RetryOnFailure + public void testRequestDesktopSiteSettingPers() throws Exception { + String url1 = mTestServer.getURL("/chrome/test/data/android/google.html"); + String url2 = mTestServer.getURL("/chrome/test/data/android/about.html"); + + navigateAndObserve(url1, url1); + + final Tab tab = mActivityTestRule.getActivity().getActivityTab(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + tab.setUseDesktopUserAgent(true /* useDesktop */, true /* reloadOnChange */); + } + }); + ChromeTabUtils.waitForTabPageLoaded(tab, url1); + + DOMUtils.clickNode(tab.getContentViewCore(), "aboutLink"); + ChromeTabUtils.waitForTabPageLoaded(tab, url2); + Assert.assertEquals("Request Desktop site setting should stay turned on", true, + mActivityTestRule.getActivity().getActivityTab().getUseDesktopUserAgent()); + } + + /** * Test Opening a link and verify that TabObserver#onPageLoadStarted gives the old and new URL. */ @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/OWNERS index 453dc77..d6d1a1da 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/OWNERS
@@ -1,2 +1 @@ -dfalcantara@chromium.org dominickn@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java index 9b56f36..4e05425 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java
@@ -7,6 +7,7 @@ import android.annotation.TargetApi; import android.app.job.JobInfo; import android.app.job.JobScheduler; +import android.app.job.JobWorkItem; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -49,7 +50,6 @@ } }; - // TODO(crbug/716236): Refer to this crbug for compilation error after the O SDK is rolled. @TargetApi(Build.VERSION_CODES.M) private static class TestJobScheduler extends JobScheduler { TestJobScheduler() {} @@ -61,6 +61,10 @@ public void cancelAll() {} @Override + public int enqueue(JobInfo job, JobWorkItem work) { + return 0; + } + @Override public List<JobInfo> getAllPendingJobs() { return null; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java index 367fe20..7a341f0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java
@@ -12,6 +12,7 @@ import android.annotation.TargetApi; import android.app.job.JobInfo; import android.app.job.JobScheduler; +import android.app.job.JobWorkItem; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -579,7 +580,6 @@ } } - // TODO(crbug/716236): Refer to this crbug for compilation error after the O SDK is rolled. /** * A JobScheduler wrapper that verifies that the expected properties are set correctly. */ @@ -600,6 +600,11 @@ public void cancelAll() {} @Override + public int enqueue(JobInfo job, JobWorkItem work) { + return 0; + } + + @Override public List<JobInfo> getAllPendingJobs() { return null; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS index 345ead2..2b5bfcd8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS
@@ -1,3 +1,2 @@ -dfalcantara@chromium.org mariakhomenko@chromium.org yusufo@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/download/OWNERS index 22c73fc..4acc65d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/OWNERS
@@ -1,4 +1,3 @@ qinmin@chromium.org -per-file DownloadActivityTest.java=dfalcantara@chromium.org per-file DownloadActivityTest.java=twellington@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/OWNERS index 92e42be0..0fa757c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/OWNERS
@@ -1,2 +1 @@ -dfalcantara@chromium.org twellington@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/OWNERS index 79becd2..5fe1a72 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/OWNERS
@@ -1 +1 @@ -dfalcantara@chromium.org +file://chrome/android/java/src/org/chromium/chrome/browser/infobar/OWNERS
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 122607422..b66562a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -34,7 +34,6 @@ import org.chromium.chrome.browser.omnibox.LocationBarLayout; import org.chromium.chrome.browser.omnibox.UrlBar; import org.chromium.chrome.browser.suggestions.FakeMostVisitedSites; -import org.chromium.chrome.browser.suggestions.TileGroupDelegateImpl; import org.chromium.chrome.browser.suggestions.TileSource; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -45,6 +44,7 @@ import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.OmniboxTestUtils; import org.chromium.chrome.test.util.RenderTestRule; +import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.KeyUtils; @@ -74,6 +74,9 @@ @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @Rule + public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule(); + + @Rule public RenderTestRule mRenderTestRule = new RenderTestRule("chrome/test/data/android/render_tests"); @@ -108,7 +111,7 @@ mMostVisitedSites = new FakeMostVisitedSites(); mMostVisitedSites.setTileSuggestions(FAKE_MOST_VISITED_TITLES, mSiteSuggestionUrls, FAKE_MOST_VISITED_WHITELIST_ICON_PATHS, FAKE_MOST_VISITED_SOURCES); - TileGroupDelegateImpl.setMostVisitedSitesForTests(mMostVisitedSites); + mSuggestionsDeps.getFactory().mostVisitedSites = mMostVisitedSites; mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL); mTab = mActivityTestRule.getActivity().getActivityTab(); NewTabPageTestUtils.waitForNtpLoaded(mTab); @@ -123,7 +126,6 @@ @After public void tearDown() throws Exception { mTestServer.stopAndDestroyServer(); - TileGroupDelegateImpl.setMostVisitedSitesForTests(null); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java index 05d73d4..33ab5216 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
@@ -37,7 +37,6 @@ import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.suggestions.ContentSuggestionsAdditionalAction; import org.chromium.chrome.browser.suggestions.FakeMostVisitedSites; -import org.chromium.chrome.browser.suggestions.TileGroupDelegateImpl; import org.chromium.chrome.browser.suggestions.TileSource; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeActivityTestRule; @@ -48,6 +47,7 @@ import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; +import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.content.browser.test.util.TestTouchUtils; import org.chromium.content.browser.test.util.TouchCommon; import org.chromium.net.test.EmbeddedTestServer; @@ -70,6 +70,9 @@ @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + @Rule + public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule(); + private static final String TEST_PAGE = "/chrome/test/data/android/navigate/simple.html"; private static final String[] FAKE_MOST_VISITED_TITLES = new String[] {"Simple"}; private static final String[] FAKE_MOST_VISITED_WHITELIST_ICON_PATHS = new String[] {""}; @@ -100,7 +103,7 @@ mMostVisitedSites = new FakeMostVisitedSites(); mMostVisitedSites.setTileSuggestions(FAKE_MOST_VISITED_TITLES, mSiteSuggestionUrls, FAKE_MOST_VISITED_WHITELIST_ICON_PATHS, FAKE_MOST_VISITED_SOURCES); - TileGroupDelegateImpl.setMostVisitedSitesForTests(mMostVisitedSites); + mSuggestionsDeps.getFactory().mostVisitedSites = mMostVisitedSites; mSource = new FakeSuggestionsSource(); mSource.setInfoForCategory(TEST_CATEGORY, @@ -109,7 +112,7 @@ ContentSuggestionsAdditionalAction.FETCH, /*showIfEmpty=*/true, "noSuggestionsMessage")); mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.INITIALIZING); - NewTabPage.setSuggestionsSourceForTests(mSource); + mSuggestionsDeps.getFactory().suggestionsSource = mSource; mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL); mTab = mActivityTestRule.getActivity().getActivityTab(); @@ -121,8 +124,6 @@ @After public void tearDown() throws Exception { - TileGroupDelegateImpl.setMostVisitedSitesForTests(null); - NewTabPage.setSuggestionsSourceForTests(null); mTestServer.stopAndDestroyServer(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OWNERS index 79becd2..9d91d5b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OWNERS
@@ -1 +1 @@ -dfalcantara@chromium.org +file://chrome/android/java/src/org/chromium/chrome/browser/omaha/OWNERS
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java index afcb158..74ebb4f1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java
@@ -41,7 +41,6 @@ import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; @@ -290,13 +289,7 @@ new WriteResultCallbackWrapperMock() { @Override public void onWriteFinished(PageRange[] pages) { - try { - descriptor.close(); - // Result is ready, signal to continue. - result.run(); - } catch (IOException ex) { - Assert.fail("Failed file operation: " + ex.toString()); - } + result.run(); } } );
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/FakeMostVisitedSites.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/FakeMostVisitedSites.java index a0fc588..afb39c3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/FakeMostVisitedSites.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/FakeMostVisitedSites.java
@@ -54,7 +54,7 @@ } @Override - public void recordTileImpression(int index, int source, int type, String url) { + public void recordTileImpression(int index, int type, int source, String url) { // Metrics are stubbed out. }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java index 3615fcc..97729b30 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.SuggestionsBottomSheetTestRule; import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils; +import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.content.browser.test.util.TestTouchUtils; /** @@ -40,9 +41,12 @@ @Rule public SuggestionsBottomSheetTestRule mSuggestionsTestRule = new SuggestionsBottomSheetTestRule(); + @Rule + public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule(); @Before public void setUp() throws InterruptedException { + mSuggestionsTestRule.initDependencies(mSuggestionsDeps.getFactory()); mSuggestionsTestRule.startMainActivityOnBlankPage(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java index b29fb71..e82cbdc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.SuggestionsBottomSheetTestRule; +import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; /** * Tests for the appearance of Article Snippets. @@ -36,6 +37,8 @@ @Rule public SuggestionsBottomSheetTestRule mSuggestionsTestRule = new SuggestionsBottomSheetTestRule(); + @Rule + public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule(); @Rule public ScreenShooter mScreenShooter = new ScreenShooter(); @@ -44,6 +47,7 @@ @Before public void setup() throws InterruptedException { + mSuggestionsTestRule.initDependencies(mSuggestionsDeps.getFactory()); mSuggestionsTestRule.startMainActivityOnBlankPage(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java index 69398e0..1c4cf2c3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
@@ -37,6 +37,7 @@ import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; +import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.TestTouchUtils; @@ -57,6 +58,9 @@ @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + @Rule + public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule(); + private static final String[] FAKE_MOST_VISITED_URLS = new String[] {"/chrome/test/data/android/navigate/one.html", "/chrome/test/data/android/navigate/two.html", @@ -77,11 +81,10 @@ mTestServer.getURL(FAKE_MOST_VISITED_URLS[2])}; mMostVisitedSites = new FakeMostVisitedSites(); + mSuggestionsDeps.getFactory().mostVisitedSites = mMostVisitedSites; mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls); - TileGroupDelegateImpl.setMostVisitedSitesForTests(mMostVisitedSites); - FakeSuggestionsSource mSource = new FakeSuggestionsSource(); - NewTabPage.setSuggestionsSourceForTests(mSource); + mSuggestionsDeps.getFactory().suggestionsSource = new FakeSuggestionsSource(); mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL); Tab mTab = mActivityTestRule.getActivity().getActivityTab(); @@ -95,8 +98,6 @@ @After public void tearDown() throws Exception { - TileGroupDelegateImpl.setMostVisitedSitesForTests(null); - NewTabPage.setSuggestionsSourceForTests(null); mTestServer.stopAndDestroyServer(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/OWNERS index 92053b9..9cf8c9c8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/OWNERS
@@ -1,4 +1,2 @@ -dfalcantara@chromium.org - per-file MultiInstanceMigrationTest.java=twellington@chromium.org per-file TabModelMergingTest.java=twellington@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/OWNERS deleted file mode 100644 index 79becd2..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -dfalcantara@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/test/ClearAppDataTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/test/ClearAppDataTestRule.java new file mode 100644 index 0000000..2a3009a9 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/test/ClearAppDataTestRule.java
@@ -0,0 +1,36 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.test; + +import android.content.Context; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import org.chromium.chrome.test.util.ApplicationData; + +/** + * JUnit test rule that just clears app data before each test. Having this as a rule allows us + * to ensure the order it's executed in with something like RuleChain, allowing us to execute it + * prior to launching the browser process. + */ +public class ClearAppDataTestRule implements TestRule { + Context mContext; + + public ClearAppDataTestRule(Context context) { + mContext = context; + } + + @Override + public Statement apply(final Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + ApplicationData.clearAppData(mContext); + } + }; + } +} \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/OWNERS deleted file mode 100644 index 79becd2..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -dfalcantara@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/OWNERS index bd7774a8..0392203 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org dominickn@chromium.org changwan@chromium.org mlamouri@chromium.org
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/OWNERS b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/OWNERS index 453dc77..d6d1a1da 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/OWNERS +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/OWNERS
@@ -1,2 +1 @@ -dfalcantara@chromium.org dominickn@chromium.org
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java index 548f7cbc..9517d18 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java
@@ -171,6 +171,40 @@ Assert.assertNull(hostBrowser); } + /** + * Tests that {@link WebApkUtils#getHostBrowserPackageName(Context)} doesn't return the current + * host browser which is cached in the {@link WebApkUtils#sHostPackage} and uninstalled. + */ + @Test + public void testDoesNotReturnTheCurrentHostBrowserAfterUninstall() { + String currentHostBrowser = BROWSER_INSTALLED_SUPPORTING_WEBAPKS; + mockInstallBrowsers(ANOTHER_BROWSER_INSTALLED_SUPPORTING_WEBAPKS); + setHostBrowserInMetadata(null); + setHostBrowserInSharedPreferences(currentHostBrowser); + + String hostBrowser = WebApkUtils.getHostBrowserPackageName(mContext); + Assert.assertEquals(currentHostBrowser, hostBrowser); + + uninstallBrowser(currentHostBrowser); + hostBrowser = WebApkUtils.getHostBrowserPackageName(mContext); + Assert.assertNotEquals(currentHostBrowser, hostBrowser); + } + + /** + * Uninstall a browser. Note: this function only works for uninstalling the non default browser. + */ + private void uninstallBrowser(String packageName) { + Intent intent = null; + try { + intent = Intent.parseUri("http://", Intent.URI_INTENT_SCHEME); + } catch (Exception e) { + Assert.fail(); + return; + } + mPackageManager.removeResolveInfosForIntent(intent, packageName); + mPackageManager.removePackage(packageName); + } + private static ResolveInfo newResolveInfo(String packageName) { ActivityInfo activityInfo = new ActivityInfo(); activityInfo.packageName = packageName;
diff --git a/chrome/android/webapk/shell_apk/shell_apk_version.gni b/chrome/android/webapk/shell_apk/shell_apk_version.gni index cdbf4e0..63a64b9 100644 --- a/chrome/android/webapk/shell_apk/shell_apk_version.gni +++ b/chrome/android/webapk/shell_apk/shell_apk_version.gni
@@ -6,7 +6,7 @@ # (including AndroidManifest.xml) is updated. This version should be incremented # prior to uploading a new ShellAPK to the WebAPK Minting Server. # Does not affect Chrome.apk -template_shell_apk_version = 9 +template_shell_apk_version = 10 # The ShellAPK version expected by Chrome. Chrome will try to update the WebAPK # if the WebAPK's ShellAPK version is less than |expected_shell_apk_version|.
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java index 2ff261f..a22a85f2 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java
@@ -38,11 +38,7 @@ Arrays.asList("com.google.android.apps.chrome", "com.android.chrome", "com.chrome.beta", "com.chrome.dev", "com.chrome.canary")); - /** - * Caches the package name of the host browser. {@link sHostPackage} might refer to a browser - * which has been uninstalled. A notification can keep the WebAPK process alive after the host - * browser has been uninstalled. - */ + /** Caches the package name of the host browser. */ private static String sHostPackage; /** For testing only. */ @@ -81,7 +77,7 @@ * @return The package name. Returns null on an error. */ public static String getHostBrowserPackageName(Context context) { - if (sHostPackage == null) { + if (sHostPackage == null || !isInstalled(context.getPackageManager(), sHostPackage)) { sHostPackage = getHostBrowserPackageNameInternal(context); if (sHostPackage != null) { writeHostBrowserToSharedPref(context, sHostPackage); @@ -91,6 +87,18 @@ return sHostPackage; } + /** Returns whether the application is installed. */ + private static boolean isInstalled(PackageManager packageManager, String packageName) { + if (TextUtils.isEmpty(packageName)) return false; + + try { + packageManager.getApplicationInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + return true; + } + /** Returns the <meta-data> value in the Android Manifest for {@link key}. */ public static String readMetaDataFromManifest(Context context, String key) { Bundle metadata = readMetaData(context);
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index f7bd9cc..afb8f991 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -4983,7 +4983,7 @@ </message> <message name="IDS_PREVIEWS_INFOBAR_TIMESTAMP_HOURS" desc="The desciption stating how old a preview version of a page is in hours. This is shown on the infobar notifying the user that a preview page has been shown."> Updated <ph name="HOURS">$1<ex>4</ex></ph>hrs ago - </message> + </message> <message name="IDS_PREVIEWS_INFOBAR_TIMESTAMP_UPDATED_NOW" desc="The desciption stating that a preview version of a page was just updated. This is shown on the infobar notifying the user that a preview page has been shown."> Updated just now </message> @@ -6467,11 +6467,8 @@ <message name="IDS_CHROME_CLEANUP_WEBUI_TITLE_RESTART" desc="A status message, appearing on the Chrome Cleanup web page, that the cleanup of unwanted software initiated by the user was performed but isn't finished. User must take additional action to finish the cleanup. 'Restart' is imperative. Short for 'To finish removing harmful software...'"> To finish removing harmful software, restart your computer </message> - <message name="IDS_CHROME_CLEANUP_LOGS_PERMISSION" desc="A checkbox label, appearing on both the Chrome Cleanup dialog and web page, asking the user for permission to send some system information to Google in order to help with detection of harmful software. The word 'settings' refers to the user's operating system settings. The word 'applications' refers to any software that is installed or runs on the user's computer."> - Send information about your system and applications to Google to help detect harmful software - </message> - <message name="IDS_CHROME_CLEANUP_LOGS_PERMISSION_WITH_LINK" desc="A checkbox label, appearing on both the Chrome Cleanup dialog and web page, asking the user for permission to send some system information to Google in order to help with detection of harmful software. The word 'settings' refers to the user's operating system settings. The word 'applications' refers to any software that is installed or runs on the user's computer. The translation for this string should have the same meaning as IDS_CHROME_CLEANUP_LOGS_PERMISSION"> - Send <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>information about your system and applications<ph name="END_LINK"></a></ph> to Google to help detect harmful software + <message name="IDS_CHROME_CLEANUP_LOGS_PERMISSION" desc="A checkbox label, appearing on both the Chrome Cleanup modal dialog and webui page, asking the user for permission to send details about the cleanup operation to Google."> + Report details to Google </message> </if>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 028cdb3b..442e7ae 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -225,6 +225,9 @@ <message name="IDS_SETTINGS_ANDROID_APPS_TITLE" desc="The title of Google Play Store (Arc++ / Android Apps) section."> Google Play Store (beta) </message> + <message name="IDS_SETTINGS_ANDROID_SETTINGS_TITLE" desc="The title of Android settings section in case Play Store app is not available."> + Android settings + </message> <message name="IDS_SETTINGS_ANDROID_APPS_LABEL" desc="The text associated with the primary section setting."> Google Play Store </message> @@ -1940,6 +1943,12 @@ </message> <!-- Site Settings Page --> + <message name="IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_HOST" desc="Template text for a child row in the content Exceptions page view. Controls the permission setting for the parent page when embedded on the specified site."> + embedded on <ph name="URL">$1<ex>www.google.com</ex></ph> + </message> + <message name="IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_ANY_HOST" desc="Template text for a child row in the content Exceptions page view. Controls the permission setting for the parent page when embedded on any site."> + embedded on any host + </message> <message name="IDS_SETTINGS_SITE_SETTINGS_CATEGORY" desc="Name of the settings page which allows users to modify a specific category under site settings."> Permission Category </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 855a0ffa..7bc31c6 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2057,6 +2057,9 @@ flag_descriptions::kAppInfoDialogDescription, kOsMac, ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAppInfoDialogMac, switches::kDisableAppInfoDialogMac)}, + {"mac-v2-sandbox", flag_descriptions::kMacV2SandboxName, + flag_descriptions::kMacV2SandboxDescription, kOsMac, + FEATURE_VALUE_TYPE(features::kMacV2Sandbox)}, {"mac-views-native-app-windows", flag_descriptions::kMacViewsNativeAppWindowsName, flag_descriptions::kMacViewsNativeAppWindowsDescription, kOsMac,
diff --git a/chrome/browser/android/DEPS b/chrome/browser/android/DEPS index bb55a8c..8f032b7 100644 --- a/chrome/browser/android/DEPS +++ b/chrome/browser/android/DEPS
@@ -2,6 +2,7 @@ "-components/devtools_bridge", "+cc/layers/layer.h", "+cc/output/context_provider.h", + "+chrome_jni_registration/chrome_jni_registration.h", "+components/doodle", "+components/ntp_snippets", "+components/spellcheck/browser",
diff --git a/chrome/browser/android/OWNERS b/chrome/browser/android/OWNERS index 391acd20..13e35e5 100644 --- a/chrome/browser/android/OWNERS +++ b/chrome/browser/android/OWNERS
@@ -1,5 +1,4 @@ bauerb@chromium.org -dfalcantara@chromium.org dtrainor@chromium.org mariakhomenko@chromium.org nyquist@chromium.org
diff --git a/chrome/browser/android/banners/OWNERS b/chrome/browser/android/banners/OWNERS index 453dc77..d6d1a1da 100644 --- a/chrome/browser/android/banners/OWNERS +++ b/chrome/browser/android/banners/OWNERS
@@ -1,2 +1 @@ -dfalcantara@chromium.org dominickn@chromium.org
diff --git a/chrome/browser/android/chrome_entry_point.cc b/chrome/browser/android/chrome_entry_point.cc index ee46cd6c..079358b 100644 --- a/chrome/browser/android/chrome_entry_point.cc +++ b/chrome/browser/android/chrome_entry_point.cc
@@ -7,6 +7,7 @@ #include "base/android/library_loader/library_loader_hooks.h" #include "base/bind.h" #include "chrome/app/android/chrome_jni_onload.h" +#include "chrome/browser/android/chrome_jni_registration.h" namespace { @@ -23,6 +24,19 @@ // Java side and only register a subset of JNI methods. base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); + + if (!base::android::IsSelectiveJniRegistrationEnabled(env)) { + if (!RegisterNonMainDexNatives(env)) { + return -1; + } + } + + if (!RegisterMainDexNatives(env)) { + return -1; + } + + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. if (base::android::IsSelectiveJniRegistrationEnabled(env)) { base::android::SetJniRegistrationType( base::android::SELECTIVE_JNI_REGISTRATION);
diff --git a/chrome/browser/android/chrome_sync_shell_entry_point.cc b/chrome/browser/android/chrome_sync_shell_entry_point.cc new file mode 100644 index 0000000..e14ea511 --- /dev/null +++ b/chrome/browser/android/chrome_sync_shell_entry_point.cc
@@ -0,0 +1,49 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/android/jni_android.h" +#include "base/android/jni_utils.h" +#include "base/android/library_loader/library_loader_hooks.h" +#include "base/bind.h" +#include "chrome/app/android/chrome_jni_onload.h" +#include "chrome/browser/android/chrome_sync_shell_jni_registration.h" + +namespace { + +bool NativeInit() { + return android::OnJNIOnLoadInit(); +} + +} // namespace + +// This is called by the VM when the shared library is first loaded. +JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { + // By default, all JNI methods are registered. However, since render processes + // don't need very much Java code, we enable selective JNI registration on the + // Java side and only register a subset of JNI methods. + base::android::InitVM(vm); + JNIEnv* env = base::android::AttachCurrentThread(); + + if (!base::android::IsSelectiveJniRegistrationEnabled(env)) { + if (!RegisterNonMainDexNatives(env)) { + return -1; + } + } + + if (!RegisterMainDexNatives(env)) { + return -1; + } + + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. + if (base::android::IsSelectiveJniRegistrationEnabled(env)) { + base::android::SetJniRegistrationType( + base::android::SELECTIVE_JNI_REGISTRATION); + } + if (!android::OnJNIOnLoadRegisterJNI(env)) { + return -1; + } + base::android::SetNativeInitializationHook(NativeInit); + return JNI_VERSION_1_4; +}
diff --git a/chrome/browser/android/metrics/OWNERS b/chrome/browser/android/metrics/OWNERS index 52aa22b..b618f9a 100644 --- a/chrome/browser/android/metrics/OWNERS +++ b/chrome/browser/android/metrics/OWNERS
@@ -1,5 +1,4 @@ asvitkine@chromium.org -dfalcantara@chromium.org mariakhomenko@chromium.org # COMPONENT: Internals>Metrics
diff --git a/chrome/browser/android/search_geolocation/OWNERS b/chrome/browser/android/search_geolocation/OWNERS index f3f66a3..9fd573ab 100644 --- a/chrome/browser/android/search_geolocation/OWNERS +++ b/chrome/browser/android/search_geolocation/OWNERS
@@ -1,2 +1 @@ benwells@chromium.org -dfalcantara@chromium.org
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn index 89c566d..b9716ae 100644 --- a/chrome/browser/android/vr_shell/BUILD.gn +++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -59,6 +59,8 @@ "ui_browser_interface.h", "ui_elements/button.cc", "ui_elements/button.h", + "ui_elements/exclusive_screen_toast.cc", + "ui_elements/exclusive_screen_toast.h", "ui_elements/exit_prompt.cc", "ui_elements/exit_prompt.h", "ui_elements/exit_prompt_backplane.cc",
diff --git a/chrome/browser/android/vr_shell/color_scheme.cc b/chrome/browser/android/vr_shell/color_scheme.cc index 178fe5b1..c65da25d 100644 --- a/chrome/browser/android/vr_shell/color_scheme.cc +++ b/chrome/browser/android/vr_shell/color_scheme.cc
@@ -40,10 +40,8 @@ normal_scheme.exit_warning_foreground; normal_scheme.transient_warning_background = normal_scheme.exit_warning_background; - normal_scheme.exclusive_screen_toast_foreground = - normal_scheme.exit_warning_foreground; - normal_scheme.exclusive_screen_toast_background = - normal_scheme.exit_warning_background; + normal_scheme.exclusive_screen_toast_foreground = 0xCCFFFFFF; + normal_scheme.exclusive_screen_toast_background = 0xCC2F2F2F; normal_scheme.permanent_warning_foreground = 0xFF444444; normal_scheme.permanent_warning_background = SK_ColorWHITE;
diff --git a/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc b/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc index 62cb453b..045fbb91 100644 --- a/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc +++ b/chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.cc
@@ -17,9 +17,11 @@ namespace { -constexpr float kBorderFactor = 0.045; -constexpr float kFontSizeFactor = 0.048; -constexpr float kTextWidthFactor = 1.0 - 3 * kBorderFactor; +constexpr float kHeight = 0.064; +constexpr float kWidthHeightRatio = 16.0; +constexpr float kFontHeight = 0.024; +constexpr float kWidthPadding = 0.02; +constexpr float kCornerRadius = 0.004; } // namespace @@ -33,29 +35,32 @@ gfx::Canvas gfx_canvas(&paint_canvas, 1.0f); gfx::Canvas* canvas = &gfx_canvas; - size_.set_width(texture_size.width()); + size_.set_height(texture_size.height()); SkPaint paint; + float meter_to_pixel_ratio = texture_size.height() / kHeight; paint.setColor(color_scheme().exclusive_screen_toast_background); auto text = l10n_util::GetStringUTF16(IDS_PRESS_APP_TO_EXIT); gfx::FontList fonts; - GetFontList(size_.width() * kFontSizeFactor, text, &fonts); - gfx::Rect text_size(size_.width() * kTextWidthFactor, 0); + int pixel_font_size = meter_to_pixel_ratio * kFontHeight; + GetFontList(pixel_font_size, text, &fonts); + gfx::Rect text_size(0, pixel_font_size); std::vector<std::unique_ptr<gfx::RenderText>> lines = PrepareDrawStringRect( text, fonts, color_scheme().exclusive_screen_toast_foreground, &text_size, - kTextAlignmentCenter, kWrappingBehaviorWrap); + kTextAlignmentNone, kWrappingBehaviorNoWrap); - DCHECK_LE(text_size.height(), - static_cast<int>((1.0 - 2 * kBorderFactor) * size_.width())); - size_.set_height(size_.width() * 2 * kBorderFactor + text_size.height()); - float radius = size_.width() * kBorderFactor; + int pixel_padding = meter_to_pixel_ratio * kWidthPadding; + size_.set_width(2 * pixel_padding + text_size.width()); + DCHECK_LE(size_.width(), texture_size.width()); + int corner_radius = meter_to_pixel_ratio * kCornerRadius; sk_canvas->drawRoundRect(SkRect::MakeWH(size_.width(), size_.height()), - radius, radius, paint); + corner_radius, corner_radius, paint); canvas->Save(); - canvas->Translate(gfx::Vector2d(size_.width() * kBorderFactor, - size_.width() * kBorderFactor)); + canvas->Translate( + gfx::Vector2d(meter_to_pixel_ratio * kWidthPadding, + (kHeight - kFontHeight) / 2 * meter_to_pixel_ratio)); for (auto& render_text : lines) render_text->Draw(canvas); canvas->Restore(); @@ -63,7 +68,7 @@ gfx::Size ExclusiveScreenToastTexture::GetPreferredTextureSize( int maximum_width) const { - return gfx::Size(maximum_width, maximum_width); + return gfx::Size(maximum_width, maximum_width / kWidthHeightRatio); } gfx::SizeF ExclusiveScreenToastTexture::GetDrawnSize() const {
diff --git a/chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.cc b/chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.cc new file mode 100644 index 0000000..e43d3e6 --- /dev/null +++ b/chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.cc
@@ -0,0 +1,25 @@ +// 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/android/vr_shell/ui_elements/exclusive_screen_toast.h" + +#include "chrome/browser/android/vr_shell/textures/ui_texture.h" +#include "chrome/browser/android/vr_shell/ui_elements/textured_element.h" + +namespace vr_shell { + +ExclusiveScreenToast::ExclusiveScreenToast(int preferred_width) + : SimpleTexturedElement(preferred_width) {} + +ExclusiveScreenToast::~ExclusiveScreenToast() = default; + +void ExclusiveScreenToast::UpdateElementSize() { + // Adjust the width of this element according to the texture. The width is + // decided by the length of the text to show. + gfx::SizeF drawn_size = GetTexture()->GetDrawnSize(); + float width = drawn_size.width() / drawn_size.height() * size().y(); + set_size({width, size().y(), 1}); +} + +} // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.h b/chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.h new file mode 100644 index 0000000..9bb7f88 --- /dev/null +++ b/chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.h
@@ -0,0 +1,28 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_VR_SHELL_UI_ELEMENTS_EXCLUSIVE_SCREEN_TOAST_H_ +#define CHROME_BROWSER_ANDROID_VR_SHELL_UI_ELEMENTS_EXCLUSIVE_SCREEN_TOAST_H_ + +#include "base/macros.h" +#include "chrome/browser/android/vr_shell/textures/exclusive_screen_toast_texture.h" +#include "chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h" + +namespace vr_shell { + +class ExclusiveScreenToast + : public SimpleTexturedElement<ExclusiveScreenToastTexture> { + public: + explicit ExclusiveScreenToast(int preferred_width); + ~ExclusiveScreenToast() override; + + private: + void UpdateElementSize() override; + + DISALLOW_COPY_AND_ASSIGN(ExclusiveScreenToast); +}; + +} // namespace vr_shell + +#endif // CHROME_BROWSER_ANDROID_VR_SHELL_UI_ELEMENTS_EXCLUSIVE_SCREEN_TOAST_H_
diff --git a/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h b/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h index 4494bbc8..2b42a2e 100644 --- a/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h +++ b/chrome/browser/android/vr_shell/ui_elements/simple_textured_element.h
@@ -30,8 +30,10 @@ ~SimpleTexturedElement() override {} T* GetDerivedTexture() { return texture_.get(); } - private: + protected: UiTexture* GetTexture() const override { return texture_.get(); } + + private: std::unique_ptr<T> texture_; DISALLOW_COPY_AND_ASSIGN(SimpleTexturedElement); @@ -42,7 +44,6 @@ PermanentSecurityWarning; typedef SimpleTexturedElement<InsecureContentTransientTexture> TransientSecurityWarning; -typedef SimpleTexturedElement<ExclusiveScreenToastTexture> ExclusiveScreenToast; typedef SimpleTexturedElement<SplashScreenIconTexture> SplashScreenIcon; } // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_interface.h b/chrome/browser/android/vr_shell/ui_interface.h index f8904642..f46ccce 100644 --- a/chrome/browser/android/vr_shell/ui_interface.h +++ b/chrome/browser/android/vr_shell/ui_interface.h
@@ -41,6 +41,7 @@ virtual void SetVideoCapturingIndicator(bool enabled) = 0; virtual void SetScreenCapturingIndicator(bool enabled) = 0; virtual void SetAudioCapturingIndicator(bool enabled) = 0; + virtual void SetBluetoothConnectedIndicator(bool enabled) = 0; virtual void SetSplashScreenIcon(const SkBitmap& bitmap) = 0; // Tab handling.
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc index f751a7e..3dd3b77 100644 --- a/chrome/browser/android/vr_shell/ui_scene_manager.cc +++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/android/vr_shell/textures/ui_texture.h" #include "chrome/browser/android/vr_shell/ui_browser_interface.h" #include "chrome/browser/android/vr_shell/ui_elements/button.h" +#include "chrome/browser/android/vr_shell/ui_elements/exclusive_screen_toast.h" #include "chrome/browser/android/vr_shell/ui_elements/exit_prompt.h" #include "chrome/browser/android/vr_shell/ui_elements/exit_prompt_backplane.h" #include "chrome/browser/android/vr_shell/ui_elements/loading_indicator.h" @@ -80,9 +81,14 @@ -0.2 * kTransientUrlBarDistance; static constexpr int kTransientUrlBarTimeoutSeconds = 6; -static constexpr float kToastDistance = 1.4; -static constexpr float kToastWidth = 0.512 * kToastDistance; -static constexpr float kToastHeight = 0.16 * kToastDistance; +static constexpr float kWebVrToastDistance = 1.0; +static constexpr float kFullscreenToastDistance = kFullscreenDistance; +static constexpr float kToastWidthDMM = 0.512; +static constexpr float kToastHeightDMM = 0.064; +static constexpr float kToastOffsetDMM = 0.004; +// When changing the value here, make sure it doesn't collide with +// kWarningAngleRadians. +static constexpr float kWebVrAngleRadians = 9.88 * M_PI / 180.0; static constexpr int kToastTimeoutSeconds = kTransientUrlBarTimeoutSeconds; static constexpr float kSplashScreenDistance = 1; @@ -432,11 +438,9 @@ element->set_debug_id(kExclusiveScreenToast); element->set_id(AllocateId()); element->set_fill(vr_shell::Fill::NONE); - element->set_size({kToastWidth, kToastHeight, 1}); - element->set_translation({0, 0, -kToastDistance}); + element->set_size({kToastWidthDMM, kToastHeightDMM, 1}); element->set_visible(false); element->set_hit_testable(false); - element->set_lock_to_fov(true); exclusive_screen_toast_ = element.get(); scene_->AddUiElement(std::move(element)); } @@ -670,6 +674,29 @@ case UNCHANGED: return; } + if (fullscreen_ && !web_vr_mode_) { + // Do not set size again. The size might have been changed by the backing + // texture size in UpdateElementSize. + exclusive_screen_toast_->set_scale( + {kFullscreenToastDistance, kFullscreenToastDistance, 1}); + exclusive_screen_toast_->set_translation( + {0, + kFullscreenVerticalOffset + kFullscreenHeight / 2 + + (kToastOffsetDMM + kToastHeightDMM) * kFullscreenToastDistance, + -kFullscreenToastDistance}); + exclusive_screen_toast_->set_rotation( + gfx::Quaternion(gfx::Vector3dF(1, 0, 0), 0.0)); + exclusive_screen_toast_->set_lock_to_fov(false); + } else if (web_vr_mode_ && web_vr_show_toast_) { + exclusive_screen_toast_->set_scale( + {kWebVrToastDistance, kWebVrToastDistance, 1}); + exclusive_screen_toast_->set_translation( + gfx::Vector3dF(0, kWebVrToastDistance * sin(kWebVrAngleRadians), + -kWebVrToastDistance * cos(kWebVrAngleRadians))); + exclusive_screen_toast_->set_rotation( + gfx::Quaternion(gfx::Vector3dF(1, 0, 0), kWebVrAngleRadians)); + exclusive_screen_toast_->set_lock_to_fov(true); + } exclusive_screen_toast_->set_visible(toast_visible); if (toast_visible) { exclusive_screen_toast_timer_.Start(
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc index d814a04..2762eca 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.cc +++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -225,6 +225,12 @@ weak_scene_manager_, enabled)); } +void VrGLThread::SetBluetoothConnectedIndicator(bool enabled) { + task_runner()->PostTask( + FROM_HERE, base::Bind(&UiSceneManager::SetBluetoothConnectedIndicator, + weak_scene_manager_, enabled)); +} + void VrGLThread::SetIsExiting() { WaitUntilThreadStarted(); task_runner()->PostTask(FROM_HERE, base::Bind(&UiSceneManager::SetIsExiting,
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h index 8e3b89d..538d89c 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.h +++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -83,6 +83,7 @@ void SetVideoCapturingIndicator(bool enabled) override; void SetScreenCapturingIndicator(bool enabled) override; void SetAudioCapturingIndicator(bool enabled) override; + void SetBluetoothConnectedIndicator(bool enabled) override; void SetIsExiting() override; void SetSplashScreenIcon(const SkBitmap& bitmap) override;
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 97878d9..07e04bf 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -615,6 +615,7 @@ int num_tabs_capturing_audio = 0; int num_tabs_capturing_video = 0; int num_tabs_capturing_screen = 0; + int num_tabs_bluetooth_connected = 0; scoped_refptr<MediaStreamCaptureIndicator> indicator = MediaCaptureDevicesDispatcher::GetInstance() ->GetMediaStreamCaptureIndicator(); @@ -639,11 +640,14 @@ num_tabs_capturing_video++; if (indicator->IsBeingMirrored(web_contents)) num_tabs_capturing_screen++; + if (web_contents->IsConnectedToBluetoothDevice()) + num_tabs_bluetooth_connected++; } bool is_capturing_audio = num_tabs_capturing_audio > 0; bool is_capturing_video = num_tabs_capturing_video > 0; bool is_capturing_screen = num_tabs_capturing_screen > 0; + bool is_bluetooth_connected = num_tabs_bluetooth_connected > 0; if (is_capturing_audio != is_capturing_audio_) { ui_->SetAudioCapturingIndicator(is_capturing_audio); is_capturing_audio_ = is_capturing_audio; @@ -656,6 +660,10 @@ ui_->SetScreenCapturingIndicator(is_capturing_screen); is_capturing_screen_ = is_capturing_screen; } + if (is_bluetooth_connected != is_bluetooth_connected_) { + ui_->SetBluetoothConnectedIndicator(is_bluetooth_connected); + is_bluetooth_connected_ = is_bluetooth_connected; + } } void VrShell::SetContentCssSize(float width, float height, float dpr) {
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index 26d1c49..2d2a627f 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -230,6 +230,7 @@ bool is_capturing_audio_ = false; bool is_capturing_video_ = false; bool is_capturing_screen_ = false; + bool is_bluetooth_connected_ = false; // Are we currently providing a gamepad factory to the gamepad manager? bool gvr_gamepad_source_active_ = false;
diff --git a/chrome/browser/android/webapk/OWNERS b/chrome/browser/android/webapk/OWNERS index aaa15c0..841bd5a1 100644 --- a/chrome/browser/android/webapk/OWNERS +++ b/chrome/browser/android/webapk/OWNERS
@@ -1,6 +1,5 @@ -dfalcantara@chromium.org dominickn@chromium.org yfriedman@chromium.org # TEAM: webapk-team@chromium.org -# COMPONENT: Mobile>WebAPKs \ No newline at end of file +# COMPONENT: Mobile>WebAPKs
diff --git a/chrome/browser/android/webapps/OWNERS b/chrome/browser/android/webapps/OWNERS index 453dc77..d6d1a1da 100644 --- a/chrome/browser/android/webapps/OWNERS +++ b/chrome/browser/android/webapps/OWNERS
@@ -1,2 +1 @@ -dfalcantara@chromium.org dominickn@chromium.org
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index 212af96..922ed687 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -433,7 +433,6 @@ set_open_about_blank_on_browser_launch(false); // Skip AppControllerOpenShortcutBrowserTest::SetUpCommandLine, which adds // startup URL. - InProcessBrowserTest::SetUpCommandLine(command_line); } SessionStartupPref::Type GetSessionStartupPref() {
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc index a4b8cd12..1dcd9f4 100644 --- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -1747,7 +1747,8 @@ #else #define MAYBE_CompositionRangeUpdates CompositionRangeUpdates #endif -IN_PROC_BROWSER_TEST_P(WebViewImeInteractiveTest, CompositionRangeUpdates) { +IN_PROC_BROWSER_TEST_P(WebViewImeInteractiveTest, + MAYBE_CompositionRangeUpdates) { ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. LoadAndLaunchPlatformApp("web_view/ime", "WebViewImeTest.Launched"); ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
diff --git a/chrome/browser/banners/OWNERS b/chrome/browser/banners/OWNERS index b1ba61f5..def6133f 100644 --- a/chrome/browser/banners/OWNERS +++ b/chrome/browser/banners/OWNERS
@@ -1,3 +1,2 @@ benwells@chromium.org -dfalcantara@chromium.org dominickn@chromium.org
diff --git a/chrome/browser/bitmap_fetcher/OWNERS b/chrome/browser/bitmap_fetcher/OWNERS index 451172b1..cd81f30c 100644 --- a/chrome/browser/bitmap_fetcher/OWNERS +++ b/chrome/browser/bitmap_fetcher/OWNERS
@@ -1,3 +1,2 @@ -dfalcantara@chromium.org groby@chromium.org petewil@chromium.org
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index f19c0ff..100d4117 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -546,8 +546,6 @@ <include name="IDR_MD_SUPERVISED_USER_CREATE_CONFIRM_JS" file="resources\md_user_manager\supervised_user_create_confirm.js" type="BINDATA" /> <include name="IDR_MD_SUPERVISED_USER_LEARN_MORE_HTML" file="resources\md_user_manager\supervised_user_learn_more.html" type="BINDATA" /> <include name="IDR_MD_SUPERVISED_USER_LEARN_MORE_JS" file="resources\md_user_manager\supervised_user_learn_more.js" type="BINDATA" /> - <include name="IDR_MD_USER_MANAGER_DIALOG_HTML" file="resources\md_user_manager\user_manager_dialog.html" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_MD_USER_MANAGER_DIALOG_JS" file="resources\md_user_manager\user_manager_dialog.js" type="BINDATA" /> <include name="IDR_MD_USER_MANAGER_HTML" file="resources\md_user_manager\user_manager.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_MD_USER_MANAGER_JS" file="resources\md_user_manager\user_manager.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_MD_USER_MANAGER_ICONS_HTML" file="resources\md_user_manager\icons.html" type="BINDATA" />
diff --git a/chrome/browser/budget_service/budget_manager_browsertest.cc b/chrome/browser/budget_service/budget_manager_browsertest.cc index f72dfb2d..f6fbcd6 100644 --- a/chrome/browser/budget_service/budget_manager_browsertest.cc +++ b/chrome/browser/budget_service/budget_manager_browsertest.cc
@@ -66,7 +66,6 @@ // TODO(harkness): Remove switch once Budget API ships. (crbug.com/617971) command_line->AppendSwitch( switches::kEnableExperimentalWebPlatformFeatures); - InProcessBrowserTest::SetUpCommandLine(command_line); } // Sets the absolute Site Engagement |score| for the testing origin, assuming
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index a2c3da7..5e14cffa 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -682,9 +682,8 @@ void AccessibilityManager::SetTouchAccessibilityAnchorPoint( const gfx::Point& anchor_point) { - ash::RootWindowController* root_window_controller = - ash::RootWindowController::ForTargetRootWindow(); - root_window_controller->SetTouchAccessibilityAnchorPoint(anchor_point); + for (auto* rwc : ash::RootWindowController::root_window_controllers()) + rwc->SetTouchAccessibilityAnchorPoint(anchor_point); } bool AccessibilityManager::IsHighContrastEnabled() const {
diff --git a/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc b/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc index da4db5c..f52da83 100644 --- a/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/magnification_controller_browsertest.cc
@@ -98,7 +98,6 @@ ~MagnificationControllerTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); // Make screens sufficiently wide to host 2 browsers side by side. command_line->AppendSwitchASCII("ash-host-window-bounds", "1200x800"); }
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc index 3ec20534..0f8424d 100644 --- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc
@@ -82,7 +82,6 @@ ~ArcKioskAppManagerTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); arc::SetArcAvailableCommandLineForTesting(command_line); }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc index 4ccc3e6..3ad0581 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -243,8 +243,6 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); - // Initialize fake_cws_ to setup web store gallery. fake_cws_->Init(embedded_test_server()); }
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc b/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc index f5ed4cf..4e089808 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc
@@ -104,7 +104,6 @@ ~ArcSessionManagerTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); arc::SetArcAvailableCommandLineForTesting(command_line); }
diff --git a/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc index 58d6a007..e2ae7fe 100644 --- a/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc
@@ -240,7 +240,6 @@ ~ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, "http://localhost"); SetArcAvailableCommandLineForTesting(command_line);
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc index 469d6da..5fa98957 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -85,7 +85,6 @@ ~ArcAuthServiceTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); arc::SetArcAvailableCommandLineForTesting(command_line); }
diff --git a/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher_browsertest.cc index 9b72db7e..6503a11 100644 --- a/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher_browsertest.cc
@@ -73,7 +73,6 @@ ~ArcRobotAuthCodeFetcherBrowserTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, "http://localhost"); arc::SetArcAvailableCommandLineForTesting(command_line);
diff --git a/chrome/browser/chromeos/arc/print/arc_print_service.cc b/chrome/browser/chromeos/arc/print/arc_print_service.cc index 9ba2acb..185629a 100644 --- a/chrome/browser/chromeos/arc/print/arc_print_service.cc +++ b/chrome/browser/chromeos/arc/print/arc_print_service.cc
@@ -8,13 +8,13 @@ #include "ash/shell.h" #include "ash/shell_delegate.h" -#include "base/files/file.h" +#include "base/bind.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "base/optional.h" -#include "base/threading/thread_checker.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" +#include "base/threading/thread_restrictions.h" #include "components/arc/arc_bridge_service.h" -#include "content/public/browser/browser_thread.h" #include "mojo/edk/embedder/embedder.h" #include "net/base/filename_util.h" #include "url/gurl.h" @@ -22,7 +22,7 @@ namespace { base::Optional<base::FilePath> SavePdf(base::File file) { - DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); base::FilePath file_path; base::CreateTemporaryFile(&file_path); @@ -42,22 +42,12 @@ return file_path; } -void OpenPdf(base::Optional<base::FilePath> file_path) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!file_path) - return; - - GURL gurl = net::FilePathToFileURL(file_path.value()); - ash::Shell::Get()->shell_delegate()->OpenUrlFromArc(gurl); - // TODO(poromov) Delete file after printing. (http://crbug.com/629843) -} - } // namespace namespace arc { ArcPrintService::ArcPrintService(ArcBridgeService* bridge_service) - : ArcService(bridge_service), binding_(this) { + : ArcService(bridge_service), binding_(this), weak_ptr_factory_(this) { arc_bridge_service()->print()->AddObserver(this); } @@ -90,9 +80,21 @@ base::File file(scoped_platform_handle.release().handle); - content::BrowserThread::PostTaskAndReplyWithResult( - content::BrowserThread::FILE, FROM_HERE, - base::Bind(&SavePdf, base::Passed(&file)), base::Bind(&OpenPdf)); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&SavePdf, base::Passed(&file)), + base::BindOnce(&ArcPrintService::OpenPdf, + weak_ptr_factory_.GetWeakPtr())); +} + +void ArcPrintService::OpenPdf(base::Optional<base::FilePath> file_path) const { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (!file_path) + return; + + GURL gurl = net::FilePathToFileURL(file_path.value()); + ash::Shell::Get()->shell_delegate()->OpenUrlFromArc(gurl); + // TODO(poromov) Delete file after printing. (http://crbug.com/629843) } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/print/arc_print_service.h b/chrome/browser/chromeos/arc/print/arc_print_service.h index 656b4dd0..17205fe1 100644 --- a/chrome/browser/chromeos/arc/print/arc_print_service.h +++ b/chrome/browser/chromeos/arc/print/arc_print_service.h
@@ -5,7 +5,11 @@ #ifndef CHROME_BROWSER_CHROMEOS_ARC_PRINT_ARC_PRINT_SERVICE_H_ #define CHROME_BROWSER_CHROMEOS_ARC_PRINT_ARC_PRINT_SERVICE_H_ +#include "base/files/file.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "base/threading/thread_checker.h" #include "components/arc/arc_service.h" #include "components/arc/common/print.mojom.h" #include "components/arc/instance_holder.h" @@ -22,14 +26,21 @@ explicit ArcPrintService(ArcBridgeService* bridge_service); ~ArcPrintService() override; - // InstanceHolder<mojom::PrintInstance>::Observer: + // InstanceHolder<mojom::PrintInstance>::Observer override: void OnInstanceReady() override; + // mojom::PrintHost override: void Print(mojo::ScopedHandle pdf_data) override; private: + // Opens the pdf file at |file_path|. + // If given |file_path| is nullopt, do nothing. + void OpenPdf(base::Optional<base::FilePath> file_path) const; + + THREAD_CHECKER(thread_checker_); mojo::Binding<mojom::PrintHost> binding_; + base::WeakPtrFactory<ArcPrintService> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ArcPrintService); };
diff --git a/chrome/browser/chromeos/drive/file_system_util.cc b/chrome/browser/chromeos/drive/file_system_util.cc index dbb73a7..4ff9eb2 100644 --- a/chrome/browser/chromeos/drive/file_system_util.cc +++ b/chrome/browser/chromeos/drive/file_system_util.cc
@@ -158,7 +158,8 @@ for (size_t i = 0; i < profiles.size(); ++i) { Profile* original_profile = profiles[i]->GetOriginalProfile(); if (original_profile == profiles[i] && - !chromeos::ProfileHelper::IsSigninProfile(original_profile)) { + !chromeos::ProfileHelper::IsSigninProfile(original_profile) && + !chromeos::ProfileHelper::IsLockScreenAppProfile(original_profile)) { const base::FilePath base = GetDriveMountPointPath(original_profile); if (base == path || base.IsParent(path)) return original_profile;
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.cc b/chrome/browser/chromeos/file_manager/volume_manager.cc index 191e334..3dbdf66 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager.cc +++ b/chrome/browser/chromeos/file_manager/volume_manager.cc
@@ -347,9 +347,12 @@ } void VolumeManager::Initialize() { - // If in Sign in profile, then skip mounting and listening for mount events. - if (chromeos::ProfileHelper::IsSigninProfile(profile_)) + // If in the Sign in profile pr the lock screen app profile, skip mounting + // and listening for mount events. + if (chromeos::ProfileHelper::IsSigninProfile(profile_) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile_)) { return; + } // Register 'Downloads' folder for the profile to the file system. const base::FilePath downloads =
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util.cc index cd568f0..36cd1404 100644 --- a/chrome/browser/chromeos/file_system_provider/mount_path_util.cc +++ b/chrome/browser/chromeos/file_system_provider/mount_path_util.cc
@@ -100,7 +100,8 @@ Profile* original_profile = profiles[i]->GetOriginalProfile(); if (original_profile != profiles[i] || - chromeos::ProfileHelper::IsSigninProfile(original_profile)) { + chromeos::ProfileHelper::IsSigninProfile(original_profile) || + chromeos::ProfileHelper::IsLockScreenAppProfile(original_profile)) { continue; }
diff --git a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc index ef3dfbc..aa468237 100644 --- a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
@@ -15,6 +15,7 @@ #include "base/path_service.h" #include "base/strings/string_util.h" #include "base/sys_info.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" @@ -22,7 +23,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/browser_resources.h" -#include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_pref_value_map.h" #include "extensions/browser/extension_pref_value_map_factory.h" #include "extensions/browser/extension_system.h" @@ -148,13 +148,10 @@ // and InputMethodEngine creation, so that the virtual keyboard web content // url won't be override by IME component extensions. base::FilePath* copied_file_path = new base::FilePath(file_path); - content::BrowserThread::PostTaskAndReplyWithResult( - content::BrowserThread::FILE, - FROM_HERE, - base::Bind(&CheckFilePath, - base::Unretained(copied_file_path)), - base::Bind(&OnFilePathChecked, - base::Unretained(profile), + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::Bind(&CheckFilePath, base::Unretained(copied_file_path)), + base::Bind(&OnFilePathChecked, base::Unretained(profile), base::Owned(new std::string(extension_id)), base::Owned(new std::string(manifest)), base::Owned(copied_file_path)));
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller.cc index bf7899fe..f0e141de 100644 --- a/chrome/browser/chromeos/lock_screen_apps/state_controller.cc +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller.cc
@@ -10,10 +10,14 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/strings/string16.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/lock_screen_apps/app_manager_impl.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/pref_names.h" #include "chromeos/chromeos_switches.h" +#include "components/prefs/pref_service.h" #include "components/session_manager/core/session_manager.h" #include "content/public/common/service_manager_connection.h" #include "extensions/browser/app_window/app_window.h" @@ -44,7 +48,10 @@ } StateController::StateController() - : binding_(this), app_window_observer_(this), session_observer_(this) { + : binding_(this), + app_window_observer_(this), + session_observer_(this), + weak_ptr_factory_(this) { DCHECK(!g_instance); DCHECK(IsEnabled()); @@ -65,6 +72,13 @@ tray_action_ptr_.FlushForTesting(); } +void StateController::SetReadyCallbackForTesting( + const base::Closure& ready_callback) { + DCHECK(ready_callback_.is_null()); + + ready_callback_ = ready_callback; +} + void StateController::SetAppManagerForTesting( std::unique_ptr<AppManager> app_manager) { DCHECK(!app_manager_); @@ -85,15 +99,49 @@ } void StateController::SetPrimaryProfile(Profile* profile) { + g_browser_process->profile_manager()->CreateProfileAsync( + chromeos::ProfileHelper::GetLockScreenAppProfilePath(), + base::Bind(&StateController::OnProfilesReady, + weak_ptr_factory_.GetWeakPtr(), profile), + base::string16() /* name */, "" /* icon_url*/, + "" /* supervised_user_id */); +} + +void StateController::OnProfilesReady(Profile* primary_profile, + Profile* lock_screen_profile, + Profile::CreateStatus status) { + // Ignore CREATED status - wait for profile to be initialized before + // continuing. + if (status == Profile::CREATE_STATUS_CREATED) + return; + + // On error, bail out - this will cause the lock screen apps to remain + // unavailable on the device. + if (status != Profile::CREATE_STATUS_INITIALIZED) { + LOG(ERROR) << "Failed to create profile for lock screen apps."; + return; + } + + DCHECK(!lock_screen_profile_); + + lock_screen_profile_ = lock_screen_profile; + lock_screen_profile_->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, + true); + // App manager might have been set previously by a test. if (!app_manager_) app_manager_ = base::MakeUnique<AppManagerImpl>(); - app_manager_->Initialize( - profile, - chromeos::ProfileHelper::GetSigninProfile()->GetOriginalProfile()); + app_manager_->Initialize(primary_profile, + lock_screen_profile->GetOriginalProfile()); session_observer_.Add(session_manager::SessionManager::Get()); OnSessionStateChanged(); + + // SessionController is fully initialized at this point. + if (!ready_callback_.is_null()) { + ready_callback_.Run(); + ready_callback_.Reset(); + } } void StateController::AddObserver(StateObserver* observer) { @@ -154,7 +202,7 @@ if (lock_screen_note_state_ != TrayActionState::kLaunching) return nullptr; - if (!chromeos::ProfileHelper::GetSigninProfile()->IsSameProfile( + if (!lock_screen_profile_->IsSameProfile( Profile::FromBrowserContext(context))) { return nullptr; } @@ -165,8 +213,8 @@ // The ownership of the window is passed to the caller of this method. note_app_window_ = new extensions::AppWindow(context, app_delegate.release(), extension); - app_window_observer_.Add(extensions::AppWindowRegistry::Get( - chromeos::ProfileHelper::GetSigninProfile())); + app_window_observer_.Add( + extensions::AppWindowRegistry::Get(lock_screen_profile_)); UpdateLockScreenNoteState(TrayActionState::kActive); return note_app_window_; }
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller.h b/chrome/browser/chromeos/lock_screen_apps/state_controller.h index b180adc..f347e83 100644 --- a/chrome/browser/chromeos/lock_screen_apps/state_controller.h +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller.h
@@ -8,17 +8,17 @@ #include <memory> #include "ash/public/interfaces/tray_action.mojom.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/scoped_observer.h" #include "chrome/browser/chromeos/lock_screen_apps/app_manager.h" #include "chrome/browser/chromeos/lock_screen_apps/state_observer.h" +#include "chrome/browser/profiles/profile.h" #include "components/session_manager/core/session_manager_observer.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/common/api/app_runtime.h" #include "mojo/public/cpp/bindings/binding.h" -class Profile; - namespace content { class BrowserContext; } @@ -27,7 +27,7 @@ class AppDelegate; class AppWindow; class Extension; -} +} // namespace extensions namespace session_manager { class SessionManager; @@ -63,6 +63,9 @@ // Has to be called before |Initialize|. void SetTrayActionPtrForTesting(ash::mojom::TrayActionPtr tray_action_ptr); void FlushTrayActionForTesting(); + // Sets the callback that will be run when the state controller is fully + // initialized and ready for action. + void SetReadyCallbackForTesting(const base::Closure& ready_callback); // Sets test AppManager implementation. Should be called before // |SetPrimaryProfile| void SetAppManagerForTesting(std::unique_ptr<AppManager> app_manager); @@ -108,6 +111,14 @@ void MoveToForeground(); private: + // Called when profiles needed to run lock screen apps are ready - i.e. when + // primary user profile was set using |SetPrimaryProfile| and the profile in + // which app lock screen windows will be run creation is done. + // |status| - The lock screen profile creation status. + void OnProfilesReady(Profile* primary_profile, + Profile* lock_screen_profile, + Profile::CreateStatus status); + // Called when app manager reports that note taking availability has changed. void OnNoteTakingAvailabilityChanged(); @@ -133,6 +144,8 @@ mojo::Binding<ash::mojom::TrayActionClient> binding_; ash::mojom::TrayActionPtr tray_action_ptr_; + Profile* lock_screen_profile_ = nullptr; + std::unique_ptr<AppManager> app_manager_; extensions::AppWindow* note_app_window_ = nullptr; @@ -144,6 +157,14 @@ session_manager::SessionManagerObserver> session_observer_; + // If set, this callback will be run when the state controller is fully + // initialized. It can be used to throttle tests until state controller + // is ready for action - i.e. until the state controller starts reacting + // to session / app manager changes. + base::Closure ready_callback_; + + base::WeakPtrFactory<StateController> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(StateController); };
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc index a28a1b8..d253fe7 100644 --- a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc
@@ -15,6 +15,7 @@ #include "base/test/scoped_command_line.h" #include "chrome/browser/chromeos/lock_screen_apps/app_manager.h" #include "chrome/browser/chromeos/lock_screen_apps/state_observer.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/ui/apps/chrome_app_delegate.h" @@ -328,34 +329,32 @@ ASSERT_TRUE(lock_screen_apps::StateController::IsEnabled()); + // Create fake lock screen app profile. + lock_screen_profile_ = profile_manager_.CreateTestingProfile( + chromeos::ProfileHelper::GetLockScreenAppProfileName()); + + InitExtensionSystem(profile()); + InitExtensionSystem(lock_screen_profile()); + + std::unique_ptr<TestAppManager> app_manager = + base::MakeUnique<TestAppManager>( + &profile_, lock_screen_profile_->GetOriginalProfile()); + app_manager_ = app_manager.get(); + state_controller_ = base::MakeUnique<lock_screen_apps::StateController>(); state_controller_->SetTrayActionPtrForTesting( tray_action_.CreateInterfacePtrAndBind()); + state_controller_->SetAppManagerForTesting(std::move(app_manager)); + state_controller_->SetReadyCallbackForTesting(ready_waiter_.QuitClosure()); state_controller_->Initialize(); state_controller_->FlushTrayActionForTesting(); state_controller_->AddObserver(&observer_); - - // Create fake sign-in profile. - TestingProfile::Builder builder; - builder.SetPath( - profile_manager_.profiles_dir().AppendASCII(chrome::kInitialProfile)); - signin_profile_ = builder.BuildIncognito( - profile_manager_.CreateTestingProfile(chrome::kInitialProfile)); - - InitExtensionSystem(profile()); - InitExtensionSystem(signin_profile()); - - std::unique_ptr<TestAppManager> app_manager = - base::MakeUnique<TestAppManager>(&profile_, - signin_profile_->GetOriginalProfile()); - app_manager_ = app_manager.get(); - state_controller_->SetAppManagerForTesting(std::move(app_manager)); } void TearDown() override { extensions::ExtensionSystem::Get(profile())->Shutdown(); - extensions::ExtensionSystem::Get(signin_profile())->Shutdown(); + extensions::ExtensionSystem::Get(lock_screen_profile())->Shutdown(); state_controller_->RemoveObserver(&observer_); state_controller_.reset(); @@ -402,17 +401,22 @@ tray_action_.ClearObservedStates(); } + void SetPrimaryProfileAndWaitUntilReady() { + state_controller_->SetPrimaryProfile(&profile_); + ready_waiter_.Run(); + } + // Helper method to move state controller to the specified state. // Should be called at the begining of tests, at most once. bool InitializeNoteTakingApp(TrayActionState target_state, bool enable_app_launch) { app_ = CreateTestNoteTakingApp(kTestAppId); - extensions::ExtensionSystem::Get(signin_profile()) + extensions::ExtensionSystem::Get(lock_screen_profile()) ->extension_service() ->AddExtension(app_.get()); app_manager_->SetInitialAppState(kTestAppId, enable_app_launch); - state_controller_->SetPrimaryProfile(&profile_); + SetPrimaryProfileAndWaitUntilReady(); if (target_state == TrayActionState::kNotAvailable) return true; @@ -446,7 +450,7 @@ if (target_state == TrayActionState::kLaunching) return true; - app_window_ = CreateNoteTakingWindow(signin_profile(), app()); + app_window_ = CreateNoteTakingWindow(lock_screen_profile(), app()); if (!app_window_->window()) { ADD_FAILURE() << "Not allowed to create app window."; return false; @@ -461,7 +465,7 @@ } TestingProfile* profile() { return &profile_; } - TestingProfile* signin_profile() { return signin_profile_; } + TestingProfile* lock_screen_profile() { return lock_screen_profile_; } session_manager::SessionManager* session_manager() { return session_manager_.get(); @@ -484,7 +488,16 @@ std::unique_ptr<base::test::ScopedCommandLine> command_line_; TestingProfileManager profile_manager_; TestingProfile profile_; - TestingProfile* signin_profile_ = nullptr; + TestingProfile* lock_screen_profile_ = nullptr; + + // Run loop used to throttle test until async state controller initialization + // is fully complete. The quit closure for this run loop will be passed to + // |state_controller_| as the callback to be run when the state controller is + // ready for action. + // NOTE: Tests should call |state_controller_->SetPrimaryProfile(Profile*)| + // before running the loop, as that is the method that starts the state + // controller. + base::RunLoop ready_waiter_; std::unique_ptr<session_manager::SessionManager> session_manager_; @@ -522,7 +535,7 @@ TEST_F(LockScreenAppStateTest, SetPrimaryProfile) { EXPECT_EQ(TestAppManager::State::kNotInitialized, app_manager()->state()); - state_controller()->SetPrimaryProfile(profile()); + SetPrimaryProfileAndWaitUntilReady(); EXPECT_EQ(TestAppManager::State::kStopped, app_manager()->state()); EXPECT_EQ(TrayActionState::kNotAvailable, @@ -538,7 +551,7 @@ EXPECT_EQ(TestAppManager::State::kNotInitialized, app_manager()->state()); app_manager()->SetInitialAppState(kTestAppId, true); - state_controller()->SetPrimaryProfile(profile()); + SetPrimaryProfileAndWaitUntilReady(); ASSERT_EQ(TestAppManager::State::kStarted, app_manager()->state()); @@ -550,7 +563,7 @@ TEST_F(LockScreenAppStateTest, SessionLock) { app_manager()->SetInitialAppState(kTestAppId, true); - state_controller()->SetPrimaryProfile(profile()); + SetPrimaryProfileAndWaitUntilReady(); ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); session_manager()->SetSessionState(session_manager::SessionState::LOCKED); @@ -584,7 +597,7 @@ } TEST_F(LockScreenAppStateTest, SessionUnlockedWhileStartingAppManager) { - state_controller()->SetPrimaryProfile(profile()); + SetPrimaryProfileAndWaitUntilReady(); ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); session_manager()->SetSessionState(session_manager::SessionState::LOCKED); @@ -612,7 +625,7 @@ } TEST_F(LockScreenAppStateTest, AppManagerNoApp) { - state_controller()->SetPrimaryProfile(profile()); + SetPrimaryProfileAndWaitUntilReady(); ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); session_manager()->SetSessionState(session_manager::SessionState::LOCKED); @@ -646,7 +659,7 @@ } TEST_F(LockScreenAppStateTest, AppAvailabilityChanges) { - state_controller()->SetPrimaryProfile(profile()); + SetPrimaryProfileAndWaitUntilReady(); ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); app_manager()->SetInitialAppState(kTestAppId, false); @@ -784,7 +797,7 @@ true /* enable_app_launch */)); std::unique_ptr<TestAppWindow> app_window = - CreateNoteTakingWindow(signin_profile(), app()); + CreateNoteTakingWindow(lock_screen_profile(), app()); EXPECT_FALSE(app_window->window()); tray_action()->SendNewNoteRequest(); @@ -800,10 +813,11 @@ EXPECT_FALSE(non_eligible_app_window->window()); EXPECT_FALSE(state_controller()->CreateAppWindowForLockScreenAction( - signin_profile(), app(), extensions::api::app_runtime::ACTION_TYPE_NONE, + lock_screen_profile(), app(), + extensions::api::app_runtime::ACTION_TYPE_NONE, base::MakeUnique<ChromeAppDelegate>(true))); - app_window = CreateNoteTakingWindow(signin_profile(), app()); + app_window = CreateNoteTakingWindow(lock_screen_profile(), app()); ASSERT_TRUE(app_window->window()); app_window->Initialize(true /* shown */); @@ -812,7 +826,7 @@ // Test that second app window cannot be registered. std::unique_ptr<TestAppWindow> second_app_window = - CreateNoteTakingWindow(signin_profile(), app()); + CreateNoteTakingWindow(lock_screen_profile(), app()); EXPECT_FALSE(second_app_window->window()); // Test the app window does not get closed by itself. @@ -837,7 +851,7 @@ true /* enable_app_launch */)); std::unique_ptr<TestAppWindow> app_window = - CreateNoteTakingWindow(signin_profile(), app()); + CreateNoteTakingWindow(lock_screen_profile(), app()); ASSERT_TRUE(app_window->window()); app_window->Initialize(false /* shown */); @@ -862,7 +876,7 @@ ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kActive, true /* enable_app_launch */)); - extensions::ExtensionSystem::Get(signin_profile()) + extensions::ExtensionSystem::Get(lock_screen_profile()) ->extension_service() ->UnloadExtension(app()->id(), extensions::UnloadedExtensionReason::UNINSTALL); @@ -881,7 +895,7 @@ scoped_refptr<extensions::Extension> secondary_app = CreateTestNoteTakingApp(kSecondaryTestAppId); - extensions::ExtensionSystem::Get(signin_profile()) + extensions::ExtensionSystem::Get(lock_screen_profile()) ->extension_service() ->AddExtension(secondary_app.get()); @@ -897,13 +911,13 @@ state_controller()->FlushTrayActionForTesting(); std::unique_ptr<TestAppWindow> app_window = - CreateNoteTakingWindow(signin_profile(), app()); + CreateNoteTakingWindow(lock_screen_profile(), app()); EXPECT_FALSE(app_window->window()); ASSERT_EQ(TrayActionState::kLaunching, state_controller()->GetLockScreenNoteState()); std::unique_ptr<TestAppWindow> secondary_app_window = - CreateNoteTakingWindow(signin_profile(), secondary_app.get()); + CreateNoteTakingWindow(lock_screen_profile(), secondary_app.get()); ASSERT_TRUE(secondary_app_window->window()); secondary_app_window->Initialize(true /* shown*/); @@ -914,7 +928,7 @@ EXPECT_FALSE(secondary_app_window->closed()); // Uninstall the app and test the secondary app window is closed. - extensions::ExtensionSystem::Get(signin_profile()) + extensions::ExtensionSystem::Get(lock_screen_profile()) ->extension_service() ->UnloadExtension(secondary_app->id(), extensions::UnloadedExtensionReason::UNINSTALL);
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc index 9307f9f9..dfee29f 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.cc +++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -451,8 +451,8 @@ app_launch_splash_screen_view_->ToggleNetworkConfig(false); // We have connectivity at this point, so we can skip the network - // configuration dialog if it is being shown. - if (showing_network_dialog_) { + // configuration dialog if it is being shown and not explicitly requested. + if (showing_network_dialog_ && !network_config_requested_) { app_launch_splash_screen_view_->Show(app_id_); showing_network_dialog_ = false; launch_splash_start_time_ = base::TimeTicks::Now().ToInternalValue();
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc index 04a96fb5..1202c44 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc
@@ -64,6 +64,8 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); const user_manager::User* user = NULL; + if (chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) + return nullptr; if (!chromeos::ProfileHelper::IsSigninProfile(profile)) user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile); return new EasyUnlockTpmKeyManager(
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index f41ec5dc..4813f64 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -915,9 +915,7 @@ RunAppLaunchNetworkDownTest(); } -// TODO(crbug.com/735442): This test is flaky. -IN_PROC_BROWSER_TEST_F(KioskTest, - DISABLED_LaunchAppWithNetworkConfigAccelerator) { +IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppWithNetworkConfigAccelerator) { ScopedCanConfigureNetwork can_configure_network(true, false); // Block app loading until the network screen is shown.
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc index 7ff1916..018dde3 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -127,7 +127,6 @@ DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( std::unique_ptr<SessionManagerClient>(fake_session_manager_client_)); - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode( ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)); }
diff --git a/chrome/browser/chromeos/login/mixin_based_browser_test.cc b/chrome/browser/chromeos/login/mixin_based_browser_test.cc index fdeaae4..a5b9ee03 100644 --- a/chrome/browser/chromeos/login/mixin_based_browser_test.cc +++ b/chrome/browser/chromeos/login/mixin_based_browser_test.cc
@@ -20,16 +20,12 @@ setup_was_launched_ = true; for (const auto& mixin : mixins_) mixin->SetUpCommandLine(command_line); - - InProcessBrowserTest::SetUpCommandLine(command_line); } void MixinBasedBrowserTest::SetUpInProcessBrowserTestFixture() { setup_was_launched_ = true; for (const auto& mixin : mixins_) mixin->SetUpInProcessBrowserTestFixture(); - - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); } void MixinBasedBrowserTest::SetUpOnMainThread() { @@ -39,12 +35,11 @@ } void MixinBasedBrowserTest::TearDownOnMainThread() { - InProcessBrowserTest::TearDownOnMainThread(); for (const auto& mixin : base::Reversed(mixins_)) mixin->TearDownInProcessBrowserTestFixture(); } + void MixinBasedBrowserTest::TearDownInProcessBrowserTestFixture() { - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); for (const auto& mixin : base::Reversed(mixins_)) mixin->TearDownInProcessBrowserTestFixture(); }
diff --git a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc index b89fca99..94a6407 100644 --- a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
@@ -73,10 +73,6 @@ network_screen_->SetNetworkStateHelperForTest(mock_network_state_helper_); } - void TearDownInProcessBrowserTestFixture() override { - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); - } - void EmulateContinueButtonExit(NetworkScreen* network_screen) { EXPECT_CALL(*mock_base_screen_delegate_, OnExit(_, ScreenExitCode::NETWORK_CONNECTED, _))
diff --git a/chrome/browser/chromeos/login/signin/merge_session_throttling_utils.cc b/chrome/browser/chromeos/login/signin/merge_session_throttling_utils.cc index 661bb8d..dbf95db 100644 --- a/chrome/browser/chromeos/login/signin/merge_session_throttling_utils.cc +++ b/chrome/browser/chromeos/login/signin/merge_session_throttling_utils.cc
@@ -62,7 +62,7 @@ // even be even added to new requests. Value of 0 (initial) means that we // probably have some profiles to restore, while 1 means that all known // profiles are restored. -base::AtomicRefCount g_all_profiles_restored_ = 0; +base::AtomicRefCount g_all_profiles_restored_(0); } // namespace @@ -101,7 +101,8 @@ // Check if there is any other profile to block on. if (ProfileSet::Get()->size() == 0) { base::AtomicRefCountInc(&g_all_profiles_restored_); - DVLOG(1) << "All profiles merged " << g_all_profiles_restored_; + DVLOG(1) << "All profiles merged " + << g_all_profiles_restored_.SubtleRefCountForDebug(); } }
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc index bbd4ca4..f8823ec 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc
@@ -78,8 +78,10 @@ KeyedService* OwnerSettingsServiceChromeOSFactory::BuildInstanceFor( content::BrowserContext* browser_context) { Profile* profile = static_cast<Profile*>(browser_context); - if (profile->IsGuestSession() || ProfileHelper::IsSigninProfile(profile)) - return NULL; + if (profile->IsGuestSession() || ProfileHelper::IsSigninProfile(profile) || + ProfileHelper::IsLockScreenAppProfile(profile)) { + return nullptr; + } return new OwnerSettingsServiceChromeOS( GetDeviceSettingsService(), profile,
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc index 7d2998c..57326e78 100644 --- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc +++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
@@ -104,11 +104,6 @@ dbus_setter_->SetSessionManagerClient( std::unique_ptr<chromeos::SessionManagerClient>( fake_session_manager_client_)); - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); -} - -void DevicePolicyCrosBrowserTest::TearDownInProcessBrowserTestFixture() { - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); } void DevicePolicyCrosBrowserTest::MarkOwnership() {
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h index 6d1159c..47c1f20 100644 --- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h +++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
@@ -53,7 +53,6 @@ ~DevicePolicyCrosBrowserTest() override; void SetUpInProcessBrowserTestFixture() override; - void TearDownInProcessBrowserTestFixture() override; virtual void MarkOwnership();
diff --git a/chrome/browser/chromeos/policy/login_profile_policy_provider.h b/chrome/browser/chromeos/policy/login_profile_policy_provider.h index 8098052..e3ad9e5f 100644 --- a/chrome/browser/chromeos/policy/login_profile_policy_provider.h +++ b/chrome/browser/chromeos/policy/login_profile_policy_provider.h
@@ -13,10 +13,10 @@ namespace policy { -// Policy provider for the login profile. Since the login profile is not -// associated with any user, it does not receive regular user policy. However, -// several device policies that control features on the login screen surface as -// user policies in the login profile. +// Policy provider for the login/lock screen app profile. Since these profiles +// are not associated with any user, it does not receive regular user policy. +// However, several device policies that control features on the login/lock +// screen surface as user policies in the login and the lock screen app profile. class LoginProfilePolicyProvider : public ConfigurationPolicyProvider, public PolicyService::Observer { public:
diff --git a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc index 5a5751a..ebdf387 100644 --- a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc +++ b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc
@@ -40,15 +40,12 @@ protected: // InProcessBrowserTest void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); affiliation_test_helper::AppendCommandLineSwitchesForLoginManager( command_line); } // InProcessBrowserTest void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - chromeos::FakeSessionManagerClient* fake_session_manager_client = new chromeos::FakeSessionManagerClient; chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc index 6ea318b..f6258fb 100644 --- a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc +++ b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc
@@ -60,9 +60,12 @@ KeyedService* UserNetworkConfigurationUpdaterFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { + // On the login/lock screen only device network policies apply. Profile* profile = Profile::FromBrowserContext(context); - if (chromeos::ProfileHelper::IsSigninProfile(profile)) - return NULL; // On the login screen only device network policies apply. + if (chromeos::ProfileHelper::IsSigninProfile(profile) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { + return nullptr; + } const user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile); @@ -70,7 +73,7 @@ // Currently, only the network policy of the primary user is supported. See // also http://crbug.com/310685 . if (user != user_manager::UserManager::Get()->GetPrimaryUser()) - return NULL; + return nullptr; ProfilePolicyConnector* profile_connector = ProfilePolicyConnectorFactory::GetForBrowserContext(context);
diff --git a/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc b/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc index b0681d7..4a3d4807 100644 --- a/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc
@@ -146,13 +146,17 @@ const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - // Don't initialize cloud policy for the signin profile. - if (chromeos::ProfileHelper::IsSigninProfile(profile)) + // Don't initialize cloud policy for the signin and the lock screen app + // profile. + if (chromeos::ProfileHelper::IsSigninProfile(profile) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { return {}; + } - // |user| should never be nullptr except for the signin profile. This object - // is created as part of the Profile creation, which happens right after - // sign-in. The just-signed-in User is the active user during that time. + // |user| should never be nullptr except for the signin and lock screen app + // profile. This object is created as part of the Profile creation, which + // happens right after sign-in. The just-signed-in User is the active user + // during that time. const user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile); CHECK(user);
diff --git a/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc b/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc index e4738e1..92a53894 100644 --- a/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc +++ b/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc
@@ -42,20 +42,12 @@ chromeos::DBusThreadManager::Initialize(); } - void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - } - void SetUpOnMainThread() override { observer_.reset(new PeripheralBatteryObserver()); } void TearDownOnMainThread() override { observer_.reset(); } - void TearDownInProcessBrowserTestFixture() override { - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); - } - protected: std::unique_ptr<PeripheralBatteryObserver> observer_;
diff --git a/chrome/browser/chromeos/printing/specifics_translation.cc b/chrome/browser/chromeos/printing/specifics_translation.cc index 4719092..bbbb300 100644 --- a/chrome/browser/chromeos/printing/specifics_translation.cc +++ b/chrome/browser/chromeos/printing/specifics_translation.cc
@@ -8,6 +8,8 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" #include "base/time/time.h" #include "chrome/browser/chromeos/printing/specifics_translation.h" #include "chromeos/printing/printer_configuration.h" @@ -49,6 +51,14 @@ } } +// Combines |make| and |model| with a space to generate a make and model string. +// If |model| already represents the make and model, the string is just |model|. +// This is to prevent strings of the form '<make> <make> <model>'. +std::string MakeAndModel(base::StringPiece make, base::StringPiece model) { + return model.starts_with(make) ? model.as_string() + : base::JoinString({make, model}, " "); +} + } // namespace std::unique_ptr<Printer> SpecificsToPrinter( @@ -61,6 +71,12 @@ printer->set_description(specifics.description()); printer->set_manufacturer(specifics.manufacturer()); printer->set_model(specifics.model()); + if (!specifics.make_and_model().empty()) { + printer->set_make_and_model(specifics.make_and_model()); + } else { + printer->set_make_and_model( + MakeAndModel(specifics.manufacturer(), specifics.model())); + } printer->set_uri(specifics.uri()); printer->set_uuid(specifics.uuid()); @@ -96,6 +112,9 @@ if (!printer.model().empty()) specifics->set_model(printer.model()); + if (!printer.make_and_model().empty()) + specifics->set_make_and_model(printer.make_and_model()); + if (!printer.uri().empty()) specifics->set_uri(printer.uri());
diff --git a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc index 5c6fb48..94a6bea 100644 --- a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc +++ b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <string> #include <utility> #include "base/memory/ptr_util.h" @@ -18,6 +19,7 @@ constexpr char kDescription[] = "The green one"; constexpr char kManufacturer[] = "Manufacturer"; constexpr char kModel[] = "MODEL"; +constexpr char kMakeAndModel[] = "Manufacturer MODEL"; constexpr char kUri[] = "ipps://notaprinter.chromium.org/ipp/print"; constexpr char kUuid[] = "UUIDUUIDUUID"; const base::Time kUpdateTime = base::Time::FromInternalValue(22114455660000); @@ -35,8 +37,7 @@ specifics.set_id(kId); specifics.set_display_name(kDisplayName); specifics.set_description(kDescription); - specifics.set_manufacturer(kManufacturer); - specifics.set_model(kModel); + specifics.set_make_and_model(kMakeAndModel); specifics.set_uri(kUri); specifics.set_uuid(kUuid); specifics.set_updated_timestamp(kUpdateTime.ToJavaTime()); @@ -49,8 +50,7 @@ EXPECT_EQ(kId, result->id()); EXPECT_EQ(kDisplayName, result->display_name()); EXPECT_EQ(kDescription, result->description()); - EXPECT_EQ(kManufacturer, result->manufacturer()); - EXPECT_EQ(kModel, result->model()); + EXPECT_EQ(kMakeAndModel, result->make_and_model()); EXPECT_EQ(kUri, result->uri()); EXPECT_EQ(kUuid, result->uuid()); EXPECT_EQ(kUpdateTime, result->last_updated()); @@ -65,8 +65,7 @@ printer.set_id(kId); printer.set_display_name(kDisplayName); printer.set_description(kDescription); - printer.set_manufacturer(kManufacturer); - printer.set_model(kModel); + printer.set_make_and_model(kMakeAndModel); printer.set_uri(kUri); printer.set_uuid(kUuid); @@ -79,8 +78,7 @@ EXPECT_EQ(kId, result->id()); EXPECT_EQ(kDisplayName, result->display_name()); EXPECT_EQ(kDescription, result->description()); - EXPECT_EQ(kManufacturer, result->manufacturer()); - EXPECT_EQ(kModel, result->model()); + EXPECT_EQ(kMakeAndModel, result->make_and_model()); EXPECT_EQ(kUri, result->uri()); EXPECT_EQ(kUuid, result->uuid()); @@ -95,6 +93,7 @@ printer.set_description(kDescription); printer.set_manufacturer(kManufacturer); printer.set_model(kModel); + printer.set_make_and_model(kMakeAndModel); printer.set_uri(kUri); printer.set_uuid(kUuid); @@ -110,6 +109,7 @@ EXPECT_EQ(kDescription, result->description()); EXPECT_EQ(kManufacturer, result->manufacturer()); EXPECT_EQ(kModel, result->model()); + EXPECT_EQ(kMakeAndModel, result->make_and_model()); EXPECT_EQ(kUri, result->uri()); EXPECT_EQ(kUuid, result->uuid()); @@ -121,10 +121,16 @@ sync_pb::PrinterSpecifics original; original.set_id(kId); original.mutable_ppd_reference()->set_autoconf(true); + original.set_manufacturer(kManufacturer); + original.set_model(kModel); + // make_and_model not set Printer printer(kId); printer.mutable_ppd_reference()->effective_make_and_model = kEffectiveMakeAndModel; + printer.set_make_and_model(kMakeAndModel); + // manufacturer not set + // model not set MergePrinterToSpecifics(printer, &original); @@ -134,6 +140,11 @@ // Verify that autoconf is cleared. EXPECT_FALSE(original.ppd_reference().autoconf()); + + // Verify that both make_and_model and the old fields are retained. + EXPECT_EQ(kMakeAndModel, original.make_and_model()); + EXPECT_EQ(kManufacturer, original.manufacturer()); + EXPECT_EQ(kModel, original.model()); } // Tests that the autoconf value overrides other PpdReference fields. @@ -167,5 +178,50 @@ EXPECT_TRUE(printer->ppd_reference().effective_make_and_model.empty()); } +TEST(SpecificsTranslationTest, OldProtoExpectedValues) { + sync_pb::PrinterSpecifics original; + original.set_id(kId); + original.set_manufacturer(kManufacturer); + original.set_model(kModel); + + auto printer = SpecificsToPrinter(original); + + // make_and_model should be computed + EXPECT_EQ(kMakeAndModel, printer->make_and_model()); + + // Ensure that manufacturer and model are still populated + EXPECT_EQ(kManufacturer, printer->manufacturer()); + EXPECT_EQ(kModel, printer->model()); +} + +TEST(SpecificsTranslationTest, OldProtoDuplicateManufacturer) { + const std::string make = "IO"; + const std::string model = "IO Radar 2000"; + + sync_pb::PrinterSpecifics original; + original.set_id(kId); + original.set_manufacturer(make); + original.set_model(model); + + auto printer = SpecificsToPrinter(original); + + EXPECT_EQ("IO Radar 2000", printer->make_and_model()); +} + +TEST(SpecificsTranslationTest, MakeAndModelPreferred) { + const std::string make = "UN"; + const std::string model = "EXPECTED"; + + sync_pb::PrinterSpecifics original; + original.set_id(kId); + original.set_manufacturer(make); + original.set_model(model); + original.set_make_and_model(kMakeAndModel); + + auto printer = SpecificsToPrinter(original); + + EXPECT_EQ(kMakeAndModel, printer->make_and_model()); +} + } // namespace printing } // namespace chromeos
diff --git a/chrome/browser/chromeos/profiles/profile_helper.cc b/chrome/browser/chromeos/profiles/profile_helper.cc index 5bc7736..bd4bb1b 100644 --- a/chrome/browser/chromeos/profiles/profile_helper.cc +++ b/chrome/browser/chromeos/profiles/profile_helper.cc
@@ -42,6 +42,9 @@ // As defined in /chromeos/dbus/cryptohome_client.cc. static const char kUserIdHashSuffix[] = "-hash"; +// The name for the lock screen app profile. +static const char kLockScreenAppProfile[] = "LockScreenAppsProfile"; + bool ShouldAddProfileDirPrefix(const std::string& user_id_hash) { // Do not add profile dir prefix for legacy profile dir and test // user profile. The reason of not adding prefix for test user profile @@ -171,6 +174,23 @@ } // static +bool ProfileHelper::IsLockScreenAppProfile(const Profile* profile) { + return profile && + profile->GetPath().BaseName().value() == kLockScreenAppProfile; +} + +// static +base::FilePath ProfileHelper::GetLockScreenAppProfilePath() { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + return profile_manager->user_data_dir().AppendASCII(kLockScreenAppProfile); +} + +// static +std::string ProfileHelper::GetLockScreenAppProfileName() { + return kLockScreenAppProfile; +} + +// static bool ProfileHelper::IsOwnerProfile(const Profile* profile) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kStubCrosSettings)) { @@ -358,8 +378,10 @@ DCHECK(!content::BrowserThread::IsThreadInitialized( content::BrowserThread::UI) || content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - if (ProfileHelper::IsSigninProfile(profile)) - return NULL; + if (ProfileHelper::IsSigninProfile(profile) || + ProfileHelper::IsLockScreenAppProfile(profile)) { + return nullptr; + } user_manager::UserManager* user_manager = user_manager::UserManager::Get();
diff --git a/chrome/browser/chromeos/profiles/profile_helper.h b/chrome/browser/chromeos/profiles/profile_helper.h index a71b4b6..2c302ba0 100644 --- a/chrome/browser/chromeos/profiles/profile_helper.h +++ b/chrome/browser/chromeos/profiles/profile_helper.h
@@ -106,6 +106,19 @@ // signin Profile. static bool IsSigninProfile(const Profile* profile); + // Returns the path used for the lock screen apps profile - profile used + // for launching platform apps that can display windows on top of the lock + // screen. + static base::FilePath GetLockScreenAppProfilePath(); + + // Returns the name used for the lock screen app profile. + static std::string GetLockScreenAppProfileName(); + + // Returns whether |profile| is the lock screen app profile - the profile used + // for launching platform apps that can display a window on top of the lock + // screen. + static bool IsLockScreenAppProfile(const Profile* profile); + // Returns true when |profile| corresponds to owner's profile. static bool IsOwnerProfile(const Profile* profile);
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc index 173b014..f7f9c8d 100644 --- a/chrome/browser/chromeos/tether/tether_service.cc +++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -46,6 +46,28 @@ return base::FeatureList::IsEnabled(features::kInstantTethering); } +void TetherService::InitializerDelegate::InitializeTether( + cryptauth::CryptAuthService* cryptauth_service, + std::unique_ptr<chromeos::tether::NotificationPresenter> + notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + chromeos::NetworkStateHandler* network_state_handler, + chromeos::ManagedNetworkConfigurationHandler* + managed_network_configuration_handler, + chromeos::NetworkConnect* network_connect, + chromeos::NetworkConnectionHandler* network_connection_handler) { + chromeos::tether::Initializer::Init( + cryptauth_service, std::move(notification_presenter), pref_service, + token_service, network_state_handler, + managed_network_configuration_handler, network_connect, + network_connection_handler); +} + +void TetherService::InitializerDelegate::ShutdownTether() { + chromeos::tether::Initializer::Shutdown(); +} + TetherService::TetherService( Profile* profile, chromeos::PowerManagerClient* power_manager_client, @@ -57,6 +79,7 @@ session_manager_client_(session_manager_client), cryptauth_service_(cryptauth_service), network_state_handler_(network_state_handler), + initializer_delegate_(base::MakeUnique<InitializerDelegate>()), weak_ptr_factory_(this) { power_manager_client_->AddObserver(this); session_manager_client_->AddObserver(this); @@ -92,7 +115,7 @@ base::MakeUnique<chromeos::tether::TetherNotificationPresenter>( profile_, message_center::MessageCenter::Get(), chromeos::NetworkConnect::Get()); - chromeos::tether::Initializer::Init( + initializer_delegate_->InitializeTether( cryptauth_service_, std::move(notification_presenter), profile_->GetPrefs(), ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), @@ -103,7 +126,7 @@ } void TetherService::StopTether() { - chromeos::tether::Initializer::Shutdown(); + initializer_delegate_->ShutdownTether(); } void TetherService::Shutdown() { @@ -198,12 +221,12 @@ } void TetherService::UpdateTetherTechnologyState() { - chromeos::NetworkStateHandler::TechnologyState tether_technology_state = + chromeos::NetworkStateHandler::TechnologyState new_tether_technology_state = GetTetherTechnologyState(); - network_state_handler_->SetTetherTechnologyState(tether_technology_state); + network_state_handler_->SetTetherTechnologyState(new_tether_technology_state); - if (tether_technology_state == + if (new_tether_technology_state == chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED) { StartTetherIfEnabled(); } else { @@ -264,3 +287,8 @@ bool TetherService::IsEnabledbyPreference() const { return profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled); } + +void TetherService::SetInitializerDelegateForTest( + std::unique_ptr<InitializerDelegate> initializer_delegate) { + initializer_delegate_ = std::move(initializer_delegate); +}
diff --git a/chrome/browser/chromeos/tether/tether_service.h b/chrome/browser/chromeos/tether/tether_service.h index 3a97135..4a174b00 100644 --- a/chrome/browser/chromeos/tether/tether_service.h +++ b/chrome/browser/chromeos/tether/tether_service.h
@@ -19,12 +19,23 @@ #include "components/prefs/pref_change_registrar.h" #include "device/bluetooth/bluetooth_adapter.h" +namespace chromeos { +class NetworkStateHandler; +class ManagedNetworkConfigurationHandler; +class NetworkConnect; +class NetworkConnectionHandler; +namespace tether { +class NotificationPresenter; +} // namespace tether +} // namespace chromeos + namespace cryptauth { class CryptAuthService; -} // cryptauth +} // namespace cryptauth class PrefRegistrySimple; class Profile; +class ProfileOAuth2TokenService; class TetherService : public KeyedService, public chromeos::PowerManagerClient::Observer, @@ -57,6 +68,24 @@ // Stop the Tether module. virtual void StopTether(); + // Delegate used to call the static functions of Initializer. Injected to + // aid in testing. + class InitializerDelegate { + public: + virtual void InitializeTether( + cryptauth::CryptAuthService* cryptauth_service, + std::unique_ptr<chromeos::tether::NotificationPresenter> + notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + chromeos::NetworkStateHandler* network_state_handler, + chromeos::ManagedNetworkConfigurationHandler* + managed_network_configuration_handler, + chromeos::NetworkConnect* network_connect, + chromeos::NetworkConnectionHandler* network_connection_handler); + virtual void ShutdownTether(); + }; + protected: // KeyedService: void Shutdown() override; @@ -113,6 +142,9 @@ // Whether Tether is enabled. bool IsEnabledbyPreference() const; + void SetInitializerDelegateForTest( + std::unique_ptr<InitializerDelegate> initializer_delegate); + // Whether the service has been shut down. bool shut_down_ = false; @@ -125,6 +157,7 @@ chromeos::SessionManagerClient* session_manager_client_; cryptauth::CryptAuthService* cryptauth_service_; chromeos::NetworkStateHandler* network_state_handler_; + std::unique_ptr<InitializerDelegate> initializer_delegate_; PrefChangeRegistrar registrar_; scoped_refptr<device::BluetoothAdapter> adapter_;
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc index 9eeb2599..76fdb5c 100644 --- a/chrome/browser/chromeos/tether/tether_service_unittest.cc +++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -90,6 +90,31 @@ int updated_technology_state_count_ = 0; }; +class TestInitializerDelegate : public TetherService::InitializerDelegate { + public: + bool is_tether_running() { return is_tether_running_; } + + // TetherService::InitializerDelegate: + void InitializeTether( + cryptauth::CryptAuthService* cryptauth_service, + std::unique_ptr<chromeos::tether::NotificationPresenter> + notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + chromeos::NetworkStateHandler* network_state_handler, + chromeos::ManagedNetworkConfigurationHandler* + managed_network_configuration_handler, + chromeos::NetworkConnect* network_connect, + chromeos::NetworkConnectionHandler* network_connection_handler) override { + is_tether_running_ = true; + } + + void ShutdownTether() override { is_tether_running_ = false; } + + private: + bool is_tether_running_ = false; +}; + } // namespace class TetherServiceTest : public chromeos::NetworkStateTest { @@ -145,10 +170,14 @@ } void CreateTetherService() { + test_initializer_delegate_ = new TestInitializerDelegate(); + tether_service_ = base::WrapUnique(new TestTetherService( profile_.get(), fake_power_manager_client_.get(), fake_session_manager_client_.get(), fake_cryptauth_service_.get(), network_state_handler())); + tether_service_->SetInitializerDelegateForTest( + base::WrapUnique(test_initializer_delegate_)); base::RunLoop().RunUntilIdle(); } @@ -189,6 +218,7 @@ std::unique_ptr<TestingPrefServiceSimple> test_pref_service_; std::unique_ptr<NiceMock<MockCryptAuthDeviceManager>> mock_cryptauth_device_manager_; + TestInitializerDelegate* test_initializer_delegate_; std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_; scoped_refptr<device::MockBluetoothAdapter> mock_adapter_; std::unique_ptr<TestTetherService> tether_service_; @@ -199,6 +229,7 @@ TEST_F(TetherServiceTest, TestShutdown) { CreateTetherService(); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); ShutdownTetherService(); @@ -206,10 +237,12 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestSuspend) { CreateTetherService(); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); fake_power_manager_client_->SendSuspendImminent(); @@ -217,16 +250,19 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); fake_power_manager_client_->SendSuspendDone(); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestScreenLock) { CreateTetherService(); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); SetIsScreenLocked(true); @@ -234,12 +270,14 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); SetIsScreenLocked(false); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestFeatureFlagDisabled) { @@ -266,6 +304,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestProhibitedByPolicy) { @@ -277,6 +316,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_PROHIBITED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestBluetoothIsNotPowered) { @@ -288,6 +328,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestCellularIsUnavailable) { @@ -304,11 +345,13 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestCellularIsAvailable) { @@ -325,35 +368,41 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Cellular())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(false); EXPECT_EQ( chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(true); EXPECT_EQ( chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); // Cellular enabled SetCellularTechnologyStateEnabled(true); ASSERT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Cellular())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(false); EXPECT_EQ( chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestEnabled) { @@ -362,6 +411,7 @@ EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(false); EXPECT_EQ( @@ -370,6 +420,7 @@ chromeos::NetworkTypePattern::Tether())); EXPECT_FALSE( profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled)); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); SetTetherTechnologyStateEnabled(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, @@ -377,6 +428,7 @@ chromeos::NetworkTypePattern::Tether())); EXPECT_TRUE( profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled)); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); } // Test against a past defect that made TetherService and NetworkStateHandler
diff --git a/chrome/browser/devtools/device/port_forwarding_browsertest.cc b/chrome/browser/devtools/device/port_forwarding_browsertest.cc index 016b64b..be48dc9 100644 --- a/chrome/browser/devtools/device/port_forwarding_browsertest.cc +++ b/chrome/browser/devtools/device/port_forwarding_browsertest.cc
@@ -40,7 +40,6 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort, base::IntToString(GetRemoteDebuggingPort())); }
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 8d579786..478d000 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -989,7 +989,6 @@ "//components/chrome_apps", "//components/constrained_window", "//components/drive", - "//components/session_manager/core", "//components/user_manager", "//remoting/base", "//remoting/host",
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc index f279dfe..324abaf 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc
@@ -108,6 +108,14 @@ << message_; } +IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTestChromeOs, ResetAdvertising) { + EnterKioskSession(); + SetAutoLaunchApp(); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/bluetooth_low_energy/reset_all_advertisements")) + << message_; +} + IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTestChromeOs, SetAdvertisingInterval) { EnterKioskSession();
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc index 2c5385e..06edf418 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
@@ -43,7 +43,6 @@ void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch(::switches::kEnableUserMediaScreenCapturing); - InProcessBrowserTest::SetUpCommandLine(command_line); } protected:
diff --git a/chrome/browser/extensions/api/socket/socket_api_unittest.cc b/chrome/browser/extensions/api/socket/socket_api_unittest.cc index c174cc6..34e18a1 100644 --- a/chrome/browser/extensions/api/socket/socket_api_unittest.cc +++ b/chrome/browser/extensions/api/socket/socket_api_unittest.cc
@@ -5,6 +5,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/extensions/extension_api_unittest.h" @@ -35,13 +36,9 @@ }; TEST_F(SocketUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketCreateFunction* function = new SocketCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(
diff --git a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc index 7801b0d..dbcdc6a2 100644 --- a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc +++ b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api_unittest.cc
@@ -5,6 +5,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/extensions/extension_api_unittest.h" @@ -48,14 +49,10 @@ }; TEST_F(SocketsTcpServerUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketsTcpServerCreateFunction* function = new SocketsTcpServerCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index c7aee0a..b89408e 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -64,7 +64,6 @@ #include "chrome/browser/extensions/updater/chromeos_extension_cache_delegate.h" #include "chrome/browser/extensions/updater/extension_cache_impl.h" #include "chromeos/chromeos_switches.h" -#include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_manager.h" #else #include "extensions/browser/updater/null_extension_cache.h" @@ -454,9 +453,8 @@ bool ChromeExtensionsBrowserClient::IsLockScreenContext( content::BrowserContext* context) { #if defined(OS_CHROMEOS) - return chromeos::ProfileHelper::IsSigninProfile( - Profile::FromBrowserContext(context)) && - session_manager::SessionManager::Get()->IsSessionStarted(); + return chromeos::ProfileHelper::IsLockScreenAppProfile( + Profile::FromBrowserContext(context)); #else return false; #endif
diff --git a/chrome/browser/extensions/chrome_process_manager_delegate.cc b/chrome/browser/extensions/chrome_process_manager_delegate.cc index 9e983ef..491892a 100644 --- a/chrome/browser/extensions/chrome_process_manager_delegate.cc +++ b/chrome/browser/extensions/chrome_process_manager_delegate.cc
@@ -22,9 +22,11 @@ #include "extensions/browser/process_manager_factory.h" #include "extensions/common/extension.h" #include "extensions/common/one_shot_event.h" +#include "extensions/common/permissions/permissions_data.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chromeos/chromeos_switches.h" #endif namespace extensions { @@ -84,6 +86,14 @@ // policy. return login_screen_apps_list->HasKey(extension.id()); } + + if (chromeos::ProfileHelper::IsLockScreenAppProfile(profile) && + !profile->IsOffTheRecord()) { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableLockScreenApps) && + extension.permissions_data()->HasAPIPermission( + APIPermission::kLockScreen); + } #endif return AreBackgroundPagesAllowedForContext(context);
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index 622235a..39db475 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -207,7 +207,6 @@ ExtensionMessageBubbleFactory::set_override_for_tests( ExtensionMessageBubbleFactory::NO_OVERRIDE); extensions::SetExtensionProtocolTestHandler(nullptr); - InProcessBrowserTest::TearDownOnMainThread(); } const Extension* ExtensionBrowserTest::LoadExtension(
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index b08bba2..763dbbbc 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -355,19 +355,6 @@ registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, content::Source<Profile>(profile_)); -#if defined(OS_CHROMEOS) - // Sign in profile extension service should observe session start - when the - // session is started, the context's process map should be updated to consider - // extension scripts to run in lock screen context (as the sign-in profile - // will be used to host lock screen apps from that point). - // TODO(tbarzic): Consider introducing a profile dedicated to lock screen apps - // so the process map's 'is lock screen context' flag does not have to be - // changed when the user session starts. - if (chromeos::ProfileHelper::IsSigninProfile(profile_)) { - registrar_.Add(this, chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources()); - } -#endif UpgradeDetector::GetInstance()->AddObserver(this); @@ -465,7 +452,8 @@ bool load_saved_extensions = true; bool load_command_line_extensions = extensions_enabled_; #if defined(OS_CHROMEOS) - if (chromeos::ProfileHelper::IsSigninProfile(profile_)) { + if (chromeos::ProfileHelper::IsSigninProfile(profile_) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile_)) { load_saved_extensions = false; load_command_line_extensions = false; } @@ -2267,20 +2255,6 @@ OnProfileDestructionStarted(); break; } -#if defined(OS_CHROMEOS) - case chrome::NOTIFICATION_SESSION_STARTED: { - DCHECK(chromeos::ProfileHelper::IsSigninProfile(profile_)); - - // When the user session starts, mark the signin context as lock screen - // context, as it will be used to host apps on lock screen. - extensions::ProcessMap::Get(profile_)->set_is_lock_screen_context(true); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&extensions::InfoMap::SetIsLockScreenContext, - system_->info_map(), true)); - break; - } -#endif default: NOTREACHED() << "Unexpected notification type.";
diff --git a/chrome/browser/extensions/extension_startup_browsertest.cc b/chrome/browser/extensions/extension_startup_browsertest.cc index 9b546f3..6ad99ad 100644 --- a/chrome/browser/extensions/extension_startup_browsertest.cc +++ b/chrome/browser/extensions/extension_startup_browsertest.cc
@@ -109,8 +109,6 @@ } void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - // Bots are on a domain, turn off the domain check for settings hardening in // order to be able to test all SettingsEnforcement groups. chrome_prefs::DisableDomainCheckForTesting();
diff --git a/chrome/browser/extensions/extension_storage_monitor.cc b/chrome/browser/extensions/extension_storage_monitor.cc index 69efb43..f3d1755a 100644 --- a/chrome/browser/extensions/extension_storage_monitor.cc +++ b/chrome/browser/extensions/extension_storage_monitor.cc
@@ -576,10 +576,8 @@ if (!extension) return; - if (!uninstall_dialog_.get()) { - uninstall_dialog_.reset(ExtensionUninstallDialog::Create( - Profile::FromBrowserContext(context_), NULL, this)); - } + uninstall_dialog_.reset(ExtensionUninstallDialog::Create( + Profile::FromBrowserContext(context_), NULL, this)); uninstall_extension_id_ = extension->id(); uninstall_dialog_->ConfirmUninstall(
diff --git a/chrome/browser/extensions/extension_system_impl.cc b/chrome/browser/extensions/extension_system_impl.cc index 251b8a2..455d900 100644 --- a/chrome/browser/extensions/extension_system_impl.cc +++ b/chrome/browser/extensions/extension_system_impl.cc
@@ -208,8 +208,10 @@ bool autoupdate_enabled = !profile_->IsGuestSession() && !profile_->IsSystemProfile(); #if defined(OS_CHROMEOS) - if (!extensions_enabled) + if (!extensions_enabled || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile_)) { autoupdate_enabled = false; + } #endif // defined(OS_CHROMEOS) extension_service_.reset(new ExtensionService( profile_, base::CommandLine::ForCurrentProcess(), @@ -232,7 +234,10 @@ if (mode >= ContentVerifierDelegate::BOOTSTRAP) content_verifier_->Start(); info_map()->SetContentVerifier(content_verifier_.get()); - +#if defined(OS_CHROMEOS) + if (chromeos::ProfileHelper::IsLockScreenAppProfile(profile_)) + info_map()->SetIsLockScreenContext(true); +#endif management_policy_.reset(new ManagementPolicy); RegisterManagementPolicyProviders(); } @@ -244,9 +249,12 @@ bool skip_session_extensions = false; #if defined(OS_CHROMEOS) // Skip loading session extensions if we are not in a user session or if the - // profile is the sign-in profile, which doesn't correspond to a user session. - skip_session_extensions = !chromeos::LoginState::Get()->IsUserLoggedIn() || - chromeos::ProfileHelper::IsSigninProfile(profile_); + // profile is the sign-in or lock screen app profile, which don't correspond + // to a user session. + skip_session_extensions = + !chromeos::LoginState::Get()->IsUserLoggedIn() || + chromeos::ProfileHelper::IsSigninProfile(profile_) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile_); if (chrome::IsRunningInForcedAppMode()) { extension_service_->component_loader()-> AddDefaultComponentExtensionsForKioskMode(skip_session_extensions);
diff --git a/chrome/browser/favicon/content_favicon_driver_browsertest.cc b/chrome/browser/favicon/content_favicon_driver_browsertest.cc index d786c929..b0182bf 100644 --- a/chrome/browser/favicon/content_favicon_driver_browsertest.cc +++ b/chrome/browser/favicon/content_favicon_driver_browsertest.cc
@@ -22,11 +22,9 @@ #include "components/favicon/core/favicon_handler.h" #include "components/favicon/core/favicon_service.h" #include "components/favicon/core/features.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/browser/web_contents_observer.h" #include "net/base/load_flags.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/url_request/url_request.h" @@ -84,48 +82,34 @@ DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate); }; -// Checks whether the FaviconDriver is waiting for a download to complete or -// for data from the FaviconService. -class FaviconDriverPendingTaskChecker { - public: - virtual ~FaviconDriverPendingTaskChecker() {} - - virtual bool HasPendingTasks() = 0; -}; - // Waits for the following the finish: // - The pending navigation. // - FaviconHandler's pending favicon database requests. // - FaviconHandler's pending downloads. -class PendingTaskWaiter : public content::NotificationObserver { +// - Optionally, for a specific page URL (as a mechanism to wait of Javascript +// completion). +class PendingTaskWaiter : public content::WebContentsObserver { public: PendingTaskWaiter(content::WebContents* web_contents, - FaviconDriverPendingTaskChecker* checker) - : checker_(checker), - load_stopped_(false), - weak_factory_(this) { - registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &web_contents->GetController())); - } + const GURL& required_url = GURL()) + : WebContentsObserver(web_contents), + required_url_(required_url), + weak_factory_(this) {} ~PendingTaskWaiter() override {} void Wait() { - if (load_stopped_ && !checker_->HasPendingTasks()) - return; - base::RunLoop run_loop; quit_closure_ = run_loop.QuitClosure(); run_loop.Run(); } private: - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override { - if (type == content::NOTIFICATION_LOAD_STOP) - load_stopped_ = true; + // content::WebContentsObserver: + void DidStopLoading() override { + if (!required_url_.is_empty() && + required_url_ != web_contents()->GetLastCommittedURL()) { + return; + } // We need to poll periodically because Delegate::OnFaviconUpdated() is not // guaranteed to be called upon completion of the last database request / @@ -146,16 +130,14 @@ void EndLoopIfCanStopWaiting() { if (!quit_closure_.is_null() && - load_stopped_ && - !checker_->HasPendingTasks()) { + !favicon::ContentFaviconDriver::FromWebContents(web_contents()) + ->HasPendingTasksForTest()) { quit_closure_.Run(); } } - FaviconDriverPendingTaskChecker* checker_; // Not owned. - bool load_stopped_; base::Closure quit_closure_; - content::NotificationRegistrar registrar_; + const GURL required_url_; base::WeakPtrFactory<PendingTaskWaiter> weak_factory_; DISALLOW_COPY_AND_ASSIGN(PendingTaskWaiter); @@ -163,8 +145,7 @@ } // namespace -class ContentFaviconDriverTest : public InProcessBrowserTest, - public FaviconDriverPendingTaskChecker { +class ContentFaviconDriverTest : public InProcessBrowserTest { public: ContentFaviconDriverTest() {} ~ContentFaviconDriverTest() override {} @@ -173,13 +154,9 @@ return browser()->tab_strip_model()->GetActiveWebContents(); } - // FaviconDriverPendingTaskChecker: - bool HasPendingTasks() override { - return favicon::ContentFaviconDriver::FromWebContents(web_contents()) - ->HasPendingTasksForTest(); - } - - favicon_base::FaviconRawBitmapResult GetFaviconForPageURL(const GURL& url) { + favicon_base::FaviconRawBitmapResult GetFaviconForPageURL( + const GURL& url, + favicon_base::IconType icon_type) { favicon::FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( browser()->profile(), ServiceAccessType::EXPLICIT_ACCESS); @@ -188,7 +165,7 @@ base::CancelableTaskTracker tracker; base::RunLoop loop; favicon_service->GetFaviconForPageURL( - url, favicon_base::FAVICON, /*desired_size_in_dip=*/0, + url, icon_type, /*desired_size_in_dip=*/0, base::Bind( [](std::vector<favicon_base::FaviconRawBitmapResult>* save_results, base::RunLoop* loop, @@ -225,7 +202,7 @@ // Initial visit in order to populate the cache. { - PendingTaskWaiter waiter(web_contents(), this); + PendingTaskWaiter waiter(web_contents()); ui_test_utils::NavigateToURLWithDisposition( browser(), url, WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); @@ -240,7 +217,7 @@ // A normal visit should fetch the favicon from either the favicon database or // the HTTP cache. { - PendingTaskWaiter waiter(web_contents(), this); + PendingTaskWaiter waiter(web_contents()); ui_test_utils::NavigateToURLWithDisposition( browser(), url, WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); @@ -251,7 +228,7 @@ // A reload ignoring the cache should refetch the favicon from the website. { - PendingTaskWaiter waiter(web_contents(), this); + PendingTaskWaiter waiter(web_contents()); chrome::ExecuteCommand(browser(), IDC_RELOAD_BYPASSING_CACHE); waiter.Wait(); } @@ -270,7 +247,7 @@ new TestResourceDispatcherHostDelegate(icon_url)); content::ResourceDispatcherHost::Get()->SetDelegate(delegate.get()); - PendingTaskWaiter waiter(web_contents(), this); + PendingTaskWaiter waiter(web_contents()); ui_test_utils::NavigateToURLWithDisposition( browser(), url, WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); @@ -278,6 +255,9 @@ #if defined(OS_ANDROID) EXPECT_TRUE(delegate->was_requested()); + EXPECT_NE( + nullptr, + GetFaviconForPageURL(url, favicon_base::WEB_MANIFEST_ICON).bitmap_data); #else EXPECT_FALSE(delegate->was_requested()); #endif @@ -298,24 +278,50 @@ base::test::ScopedFeatureList override_features; override_features.InitAndDisableFeature(favicon::kFaviconsFromWebManifest); - PendingTaskWaiter waiter(web_contents(), this); + PendingTaskWaiter waiter(web_contents()); ui_test_utils::NavigateToURLWithDisposition( browser(), url, WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); waiter.Wait(); } - ASSERT_NE(nullptr, GetFaviconForPageURL(url).bitmap_data); + ASSERT_NE(nullptr, + GetFaviconForPageURL(url, favicon_base::FAVICON).bitmap_data); ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); // Visit the page again now that the feature is enabled (default). { - PendingTaskWaiter waiter(web_contents(), this); + PendingTaskWaiter waiter(web_contents()); ui_test_utils::NavigateToURLWithDisposition( browser(), url, WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); waiter.Wait(); } - EXPECT_NE(nullptr, GetFaviconForPageURL(url).bitmap_data); + EXPECT_NE(nullptr, + GetFaviconForPageURL(url, favicon_base::FAVICON).bitmap_data); } + +#if defined(OS_ANDROID) +IN_PROC_BROWSER_TEST_F(ContentFaviconDriverTest, + LoadIconFromWebManifestDespitePushState) { + base::test::ScopedFeatureList override_features; + override_features.InitAndEnableFeature(favicon::kFaviconsFromWebManifest); + + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url = + embedded_test_server()->GetURL("/favicon/pushstate_with_manifest.html"); + GURL pushstate_url = embedded_test_server()->GetURL( + "/favicon/pushstate_with_manifest.html#pushState"); + + PendingTaskWaiter waiter(web_contents(), /*required_url=*/pushstate_url); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_NONE); + waiter.Wait(); + + EXPECT_NE(nullptr, + GetFaviconForPageURL(pushstate_url, favicon_base::WEB_MANIFEST_ICON) + .bitmap_data); +} +#endif
diff --git a/chrome/browser/first_run/first_run_browsertest.cc b/chrome/browser/first_run/first_run_browsertest.cc index 4aa424e..ab22236 100644 --- a/chrome/browser/first_run/first_run_browsertest.cc +++ b/chrome/browser/first_run/first_run_browsertest.cc
@@ -107,7 +107,6 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kForceFirstRun); EXPECT_EQ(first_run::AUTO_IMPORT_NONE, first_run::auto_import_state());
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 183f225d..27a9633 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1477,6 +1477,12 @@ "permissions dialog, or the details link (which is a link to the Web " "Store)."; +const char kMacV2SandboxName[] = "Mac V2 Sandbox"; + +const char kMacV2SandboxDescription[] = + "Eliminates the unsandboxed warmup phase and sandboxes processes for their " + "entire life cycle."; + const char kMacViewsNativeAppWindowsName[] = "Toolkit-Views App Windows."; const char kMacViewsNativeAppWindowsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 244897d..41a03a2 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1211,6 +1211,9 @@ extern const char kMacTouchBarName[]; extern const char kMacTouchBarDescription[]; +extern const char kMacV2SandboxName[]; +extern const char kMacV2SandboxDescription[]; + extern const char kMacViewsNativeAppWindowsName[]; extern const char kMacViewsNativeAppWindowsDescription[];
diff --git a/chrome/browser/lifetime/browser_close_manager_browsertest.cc b/chrome/browser/lifetime/browser_close_manager_browsertest.cc index 1b3e44a..1897702a 100644 --- a/chrome/browser/lifetime/browser_close_manager_browsertest.cc +++ b/chrome/browser/lifetime/browser_close_manager_browsertest.cc
@@ -351,8 +351,14 @@ // Test that the tab closed after the aborted shutdown attempt is not re-opened // when restoring the session. +// Flaky on Windows trybots, see https://crbug.com/737860. +#if defined(OS_WIN) +#define MAYBE_TestSessionRestore DISABLED_TestSessionRestore +#else +#define MAYBE_TestSessionRestore TestSessionRestore +#endif IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, - TestSessionRestore) { + MAYBE_TestSessionRestore) { // The testing framework launches Chrome with about:blank as args. EXPECT_EQ(2, browser()->tab_strip_model()->count()); EXPECT_EQ(GURL(chrome::kChromeUIVersionURL),
diff --git a/chrome/browser/local_discovery/service_discovery_client_mdns.cc b/chrome/browser/local_discovery/service_discovery_client_mdns.cc index ff43bb8..0c1e2ca 100644 --- a/chrome/browser/local_discovery/service_discovery_client_mdns.cc +++ b/chrome/browser/local_discovery/service_discovery_client_mdns.cc
@@ -6,12 +6,12 @@ #include <stddef.h> -#include <memory> #include <utility> #include <vector> #include "base/location.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -32,7 +32,7 @@ // Handles interaction of client code on UI thread end net code on mdns thread. class ServiceDiscoveryClientMdns::Proxy { public: - typedef base::WeakPtr<Proxy> WeakPtr; + using WeakPtr = base::WeakPtr<Proxy>; explicit Proxy(ServiceDiscoveryClientMdns* client) : client_(client), @@ -54,10 +54,10 @@ // Notifies proxies that new mDNS instance is ready. virtual void OnNewMdnsReady() { - DCHECK(!client_->need_dalay_mdns_tasks_); + DCHECK(!client_->need_delay_mdns_tasks_); if (IsValid()) { - for (size_t i = 0; i < delayed_tasks_.size(); ++i) - client_->mdns_runner_->PostTask(FROM_HERE, delayed_tasks_[i]); + for (const auto& task : delayed_tasks_) + client_->mdns_runner_->PostTask(FROM_HERE, task); } delayed_tasks_.clear(); } @@ -72,11 +72,12 @@ protected: void PostToMdnsThread(const base::Closure& task) { DCHECK(IsValid()); - // The first task on IO thread for each |mdns_| instance must be |InitMdns|. - // |OnInterfaceListReady| could be delayed by |GetMDnsInterfacesToBind| - // running on FILE thread, so |PostToMdnsThread| could be called to post - // task for |mdns_| that is not initialized yet. - if (!client_->need_dalay_mdns_tasks_) { + // The first task on the IO thread for each |mdns_| instance must be + // InitMdns(). OnInterfaceListReady() could be delayed by + // GetMDnsInterfacesToBind() running on a background task runner, so + // PostToMdnsThread() could be called to post task for |mdns_| that is not + // initialized yet. + if (!client_->need_delay_mdns_tasks_) { client_->mdns_runner_->PostTask(FROM_HERE, task); return; } @@ -108,6 +109,7 @@ // Delayed |mdns_runner_| tasks. std::vector<base::Closure> delayed_tasks_; base::WeakPtrFactory<Proxy> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(Proxy); }; @@ -116,7 +118,7 @@ const int kMaxRestartAttempts = 10; const int kRestartDelayOnNetworkChangeSeconds = 3; -typedef base::Callback<void(bool)> MdnsInitCallback; +using MdnsInitCallback = base::Callback<void(bool)>; class SocketFactory : public net::MDnsSocketFactory { public: @@ -152,7 +154,7 @@ template<class T> class ProxyBase : public ServiceDiscoveryClientMdns::Proxy, public T { public: - typedef ProxyBase<T> Base; + using Base = ProxyBase<T>; explicit ProxyBase(ServiceDiscoveryClientMdns* client) : Proxy(client) { @@ -181,6 +183,7 @@ private: std::unique_ptr<T> implementation_; + DISALLOW_COPY_AND_ASSIGN(ProxyBase); }; @@ -242,6 +245,7 @@ } std::string service_type_; ServiceWatcher::UpdatedCallback callback_; + DISALLOW_COPY_AND_ASSIGN(ServiceWatcherProxy); }; @@ -281,6 +285,7 @@ } std::string service_name_; + DISALLOW_COPY_AND_ASSIGN(ServiceResolverProxy); }; @@ -328,7 +333,7 @@ ServiceDiscoveryClientMdns::ServiceDiscoveryClientMdns() : mdns_runner_(BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)), restart_attempts_(0), - need_dalay_mdns_tasks_(true), + need_delay_mdns_tasks_(true), weak_ptr_factory_(this) { DCHECK_CURRENTLY_ON(BrowserThread::UI); net::NetworkChangeNotifier::AddNetworkChangeObserver(this); @@ -340,8 +345,9 @@ const std::string& service_type, const ServiceWatcher::UpdatedCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return std::unique_ptr<ServiceWatcher>( - new ServiceWatcherProxy(this, service_type, callback)); + auto watcher = + base::MakeUnique<ServiceWatcherProxy>(this, service_type, callback); + return std::move(watcher); } std::unique_ptr<ServiceResolver> @@ -349,8 +355,9 @@ const std::string& service_name, const ServiceResolver::ResolveCompleteCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return std::unique_ptr<ServiceResolver>( - new ServiceResolverProxy(this, service_name, callback)); + auto resolver = + base::MakeUnique<ServiceResolverProxy>(this, service_name, callback); + return std::move(resolver); } std::unique_ptr<LocalDomainResolver> @@ -359,8 +366,9 @@ net::AddressFamily address_family, const LocalDomainResolver::IPAddressCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return std::unique_ptr<LocalDomainResolver>( - new LocalDomainResolverProxy(this, domain, address_family, callback)); + auto resolver = base::MakeUnique<LocalDomainResolverProxy>( + this, domain, address_family, callback); + return std::move(resolver); } ServiceDiscoveryClientMdns::~ServiceDiscoveryClientMdns() { @@ -380,16 +388,17 @@ void ServiceDiscoveryClientMdns::ScheduleStartNewClient() { DCHECK_CURRENTLY_ON(BrowserThread::UI); OnBeforeMdnsDestroy(); - if (restart_attempts_ < kMaxRestartAttempts) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&ServiceDiscoveryClientMdns::StartNewClient, - weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromSeconds(kRestartDelayOnNetworkChangeSeconds * - (1 << restart_attempts_))); - } else { + if (restart_attempts_ >= kMaxRestartAttempts) { ReportSuccess(); + return; } + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&ServiceDiscoveryClientMdns::StartNewClient, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromSeconds(kRestartDelayOnNetworkChangeSeconds * + (1 << restart_attempts_))); } void ServiceDiscoveryClientMdns::StartNewClient() { @@ -397,7 +406,7 @@ ++restart_attempts_; DestroyMdns(); mdns_ = net::MDnsClient::CreateDefault(); - client_.reset(new ServiceDiscoveryClientImpl(mdns_.get())); + client_ = base::MakeUnique<ServiceDiscoveryClientImpl>(mdns_.get()); BrowserThread::PostTaskAndReplyWithResult( BrowserThread::FILE, FROM_HERE, @@ -425,7 +434,7 @@ ReportSuccess(); // Initialization is done, no need to delay tasks. - need_dalay_mdns_tasks_ = false; + need_delay_mdns_tasks_ = false; for (Proxy& observer : proxies_) observer.OnNewMdnsReady(); } @@ -437,7 +446,7 @@ } void ServiceDiscoveryClientMdns::OnBeforeMdnsDestroy() { - need_dalay_mdns_tasks_ = true; + need_delay_mdns_tasks_ = true; weak_ptr_factory_.InvalidateWeakPtrs(); for (Proxy& observer : proxies_) observer.OnMdnsDestroy(); @@ -445,8 +454,8 @@ void ServiceDiscoveryClientMdns::DestroyMdns() { OnBeforeMdnsDestroy(); - // After calling |Proxy::OnMdnsDestroy| all references to client_ and mdns_ - // should be destroyed. + // After calling Proxy::OnMdnsDestroy(), all references to |client_| and + // |mdns_| should be destroyed. if (client_) mdns_runner_->DeleteSoon(FROM_HERE, client_.release()); if (mdns_)
diff --git a/chrome/browser/local_discovery/service_discovery_client_mdns.h b/chrome/browser/local_discovery/service_discovery_client_mdns.h index 56372d1..a1c0bdc 100644 --- a/chrome/browser/local_discovery/service_discovery_client_mdns.h +++ b/chrome/browser/local_discovery/service_discovery_client_mdns.h
@@ -5,10 +5,9 @@ #ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MDNS_H_ #define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MDNS_H_ -#include <set> +#include <memory> #include <string> -#include "base/cancelable_callback.h" #include "base/macros.h" #include "base/observer_list.h" #include "chrome/browser/local_discovery/service_discovery_client.h" @@ -18,16 +17,17 @@ namespace local_discovery { -// Implementation of ServiceDiscoverySharedClient with front-end of UI thread -// and networking code on IO thread. +// Implementation of ServiceDiscoverySharedClient with the front-end on the +// UI thread and the networking code on the IO thread. class ServiceDiscoveryClientMdns : public ServiceDiscoverySharedClient, public net::NetworkChangeNotifier::NetworkChangeObserver { public: class Proxy; + ServiceDiscoveryClientMdns(); - // ServiceDiscoveryClient implementation. + // ServiceDiscoveryClient: std::unique_ptr<ServiceWatcher> CreateServiceWatcher( const std::string& service_type, const ServiceWatcher::UpdatedCallback& callback) override; @@ -39,7 +39,7 @@ net::AddressFamily address_family, const LocalDomainResolver::IPAddressCallback& callback) override; - // net::NetworkChangeNotifier::NetworkChangeObserver implementation. + // net::NetworkChangeNotifier::NetworkChangeObserver: void OnNetworkChanged( net::NetworkChangeNotifier::ConnectionType type) override; @@ -66,11 +66,10 @@ std::unique_ptr<ServiceDiscoveryClient> client_; // Counter of restart attempts we have made after network change. - int restart_attempts_; + int restart_attempts_ = 0; - // If false delay tasks until initialization is posted to |mdns_runner_| - // thread. - bool need_dalay_mdns_tasks_; + // If false, delay tasks until initialization is posted to |mdns_runner_|. + bool need_delay_mdns_tasks_ = true; base::WeakPtrFactory<ServiceDiscoveryClientMdns> weak_ptr_factory_;
diff --git a/chrome/browser/local_discovery/service_discovery_shared_client.cc b/chrome/browser/local_discovery/service_discovery_shared_client.cc index aa18368d..cdc48d9 100644 --- a/chrome/browser/local_discovery/service_discovery_shared_client.cc +++ b/chrome/browser/local_discovery/service_discovery_shared_client.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/local_discovery/service_discovery_shared_client.h" +#include <memory> + #include "build/build_config.h" #include "net/net_features.h" @@ -14,27 +16,25 @@ #include "base/timer/elapsed_timer.h" #include "chrome/installer/util/browser_distribution.h" #include "chrome/installer/util/firewall_manager_win.h" -#endif // OS_WIN +#endif #if defined(OS_MACOSX) #include "chrome/browser/local_discovery/service_discovery_client_mac_factory.h" #endif #if BUILDFLAG(ENABLE_MDNS) +#include "base/memory/ref_counted.h" #include "chrome/browser/local_discovery/service_discovery_client_mdns.h" -#endif // ENABLE_MDNS +#endif + +namespace local_discovery { + +using content::BrowserThread; namespace { #if defined(OS_WIN) - -bool g_is_firewall_ready = false; -bool g_is_firewall_state_reported = false; - void ReportFirewallStats() { - if (g_is_firewall_state_reported) - return; - g_is_firewall_state_reported = true; base::FilePath exe_path; if (!PathService::Get(base::FILE_EXE, &exe_path)) return; @@ -44,21 +44,14 @@ exe_path); if (!manager) return; - g_is_firewall_ready = manager->CanUseLocalPorts(); + bool is_firewall_ready = manager->CanUseLocalPorts(); UMA_HISTOGRAM_TIMES("LocalDiscovery.FirewallAccessTime", timer.Elapsed()); - UMA_HISTOGRAM_BOOLEAN("LocalDiscovery.IsFirewallReady", g_is_firewall_ready); + UMA_HISTOGRAM_BOOLEAN("LocalDiscovery.IsFirewallReady", is_firewall_ready); } -#endif // OS_WIN +#endif // defined(OS_WIN) -} // namespace +ServiceDiscoverySharedClient* g_service_discovery_client = nullptr; - -namespace local_discovery { - -using content::BrowserThread; - -namespace { -ServiceDiscoverySharedClient* g_service_discovery_client = NULL; } // namespace ServiceDiscoverySharedClient::ServiceDiscoverySharedClient() { @@ -70,42 +63,35 @@ ServiceDiscoverySharedClient::~ServiceDiscoverySharedClient() { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_EQ(g_service_discovery_client, this); - g_service_discovery_client = NULL; + g_service_discovery_client = nullptr; } -#if BUILDFLAG(ENABLE_MDNS) || defined(OS_MACOSX) - +// static scoped_refptr<ServiceDiscoverySharedClient> ServiceDiscoverySharedClient::GetInstance() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - +#if BUILDFLAG(ENABLE_MDNS) || defined(OS_MACOSX) if (g_service_discovery_client) return g_service_discovery_client; #if defined(OS_WIN) - if (!g_is_firewall_state_reported) { + static bool is_firewall_state_reported = false; + if (!is_firewall_state_reported) { + is_firewall_state_reported = true; BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(&ReportFirewallStats)); } -#endif // OS_WIN +#endif // defined(OS_WIN) #if defined(OS_MACOSX) return ServiceDiscoveryClientMacFactory::CreateInstance(); -#else // OS_MACOSX - - return new ServiceDiscoveryClientMdns(); -#endif // OS_MACOSX -} - #else - -scoped_refptr<ServiceDiscoverySharedClient> - ServiceDiscoverySharedClient::GetInstance() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); + return make_scoped_refptr(new ServiceDiscoveryClientMdns()); +#endif // defined(OS_MACOSX) +#else NOTIMPLEMENTED(); - return NULL; + return nullptr; +#endif // BUILDFLAG(ENABLE_MDNS) || defined(OS_MACOSX) } -#endif // ENABLE_MDNS - } // namespace local_discovery
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.cc b/chrome/browser/media/android/remote/remote_media_player_bridge.cc index 531e3f4..6c3e609 100644 --- a/chrome/browser/media/android/remote/remote_media_player_bridge.cc +++ b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
@@ -262,7 +262,6 @@ // static bool RemoteMediaPlayerBridge::RegisterRemoteMediaPlayerBridge(JNIEnv* env) { bool ret = RegisterNativesImpl(env); - DCHECK(g_RemoteMediaPlayerBridge_clazz); return ret; }
diff --git a/chrome/browser/media/android/router/media_router_android_bridge.cc b/chrome/browser/media/android/router/media_router_android_bridge.cc index e56bbb59..4c57cde 100644 --- a/chrome/browser/media/android/router/media_router_android_bridge.cc +++ b/chrome/browser/media/android/router/media_router_android_bridge.cc
@@ -29,7 +29,6 @@ // static bool MediaRouterAndroidBridge::Register(JNIEnv* env) { bool ret = RegisterNativesImpl(env); - DCHECK(g_ChromeMediaRouter_clazz); return ret; }
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 1417d93..8b64aa7 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -778,10 +778,22 @@ } IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, LoadLoadableSession) { + // TODO(jrummell): Support file IO in mojo CDM. See http://crbug.com/479923 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + TestPlaybackCase(kExternalClearKeyKeySystem, kLoadableSession, kEnded); } IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, LoadUnknownSession) { + // TODO(jrummell): Support file IO in mojo CDM. See http://crbug.com/479923 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + TestPlaybackCase(kExternalClearKeyKeySystem, kUnknownSession, kEmeSessionNotFound); }
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc index f6badf40..c291525 100644 --- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc +++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -159,10 +159,6 @@ clear_key_exclusive_video_common_codecs_.push_back("vp09.03.10.10"); } - void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); - } - typedef std::vector<std::string> CodecVector; const CodecVector& no_codecs() const { return no_codecs_; }
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation_service_delegate_impl.cc index 58ac00d7..1f9262c 100644 --- a/chrome/browser/media/router/presentation_service_delegate_impl.cc +++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc
@@ -338,7 +338,7 @@ void SetDefaultPresentationUrls( const RenderFrameHostId& render_frame_host_id, const std::vector<GURL>& default_presentation_urls, - const content::PresentationConnectionCallback& callback); + content::DefaultPresentationConnectionCallback callback); void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id, DelegateObserver* observer); void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id); @@ -405,7 +405,7 @@ std::unique_ptr<PresentationRequest> default_presentation_request_; // Callback to invoke when default presentation has started. - content::PresentationConnectionCallback + content::DefaultPresentationConnectionCallback default_presentation_started_callback_; // References to the observers listening for changes to this tab WebContent's @@ -508,7 +508,7 @@ void PresentationFrameManager::SetDefaultPresentationUrls( const RenderFrameHostId& render_frame_host_id, const std::vector<GURL>& default_presentation_urls, - const content::PresentationConnectionCallback& callback) { + content::DefaultPresentationConnectionCallback callback) { if (!IsMainFrame(render_frame_host_id)) return; @@ -667,10 +667,10 @@ int render_process_id, int render_frame_id, const std::vector<GURL>& default_presentation_urls, - const content::PresentationConnectionCallback& callback) { + content::DefaultPresentationConnectionCallback callback) { RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id); frame_manager_->SetDefaultPresentationUrls( - render_frame_host_id, default_presentation_urls, callback); + render_frame_host_id, default_presentation_urls, std::move(callback)); } void PresentationServiceDelegateImpl::OnJoinRouteResponse( @@ -678,11 +678,11 @@ int render_frame_id, const GURL& presentation_url, const std::string& presentation_id, - const content::PresentationConnectionCallback& success_cb, - const content::PresentationConnectionErrorCallback& error_cb, + content::PresentationConnectionCallback success_cb, + content::PresentationConnectionErrorCallback error_cb, const RouteRequestResult& result) { if (!result.route()) { - error_cb.Run(content::PresentationError( + std::move(error_cb).Run(content::PresentationError( content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND, result.error())); } else { DVLOG(1) << "OnJoinRouteResponse: " @@ -695,14 +695,14 @@ frame_manager_->OnPresentationConnection( RenderFrameHostId(render_process_id, render_frame_id), presentation_info, *result.route()); - success_cb.Run(presentation_info); + std::move(success_cb).Run(presentation_info); } } void PresentationServiceDelegateImpl::OnStartPresentationSucceeded( int render_process_id, int render_frame_id, - const content::PresentationConnectionCallback& success_cb, + content::PresentationConnectionCallback success_cb, const content::PresentationInfo& new_presentation_info, const MediaRoute& route) { DVLOG(1) << "OnStartPresentationSucceeded: " @@ -712,18 +712,19 @@ frame_manager_->OnPresentationConnection( RenderFrameHostId(render_process_id, render_frame_id), new_presentation_info, route); - success_cb.Run(new_presentation_info); + std::move(success_cb).Run(new_presentation_info); } void PresentationServiceDelegateImpl::StartPresentation( int render_process_id, int render_frame_id, const std::vector<GURL>& presentation_urls, - const content::PresentationConnectionCallback& success_cb, - const content::PresentationConnectionErrorCallback& error_cb) { + content::PresentationConnectionCallback success_cb, + content::PresentationConnectionErrorCallback error_cb) { if (presentation_urls.empty()) { - error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN, - "Invalid presentation arguments.")); + std::move(error_cb).Run( + content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN, + "Invalid presentation arguments.")); return; } @@ -732,7 +733,7 @@ if (presentation_urls.empty() || std::find_if_not(presentation_urls.begin(), presentation_urls.end(), IsValidPresentationUrl) != presentation_urls.end()) { - error_cb.Run(content::PresentationError( + std::move(error_cb).Run(content::PresentationError( content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND, "Invalid presentation URL.")); return; @@ -743,18 +744,18 @@ new CreatePresentationConnectionRequest( render_frame_host_id, presentation_urls, GetLastCommittedURLForFrame(render_frame_host_id), - base::Bind( + base::BindOnce( &PresentationServiceDelegateImpl::OnStartPresentationSucceeded, weak_factory_.GetWeakPtr(), render_process_id, render_frame_id, - success_cb), - error_cb)); + std::move(success_cb)), + std::move(error_cb))); MediaRouterDialogController* controller = MediaRouterDialogController::GetOrCreateForWebContents(web_contents_); if (!controller->ShowMediaRouterDialogForPresentation(std::move(request))) { LOG(ERROR) << "Media router dialog already exists. Ignoring StartPresentation."; - error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN, - "Unable to create dialog.")); + std::move(error_cb).Run(content::PresentationError( + content::PRESENTATION_ERROR_UNKNOWN, "Unable to create dialog.")); return; } } @@ -764,11 +765,11 @@ int render_frame_id, const std::vector<GURL>& presentation_urls, const std::string& presentation_id, - const content::PresentationConnectionCallback& success_cb, - const content::PresentationConnectionErrorCallback& error_cb) { + content::PresentationConnectionCallback success_cb, + content::PresentationConnectionErrorCallback error_cb) { DVLOG(2) << "PresentationServiceDelegateImpl::ReconnectPresentation"; if (presentation_urls.empty()) { - error_cb.Run(content::PresentationError( + std::move(error_cb).Run(content::PresentationError( content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND, "Invalid presentation arguments.")); return; @@ -780,7 +781,7 @@ #if !defined(OS_ANDROID) if (IsAutoJoinPresentationId(presentation_id) && ShouldCancelAutoJoinForOrigin(origin)) { - error_cb.Run(content::PresentationError( + std::move(error_cb).Run(content::PresentationError( content::PRESENTATION_ERROR_PRESENTATION_REQUEST_CANCELLED, "Auto-join request cancelled by user preferences.")); return; @@ -809,17 +810,18 @@ auto result = RouteRequestResult::FromSuccess(*route, presentation_id); OnJoinRouteResponse(render_process_id, render_frame_id, - presentation_urls[0], presentation_id, success_cb, - error_cb, *result); + presentation_urls[0], presentation_id, + std::move(success_cb), std::move(error_cb), *result); } else { // TODO(crbug.com/627655): Handle multiple URLs. const GURL& presentation_url = presentation_urls[0]; bool incognito = web_contents_->GetBrowserContext()->IsOffTheRecord(); std::vector<MediaRouteResponseCallback> route_response_callbacks; - route_response_callbacks.push_back(base::BindOnce( - &PresentationServiceDelegateImpl::OnJoinRouteResponse, - weak_factory_.GetWeakPtr(), render_process_id, render_frame_id, - presentation_url, presentation_id, success_cb, error_cb)); + route_response_callbacks.push_back( + base::BindOnce(&PresentationServiceDelegateImpl::OnJoinRouteResponse, + weak_factory_.GetWeakPtr(), render_process_id, + render_frame_id, presentation_url, presentation_id, + std::move(success_cb), std::move(error_cb))); router_->JoinRoute(MediaSourceForPresentationUrl(presentation_url).id(), presentation_id, origin, web_contents_, std::move(route_response_callbacks), base::TimeDelta(),
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.h b/chrome/browser/media/router/presentation_service_delegate_impl.h index aa45a23..0e368db7 100644 --- a/chrome/browser/media/router/presentation_service_delegate_impl.h +++ b/chrome/browser/media/router/presentation_service_delegate_impl.h
@@ -95,20 +95,20 @@ int render_process_id, int render_frame_id, const std::vector<GURL>& default_presentation_urls, - const content::PresentationConnectionCallback& callback) override; + content::DefaultPresentationConnectionCallback callback) override; void StartPresentation( int render_process_id, int render_frame_id, const std::vector<GURL>& presentation_urls, - const content::PresentationConnectionCallback& success_cb, - const content::PresentationConnectionErrorCallback& error_cb) override; + content::PresentationConnectionCallback success_cb, + content::PresentationConnectionErrorCallback error_cb) override; void ReconnectPresentation( int render_process_id, int render_frame_id, const std::vector<GURL>& presentation_urls, const std::string& presentation_id, - const content::PresentationConnectionCallback& success_cb, - const content::PresentationConnectionErrorCallback& error_cb) override; + content::PresentationConnectionCallback success_cb, + content::PresentationConnectionErrorCallback error_cb) override; void CloseConnection(int render_process_id, int render_frame_id, const std::string& presentation_id) override; @@ -196,14 +196,14 @@ int render_frame_id, const GURL& presentation_url, const std::string& presentation_id, - const content::PresentationConnectionCallback& success_cb, - const content::PresentationConnectionErrorCallback& error_cb, + content::PresentationConnectionCallback success_cb, + content::PresentationConnectionErrorCallback error_cb, const RouteRequestResult& result); void OnStartPresentationSucceeded( int render_process_id, int render_frame_id, - const content::PresentationConnectionCallback& success_cb, + content::PresentationConnectionCallback success_cb, const content::PresentationInfo& new_presentation_info, const MediaRoute& route);
diff --git a/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc b/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc index 89b7897..7b2723e 100644 --- a/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc +++ b/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
@@ -85,7 +85,6 @@ // FILE thread's tasks being marked as shutdown blocking for legacy // reasons). file_system_context_ = nullptr; - InProcessBrowserTest::TearDownOnMainThread(); } // Write |content| into |filename| in a test file system and try to move
diff --git a/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.cc b/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.cc index 8009a708..2893bc92 100644 --- a/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.cc +++ b/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.cc
@@ -9,7 +9,6 @@ #include "base/single_thread_task_runner.h" #include "build/build_config.h" #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" -#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/extensions/chrome_utility_extensions_messages.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc index 89f96c80..a8e0dbd 100644 --- a/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc +++ b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/logging.h" #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" -#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/extensions/chrome_utility_extensions_messages.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 0899036..9da2ed18 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -316,13 +316,13 @@ start_time_(base::TimeTicks::Now()), has_uploaded_profiler_data_(false), weak_ptr_factory_(this) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); RecordCommandLineMetrics(); RegisterForNotifications(); } ChromeMetricsServiceClient::~ChromeMetricsServiceClient() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::GlobalHistogramAllocator* allocator = base::GlobalHistogramAllocator::Get(); if (allocator) { @@ -517,7 +517,7 @@ void ChromeMetricsServiceClient::CollectFinalMetricsForLog( const base::Closure& done_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); collect_final_metrics_done_callback_ = done_callback; @@ -790,7 +790,7 @@ } void ChromeMetricsServiceClient::CollectFinalHistograms() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Begin the multi-step process of collecting memory usage histograms: // First spawn a task to collect the memory details; when that task is @@ -814,7 +814,7 @@ } void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // This function should only be called as the callback from an ansynchronous // step. @@ -859,7 +859,7 @@ } void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // This function should only be called as the callback from an ansynchronous // step. @@ -936,9 +936,12 @@ profile, new ukm::debug::DebugPage(base::Bind( &BindableGetUkmService, weak_ptr_factory_.GetWeakPtr()))); #if defined(OS_CHROMEOS) - // Ignore the signin profile for sync disables / history deletion. - if (chromeos::ProfileHelper::IsSigninProfile(profile)) + // Ignore the signin and lock screen app profile for sync disables / history + // deletion. + if (chromeos::ProfileHelper::IsSigninProfile(profile) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { return; + } #endif history::HistoryService* history_service = HistoryServiceFactory::GetForProfile(profile, @@ -954,7 +957,7 @@ int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); switch (type) { case chrome::NOTIFICATION_BROWSER_OPENED:
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.h b/chrome/browser/metrics/chrome_metrics_service_client.h index bfb2ccd..293b6ee 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.h +++ b/chrome/browser/metrics/chrome_metrics_service_client.h
@@ -15,7 +15,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" +#include "base/sequence_checker.h" #include "build/build_config.h" #include "chrome/browser/metrics/metrics_memory_details.h" #include "components/metrics/metrics_log_uploader.h" @@ -171,7 +171,7 @@ void CountBrowserCrashDumpAttempts(); #endif // OS_WIN - base::ThreadChecker thread_checker_; + SEQUENCE_CHECKER(sequence_checker_); // Weak pointer to the MetricsStateManager. metrics::MetricsStateManager* metrics_state_manager_;
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.cc b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.cc index 5f436cc6..4784bdee 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.cc +++ b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.cc
@@ -55,6 +55,14 @@ } } +void DesktopSessionDurationTracker::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void DesktopSessionDurationTracker::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + void DesktopSessionDurationTracker::OnUserEvent() { if (!is_visible_) return; @@ -117,6 +125,9 @@ is_first_session_ = false; session_start_ = base::TimeTicks::Now(); StartTimer(inactivity_timeout_); + + for (Observer& observer : observer_list_) + observer.OnSessionStarted(session_start_); } void DesktopSessionDurationTracker::EndSession( @@ -131,6 +142,9 @@ if (delta < kZeroTime) delta = kZeroTime; + for (Observer& observer : observer_list_) + observer.OnSessionEnded(delta); + DVLOG(4) << "Logging session length of " << delta.InSeconds() << " seconds."; // Note: This metric is recorded separately for Android in
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h index 53776789..3c1fcb4 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h +++ b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/metrics/desktop_session_duration/audible_contents_tracker.h" @@ -18,6 +19,14 @@ // visibility, audio and user interaction. class DesktopSessionDurationTracker : public AudibleContentsTracker::Observer { public: + // The methods for the observer will be called on the UI thread. + class Observer { + public: + virtual ~Observer() {} + virtual void OnSessionStarted(base::TimeTicks session_start) {} + virtual void OnSessionEnded(base::TimeDelta session_length) {} + }; + // Creates the |DesktopSessionDurationTracker| instance and initializes the // observers that notify to it. static void Initialize(); @@ -45,6 +54,10 @@ inactivity_timeout_ = base::TimeDelta::FromSeconds(seconds); } + // For observing the status of the session tracker. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + protected: DesktopSessionDurationTracker(); ~DesktopSessionDurationTracker() override; @@ -89,6 +102,8 @@ base::OneShotTimer timer_; + base::ObserverList<Observer> observer_list_; + ChromeVisibilityObserver visibility_observer_; AudibleContentsTracker audio_tracker_;
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc index a828849..1514fad 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc +++ b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc
@@ -40,6 +40,31 @@ DISALLOW_COPY_AND_ASSIGN(MockDesktopSessionDurationTracker); }; +// Mock class for |DesktopSessionDurationTracker::Observer| for testing. +class MockDesktopSessionObserver + : public metrics::DesktopSessionDurationTracker::Observer { + public: + MockDesktopSessionObserver() {} + + bool session_started_seen() const { return session_started_seen_; } + bool session_ended_seen() const { return session_ended_seen_; } + + protected: + // metrics::DesktopSessionDurationTracker::Observer: + void OnSessionStarted(base::TimeTicks session_start) override { + session_started_seen_ = true; + } + void OnSessionEnded(base::TimeDelta session_length) override { + session_ended_seen_ = true; + } + + private: + bool session_started_seen_ = false; + bool session_ended_seen_ = false; + + DISALLOW_COPY_AND_ASSIGN(MockDesktopSessionObserver); +}; + class DesktopSessionDurationTrackerTest : public testing::Test { public: DesktopSessionDurationTrackerTest() @@ -55,6 +80,7 @@ base::HistogramTester histogram_tester_; MockDesktopSessionDurationTracker instance_; + MockDesktopSessionObserver observer_; private: base::MessageLoop loop_; @@ -206,3 +232,34 @@ ExpectTotalDuration(after_session_end - before_session_start - kDelay); } + +TEST_F(DesktopSessionDurationTrackerTest, TestObserver) { + instance_.SetInactivityTimeoutForTesting(1); + + instance_.AddObserver(&observer_); + + EXPECT_FALSE(instance_.in_session()); + EXPECT_FALSE(instance_.is_visible()); + EXPECT_FALSE(observer_.session_started_seen()); + EXPECT_FALSE(observer_.session_ended_seen()); + histogram_tester_.ExpectTotalCount("Session.TotalDuration", 0); + + instance_.OnVisibilityChanged(true, kZeroTime); + instance_.OnUserEvent(); + EXPECT_TRUE(instance_.in_session()); + EXPECT_TRUE(instance_.is_visible()); + EXPECT_FALSE(observer_.session_ended_seen()); + EXPECT_TRUE(observer_.session_started_seen()); + histogram_tester_.ExpectTotalCount("Session.TotalDuration", 0); + + // Wait until the session expires. + while (!instance_.is_timeout()) { + base::RunLoop().RunUntilIdle(); + } + + EXPECT_FALSE(instance_.in_session()); + EXPECT_TRUE(instance_.is_visible()); + EXPECT_TRUE(observer_.session_started_seen()); + EXPECT_TRUE(observer_.session_ended_seen()); + histogram_tester_.ExpectTotalCount("Session.TotalDuration", 1); +}
diff --git a/chrome/browser/metrics/thread_watcher_unittest.cc b/chrome/browser/metrics/thread_watcher_unittest.cc index 20349ba..271b96c 100644 --- a/chrome/browser/metrics/thread_watcher_unittest.cc +++ b/chrome/browser/metrics/thread_watcher_unittest.cc
@@ -246,22 +246,22 @@ static const TimeDelta kSleepTime; static const TimeDelta kUnresponsiveTime; static const char kIOThreadName[]; - static const char kDBThreadName[]; + static const char kUIThreadName[]; static const char kCrashOnHangThreadNames[]; static const char kThreadNamesAndLiveThreshold[]; static const char kCrashOnHangThreadData[]; CustomThreadWatcher* io_watcher_; - CustomThreadWatcher* db_watcher_; + CustomThreadWatcher* ui_watcher_; ThreadWatcherList* thread_watcher_list_; ThreadWatcherTest() : setup_complete_(&lock_), initialized_(false) { - db_thread_.reset(new content::TestBrowserThread(BrowserThread::DB)); + ui_thread_.reset(new content::TestBrowserThread(BrowserThread::UI)); io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO)); watchdog_thread_.reset(new WatchDogThread()); - db_thread_->StartAndWaitForTesting(); + ui_thread_->StartAndWaitForTesting(); io_thread_->StartAndWaitForTesting(); watchdog_thread_->StartAndWaitForTesting(); @@ -288,15 +288,14 @@ EXPECT_EQ(io_watcher_, registered_io_watcher); EXPECT_EQ(io_watcher_, thread_watcher_list_->Find(BrowserThread::IO)); - // Create thread watcher object for the DB thread. - std::unique_ptr<CustomThreadWatcher> db_watcher( - new CustomThreadWatcher(BrowserThread::DB, kDBThreadName, - kSleepTime, kUnresponsiveTime)); - db_watcher_ = db_watcher.get(); - ThreadWatcher* registered_db_watcher = - ThreadWatcherList::Register(std::move(db_watcher)); - EXPECT_EQ(db_watcher_, registered_db_watcher); - EXPECT_EQ(db_watcher_, thread_watcher_list_->Find(BrowserThread::DB)); + // Create thread watcher object for the UI thread. + std::unique_ptr<CustomThreadWatcher> ui_watcher(new CustomThreadWatcher( + BrowserThread::UI, kUIThreadName, kSleepTime, kUnresponsiveTime)); + ui_watcher_ = ui_watcher.get(); + ThreadWatcher* registered_ui_watcher = + ThreadWatcherList::Register(std::move(ui_watcher)); + EXPECT_EQ(ui_watcher_, registered_ui_watcher); + EXPECT_EQ(ui_watcher_, thread_watcher_list_->Find(BrowserThread::UI)); { base::AutoLock lock(lock_); @@ -318,9 +317,9 @@ ~ThreadWatcherTest() override { ThreadWatcherList::DeleteAll(); io_watcher_ = nullptr; - db_watcher_ = nullptr; + ui_watcher_ = nullptr; io_thread_.reset(); - db_thread_.reset(); + ui_thread_.reset(); watchdog_thread_.reset(); thread_watcher_list_ = nullptr; } @@ -330,7 +329,7 @@ base::Lock lock_; base::ConditionVariable setup_complete_; bool initialized_; - std::unique_ptr<content::TestBrowserThread> db_thread_; + std::unique_ptr<content::TestBrowserThread> ui_thread_; std::unique_ptr<content::TestBrowserThread> io_thread_; std::unique_ptr<WatchDogThread> watchdog_thread_; @@ -342,7 +341,7 @@ const TimeDelta ThreadWatcherTest::kUnresponsiveTime = TimeDelta::FromMilliseconds(500); const char ThreadWatcherTest::kIOThreadName[] = "IO"; -const char ThreadWatcherTest::kDBThreadName[] = "DB"; +const char ThreadWatcherTest::kUIThreadName[] = "UI"; const char ThreadWatcherTest::kCrashOnHangThreadNames[] = "UI,IO"; const char ThreadWatcherTest::kThreadNamesAndLiveThreshold[] = "UI:4,IO:4"; const char ThreadWatcherTest::kCrashOnHangThreadData[] = @@ -460,12 +459,12 @@ EXPECT_EQ(kUnresponsiveTime, io_watcher_->unresponsive_time()); EXPECT_FALSE(io_watcher_->active()); - // Check ThreadWatcher object of watched DB thread has correct data. - EXPECT_EQ(BrowserThread::DB, db_watcher_->thread_id()); - EXPECT_EQ(kDBThreadName, db_watcher_->thread_name()); - EXPECT_EQ(kSleepTime, db_watcher_->sleep_time()); - EXPECT_EQ(kUnresponsiveTime, db_watcher_->unresponsive_time()); - EXPECT_FALSE(db_watcher_->active()); + // Check ThreadWatcher object of watched UI thread has correct data. + EXPECT_EQ(BrowserThread::UI, ui_watcher_->thread_id()); + EXPECT_EQ(kUIThreadName, ui_watcher_->thread_name()); + EXPECT_EQ(kSleepTime, ui_watcher_->sleep_time()); + EXPECT_EQ(kUnresponsiveTime, ui_watcher_->unresponsive_time()); + EXPECT_FALSE(ui_watcher_->active()); } // Test ActivateThreadWatching and DeActivateThreadWatching of IO thread. This @@ -546,11 +545,10 @@ // Test watching of multiple threads with all threads not responding. TEST_F(ThreadWatcherTest, MultipleThreadsResponding) { - // Check for DB thread to perform ping/pong messaging. - WatchDogThread::PostTask( - FROM_HERE, - base::Bind(&ThreadWatcher::ActivateThreadWatching, - base::Unretained(db_watcher_))); + // Check for UI thread to perform ping/pong messaging. + WatchDogThread::PostTask(FROM_HERE, + base::Bind(&ThreadWatcher::ActivateThreadWatching, + base::Unretained(ui_watcher_))); // Check for IO thread to perform ping/pong messaging. WatchDogThread::PostTask( @@ -558,16 +556,16 @@ base::Bind(&ThreadWatcher::ActivateThreadWatching, base::Unretained(io_watcher_))); - // Verify DB thread is responding with ping/pong messaging. - db_watcher_->WaitForCheckResponse( + // Verify UI thread is responding with ping/pong messaging. + ui_watcher_->WaitForCheckResponse( kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL); - EXPECT_GT(db_watcher_->ping_sent_, static_cast<uint64_t>(0)); - EXPECT_GT(db_watcher_->pong_received_, static_cast<uint64_t>(0)); - EXPECT_GE(db_watcher_->ping_sequence_number_, static_cast<uint64_t>(0)); - EXPECT_GT(base::subtle::NoBarrier_Load(&(db_watcher_->success_response_)), - static_cast<base::subtle::Atomic32>(0)); - EXPECT_EQ(base::subtle::NoBarrier_Load(&(db_watcher_->failed_response_)), - static_cast<base::subtle::Atomic32>(0)); + EXPECT_GT(ui_watcher_->ping_sent_, static_cast<uint64_t>(0)); + EXPECT_GT(ui_watcher_->pong_received_, static_cast<uint64_t>(0)); + EXPECT_GE(ui_watcher_->ping_sequence_number_, static_cast<uint64_t>(0)); + EXPECT_GT(base::subtle::NoBarrier_Load(&(ui_watcher_->success_response_)), + static_cast<base::subtle::Atomic32>(0)); + EXPECT_EQ(base::subtle::NoBarrier_Load(&(ui_watcher_->failed_response_)), + static_cast<base::subtle::Atomic32>(0)); // Verify IO thread is responding with ping/pong messaging. io_watcher_->WaitForCheckResponse( @@ -586,10 +584,9 @@ base::Bind(&ThreadWatcher::DeActivateThreadWatching, base::Unretained(io_watcher_))); - WatchDogThread::PostTask( - FROM_HERE, - base::Bind(&ThreadWatcher::DeActivateThreadWatching, - base::Unretained(db_watcher_))); + WatchDogThread::PostTask(FROM_HERE, + base::Bind(&ThreadWatcher::DeActivateThreadWatching, + base::Unretained(ui_watcher_))); } // Test watching of multiple threads with one of the threads not responding. @@ -603,11 +600,10 @@ base::BindOnce(&CustomThreadWatcher::VeryLongMethod, base::Unretained(io_watcher_), kUnresponsiveTime * 10)); - // Activate watching of DB thread. - WatchDogThread::PostTask( - FROM_HERE, - base::Bind(&ThreadWatcher::ActivateThreadWatching, - base::Unretained(db_watcher_))); + // Activate watching of UI thread. + WatchDogThread::PostTask(FROM_HERE, + base::Bind(&ThreadWatcher::ActivateThreadWatching, + base::Unretained(ui_watcher_))); // Activate watching of IO thread. WatchDogThread::PostTask( @@ -615,13 +611,13 @@ base::Bind(&ThreadWatcher::ActivateThreadWatching, base::Unretained(io_watcher_))); - // Verify DB thread is responding with ping/pong messaging. - db_watcher_->WaitForCheckResponse( + // Verify UI thread is responding with ping/pong messaging. + ui_watcher_->WaitForCheckResponse( kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL); - EXPECT_GT(base::subtle::NoBarrier_Load(&(db_watcher_->success_response_)), - static_cast<base::subtle::Atomic32>(0)); - EXPECT_EQ(base::subtle::NoBarrier_Load(&(db_watcher_->failed_response_)), - static_cast<base::subtle::Atomic32>(0)); + EXPECT_GT(base::subtle::NoBarrier_Load(&(ui_watcher_->success_response_)), + static_cast<base::subtle::Atomic32>(0)); + EXPECT_EQ(base::subtle::NoBarrier_Load(&(ui_watcher_->failed_response_)), + static_cast<base::subtle::Atomic32>(0)); // Verify IO thread is not responding for ping messages. io_watcher_->WaitForCheckResponse( @@ -636,10 +632,9 @@ FROM_HERE, base::Bind(&ThreadWatcher::DeActivateThreadWatching, base::Unretained(io_watcher_))); - WatchDogThread::PostTask( - FROM_HERE, - base::Bind(&ThreadWatcher::DeActivateThreadWatching, - base::Unretained(db_watcher_))); + WatchDogThread::PostTask(FROM_HERE, + base::Bind(&ThreadWatcher::DeActivateThreadWatching, + base::Unretained(ui_watcher_))); // Wait for the io_watcher_'s VeryLongMethod to finish. io_watcher_->WaitForWaitStateChange(kUnresponsiveTime * 10, ALL_DONE);
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc index d1d7e8a..362e0fa 100644 --- a/chrome/browser/net/predictor_browsertest.cc +++ b/chrome/browser/net/predictor_browsertest.cc
@@ -514,7 +514,6 @@ void SetUpInProcessBrowserTestFixture() override { scoped_host_resolver_proc_.reset(new net::ScopedDefaultHostResolverProc( rule_based_resolver_proc_.get())); - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); } void SetUpCommandLine(base::CommandLine* command_line) override { @@ -605,7 +604,6 @@ } void TearDownInProcessBrowserTestFixture() override { - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); scoped_host_resolver_proc_.reset(); }
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux_unittest.cc b/chrome/browser/notifications/notification_platform_bridge_linux_unittest.cc index aeae250..c179e06 100644 --- a/chrome/browser/notifications/notification_platform_bridge_linux_unittest.cc +++ b/chrome/browser/notifications/notification_platform_bridge_linux_unittest.cc
@@ -26,6 +26,7 @@ #include "ui/gfx/image/image_skia.h" using testing::_; +using testing::ByMove; using testing::Return; using testing::StrictMock; @@ -155,9 +156,9 @@ return request; } -dbus::Response* GetIdResponse(uint32_t id) { - dbus::Response* response = dbus::Response::CreateEmpty().release(); - dbus::MessageWriter writer(response); +std::unique_ptr<dbus::Response> GetIdResponse(uint32_t id) { + std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); + dbus::MessageWriter writer(response.get()); writer.AppendUint32(id); return response; } @@ -167,15 +168,6 @@ arg3.Run("" /* interface_name */, "" /* signal_name */, true /* success */); } -ACTION_P(OnGetCapabilities, capabilities) { - // MockObjectProxy::CallMethodAndBlock will wrap the return value in - // a unique_ptr. - dbus::Response* response = dbus::Response::CreateEmpty().release(); - dbus::MessageWriter writer(response); - writer.AppendArrayOfStrings(capabilities); - return response; -} - ACTION_P2(OnNotify, verifier, id) { verifier(ParseRequest(arg0)); return GetIdResponse(id); @@ -190,7 +182,7 @@ EXPECT_TRUE(reader.PopUint32(&uint32)); EXPECT_FALSE(reader.HasMoreData()); - return dbus::Response::CreateEmpty().release(); + return dbus::Response::CreateEmpty(); } ACTION_P(OnNotificationBridgeReady, success) { @@ -242,9 +234,12 @@ dbus::ObjectPath(kFreedesktopNotificationsPath))) .WillOnce(Return(mock_notification_proxy_.get())); + std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); + dbus::MessageWriter writer(response.get()); + writer.AppendArrayOfStrings(capabilities); EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("GetCapabilities"), _)) - .WillOnce(OnGetCapabilities(capabilities)); + CallMethodAndBlock(Calls("GetCapabilities"), _)) + .WillOnce(Return(ByMove(std::move(response)))); if (connect_signals) { EXPECT_CALL( @@ -295,10 +290,10 @@ TEST_F(NotificationPlatformBridgeLinuxTest, NotifyAndCloseFormat) { EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("Notify"), _)) + CallMethodAndBlock(Calls("Notify"), _)) .WillOnce(OnNotify([](const NotificationRequest&) {}, 1)); EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("CloseNotification"), _)) + CallMethodAndBlock(Calls("CloseNotification"), _)) .WillOnce(OnCloseNotification()); CreateNotificationBridgeLinux(); @@ -310,7 +305,7 @@ TEST_F(NotificationPlatformBridgeLinuxTest, ProgressPercentageAddedToSummary) { EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("Notify"), _)) + CallMethodAndBlock(Calls("Notify"), _)) .WillOnce(OnNotify( [](const NotificationRequest& request) { EXPECT_EQ( @@ -331,7 +326,7 @@ TEST_F(NotificationPlatformBridgeLinuxTest, NotificationListItemsInBody) { EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("Notify"), _)) + CallMethodAndBlock(Calls("Notify"), _)) .WillOnce(OnNotify( [](const NotificationRequest& request) { EXPECT_EQ("<b>abc</b> 123\n<b>def</b> 456", request.body); @@ -353,7 +348,7 @@ const int32_t kExpireTimeoutDefault = -1; const int32_t kExpireTimeoutNever = 0; EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("Notify"), _)) + CallMethodAndBlock(Calls("Notify"), _)) .WillOnce(OnNotify( [=](const NotificationRequest& request) { EXPECT_EQ(kExpireTimeoutDefault, request.expire_timeout); @@ -387,7 +382,7 @@ gfx::Image(CreateImageSkia(original_width, original_height)); EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("Notify"), _)) + CallMethodAndBlock(Calls("Notify"), _)) .WillOnce(OnNotify( [=](const NotificationRequest& request) { std::string file_name; @@ -416,7 +411,7 @@ TEST_F(NotificationPlatformBridgeLinuxTest, NotificationAttribution) { EXPECT_CALL(*mock_notification_proxy_.get(), - MockCallMethodAndBlock(Calls("Notify"), _)) + CallMethodAndBlock(Calls("Notify"), _)) .WillOnce(OnNotify( [](const NotificationRequest& request) { EXPECT_EQ(
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index 0b6f6cd0..21a04dc2 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -838,7 +838,6 @@ scoped_feature_list_.InitWithFeatures( {}, {features::kNotificationContentImage}); #endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); } private:
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc index 23fc12c..0c5d528 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -91,6 +91,8 @@ void(WebContents*, const GURL&, const std::string&, bool)); MOCK_METHOD3(ShowPhishingInterstitial, void(const GURL&, const std::string&, content::WebContents*)); + MOCK_METHOD0(GetSyncAccountType, + safe_browsing::PasswordProtectionService::SyncAccountType()); private: DISALLOW_COPY_AND_ASSIGN(MockPasswordProtectionService);
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc index da7d448..9852deb5 100644 --- a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc +++ b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc
@@ -337,10 +337,10 @@ std::set<std::string> failing_methods_; private: - dbus::Response* KLauncherMethodCall( + std::unique_ptr<dbus::Response> KLauncherMethodCall( dbus::MethodCall* method_call, testing::Unused); - dbus::Response* KWalletMethodCall( + std::unique_ptr<dbus::Response> KWalletMethodCall( dbus::MethodCall* method_call, testing::Unused); }; @@ -353,7 +353,7 @@ new dbus::MockObjectProxy(mock_session_bus_.get(), "org.kde.klauncher", dbus::ObjectPath("/KLauncher")); - EXPECT_CALL(*mock_klauncher_proxy_.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_klauncher_proxy_.get(), CallMethodAndBlock(_, _)) .WillRepeatedly( Invoke(this, &NativeBackendKWalletTest::KLauncherMethodCall)); @@ -368,7 +368,7 @@ "org.kde.kwalletd", dbus::ObjectPath("/modules/kwalletd")); } - EXPECT_CALL(*mock_kwallet_proxy_.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_kwallet_proxy_.get(), CallMethodAndBlock(_, _)) .WillRepeatedly( Invoke(this, &NativeBackendKWalletTest::KWalletMethodCall)); @@ -460,7 +460,7 @@ CheckPasswordForms("Chrome Form Data (42)", ExpectationArray()); } -dbus::Response* NativeBackendKWalletTest::KLauncherMethodCall( +std::unique_ptr<dbus::Response> NativeBackendKWalletTest::KLauncherMethodCall( dbus::MethodCall* method_call, testing::Unused) { EXPECT_EQ("org.kde.KLauncher", method_call->GetInterface()); EXPECT_EQ("start_service_by_desktop_name", method_call->GetMember()); @@ -498,10 +498,10 @@ writer.AppendString(std::string()); // dbus_name writer.AppendString(klauncher_error_); writer.AppendInt32(1234); // pid - return response.release(); + return response; } -dbus::Response* NativeBackendKWalletTest::KWalletMethodCall( +std::unique_ptr<dbus::Response> NativeBackendKWalletTest::KWalletMethodCall( dbus::MethodCall* method_call, testing::Unused) { if (!kwallet_running_) return nullptr; @@ -618,7 +618,7 @@ } EXPECT_TRUE(response); - return response.release(); + return response; } void NativeBackendKWalletTest::CheckPasswordForms(
diff --git a/chrome/browser/payments/site_per_process_payments_browsertest.cc b/chrome/browser/payments/site_per_process_payments_browsertest.cc index ccf183e..3891334 100644 --- a/chrome/browser/payments/site_per_process_payments_browsertest.cc +++ b/chrome/browser/payments/site_per_process_payments_browsertest.cc
@@ -29,7 +29,6 @@ ~SitePerProcessPaymentsBrowserTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); // HTTPS server only serves a valid cert for localhost, so this is needed // to load pages from other hosts without an error. command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc index 86a3c39..05e3bff 100644 --- a/chrome/browser/permissions/permission_request_manager_browsertest.cc +++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -86,7 +86,6 @@ void TearDownOnMainThread() override { mock_permission_prompt_factory_.reset(); - InProcessBrowserTest::TearDownOnMainThread(); } PermissionRequestManager* GetPermissionRequestManager() {
diff --git a/chrome/browser/permissions/permission_update_infobar_delegate_android.cc b/chrome/browser/permissions/permission_update_infobar_delegate_android.cc index 8f2c885..f72bb1a 100644 --- a/chrome/browser/permissions/permission_update_infobar_delegate_android.cc +++ b/chrome/browser/permissions/permission_update_infobar_delegate_android.cc
@@ -14,7 +14,6 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/web_contents.h" #include "jni/PermissionUpdateInfoBarDelegate_jni.h" #include "ui/android/window_android.h" @@ -31,9 +30,7 @@ << "Caller should check ShouldShowPermissionInfobar before creating the " << "infobar."; - content::ContentViewCore* cvc = - content::ContentViewCore::FromWebContents(web_contents); - ui::WindowAndroid* window_android = cvc->GetWindowAndroid(); + auto* window_android = web_contents->GetNativeView()->GetWindowAndroid(); std::vector<std::string> permissions; int message_id = -1; @@ -105,11 +102,9 @@ if (!web_contents) return false; - content::ContentViewCore* cvc = - content::ContentViewCore::FromWebContents(web_contents); - if (!cvc || !cvc->GetWindowAndroid()) + auto* window_android = web_contents->GetNativeView()->GetWindowAndroid(); + if (!window_android) return false; - ui::WindowAndroid* window_android = cvc->GetWindowAndroid(); for (ContentSettingsType content_settings_type : content_settings_types) { std::vector<std::string> android_permissions;
diff --git a/chrome/browser/permissions/permissions_browsertest.cc b/chrome/browser/permissions/permissions_browsertest.cc index 92440a7..b9e609a 100644 --- a/chrome/browser/permissions/permissions_browsertest.cc +++ b/chrome/browser/permissions/permissions_browsertest.cc
@@ -34,8 +34,6 @@ void PermissionsBrowserTest::TearDownOnMainThread() { prompt_factory_.reset(); - - InProcessBrowserTest::TearDownOnMainThread(); } bool PermissionsBrowserTest::RunScriptReturnBool(const std::string& script) {
diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc index a595184..53c85a9 100644 --- a/chrome/browser/policy/profile_policy_connector.cc +++ b/chrome/browser/policy/profile_policy_connector.cc
@@ -98,11 +98,12 @@ #if defined(OS_CHROMEOS) if (!user) { DCHECK(schema_registry); - // This case occurs for the signin profile. + // This case occurs for the signin and the lock screen app profiles. special_user_policy_provider_.reset( new LoginProfilePolicyProvider(connector->GetPolicyService())); } else { - // |user| should never be nullptr except for the signin profile. + // |user| should never be nullptr except for the signin and the lock screen + // app profile. is_primary_user_ = user == user_manager::UserManager::Get()->GetPrimaryUser(); // Note that |DeviceLocalAccountPolicyProvider::Create| returns nullptr when @@ -179,8 +180,8 @@ return policy_store_; #if defined(OS_CHROMEOS) if (special_user_policy_provider_) { - // |special_user_policy_provider_| is non-null for device-local accounts and - // for the login profile. + // |special_user_policy_provider_| is non-null for device-local accounts, + // for the login profile, and the lock screen app profile. const DeviceCloudPolicyManagerChromeOS* const device_cloud_policy_manager = g_browser_process->platform_part() ->browser_policy_connector_chromeos()
diff --git a/chrome/browser/policy/profile_policy_connector_factory.cc b/chrome/browser/policy/profile_policy_connector_factory.cc index 314cae16..a6b7cd2d5 100644 --- a/chrome/browser/policy/profile_policy_connector_factory.cc +++ b/chrome/browser/policy/profile_policy_connector_factory.cc
@@ -107,7 +107,8 @@ #if defined(OS_CHROMEOS) Profile* const profile = Profile::FromBrowserContext(context); - if (!chromeos::ProfileHelper::IsSigninProfile(profile)) { + if (!chromeos::ProfileHelper::IsSigninProfile(profile) && + !chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile); CHECK(user); }
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc index e18f3bee..ac80bb6 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -7,8 +7,6 @@ #include <math.h> #include <stddef.h> -#include <set> -#include <utility> #include <vector> #include "base/bind.h" @@ -94,8 +92,7 @@ PredictorDatabaseFactory::GetForProfile(profile_)->autocomplete_table(); // Observe all main frame loads so we can wait for the first to complete - // before accessing DB sequence of the AutocompleteActionPredictorTable and - // IO thread to build the local cache. + // before accessing DB and IO threads to build the local cache. notification_registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources()); @@ -330,8 +327,8 @@ // available. std::vector<AutocompleteActionPredictorTable::Row>* rows = new std::vector<AutocompleteActionPredictorTable::Row>(); - table_->GetTaskRunner()->PostTaskAndReply( - FROM_HERE, + content::BrowserThread::PostTaskAndReply( + content::BrowserThread::DB, FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::GetAllRows, table_, rows), base::BindOnce(&AutocompleteActionPredictor::CreateCaches, AsWeakPtr(), @@ -345,8 +342,8 @@ db_id_cache_.clear(); if (table_.get()) { - table_->GetTaskRunner()->PostTask( - FROM_HERE, + content::BrowserThread::PostTask( + content::BrowserThread::DB, FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::DeleteAllRows, table_)); } @@ -376,9 +373,10 @@ } if (table_.get()) { - table_->GetTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, - table_, id_list)); + content::BrowserThread::PostTask( + content::BrowserThread::DB, FROM_HERE, + base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, table_, + id_list)); } UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", @@ -418,8 +416,8 @@ } if (table_.get()) { - table_->GetTaskRunner()->PostTask( - FROM_HERE, + content::BrowserThread::PostTask( + content::BrowserThread::DB, FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::AddAndUpdateRows, table_, rows_to_add, rows_to_update)); } @@ -477,9 +475,10 @@ std::vector<AutocompleteActionPredictorTable::Row::Id> ids_to_delete; DeleteOldIdsFromCaches(url_db, &ids_to_delete); - table_->GetTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, - table_, ids_to_delete)); + content::BrowserThread::PostTask( + content::BrowserThread::DB, FROM_HERE, + base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, table_, + ids_to_delete)); FinishInitialization(); if (incognito_predictor_)
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_table.cc b/chrome/browser/predictors/autocomplete_action_predictor_table.cc index 49c01518..380ebd9 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_table.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_table.cc
@@ -4,8 +4,7 @@ #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" -#include <cstddef> -#include <utility> +#include <stddef.h> #include "base/guid.h" #include "base/logging.h" @@ -79,7 +78,7 @@ void AutocompleteActionPredictorTable::GetRow(const Row::Id& id, Row* row) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -94,7 +93,7 @@ } void AutocompleteActionPredictorTable::GetAllRows(Rows* row_buffer) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -113,7 +112,7 @@ void AutocompleteActionPredictorTable::AddRow( const AutocompleteActionPredictorTable::Row& row) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -122,7 +121,7 @@ void AutocompleteActionPredictorTable::UpdateRow( const AutocompleteActionPredictorTable::Row& row) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -132,7 +131,7 @@ void AutocompleteActionPredictorTable::AddAndUpdateRows( const Rows& rows_to_add, const Rows& rows_to_update) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -180,7 +179,7 @@ void AutocompleteActionPredictorTable::DeleteRows( const std::vector<Row::Id>& id_list) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -207,7 +206,7 @@ } void AutocompleteActionPredictorTable::DeleteAllRows() { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -220,14 +219,15 @@ statement.Run(); } -AutocompleteActionPredictorTable::AutocompleteActionPredictorTable( - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : PredictorTableBase(std::move(db_task_runner)) {} +AutocompleteActionPredictorTable::AutocompleteActionPredictorTable() + : PredictorTableBase() { +} -AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() = default; +AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() { +} void AutocompleteActionPredictorTable::CreateTableIfNonExistent() { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return; @@ -246,7 +246,7 @@ } void AutocompleteActionPredictorTable::LogDatabaseStats() { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); if (CantAccessDatabase()) return;
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_table.h b/chrome/browser/predictors/autocomplete_action_predictor_table.h index e4622db..425c4b01 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_table.h +++ b/chrome/browser/predictors/autocomplete_action_predictor_table.h
@@ -32,7 +32,7 @@ // would allow DeleteOldEntries to be cheaper through use of a join. // // All the functions apart from constructor and destructor have to be called in -// the DB sequence provided to the constructor of this class. +// the DB thread. class AutocompleteActionPredictorTable : public PredictorTableBase { public: struct Row { @@ -62,7 +62,7 @@ typedef std::vector<Row> Rows; - // DB sequence functions. + // DB thread functions. void GetRow(const Row::Id& id, Row* row); void GetAllRows(Rows* row_buffer); void AddRow(const Row& row); @@ -74,11 +74,10 @@ private: friend class PredictorDatabaseInternal; - explicit AutocompleteActionPredictorTable( - scoped_refptr<base::SequencedTaskRunner> db_task_runner); + AutocompleteActionPredictorTable(); ~AutocompleteActionPredictorTable() override; - // PredictorTableBase methods (DB sequence). + // PredictorTableBase methods (DB thread). void CreateTableIfNonExistent() override; void LogDatabaseStats() override;
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc b/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc index e480259..f4598be1 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc
@@ -4,24 +4,25 @@ #include <stddef.h> -#include <memory> #include <vector> +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/predictors/predictor_database_factory.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; using base::TimeDelta; +using content::BrowserThread; using predictors::AutocompleteActionPredictorTable; namespace predictors { @@ -44,6 +45,7 @@ TestingProfile* profile() { return &profile_; } protected: + // Test functions that can be run against this text fixture or // AutocompleteActionPredictorTableReopenTest that inherits from this. void TestGetRow(); @@ -77,9 +79,8 @@ } void AutocompleteActionPredictorTableTest::SetUp() { - db_ = base::MakeUnique<PredictorDatabase>( - &profile_, base::SequencedTaskRunnerHandle::Get()); - content::RunAllBlockingPoolTasksUntilIdle(); + db_.reset(new PredictorDatabase(&profile_)); + base::RunLoop().RunUntilIdle(); test_db_.push_back(AutocompleteActionPredictorTable::Row( "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", @@ -96,8 +97,8 @@ } void AutocompleteActionPredictorTableTest::TearDown() { - db_ = nullptr; - content::RunAllBlockingPoolTasksUntilIdle(); + db_.reset(NULL); + base::RunLoop().RunUntilIdle(); test_db_.clear(); }
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc index 1df1038..f63eeea 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc
@@ -5,14 +5,13 @@ #include "chrome/browser/predictors/autocomplete_action_predictor.h" #include <stddef.h> -#include <string> -#include <vector> #include "base/auto_reset.h" #include "base/command_line.h" #include "base/guid.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -25,7 +24,6 @@ #include "components/history/core/browser/url_database.h" #include "components/omnibox/browser/autocomplete_match.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; @@ -87,8 +85,13 @@ class AutocompleteActionPredictorTest : public testing::Test { public: AutocompleteActionPredictorTest() - : profile_(base::MakeUnique<TestingProfile>()), predictor_(nullptr) {} - ~AutocompleteActionPredictorTest() override = default; + : profile_(new TestingProfile()), predictor_(nullptr) {} + + ~AutocompleteActionPredictorTest() override { + predictor_.reset(NULL); + profile_.reset(NULL); + base::RunLoop().RunUntilIdle(); + } void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( @@ -96,10 +99,9 @@ switches::kPrerenderFromOmniboxSwitchValueEnabled); ASSERT_TRUE(profile_->CreateHistoryService(true, false)); - predictor_ = base::MakeUnique<AutocompleteActionPredictor>(profile_.get()); + predictor_.reset(new AutocompleteActionPredictor(profile_.get())); predictor_->CreateLocalCachesFromDatabase(); profile_->BlockUntilHistoryProcessesPendingRequests(); - content::RunAllBlockingPoolTasksUntilIdle(); ASSERT_TRUE(predictor_->initialized_); ASSERT_TRUE(db_cache()->empty());
diff --git a/chrome/browser/predictors/glowplug_key_value_data.h b/chrome/browser/predictors/glowplug_key_value_data.h index 6abd994f2..bfb416c 100644 --- a/chrome/browser/predictors/glowplug_key_value_data.h +++ b/chrome/browser/predictors/glowplug_key_value_data.h
@@ -5,11 +5,9 @@ #ifndef CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ #define CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ -#include <algorithm> #include <map> #include <memory> #include <string> -#include <utility> #include <vector> #include "base/location.h" @@ -28,9 +26,8 @@ // the memory. The cache size is limited by max_size parameter using Compare // function to decide which entry should be evicted. // -// InitializeOnDBSequence() must be called on the DB sequence of the -// ResourcePrefetchPredictorTables. All other methods must be called on UI -// thread. +// InitializeOnDBThread() must be called on DB thread. All other methods must be +// called on UI thread. template <typename T, typename Compare> class GlowplugKeyValueData { public: @@ -38,9 +35,8 @@ GlowplugKeyValueTable<T>* backend, size_t max_size); - // Must be called on the DB sequence of the ResourcePrefetchPredictorTables - // before calling all other methods. - void InitializeOnDBSequence(); + // Must be called on DB thread before calling all other methods. + void InitializeOnDBThread(); // Assigns data associated with the |key| to |data|. Returns true iff the // |key| exists, false otherwise. |data| pointer may be nullptr to get the @@ -89,10 +85,10 @@ } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::InitializeOnDBSequence() { - DCHECK(tables_->GetTaskRunner()->RunsTasksInCurrentSequence()); +void GlowplugKeyValueData<T, Compare>::InitializeOnDBThread() { + DCHECK_CURRENTLY_ON(content::BrowserThread::DB); auto data_map = base::MakeUnique<std::map<std::string, T>>(); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<T>::GetAllData, base::Unretained(backend_table_), data_map.get())); @@ -105,7 +101,7 @@ data_map->erase(entry_to_delete); } if (keys_to_delete.size() > 0) { - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<T>::DeleteData, base::Unretained(backend_table_), std::vector<std::string>(keys_to_delete))); }
diff --git a/chrome/browser/predictors/glowplug_key_value_table.h b/chrome/browser/predictors/glowplug_key_value_table.h index 7b0cbcc..cdf5019 100644 --- a/chrome/browser/predictors/glowplug_key_value_table.h +++ b/chrome/browser/predictors/glowplug_key_value_table.h
@@ -38,8 +38,7 @@ // always consists of two columns, TEXT type "key" and BLOB type "proto". The // class doesn't manage the creation and the deletion of the table. // -// All the functions except of the constructor must be called on a DB sequence -// of the ResourcePrefetchPredictorTables. +// All the functions except of the constructor must be called on a DB thread. // The preferred way to call the methods of this class is passing the method to // ResourcePrefetchPredictorTables::ScheduleDBTask(). //
diff --git a/chrome/browser/predictors/loading_predictor_unittest.cc b/chrome/browser/predictors/loading_predictor_unittest.cc index 5916709d..67e3497 100644 --- a/chrome/browser/predictors/loading_predictor_unittest.cc +++ b/chrome/browser/predictors/loading_predictor_unittest.cc
@@ -10,11 +10,11 @@ #include <utility> #include <vector> +#include "base/run_loop.h" #include "base/test/histogram_tester.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -40,14 +40,17 @@ protected: content::TestBrowserThreadBundle thread_bundle_; - std::unique_ptr<TestingProfile> profile_; std::unique_ptr<LoadingPredictor> predictor_; + std::unique_ptr<TestingProfile> profile_; }; LoadingPredictorTest::LoadingPredictorTest() : profile_(base::MakeUnique<TestingProfile>()) {} -LoadingPredictorTest::~LoadingPredictorTest() = default; +LoadingPredictorTest::~LoadingPredictorTest() { + profile_ = nullptr; + base::RunLoop().RunUntilIdle(); +} void LoadingPredictorTest::SetUp() { LoadingPredictorConfig config; @@ -66,7 +69,7 @@ predictor_->set_mock_resource_prefetch_predictor(std::move(mock)); predictor_->StartInitialization(); - content::RunAllBlockingPoolTasksUntilIdle(); + base::RunLoop().RunUntilIdle(); } void LoadingPredictorTest::TearDown() {
diff --git a/chrome/browser/predictors/loading_stats_collector_unittest.cc b/chrome/browser/predictors/loading_stats_collector_unittest.cc index 2c0eb9b..f79b50b 100644 --- a/chrome/browser/predictors/loading_stats_collector_unittest.cc +++ b/chrome/browser/predictors/loading_stats_collector_unittest.cc
@@ -5,11 +5,11 @@ #include "chrome/browser/predictors/loading_stats_collector.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/test/histogram_tester.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -56,7 +56,10 @@ LoadingStatsCollectorTest::LoadingStatsCollectorTest() : profile_(base::MakeUnique<TestingProfile>()) {} -LoadingStatsCollectorTest::~LoadingStatsCollectorTest() = default; +LoadingStatsCollectorTest::~LoadingStatsCollectorTest() { + profile_ = nullptr; + base::RunLoop().RunUntilIdle(); +} void LoadingStatsCollectorTest::SetUp() { LoadingPredictorConfig config; @@ -67,7 +70,7 @@ stats_collector_ = base::MakeUnique<LoadingStatsCollector>(mock_predictor_.get(), config); histogram_tester_ = base::MakeUnique<base::HistogramTester>(); - content::RunAllBlockingPoolTasksUntilIdle(); + base::RunLoop().RunUntilIdle(); } void LoadingStatsCollectorTest::TearDown() {
diff --git a/chrome/browser/predictors/predictor_database.cc b/chrome/browser/predictors/predictor_database.cc index 11149a0..24eafe97 100644 --- a/chrome/browser/predictors/predictor_database.cc +++ b/chrome/browser/predictors/predictor_database.cc
@@ -12,7 +12,6 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" -#include "base/sequenced_task_runner.h" #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" #include "chrome/browser/predictors/loading_predictor_config.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" @@ -34,24 +33,21 @@ namespace predictors { // Refcounted as it is created, initialized and destroyed on a different thread -// to the DB sequence provided to the constructor of this class that is required -// for all methods performing database access. +// to the DB thread that is required for all methods performing database access. class PredictorDatabaseInternal : public base::RefCountedThreadSafe<PredictorDatabaseInternal> { private: friend class base::RefCountedThreadSafe<PredictorDatabaseInternal>; friend class PredictorDatabase; - explicit PredictorDatabaseInternal( - Profile* profile, - scoped_refptr<base::SequencedTaskRunner> db_task_runner); + explicit PredictorDatabaseInternal(Profile* profile); virtual ~PredictorDatabaseInternal(); // Opens the database file from the profile path. Separated from the // constructor to ease construction/destruction of this object on one thread - // but database access on the DB sequence of |db_task_runner_|. + // but database access on the DB thread. void Initialize(); - void LogDatabaseStats(); // DB sequence. + void LogDatabaseStats(); // DB Thread. // Cancels pending DB transactions. Should only be called on the UI thread. void SetCancelled(); @@ -59,7 +55,6 @@ bool is_loading_predictor_enabled_; base::FilePath db_path_; std::unique_ptr<sql::Connection> db_; - scoped_refptr<base::SequencedTaskRunner> db_task_runner_; // TODO(shishir): These tables may not need to be refcounted. Maybe move them // to using a WeakPtr instead. @@ -69,16 +64,12 @@ DISALLOW_COPY_AND_ASSIGN(PredictorDatabaseInternal); }; -PredictorDatabaseInternal::PredictorDatabaseInternal( - Profile* profile, - scoped_refptr<base::SequencedTaskRunner> db_task_runner) + +PredictorDatabaseInternal::PredictorDatabaseInternal(Profile* profile) : db_path_(profile->GetPath().Append(kPredictorDatabaseName)), - db_(base::MakeUnique<sql::Connection>()), - db_task_runner_(db_task_runner), - autocomplete_table_( - new AutocompleteActionPredictorTable(db_task_runner_)), - resource_prefetch_tables_( - new ResourcePrefetchPredictorTables(db_task_runner_)) { + db_(new sql::Connection()), + autocomplete_table_(new AutocompleteActionPredictorTable()), + resource_prefetch_tables_(new ResourcePrefetchPredictorTables()) { db_->set_histogram_tag("Predictor"); // This db does not use [meta] table, store mmap status data elsewhere. @@ -88,13 +79,15 @@ } PredictorDatabaseInternal::~PredictorDatabaseInternal() { - // The connection pointer needs to be deleted on the DB sequence since there - // might be a task in progress on the DB sequence which uses this connection. - db_task_runner_->DeleteSoon(FROM_HERE, db_.release()); + // The connection pointer needs to be deleted on the DB thread since there + // might be a task in progress on the DB thread which uses this connection. + if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) + BrowserThread::DeleteSoon(BrowserThread::DB, FROM_HERE, db_.release()); } void PredictorDatabaseInternal::Initialize() { - DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB) || + !BrowserThread::IsMessageLoopValid(BrowserThread::DB)); // TODO(tburkard): figure out if we need this. // db_->set_exclusive_locking(); bool success = db_->Open(db_path_); @@ -113,27 +106,27 @@ } void PredictorDatabaseInternal::SetCancelled() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || - !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || + !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); autocomplete_table_->SetCancelled(); resource_prefetch_tables_->SetCancelled(); } void PredictorDatabaseInternal::LogDatabaseStats() { - DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB) || + !BrowserThread::IsMessageLoopValid(BrowserThread::DB)); autocomplete_table_->LogDatabaseStats(); if (is_loading_predictor_enabled_) resource_prefetch_tables_->LogDatabaseStats(); } -PredictorDatabase::PredictorDatabase( - Profile* profile, - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : db_(new PredictorDatabaseInternal(profile, db_task_runner)) { - db_task_runner->PostTask( - FROM_HERE, base::BindOnce(&PredictorDatabaseInternal::Initialize, db_)); +PredictorDatabase::PredictorDatabase(Profile* profile) + : db_(new PredictorDatabaseInternal(profile)) { + BrowserThread::PostTask( + BrowserThread::DB, FROM_HERE, + base::BindOnce(&PredictorDatabaseInternal::Initialize, db_)); } PredictorDatabase::~PredictorDatabase() {
diff --git a/chrome/browser/predictors/predictor_database.h b/chrome/browser/predictors/predictor_database.h index 2aa1e0a..4bf4e5e 100644 --- a/chrome/browser/predictors/predictor_database.h +++ b/chrome/browser/predictors/predictor_database.h
@@ -11,10 +11,6 @@ class Profile; -namespace base { -class SequencedTaskRunner; -} - namespace sql { class Connection; } @@ -27,8 +23,7 @@ class PredictorDatabase : public KeyedService { public: - PredictorDatabase(Profile* profile, - scoped_refptr<base::SequencedTaskRunner> db_task_runner); + explicit PredictorDatabase(Profile* profile); ~PredictorDatabase() override; scoped_refptr<AutocompleteActionPredictorTable> autocomplete_table();
diff --git a/chrome/browser/predictors/predictor_database_factory.cc b/chrome/browser/predictors/predictor_database_factory.cc index 7c80152c..588847f5 100644 --- a/chrome/browser/predictors/predictor_database_factory.cc +++ b/chrome/browser/predictors/predictor_database_factory.cc
@@ -4,10 +4,7 @@ #include "chrome/browser/predictors/predictor_database_factory.h" -#include <utility> - #include "base/bind.h" -#include "base/task_scheduler/post_task.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -35,12 +32,7 @@ KeyedService* PredictorDatabaseFactory::BuildServiceInstanceFor( content::BrowserContext* profile) const { - scoped_refptr<base::SequencedTaskRunner> db_task_runner = - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BACKGROUND, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); - return new PredictorDatabase(static_cast<Profile*>(profile), - std::move(db_task_runner)); + return new PredictorDatabase(static_cast<Profile*>(profile)); } } // namespace predictors
diff --git a/chrome/browser/predictors/predictor_table_base.cc b/chrome/browser/predictors/predictor_table_base.cc index 5e7a35c..8175e71d 100644 --- a/chrome/browser/predictors/predictor_table_base.cc +++ b/chrome/browser/predictors/predictor_table_base.cc
@@ -4,10 +4,7 @@ #include "chrome/browser/predictors/predictor_table_base.h" -#include <utility> - #include "base/logging.h" -#include "base/sequenced_task_runner.h" #include "content/public/browser/browser_thread.h" #include "sql/connection.h" @@ -15,19 +12,14 @@ namespace predictors { -base::SequencedTaskRunner* PredictorTableBase::GetTaskRunner() { - return db_task_runner_.get(); +PredictorTableBase::PredictorTableBase() : db_(NULL) { } -PredictorTableBase::PredictorTableBase( - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : db_task_runner_(std::move(db_task_runner)), db_(nullptr) {} - PredictorTableBase::~PredictorTableBase() { } void PredictorTableBase::Initialize(sql::Connection* db) { - DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); db_ = db; CreateTableIfNonExistent(); } @@ -37,17 +29,17 @@ } sql::Connection* PredictorTableBase::DB() { - DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); return db_; } void PredictorTableBase::ResetDB() { - DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); - db_ = nullptr; + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + db_ = NULL; } bool PredictorTableBase::CantAccessDatabase() { - DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); return cancelled_.IsSet() || !db_; }
diff --git a/chrome/browser/predictors/predictor_table_base.h b/chrome/browser/predictors/predictor_table_base.h index 5c0c0e65..601370e 100644 --- a/chrome/browser/predictors/predictor_table_base.h +++ b/chrome/browser/predictors/predictor_table_base.h
@@ -9,10 +9,6 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/cancellation_flag.h" -namespace base { -class SequencedTaskRunner; -} - namespace sql { class Connection; } @@ -22,20 +18,14 @@ // Base class for all tables in the PredictorDatabase. // // Refcounted as it is created and destroyed in the UI thread but all database -// related functions need to happen in the database sequence. The task runner -// for this sequence is provided by the client to the constructor of this class. +// related functions need to happen in the database thread. class PredictorTableBase : public base::RefCountedThreadSafe<PredictorTableBase> { - public: - // Returns a SequencedTaskRunner that is used to run tasks on the DB sequence. - base::SequencedTaskRunner* GetTaskRunner(); - protected: - explicit PredictorTableBase( - scoped_refptr<base::SequencedTaskRunner> db_task_runner); + PredictorTableBase(); virtual ~PredictorTableBase(); - // DB sequence functions. + // DB thread functions. virtual void CreateTableIfNonExistent() = 0; virtual void LogDatabaseStats() = 0; void Initialize(sql::Connection* db); @@ -50,7 +40,6 @@ friend class base::RefCountedThreadSafe<PredictorTableBase>; - scoped_refptr<base::SequencedTaskRunner> db_task_runner_; sql::Connection* db_; DISALLOW_COPY_AND_ASSIGN(PredictorTableBase);
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc index 5d3b5114..7c90514 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -157,19 +157,19 @@ GetUrlVisitCountTask::~GetUrlVisitCountTask() {} -void InitializeOnDBSequence( +void InitializeOnDBThread( ResourcePrefetchPredictor::PrefetchDataMap* url_resource_data, ResourcePrefetchPredictor::PrefetchDataMap* host_resource_data, ResourcePrefetchPredictor::RedirectDataMap* url_redirect_data, ResourcePrefetchPredictor::RedirectDataMap* host_redirect_data, ResourcePrefetchPredictor::ManifestDataMap* manifest_data, ResourcePrefetchPredictor::OriginDataMap* origin_data) { - url_resource_data->InitializeOnDBSequence(); - host_resource_data->InitializeOnDBSequence(); - url_redirect_data->InitializeOnDBSequence(); - host_redirect_data->InitializeOnDBSequence(); - manifest_data->InitializeOnDBSequence(); - origin_data->InitializeOnDBSequence(); + url_resource_data->InitializeOnDBThread(); + host_resource_data->InitializeOnDBThread(); + url_redirect_data->InitializeOnDBThread(); + host_redirect_data->InitializeOnDBThread(); + manifest_data->InitializeOnDBThread(); + origin_data->InitializeOnDBThread(); } } // namespace @@ -421,7 +421,7 @@ // Get raw pointers to pass to the first task. Ownership of the unique_ptrs // will be passed to the reply task. - auto task = base::BindOnce(InitializeOnDBSequence, url_resource_data.get(), + auto task = base::BindOnce(InitializeOnDBThread, url_resource_data.get(), host_resource_data.get(), url_redirect_data.get(), host_redirect_data.get(), manifest_data.get(), origin_data.get()); @@ -431,8 +431,8 @@ std::move(url_redirect_data), std::move(host_redirect_data), std::move(manifest_data), std::move(origin_data)); - tables_->GetTaskRunner()->PostTaskAndReply(FROM_HERE, std::move(task), - std::move(reply)); + BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE, std::move(task), + std::move(reply)); } void ResourcePrefetchPredictor::RecordURLRequest( @@ -441,7 +441,7 @@ if (initialization_state_ != INITIALIZED) return; - DCHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); + CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); OnMainFrameRequest(request); }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h index 28df24d..7db2504 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.h +++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -93,13 +93,13 @@ // LoadingDataCollector on the UI thread. This is owned by the ProfileIOData // for the profile. // * ResourcePrefetchPredictorTables - Persists ResourcePrefetchPredictor data -// to a sql database. Runs entirely on the DB sequence provided by the client -// to the constructor of this class. Owned by the PredictorDatabase. +// to a sql database. Runs entirely on the DB thread. Owned by the +// PredictorDatabase. // * ResourcePrefetchPredictor - Learns about resource requirements per URL in // the UI thread through the LoadingPredictorObserver and persists -// it to disk in the DB sequence through the ResourcePrefetchPredictorTables. -// It initiates resource prefetching using the ResourcePrefetcherManager. -// Owned by profile. +// it to disk in the DB thread through the ResourcePrefetchPredictorTables. It +// initiates resource prefetching using the ResourcePrefetcherManager. Owned +// by profile. // * ResourcePrefetcherManager - Manages the ResourcePrefetchers that do the // prefetching on the IO thread. The manager is owned by the // ResourcePrefetchPredictor and interfaces between the predictor on the UI @@ -216,9 +216,8 @@ Profile* profile); ~ResourcePrefetchPredictor() override; - // Starts initialization by posting a task to the DB sequence of the - // ResourcePrefetchPredictorTables to read the predictor database. Virtual for - // testing. + // Starts initialization by posting a task to the DB thread to read the + // predictor database. Virtual for testing. virtual void StartInitialization(); virtual void Shutdown();
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc index 13e9a7a4..bfce3282c 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc
@@ -11,6 +11,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" +#include "content/public/browser/browser_thread.h" #include "sql/statement.h" using google::protobuf::MessageLite; @@ -75,6 +76,8 @@ namespace predictors { +using content::BrowserThread; + // static void ResourcePrefetchPredictorTables::TrimResources( PrefetchData* data, @@ -132,9 +135,7 @@ }); } -ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables( - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : PredictorTableBase(db_task_runner) { +ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() { url_resource_table_ = base::MakeUnique<GlowplugKeyValueTable<PrefetchData>>( kUrlResourceTableName); url_redirect_table_ = base::MakeUnique<GlowplugKeyValueTable<RedirectData>>( @@ -219,15 +220,14 @@ void ResourcePrefetchPredictorTables::ScheduleDBTask( const tracked_objects::Location& from_here, DBTask task) { - GetTaskRunner()->PostTask( - from_here, - base::BindOnce( - &ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBSequence, this, - std::move(task))); + BrowserThread::PostTask( + BrowserThread::DB, from_here, + base::BindOnce(&ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBThread, + this, std::move(task))); } -void ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBSequence(DBTask task) { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); +void ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBThread(DBTask task) { + DCHECK_CURRENTLY_ON(BrowserThread::DB); if (CantAccessDatabase()) return; @@ -323,7 +323,7 @@ } void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + DCHECK_CURRENTLY_ON(BrowserThread::DB); if (CantAccessDatabase()) return; @@ -352,7 +352,7 @@ } void ResourcePrefetchPredictorTables::LogDatabaseStats() { - DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); + DCHECK_CURRENTLY_ON(BrowserThread::DB); if (CantAccessDatabase()) return;
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.h b/chrome/browser/predictors/resource_prefetch_predictor_tables.h index 705f529..9d92dc83 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.h +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.h
@@ -26,7 +26,7 @@ namespace predictors { // Interface for database tables used by the ResourcePrefetchPredictor. -// All methods except the ExecuteDBTaskOnDBSequence need to be called on the UI +// All methods except the constructor and destructor need to be called on the DB // thread. // // Currently manages: @@ -44,7 +44,7 @@ virtual void ScheduleDBTask(const tracked_objects::Location& from_here, DBTask task); - virtual void ExecuteDBTaskOnDBSequence(DBTask task); + virtual void ExecuteDBTaskOnDBThread(DBTask task); virtual GlowplugKeyValueTable<PrefetchData>* url_resource_table(); virtual GlowplugKeyValueTable<RedirectData>* url_redirect_table(); @@ -87,8 +87,7 @@ protected: // Protected for testing. Use PredictorDatabase::resource_prefetch_tables() // instead of this constructor. - ResourcePrefetchPredictorTables( - scoped_refptr<base::SequencedTaskRunner> db_task_runner); + ResourcePrefetchPredictorTables(); ~ResourcePrefetchPredictorTables() override; private:
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc index 1628e95..34fd28f 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc
@@ -7,14 +7,14 @@ #include <utility> #include <vector> +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "net/base/request_priority.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,7 +34,7 @@ void SetUp() override; void TearDown() override; - void DeleteAllData(); + void DeleteAllData() const; void GetAllData(PrefetchDataMap* url_resource_data, PrefetchDataMap* host_resource_data, RedirectDataMap* url_redirect_data, @@ -50,7 +50,6 @@ void TestDeleteAllData(); content::TestBrowserThreadBundle thread_bundle_; - scoped_refptr<base::SequencedTaskRunner> task_runner_; TestingProfile profile_; std::unique_ptr<PredictorDatabase> db_; scoped_refptr<ResourcePrefetchPredictorTables> tables_; @@ -114,10 +113,9 @@ }; ResourcePrefetchPredictorTablesTest::ResourcePrefetchPredictorTablesTest() - : task_runner_(base::SequencedTaskRunnerHandle::Get()), - db_(base::MakeUnique<PredictorDatabase>(&profile_, task_runner_)), + : db_(new PredictorDatabase(&profile_)), tables_(db_->resource_prefetch_tables()) { - content::RunAllBlockingPoolTasksUntilIdle(); + base::RunLoop().RunUntilIdle(); } ResourcePrefetchPredictorTablesTest::~ResourcePrefetchPredictorTablesTest() { @@ -126,13 +124,12 @@ void ResourcePrefetchPredictorTablesTest::SetUp() { DeleteAllData(); InitializeSampleData(); - content::RunAllBlockingPoolTasksUntilIdle(); } void ResourcePrefetchPredictorTablesTest::TearDown() { tables_ = nullptr; - db_ = nullptr; - content::RunAllBlockingPoolTasksUntilIdle(); + db_.reset(); + base::RunLoop().RunUntilIdle(); } void ResourcePrefetchPredictorTablesTest::TestGetAllData() { @@ -157,29 +154,29 @@ std::vector<std::string> urls_to_delete = {"http://www.google.com", "http://www.yahoo.com"}; std::vector<std::string> hosts_to_delete = {"www.yahoo.com"}; - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::DeleteData, base::Unretained(tables_->url_resource_table()), urls_to_delete)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::DeleteData, base::Unretained(tables_->host_resource_table()), hosts_to_delete)); urls_to_delete = {"http://fb.com/google", "http://google.com"}; hosts_to_delete = {"microsoft.com"}; - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::DeleteData, base::Unretained(tables_->url_redirect_table()), urls_to_delete)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::DeleteData, base::Unretained(tables_->host_redirect_table()), hosts_to_delete)); hosts_to_delete = {"en.wikipedia.org"}; - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<precache::PrecacheManifest>::DeleteData, base::Unretained(tables_->manifest_table()), hosts_to_delete)); hosts_to_delete = {"twitter.com"}; - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<OriginData>::DeleteData, base::Unretained(tables_->origin_table()), hosts_to_delete)); @@ -229,7 +226,7 @@ google.add_resources(), "http://www.resources.google.com/script.js", content::RESOURCE_TYPE_SCRIPT, 12, 0, 0, 8.5, net::MEDIUM, true, true); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), google.primary_key(), google)); @@ -239,7 +236,7 @@ yahoo.add_resources(), "http://www.yahoo.com/image.png", content::RESOURCE_TYPE_IMAGE, 120, 1, 1, 10.0, net::MEDIUM, true, false); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->host_resource_table()), yahoo.primary_key(), yahoo)); @@ -248,7 +245,7 @@ InitializeRedirectStat(facebook.add_redirect_endpoints(), "https://facebook.fr/google", 4, 2, 1); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), facebook.primary_key(), facebook)); @@ -259,7 +256,7 @@ InitializeRedirectStat(microsoft.add_redirect_endpoints(), "microsoft.org", 7, 2, 0); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), microsoft.primary_key(), microsoft)); @@ -269,14 +266,14 @@ "https://www.theverge.com/main.js", 0.7, precache::PrecacheResource::RESOURCE_TYPE_SCRIPT); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<precache::PrecacheManifest>::UpdateData, base::Unretained(tables_->manifest_table()), "theverge.com", theverge)); OriginData twitter = CreateOriginData("twitter.com"); InitializeOriginStat(twitter.add_origins(), "https://dogs.twitter.com", 10, 1, 0, 12., false, true); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), twitter.host(), twitter)); @@ -549,23 +546,23 @@ m->insert(*it); } -void ResourcePrefetchPredictorTablesTest::DeleteAllData() { - tables_->ExecuteDBTaskOnDBSequence( +void ResourcePrefetchPredictorTablesTest::DeleteAllData() const { + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::DeleteAllData, base::Unretained(tables_->url_resource_table()))); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::DeleteAllData, base::Unretained(tables_->url_redirect_table()))); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::DeleteAllData, base::Unretained(tables_->host_resource_table()))); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::DeleteAllData, base::Unretained(tables_->host_redirect_table()))); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<precache::PrecacheManifest>::DeleteAllData, base::Unretained(tables_->manifest_table()))); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<OriginData>::DeleteAllData, base::Unretained(tables_->origin_table()))); } @@ -577,22 +574,22 @@ RedirectDataMap* host_redirect_data, ManifestDataMap* manifest_data, OriginDataMap* origin_data) const { - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::GetAllData, base::Unretained(tables_->url_resource_table()), url_resource_data)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::GetAllData, base::Unretained(tables_->url_redirect_table()), url_redirect_data)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::GetAllData, base::Unretained(tables_->host_resource_table()), host_resource_data)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::GetAllData, base::Unretained(tables_->host_redirect_table()), host_redirect_data)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<precache::PrecacheManifest>::GetAllData, base::Unretained(tables_->manifest_table()), manifest_data)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<OriginData>::GetAllData, base::Unretained(tables_->origin_table()), origin_data)); } @@ -638,15 +635,15 @@ test_url_data_.insert(std::make_pair(reddit.primary_key(), reddit)); test_url_data_.insert(std::make_pair(yahoo.primary_key(), yahoo)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), google.primary_key(), google)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), reddit.primary_key(), reddit)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), yahoo.primary_key(), yahoo)); @@ -683,11 +680,11 @@ test_host_data_.insert(std::make_pair(facebook.primary_key(), facebook)); test_host_data_.insert(std::make_pair(yahoo.primary_key(), yahoo)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->host_resource_table()), facebook.primary_key(), facebook)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->host_resource_table()), yahoo.primary_key(), yahoo)); @@ -716,15 +713,15 @@ test_url_redirect_data_.insert( std::make_pair(google.primary_key(), google)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), facebook.primary_key(), facebook)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), nytimes.primary_key(), nytimes)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), google.primary_key(), google)); @@ -746,11 +743,11 @@ test_host_redirect_data_.insert( std::make_pair(microsoft.primary_key(), microsoft)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), bbc.primary_key(), bbc)); - tables_->ExecuteDBTaskOnDBSequence( + tables_->ExecuteDBTaskOnDBThread( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), microsoft.primary_key(), microsoft)); @@ -777,11 +774,11 @@ test_manifest_data_.insert(std::make_pair("en.wikipedia.org", wikipedia)); test_manifest_data_.insert(std::make_pair("youtube.com", youtube)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<precache::PrecacheManifest>::UpdateData, base::Unretained(tables_->manifest_table()), "en.wikipedia.org", wikipedia)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<precache::PrecacheManifest>::UpdateData, base::Unretained(tables_->manifest_table()), "youtube.com", youtube)); } @@ -805,18 +802,18 @@ test_origin_data_.insert({"twitter.com", twitter}); test_origin_data_.insert({"abc.xyz", alphabet}); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), twitter.host(), twitter)); - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + tables_->ExecuteDBTaskOnDBThread(base::BindOnce( &GlowplugKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), alphabet.host(), alphabet)); } } void ResourcePrefetchPredictorTablesTest::ReopenDatabase() { - db_ = base::MakeUnique<PredictorDatabase>(&profile_, task_runner_); - content::RunAllBlockingPoolTasksUntilIdle(); + db_.reset(new PredictorDatabase(&profile_)); + base::RunLoop().RunUntilIdle(); tables_ = db_->resource_prefetch_tables(); }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc index 1b00760f..c4553461 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -10,8 +10,8 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "base/test/histogram_tester.h" -#include "base/test/test_simple_task_runner.h" #include "base/time/time.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/predictors/loading_predictor.h" @@ -23,7 +23,6 @@ #include "components/history/core/browser/history_types.h" #include "components/sessions/core/session_id.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_utils.h" #include "net/http/http_response_headers.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_context.h" @@ -69,16 +68,14 @@ class MockResourcePrefetchPredictorTables : public ResourcePrefetchPredictorTables { public: - MockResourcePrefetchPredictorTables( - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : ResourcePrefetchPredictorTables(std::move(db_task_runner)) {} + MockResourcePrefetchPredictorTables() = default; void ScheduleDBTask(const tracked_objects::Location& from_here, DBTask task) override { - ExecuteDBTaskOnDBSequence(std::move(task)); + ExecuteDBTaskOnDBThread(std::move(task)); } - void ExecuteDBTaskOnDBSequence(DBTask task) override { + void ExecuteDBTaskOnDBThread(DBTask task) override { std::move(task).Run(nullptr); } @@ -163,7 +160,8 @@ void InitializePredictor() { loading_predictor_->StartInitialization(); - db_task_runner_->RunUntilIdle(); + base::RunLoop loop; + loop.RunUntilIdle(); // Runs the DB lookup. profile_->BlockUntilHistoryProcessesPendingRequests(); } @@ -180,7 +178,6 @@ content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<TestingProfile> profile_; - scoped_refptr<base::TestSimpleTaskRunner> db_task_runner_; net::TestURLRequestContext url_request_context_; std::unique_ptr<LoadingPredictor> loading_predictor_; @@ -201,11 +198,12 @@ ResourcePrefetchPredictorTest::ResourcePrefetchPredictorTest() : profile_(new TestingProfile()), - db_task_runner_(new base::TestSimpleTaskRunner()), - mock_tables_(new StrictMock<MockResourcePrefetchPredictorTables>( - db_task_runner_)) {} + mock_tables_(new StrictMock<MockResourcePrefetchPredictorTables>()) {} -ResourcePrefetchPredictorTest::~ResourcePrefetchPredictorTest() = default; +ResourcePrefetchPredictorTest::~ResourcePrefetchPredictorTest() { + profile_.reset(NULL); + base::RunLoop().RunUntilIdle(); +} void ResourcePrefetchPredictorTest::SetUp() { InitializeSampleData(); @@ -226,7 +224,7 @@ url_request_job_factory_.Reset(); url_request_context_.set_job_factory(&url_request_job_factory_); - histogram_tester_ = base::MakeUnique<base::HistogramTester>(); + histogram_tester_.reset(new base::HistogramTester()); } void ResourcePrefetchPredictorTest::TearDown() {
diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc index e876c33..427d73b 100644 --- a/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chrome/browser/printing/pdf_to_emf_converter.cc
@@ -19,7 +19,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/chrome_utility_printing_messages.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/printing/pwg_raster_converter.cc b/chrome/browser/printing/pwg_raster_converter.cc index 95934fb..5f450932 100644 --- a/chrome/browser/printing/pwg_raster_converter.cc +++ b/chrome/browser/printing/pwg_raster_converter.cc
@@ -19,7 +19,6 @@ #include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/chrome_utility_printing_messages.h" #include "chrome/grit/generated_resources.h" #include "components/cloud_devices/common/cloud_device_description.h"
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 2792fe5..a3d038d 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -436,11 +436,12 @@ "profile files to the root directory!"; #if defined(OS_CHROMEOS) - if (!chromeos::ProfileHelper::IsSigninProfile(this)) { + if (!chromeos::ProfileHelper::IsSigninProfile(this) && + !chromeos::ProfileHelper::IsLockScreenAppProfile(this)) { const user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(this); // A |User| instance should always exist for a profile which is not the - // initial or the sign-in profile. + // initial, the sign-in or the lock screen app profile. CHECK(user); LOG_IF(FATAL, !session_manager::SessionManager::Get()->HasSessionForAccountId( @@ -694,7 +695,8 @@ // mark the session as initialized. Need to do this before we restart below // so we don't get in a weird state where we restart before the session is // marked as initialized and so try to initialize it again. - if (!chromeos::ProfileHelper::IsSigninProfile(this)) { + if (!chromeos::ProfileHelper::IsSigninProfile(this) && + !chromeos::ProfileHelper::IsLockScreenAppProfile(this)) { chromeos::ProfileHelper* profile_helper = chromeos::ProfileHelper::Get(); user_manager::UserManager::Get()->OnProfileInitialized( profile_helper->GetUserByProfile(this));
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 824002c..e9fa0c5 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -1074,45 +1074,6 @@ {base::MayBlock(), base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}), IsOffTheRecord())); - - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("domain_security_policy", R"( - semantics { - sender: "Domain Security Policy" - description: - "Websites can opt in to have Chrome send reports to them when " - "Chrome observes connections to that website that do not meet " - "stricter security policies, such as with HTTP Public Key Pinning. " - "Websites can use this feature to discover misconfigurations that " - "prevent them from complying with stricter security policies that " - "they've opted in to." - trigger: - "Chrome observes that a user is loading a resource from a website " - "that has opted in for security policy reports, and the connection " - "does not meet the required security policies." - data: - "The time of the request, the hostname and port being requested, " - "the certificate chain, and sometimes certificate revocation " - "information included on the connection." - destination: OTHER - } - policy { - cookies_allowed: false - setting: "This feature cannot be disabled by settings." - policy_exception_justification: - "Not implemented, this is a feature that websites can opt into and " - "thus there is no Chrome-wide policy to disable it." - })"); - certificate_report_sender_.reset( - new net::ReportSender(main_request_context_.get(), traffic_annotation)); - transport_security_state->SetReportSender(certificate_report_sender_.get()); - - expect_ct_reporter_.reset( - new ChromeExpectCTReporter(main_request_context_.get())); - transport_security_state->SetExpectCTReporter(expect_ct_reporter_.get()); - - transport_security_state->SetRequireCTDelegate( - ct_policy_manager_->GetDelegate()); main_request_context_storage_->set_transport_security_state( std::move(transport_security_state)); @@ -1193,6 +1154,47 @@ InitializeInternal(profile_params_.get(), protocol_handlers, std::move(request_interceptors)); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("domain_security_policy", R"( + semantics { + sender: "Domain Security Policy" + description: + "Websites can opt in to have Chrome send reports to them when " + "Chrome observes connections to that website that do not meet " + "stricter security policies, such as with HTTP Public Key Pinning. " + "Websites can use this feature to discover misconfigurations that " + "prevent them from complying with stricter security policies that " + "they've opted in to." + trigger: + "Chrome observes that a user is loading a resource from a website " + "that has opted in for security policy reports, and the connection " + "does not meet the required security policies." + data: + "The time of the request, the hostname and port being requested, " + "the certificate chain, and sometimes certificate revocation " + "information included on the connection." + destination: OTHER + } + policy { + cookies_allowed: false + setting: "This feature cannot be disabled by settings." + policy_exception_justification: + "Not implemented, this is a feature that websites can opt into and " + "thus there is no Chrome-wide policy to disable it." + })"); + certificate_report_sender_.reset( + new net::ReportSender(main_request_context_.get(), traffic_annotation)); + main_request_context_->transport_security_state()->SetReportSender( + certificate_report_sender_.get()); + + expect_ct_reporter_.reset( + new ChromeExpectCTReporter(main_request_context_.get())); + main_request_context_->transport_security_state()->SetExpectCTReporter( + expect_ct_reporter_.get()); + + main_request_context_->transport_security_state()->SetRequireCTDelegate( + ct_policy_manager_->GetDelegate()); + profile_params_.reset(); initialized_ = true; }
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index bf0157257..00635b8 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -1211,6 +1211,11 @@ chromeos::ProfileHelper::IsSigninProfile(profile)) { extensions_enabled = true; } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableLockScreenApps) && + chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { + extensions_enabled = true; + } #endif extensions::ExtensionSystem::Get(profile)->InitForRegularProfile( extensions_enabled); @@ -1609,8 +1614,10 @@ bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) { #if defined(OS_CHROMEOS) - if (chromeos::ProfileHelper::IsSigninProfile(profile)) + if (chromeos::ProfileHelper::IsSigninProfile(profile) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { return true; + } #endif return profile->IsGuestSession() || profile->IsSystemProfile(); }
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index 34d127ec..24c32b4 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -145,7 +145,6 @@ // Enable experimental features for subscription restrictions. command_line->AppendSwitch( switches::kEnableExperimentalWebPlatformFeatures); - InProcessBrowserTest::SetUpCommandLine(command_line); } // InProcessBrowserTest:
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index c90176f4..2e8532b 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -740,7 +740,7 @@ base::RunLoop run_loop; bool response_received = false; thumbnail_capturer->RequestThumbnailForContextNode( - 0, gfx::Size(2048, 2048), + 0, gfx::Size(2048, 2048), chrome::mojom::ImageFormat::JPEG, base::Bind(callback, &response_received, run_loop.QuitClosure())); run_loop.Run();
diff --git a/chrome/browser/resources/about_conflicts.html b/chrome/browser/resources/about_conflicts.html index 739db71..59602ea 100644 --- a/chrome/browser/resources/about_conflicts.html +++ b/chrome/browser/resources/about_conflicts.html
@@ -36,13 +36,13 @@ h1 { font-size: 156%; font-weight: bold; - padding: 0; margin: 0; + padding: 0; } #blurb-container { - padding-bottom: 1.5em; font-size: 120%; + padding-bottom: 1.5em; } div.content { @@ -51,11 +51,11 @@ } .section-header { - background: #ebeff9; - border-top: 1px solid #b5c7de; + -webkit-padding-start: 5px; + background: rgb(235, 239, 249); + border-top: 1px solid rgb(181, 199, 222); font-size: 99%; padding-bottom: 2px; - -webkit-padding-start: 5px; padding-top: 3px; width: 100%; } @@ -73,14 +73,14 @@ } .vbox-container { - display: -webkit-box; -webkit-box-orient: vertical; + display: -webkit-box; } .wbox { - display: -webkit-box; -webkit-box-align: stretch; -webkit-box-flex: 1; + display: -webkit-box; } #top { @@ -101,13 +101,13 @@ } .no-modules { + font-size: 1.2em; margin: 6em 0 0; text-align: center; - font-size: 1.2em; } .suspected-bad { - color: #DD7700; + color: rgb(221, 119, 0); } .confirmed-bad { @@ -119,8 +119,8 @@ } .extra-info-text { - margin-top: -1em; margin-bottom: 1em; + margin-top: -1em; } .clearing { @@ -240,8 +240,10 @@ </div> </div> </div> +<script src="chrome://resources/js/cr.js"></script> <script src="chrome://resources/js/jstemplate_compiled.js"></script> <script src="chrome://resources/js/load_time_data.js"></script> +<script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/util.js"></script> <script src="chrome://conflicts/strings.js"></script>
diff --git a/chrome/browser/resources/about_conflicts.js b/chrome/browser/resources/about_conflicts.js index 08984983..f243c2d 100644 --- a/chrome/browser/resources/about_conflicts.js +++ b/chrome/browser/resources/about_conflicts.js
@@ -43,7 +43,7 @@ * should reply to returnModuleList() (below). */ function requestModuleListData() { - chrome.send('requestModuleList'); + cr.sendWithPromise('requestModuleList').then(returnModuleList); } /**
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js b/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js index bbbe580..1402c3f 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js +++ b/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js
@@ -96,9 +96,17 @@ var extraCellsPositions = extraCellsSpans.map(function(span) { return text.getSpanStart(span); }); + var formTypeMap = new Array(text.length).fill(0); + text.getSpansInstanceOf(cvox.BrailleTextStyleSpan).forEach(function(span) { + var start = text.getSpanStart(span); + var end = text.getSpanEnd(span); + for (var i = start; i < end; i++) + formTypeMap[i] |= span.formType; + }); + if (expandRanges.length == 0 && extraCellsSpans.length == 0) { this.defaultTranslator_.translate( - text.toString(), + text.toString(), formTypeMap, cvox.ExpandingBrailleTranslator.nullParamsToEmptyAdapter_( text.length, callback)); return; @@ -180,6 +188,7 @@ chunksToTranslate.forEach(function(chunk) { chunk.translator.translate( text.toString().substring(chunk.start, chunk.end), + formTypeMap.slice(chunk.start, chunk.end), cvox.ExpandingBrailleTranslator.nullParamsToEmptyAdapter_( chunk.end - chunk.start, goog.partial(chunkTranslated, chunk))); });
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs b/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs index 00a8c99f..0b772a51 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs +++ b/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs
@@ -19,6 +19,7 @@ /** @override */ closureModuleDeps: [ 'Spannable', + 'cvox.BrailleTextStyleSpan', 'cvox.ExpandingBrailleTranslator', 'cvox.LibLouis', 'cvox.ValueSelectionSpan', @@ -36,19 +37,24 @@ * @constructor * @extends {cvox.LibLouis.Translator} */ -function FakeTranslator(resultChar) { +function FakeTranslator(resultChar, opt_styleMap) { /** @private {string} */ this.resultChar_ = resultChar; + /** @private {!Object} */ + this.styleMap_ = opt_styleMap || {}; } FakeTranslator.prototype = { /** @Override */ - translate: function(text, callback) { + translate: function(text, formTypeMap, callback) { var result = new Uint8Array(text.length); var textToBraille = []; var brailleToText = []; for (var i = 0; i < text.length; ++i) { - result[i] = this.resultChar_.charCodeAt(0); + var formType = this.styleMap_[formTypeMap[i]]; + if (formType) + formType = formType.charCodeAt(0); + result[i] = formType || this.resultChar_.charCodeAt(0); textToBraille.push(i); brailleToText.push(i); } @@ -79,7 +85,7 @@ var contractedTranslator = new FakeTranslator('c'); // Translator that always results in an error. var uncontractedTranslator = { - translate: function(text, callback) { + translate: function(text, formTypeMap, callback) { callback(null, null, null); } }; @@ -141,7 +147,7 @@ } if (extraCellsSpan) expectedBrailleToText.splice(extraCellsSpanPos, 0, extraCellsSpanPos); - + expandingTranslator.translate( text, valueExpansion, function(cells, textToBraille, brailleToText) { assertArrayBufferMatches(expectedOutput, cells, name); @@ -226,7 +232,7 @@ * selection is added if undefined. * @param {=opt_selectionEnd} Selection end if selection is not a caret. */ -function createText(text, opt_selectionStart, opt_selectionEnd) { +function createText(text, opt_selectionStart, opt_selectionEnd, opt_style) { var result = new Spannable(text); result.setSpan(new cvox.ValueSpan, 0, text.length); @@ -236,6 +242,13 @@ opt_selectionStart, goog.isDef(opt_selectionEnd) ? opt_selectionEnd : opt_selectionStart); } + + if (goog.isDef(opt_style)) { + result.setSpan( + new cvox.BrailleTextStyleSpan(opt_style.formType), + opt_style.start, + opt_style.end); + } return result; } @@ -299,3 +312,20 @@ 2 * (TESTDATA.length * 4 + TESTDATA_WITH_SELECTION.length); assertEquals(totalExpectedTranslationTests, totalRunTranslationTests); }); + +TEST_F('CvoxExpandingBrailleTranslatorUnitTest', 'StyleTranslations', + function() { + var formTypeMap = {}; + formTypeMap[cvox.LibLouis.FormType.BOLD] = 'b'; + formTypeMap[cvox.LibLouis.FormType.ITALIC] = 'i'; + formTypeMap[cvox.LibLouis.FormType.UNDERLINE] = 'u'; + var translator = new cvox.ExpandingBrailleTranslator( + new FakeTranslator('c', formTypeMap), + new FakeTranslator('u')); + translator.translate(createText('a test of text', undefined, undefined, { + start: 2, end: 6, formType: cvox.LibLouis.FormType.BOLD}), + cvox.ExpandingBrailleTranslator.ExpansionType.NONE, + function(cells) { + assertArrayBufferMatches('ccbbbbcccccccc', cells); + }); +});
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js b/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js index ddd3b8bc..a0c02f2f 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js +++ b/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js
@@ -7,7 +7,7 @@ */ goog.provide('cvox.LibLouis'); - +goog.provide('cvox.LibLouis.FormType'); /** * Encapsulates a liblouis Native Client instance in the page. @@ -50,6 +50,20 @@ /** + * Constants taken from liblouis.h. + * Controls braille indicator insertion during translation. + * @enum {number} + */ +cvox.LibLouis.FormType = { + PLAIN_TEXT: 0, + ITALIC: 1, + UNDERLINE: 2, + BOLD: 4, + COMPUTER_BRAILLE: 8 +}; + + +/** * Set to {@code true} to enable debug logging of RPC messages. * @type {boolean} */ @@ -239,12 +253,17 @@ * text positions. If translation fails for any reason, all parameters are * {@code null}. */ -cvox.LibLouis.Translator.prototype.translate = function(text, callback) { +cvox.LibLouis.Translator.prototype.translate = function( + text, formTypeMap, callback) { if (!this.instance_.isAttached()) { callback(null /*cells*/, null /*textToBraille*/, null /*brailleToText*/); return; } - var message = {'table_names': this.tableNames_, 'text': text}; + var message = { + 'table_names': this.tableNames_, + 'text': text, + form_type_map: formTypeMap + }; this.instance_.rpc_('Translate', message, function(reply) { var cells = null; var textToBraille = null;
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs b/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs index 90c6da9..ee2533c0 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs
@@ -69,7 +69,7 @@ TEST_F('CvoxLibLouisTest', 'testTranslateComputerBraille', function() { var liblouis = this.createAndAttachLiblouis(); this.withTranslator(liblouis, 'en-us-comp8.ctb', function(translator) { - translator.translate('Hello!', this.newCallback( + translator.translate('Hello!', [], this.newCallback( function(cells, textToBraille, brailleToText) { assertEqualsUint8Array([0x53, 0x11, 0x07, 0x07, 0x15, 0x2e], cells); assertEqualsJSON([0, 1, 2, 3, 4, 5], textToBraille); @@ -92,7 +92,7 @@ var liblouis = this.createAndAttachLiblouis(); // This is one of the moderately large tables. this.withTranslator(liblouis, 'de-de-g2.ctb', function(translator) { - translator.translate('München', this.newCallback( + translator.translate('München', [], this.newCallback( function(cells, textToBraille, brailleToText) { assertEqualsUint8Array([0x0d, 0x33, 0x1d, 0x39, 0x09], cells); assertEqualsJSON([0, 1, 2, 3, 3, 4, 4], textToBraille); @@ -142,7 +142,7 @@ var liblouis = this.createAndAttachLiblouis(); this.withTranslator(liblouis, 'de-de-comp8.ctb', function(translator) { liblouis.detach(); - translator.translate('Hamburg', this.newCallback( + translator.translate('Hamburg', [], this.newCallback( function(cells, textToBraille, brailleToText) { assertEquals(null, cells); assertEquals(null, textToBraille); @@ -155,7 +155,7 @@ var liblouis = this.createAndAttachLiblouis(); this.withTranslator(liblouis, 'de-de-comp8.ctb', function(translator) { var called = false; - translator.translate('Berlin', this.newCallback( + translator.translate('Berlin', [], this.newCallback( function(cells, textToBraille, brailleToText) { assertEquals(null, cells); assertEquals(null, textToBraille); @@ -170,7 +170,7 @@ TEST_F('CvoxLibLouisTest', 'testKeyEventStaticData', function() { var liblouis = this.createAndAttachLiblouis(); this.withTranslator(liblouis, 'en-us-comp8.ctb', function(translator) { - translator.translate('abcdefghijklmnopqrstuvwxyz 0123456789', + translator.translate('abcdefghijklmnopqrstuvwxyz 0123456789', [], this.newCallback( function(cells, textToBraille, brailleToText) { // A-Z.
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/spans.js b/chrome/browser/resources/chromeos/chromevox/braille/spans.js index 525b107..e9362bb 100644 --- a/chrome/browser/resources/chromeos/chromevox/braille/spans.js +++ b/chrome/browser/resources/chromeos/chromevox/braille/spans.js
@@ -7,10 +7,12 @@ * and selections. */ +goog.provide('cvox.BrailleTextStyleSpan'); goog.provide('cvox.ExtraCellsSpan'); goog.provide('cvox.ValueSelectionSpan'); goog.provide('cvox.ValueSpan'); +goog.require('cvox.LibLouis.FormType'); goog.require('Spannable'); /** @@ -72,3 +74,14 @@ /** @type {ArrayBuffer} */ this.cells = new Uint8Array(0).buffer; }; + + +/** + * Indicates a text form during translation in Liblouis. + * @param {cvox.LibLouis.FormType} formType + * @constructor + */ +cvox.BrailleTextStyleSpan = function(formType) { + /** @type {cvox.LibLouis.FormType} */ + this.formType = formType; +};
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js index 96f2635..aa6c338 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -98,6 +98,13 @@ */ DesktopAutomationHandler.announceActions = false; +/** + * The url of the keyboard. + * @const {string} + */ +DesktopAutomationHandler.KEYBOARD_URL = + 'chrome-extension://jkghodnilhceideoidjikpgommlajknk/inputview.html'; + DesktopAutomationHandler.prototype = { __proto__: BaseAutomationHandler.prototype, @@ -423,9 +430,13 @@ while (voxTarget && voxTarget.parent && voxTarget.parent.state.editable) voxTarget = voxTarget.parent; - // It is possible that ChromeVox has range over some other node - // when a text field is focused. - if (!target.state.focused || target != voxTarget) + // It is possible that ChromeVox has range over some other node when a text + // field is focused. Only allow this when focus is on a desktop node or + // ChromeVox is over the keyboard. + if (!target.state.focused || + (target != voxTarget && target.root.role != RoleType.DESKTOP && + voxTarget.root.url.indexOf(DesktopAutomationHandler.KEYBOARD_URL) != + 0)) return; this.createTextEditHandlerIfNeeded_(target);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js index 60580fd..3b501d4 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js
@@ -17,6 +17,7 @@ goog.require('cursors.Range'); goog.require('cvox.BrailleBackground'); goog.require('cvox.ChromeVoxEditableTextBase'); +goog.require('cvox.LibLouis.FormType'); goog.scope(function() { var AutomationEvent = chrome.automation.AutomationEvent; @@ -24,6 +25,7 @@ var Cursor = cursors.Cursor; var Dir = constants.Dir; var EventType = chrome.automation.EventType; +var FormType = cvox.LibLouis.FormType; var Range = cursors.Range; var RoleType = chrome.automation.RoleType; var StateType = chrome.automation.StateType; @@ -322,7 +324,7 @@ // Describe the current line. This accounts for previous/current // selections and picking the line edge boundary that changed (as computed // above). This is also the code path for describing paste. - cvox.ChromeVox.tts.speak(cur.text, cvox.QueueMode.CATEGORY_FLUSH); + this.speakCurrentRichLine_(prev); this.brailleCurrentRichLine_(); } @@ -385,10 +387,52 @@ } }, + /** + * @param {editing.EditableLine} prevLine + * @private + */ + speakCurrentRichLine_: function(prevLine) { + var prev = prevLine ? prevLine.startContainer_ : this.node_; + var lineNodes = + this.line_.value_.getSpansInstanceOf(this.node_.constructor); + var queueMode = cvox.QueueMode.CATEGORY_FLUSH; + for (var i = 0, cur; cur = lineNodes[i]; i++) { + if (cur.children.length) + continue; + new Output() + .withRichSpeech( + Range.fromNode(cur), Range.fromNode(prev), + Output.EventType.NAVIGATE) + .withQueueMode(queueMode) + .go(); + prev = cur; + queueMode = cvox.QueueMode.QUEUE; + } + }, + /** @private */ brailleCurrentRichLine_: function() { var cur = this.line_; - var value = cur.value_; + var value = new Spannable(cur.value_); + if (!this.node_.constructor) + return; + value.getSpansInstanceOf(this.node_.constructor).forEach(function(span) { + var style = span.role == RoleType.INLINE_TEXT_BOX ? span.parent : span; + if (!style) + return; + var formType = FormType.PLAIN_TEXT; + if (style.bold) + formType |= FormType.BOLD; + if (style.italic) + formType |= FormType.ITALIC; + if (style.underline) + formType |= FormType.UNDERLINE; + if (formType == FormType.PLAIN_TEXT) + return; + var start = value.getSpanStart(span); + var end = value.getSpanEnd(span); + value.setSpan(new cvox.BrailleTextStyleSpan(formType), start, end); + }); value.setSpan(new cvox.ValueSpan(0), 0, cur.value_.length); value.setSpan( new cvox.ValueSelectionSpan(), cur.startOffset, cur.endOffset);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs index 79809daa..6bfb586 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs
@@ -246,13 +246,13 @@ .expectSpeech('\n') .expectBraille('\n') .call(moveByLine) - .expectSpeech('This is a test of rich text') + .expectSpeech('This is a ', 'test', 'Link', ' of rich text') .expectBraille('This is a test of rich text') .call(moveByLine) .expectSpeech('\n') .expectBraille('\n') .call(moveByLine) - .expectSpeech('hello') + .expectSpeech('hello', 'Heading 2') .expectBraille('hello') .replay(); });
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd index 37943929..9a1eada 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -1699,7 +1699,7 @@ <message desc="In an editable text box, describes a blank line." name="IDS_CHROMEVOX_TEXT_BOX_BLANK"> Blank </message> - <message desc="In an editable text box, describes a line with only whitespace." name="IDS_CHROMEVOX_TEXT_BOX_WHITESPACE"> + <message desc="In an editable text box, describes a line with only whitespace." name="IDS_CHROMEVOX_TEXT_BOX_WHITESPACE" meaning="UI element"> Space </message> <message desc="Further describes a list-like element with a number of items. e.g. This will be combined with other messages to produce: List with 3 items." name="IDS_CHROMEVOX_LIST_WITH_ITEMS_NOT_PLURALIZED">
diff --git a/chrome/browser/resources/chromeos/compiled_resources2.gyp b/chrome/browser/resources/chromeos/compiled_resources2.gyp index 7269606b..27fac69 100644 --- a/chrome/browser/resources/chromeos/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/compiled_resources2.gyp
@@ -14,7 +14,7 @@ '<(DEPTH)/third_party/jstemplate/util.js', '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', '<(DEPTH)/third_party/jstemplate/jstemplate.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_onc_types.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js', '<(DEPTH)/ui/webui/resources/js/action_link.js', '<(DEPTH)/ui/webui/resources/js/cr.js', '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', @@ -86,7 +86,7 @@ '<(DEPTH)/third_party/closure_compiler/externs/networking_private.js', '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', '<(DEPTH)/third_party/closure_compiler/externs/web_animations.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_network_icon_externs.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js', '../options/options_bundle.js', # Note: ^ this is just a copy of # ../options/compiled_resources2.gyp:options_bundle#source_files. Most @@ -108,7 +108,7 @@ '<(DEPTH)/third_party/jstemplate/util.js', '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', '<(DEPTH)/third_party/jstemplate/jstemplate.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_onc_types.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js', '<(DEPTH)/ui/webui/resources/js/action_link.js', '<(DEPTH)/ui/webui/resources/js/cr.js', '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', @@ -180,7 +180,7 @@ '<(DEPTH)/third_party/closure_compiler/externs/networking_private.js', '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', '<(DEPTH)/third_party/closure_compiler/externs/web_animations.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_network_icon_externs.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js', '../options/options_bundle.js', # Note: ^ this is just a copy of # ../options/compiled_resources2.gyp:options_bundle#source_files. Most
diff --git a/chrome/browser/resources/chromeos/emulator/audio_settings.html b/chrome/browser/resources/chromeos/emulator/audio_settings.html index 207c70e..eacb65eb 100644 --- a/chrome/browser/resources/chromeos/emulator/audio_settings.html +++ b/chrome/browser/resources/chromeos/emulator/audio_settings.html
@@ -1,9 +1,10 @@ <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/shared_style_css.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/neon-animation/neon-animatable-behavior.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-checkbox/paper-checkbox.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> @@ -15,11 +16,11 @@ <template> <!-- TODO(michaelpg): Wrap the line below to fit within the 80-char limit. See https://github.com/Polymer/polymer/pull/3668. --> - <style include="device-emulator-shared-styles iron-flex iron-flex-alignment iron-positioning"> + <style include="device-emulator-shared-styles cr-shared-style iron-flex iron-flex-alignment iron-positioning"> </style> - <paper-dialog with-backdrop id="editDialog"> - <div class="element-label">[[currentEditableObject.deviceName]]</div> - <div> + <dialog is="cr-dialog" id="editDialog"> + <div class="title">[[currentEditableObject.deviceName]]</div> + <div class="body"> <form> <div class="form-field-section"> <paper-input value="{{currentEditableObject.deviceName}}" @@ -53,11 +54,12 @@ </div> </form> </div> - <div class="buttons"> - <paper-button on-click="insertEditedAudioNode" - dialog-dismiss>Done</paper-button> + <div class="button-container"> + <paper-button class="action-button" on-click="insertEditedAudioNode"> + Done + </paper-button> </div> - </paper-dialog> + </dialog> <div class="layout vertical"> <div class="element-label">
diff --git a/chrome/browser/resources/chromeos/emulator/audio_settings.js b/chrome/browser/resources/chromeos/emulator/audio_settings.js index 08ef9c2..712eab02 100644 --- a/chrome/browser/resources/chromeos/emulator/audio_settings.js +++ b/chrome/browser/resources/chromeos/emulator/audio_settings.js
@@ -160,6 +160,7 @@ // in |node|. var node = this.nodes[this.currentEditIndex]; chrome.send('insertAudioNode', [node]); + this.$.editDialog.close(); }, /** @@ -199,7 +200,7 @@ var index = event.model.index; this.currentEditIndex = index; this.currentEditableObject = this.nodes[index]; - this.$.editDialog.toggle(); + this.$.editDialog.showModal(); }, /**
diff --git a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html index f842830e..b64ecf6 100644 --- a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html +++ b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html
@@ -1,9 +1,10 @@ <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/shared_style_css.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/neon-animation/neon-animatable-behavior.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-checkbox/paper-checkbox.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> @@ -15,12 +16,11 @@ <template> <!-- TODO(michaelpg): Wrap the line below to fit within the 80-char limit. See https://github.com/Polymer/polymer/pull/3668. --> - <style include="device-emulator-shared-styles iron-flex iron-flex-alignment iron-positioning"> + <style include="device-emulator-shared-styles cr-shared-style iron-flex iron-flex-alignment iron-positioning"> </style> - <paper-dialog on-iron-overlay-opened="editDialogOpened" with-backdrop - id="editDialog"> - <div class="element-label">[[currentEditableObject.alias]]</div> - <div> + <dialog is="cr-dialog" id="editDialog"> + <div class="title">[[currentEditableObject.alias]]</div> + <div class="body"> <form> <div class="form-field-section"> <paper-input value="{{currentEditableObject.alias}}" @@ -94,10 +94,12 @@ </div> </form> </div> - <div class="buttons"> - <paper-button dialog-dismiss>Close</paper-button> + <div class="button-container"> + <paper-button class="action-button" on-tap="onCloseTap_"> + Close + </paper-button> </div> - </paper-dialog> + </dialog> <div class="layout vertical"> <div class="element-label">
diff --git a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js index aa04e9e3..e4d7294 100644 --- a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js +++ b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js
@@ -173,15 +173,6 @@ } }, - /** - * Called when the device edit dialog is opened. Re-validates necessary input - * fields. - */ - editDialogOpened: function() { - this.validateAddress(); - this.validatePath(); - }, - handleAddressInput: function() { this.autoFormatAddress(); this.validateAddress(); @@ -480,7 +471,14 @@ var index = event.model.index; this.currentEditIndex = index; this.currentEditableObject = this.devices[index]; - this.$.editDialog.toggle(); + this.$.editDialog.showModal(); + this.validateAddress(); + this.validatePath(); + }, + + /** @private */ + onCloseTap_: function() { + this.$.editDialog.close(); }, /**
diff --git a/chrome/browser/resources/chromeos/emulator/shared_styles.html b/chrome/browser/resources/chromeos/emulator/shared_styles.html index a477f14..ec420bc4 100644 --- a/chrome/browser/resources/chromeos/emulator/shared_styles.html +++ b/chrome/browser/resources/chromeos/emulator/shared_styles.html
@@ -13,12 +13,6 @@ -webkit-margin-start: 15px; } - paper-dialog { - height: 90%; - overflow-y: scroll; - width: 40%; - } - paper-radio-button { display: inline-block; }
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.html b/chrome/browser/resources/chromeos/login/oobe_welcome.html index 275db8a..b101431 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.html +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.html
@@ -2,9 +2,9 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_select.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_select.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
diff --git a/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp b/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp index 2f02c48d..b43625b1 100644 --- a/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp
@@ -6,8 +6,8 @@ { 'target_name': 'network_ui', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_network_icon_externs', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_network_icon_externs', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', '<(EXTERNS_GYP):networking_private',
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.html b/chrome/browser/resources/chromeos/network_ui/network_ui.html index 896c20d0..09b377c 100644 --- a/chrome/browser/resources/chromeos/network_ui/network_ui.html +++ b/chrome/browser/resources/chromeos/network_ui/network_ui.html
@@ -6,9 +6,9 @@ <title id="network" i18n-content="titleText"></title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://network/network_ui.css"> - <link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> - <link rel="import" href="chrome://resources/cr_elements/network/cr_network_select.html"> - <link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> + <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> + <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_select.html"> + <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
diff --git a/chrome/browser/resources/chromeos/quick_unlock/compiled_resources2.gyp b/chrome/browser/resources/chromeos/quick_unlock/compiled_resources2.gyp index 427e9c53..a953cb94 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/quick_unlock/compiled_resources2.gyp
@@ -4,6 +4,15 @@ { 'targets': [ { + 'target_name': 'md_pin_keyboard', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-button/compiled_resources2.gyp:paper-button-extracted', + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'pin_keyboard', 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
diff --git a/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html b/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html index 37465ce..c6e23ebd 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html +++ b/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html
@@ -176,7 +176,7 @@ } </style> - <div id="root"> + <div id="root" on-contextmenu="onContextMenu_"> <div id="container-constrained-width"> <div class="row first-row"> <paper-input id="pinInput" type="password" no-label-float @@ -260,7 +260,7 @@ has-content$="[[hasInput_(value)]]" icon="pin-keyboard:backspace" on-pointerdown="onBackspacePointerDown_" - on-pointerout="onBackspacePointerOut_" + on-pointerout="clearAndReset_" on-pointerup="onBackspacePointerUp_" aria-label="$i18n{pinKeyboardDeleteAccessibleName}" noink>
diff --git a/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.js b/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.js index bac665b..2ebcaaf4 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.js +++ b/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.js
@@ -174,9 +174,26 @@ this.passwordElement.selectionEnd = end; }, - /** Transfers focus to the input element. */ - focus: function() { - this.passwordElement.focus(); + /** + * Transfers blur to the input element. + */ + blur: function() { + this.passwordElement.blur(); + }, + + /** + * Transfers focus to the input element. This should not bring up the virtual + * keyboard, if it is enabled. After focus, moves the caret to the correct + * location if specified. + * @param {number=} opt_selectionStart + * @param {number=} opt_selectionEnd + */ + focus: function(opt_selectionStart, opt_selectionEnd) { + setTimeout(function() { + this.passwordElement.focus(); + this.selectionStart_ = opt_selectionStart || 0; + this.selectionEnd_ = opt_selectionEnd || 0; + }.bind(this), 0); }, /** @@ -192,16 +209,14 @@ var selectionStart = this.selectionStart_; this.value = this.value.substring(0, this.selectionStart_) + numberValue + this.value.substring(this.selectionEnd_); - this.selectionStart_ = selectionStart + 1; - this.selectionEnd_ = this.selectionStart_; // If a number button is clicked, we do not want to switch focus to the // button, therefore we transfer focus back to the input, but if a number // button is tabbed into, it should keep focus, so users can use tab and // spacebar/return to enter their PIN. if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); + this.focus(selectionStart + 1, selectionStart + 1); + event.stopImmediatePropagation(); }, /** Fires a submit event with the current PIN value. */ @@ -233,7 +248,7 @@ // character in front of the caret. var selectionStart = this.selectionStart_; var selectionEnd = this.selectionEnd_; - if (selectionStart == selectionEnd) + if (selectionStart == selectionEnd && selectionStart) selectionStart--; this.value = this.value.substring(0, selectionStart) + @@ -258,8 +273,8 @@ }.bind(this), INITIAL_BACKSPACE_DELAY_MS); if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); + this.focus(this.selectionStart_, this.selectionEnd_); + event.stopImmediatePropagation(); }, /** @@ -274,20 +289,6 @@ }, /** - * Called when the user exits the backspace button. Stops the interval - * callback. - * @param {Event} event The event object. - * @private - */ - onBackspacePointerOut_: function(event) { - this.clearAndReset_(); - - if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); - }, - - /** * Called when the user unpresses or untouches the backspace button. Stops the * interval callback and fires a backspace event if there is no interval * running. @@ -300,9 +301,14 @@ this.onPinClear_(); this.clearAndReset_(); + // Since on-down gives the input element focus, the input element will + // already have focus when on-up is called. This will actually bring up the + // virtual keyboard, even if focus() is wrapped in a setTimeout. Blur the + // input element first to workaround this. + this.blur(); if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); + this.focus(this.selectionStart_, this.selectionEnd_); + event.stopImmediatePropagation(); }, /** @@ -395,5 +401,16 @@ // (just numbers), if the document direction is rtl. return (document.dir == 'rtl') && !Number.isInteger(+password); }, + + /** + * Catch and stop propagation of context menu events since we the backspace + * button can be held down on touch. + * @param {!Event} e + * @private + */ + onContextMenu_: function(e) { + e.preventDefault(); + e.stopPropagation(); + }, }); })();
diff --git a/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html b/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html index 4c71b1ae..8c9bf45 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html +++ b/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.html
@@ -174,7 +174,7 @@ } </style> - <div id="root"> + <div id="root" on-contextmenu="onContextMenu_"> <div id="container-constrained-width"> <div class="row first-row"> <paper-input id="pinInput" type="password" no-label-float @@ -183,7 +183,7 @@ has-content$="[[hasInput_(value)]]" label="[[getInputPlaceholder_(enablePassword)]]" on-keydown="onInputKeyDown_" - hidden="[[!showPinInput_]]" autofocus> + hidden="[[!showPinInput_]]"> </paper-input> </div> <content select="[problem]"></content> @@ -251,7 +251,7 @@ has-content$="[[hasInput_(value)]]" icon="pin-keyboard:backspace" on-pointerdown="onBackspacePointerDown_" - on-pointerout="onBackspacePointerOut_" + on-pointerout="clearAndReset_" on-pointerup="onBackspacePointerUp_" aria-label="$i18n{pinKeyboardDeleteAccessibleName}" noink>
diff --git a/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.js b/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.js index bac665b..2ebcaaf4 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.js +++ b/chrome/browser/resources/chromeos/quick_unlock/pin_keyboard.js
@@ -174,9 +174,26 @@ this.passwordElement.selectionEnd = end; }, - /** Transfers focus to the input element. */ - focus: function() { - this.passwordElement.focus(); + /** + * Transfers blur to the input element. + */ + blur: function() { + this.passwordElement.blur(); + }, + + /** + * Transfers focus to the input element. This should not bring up the virtual + * keyboard, if it is enabled. After focus, moves the caret to the correct + * location if specified. + * @param {number=} opt_selectionStart + * @param {number=} opt_selectionEnd + */ + focus: function(opt_selectionStart, opt_selectionEnd) { + setTimeout(function() { + this.passwordElement.focus(); + this.selectionStart_ = opt_selectionStart || 0; + this.selectionEnd_ = opt_selectionEnd || 0; + }.bind(this), 0); }, /** @@ -192,16 +209,14 @@ var selectionStart = this.selectionStart_; this.value = this.value.substring(0, this.selectionStart_) + numberValue + this.value.substring(this.selectionEnd_); - this.selectionStart_ = selectionStart + 1; - this.selectionEnd_ = this.selectionStart_; // If a number button is clicked, we do not want to switch focus to the // button, therefore we transfer focus back to the input, but if a number // button is tabbed into, it should keep focus, so users can use tab and // spacebar/return to enter their PIN. if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); + this.focus(selectionStart + 1, selectionStart + 1); + event.stopImmediatePropagation(); }, /** Fires a submit event with the current PIN value. */ @@ -233,7 +248,7 @@ // character in front of the caret. var selectionStart = this.selectionStart_; var selectionEnd = this.selectionEnd_; - if (selectionStart == selectionEnd) + if (selectionStart == selectionEnd && selectionStart) selectionStart--; this.value = this.value.substring(0, selectionStart) + @@ -258,8 +273,8 @@ }.bind(this), INITIAL_BACKSPACE_DELAY_MS); if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); + this.focus(this.selectionStart_, this.selectionEnd_); + event.stopImmediatePropagation(); }, /** @@ -274,20 +289,6 @@ }, /** - * Called when the user exits the backspace button. Stops the interval - * callback. - * @param {Event} event The event object. - * @private - */ - onBackspacePointerOut_: function(event) { - this.clearAndReset_(); - - if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); - }, - - /** * Called when the user unpresses or untouches the backspace button. Stops the * interval callback and fires a backspace event if there is no interval * running. @@ -300,9 +301,14 @@ this.onPinClear_(); this.clearAndReset_(); + // Since on-down gives the input element focus, the input element will + // already have focus when on-up is called. This will actually bring up the + // virtual keyboard, even if focus() is wrapped in a setTimeout. Blur the + // input element first to workaround this. + this.blur(); if (!event.target.receivedFocusFromKeyboard) - this.focus(); - event.preventDefault(); + this.focus(this.selectionStart_, this.selectionEnd_); + event.stopImmediatePropagation(); }, /** @@ -395,5 +401,16 @@ // (just numbers), if the document direction is rtl. return (document.dir == 'rtl') && !Number.isInteger(+password); }, + + /** + * Catch and stop propagation of context menu events since we the backspace + * button can be held down on touch. + * @param {!Event} e + * @private + */ + onContextMenu_: function(e) { + e.preventDefault(); + e.stopPropagation(); + }, }); })();
diff --git a/chrome/browser/resources/help/compiled_resources2.gyp b/chrome/browser/resources/help/compiled_resources2.gyp index 6ce08ca..cbf5e3f 100644 --- a/chrome/browser/resources/help/compiled_resources2.gyp +++ b/chrome/browser/resources/help/compiled_resources2.gyp
@@ -14,7 +14,7 @@ '<(DEPTH)/third_party/jstemplate/util.js', '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', '<(DEPTH)/third_party/jstemplate/jstemplate.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_onc_types.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js', '<(DEPTH)/ui/webui/resources/js/action_link.js', '<(DEPTH)/ui/webui/resources/js/cr.js', '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', @@ -86,7 +86,7 @@ '<(DEPTH)/third_party/closure_compiler/externs/networking_private.js', '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', '<(DEPTH)/third_party/closure_compiler/externs/web_animations.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_network_icon_externs.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js', '../options/options_bundle.js', # Note: ^ this is just a copy of # ../options/compiled_resources2.gyp:options_bundle#source_files. Most
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.html b/chrome/browser/resources/md_bookmarks/command_manager.html index bc9b3e5b..d83d555 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.html +++ b/chrome/browser/resources/md_bookmarks/command_manager.html
@@ -33,7 +33,7 @@ command$="[[command]]" hidden$="[[!isCommandVisible_(command, menuIds_)]]" disabled$="[[!isCommandEnabled_(command, menuIds_)]]" - on-tap="onCommandClick_"> + on-click="onCommandClick_"> <span class="label"> [[getCommandLabel_(command, menuIds_)]] </span>
diff --git a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp index 70b5f5b..5c5d2a4 100644 --- a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp +++ b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
@@ -111,6 +111,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', 'actions', 'command_manager', + 'item', 'store_client', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/chrome/browser/resources/md_bookmarks/list.js b/chrome/browser/resources/md_bookmarks/list.js index c14fee3..e011bbc 100644 --- a/chrome/browser/resources/md_bookmarks/list.js +++ b/chrome/browser/resources/md_bookmarks/list.js
@@ -46,6 +46,7 @@ listeners: { 'click': 'deselectItems_', + 'open-item-menu': 'onOpenItemMenu_', }, attached: function() { @@ -132,6 +133,19 @@ }, /** + * @param {Event} e + * @private + */ + onOpenItemMenu_: function(e) { + var index = this.displayedIds_.indexOf( + /** @type {BookmarksItemElement} */ (e.path[0]).itemId); + var list = this.$.bookmarksCard; + // If the item is not visible, scroll to it before rendering the menu. + if (index < list.firstVisibleIndex || index > list.lastVisibleIndex) + list.scrollToIndex(index); + }, + + /** * @param {KeyboardEvent} e * @private */
diff --git a/chrome/browser/resources/md_user_manager/error_dialog.html b/chrome/browser/resources/md_user_manager/error_dialog.html index 6c403d34..f7964ca 100644 --- a/chrome/browser/resources/md_user_manager/error_dialog.html +++ b/chrome/browser/resources/md_user_manager/error_dialog.html
@@ -1,14 +1,12 @@ <link rel="import" href="/shared_styles.html"> -<link rel="import" href="/user_manager_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <dom-module id="error-dialog"> <template> <style include="shared-styles"> - #dialog { - --user-manager-dialog-title-bar: { - border-bottom: 0; - }; + :host { + color: var(--primary-text-color); } #message { @@ -17,11 +15,11 @@ word-wrap: break-word; } </style> - <user-manager-dialog id="dialog"> + <dialog is="cr-dialog" id="dialog"> <div class="body"> <div id="message">[[message_]]</div> </div> - </user-manager-dialog> + </dialog> </template> <script src="error_dialog.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_user_manager/error_dialog.js b/chrome/browser/resources/md_user_manager/error_dialog.js index 70d8acd..0b15eb7 100644 --- a/chrome/browser/resources/md_user_manager/error_dialog.js +++ b/chrome/browser/resources/md_user_manager/error_dialog.js
@@ -24,7 +24,7 @@ */ show: function(message) { this.message_ = message; - this.$.dialog.open(); + this.$.dialog.showModal(); } }); })();
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 84131ec..dea9538 100644 --- a/chrome/browser/resources/md_user_manager/import_supervised_user.html +++ b/chrome/browser/resources/md_user_manager/import_supervised_user.html
@@ -1,5 +1,6 @@ <link rel="import" href="/shared_styles.html"> -<link rel="import" href="/user_manager_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> @@ -9,7 +10,7 @@ <dom-module id="import-supervised-user"> <template> - <style include="shared-styles iron-flex iron-flex-alignment iron-positioning"> + <style include="shared-styles cr-shared-style iron-flex iron-flex-alignment iron-positioning"> :host { --item-height: 52px; --items-container-max-height: calc(var(--item-height) * 4); @@ -60,7 +61,7 @@ flex-shrink: 0; } </style> - <user-manager-dialog id="dialog"> + <dialog is="cr-dialog" id="dialog"> <div class="title">$i18n{supervisedUserImportTitle}</div> <div class="body"> <div id="message">$i18n{supervisedUserImportText}</div> @@ -76,17 +77,17 @@ </template> </paper-listbox> </div> - <div class="footer horizontal end-justified layout"> - <paper-button id="cancel" class="action secondary" dialog-dismiss> + <div class="button-container"> + <paper-button id="cancel" class="cancel-button" on-tap="onCancelTap_"> $i18n{cancel} </paper-button> - <paper-button id="import" class="action primary" + <paper-button id="import" class="action-button" on-tap="onImportTap_" disabled="[[isImportDisabled_(supervisedUserIndex_)]]"> $i18n{supervisedUserImportOk} </paper-button> </div> - </user-manager-dialog> + </dialog> </template> <script src="import_supervised_user.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_user_manager/import_supervised_user.js b/chrome/browser/resources/md_user_manager/import_supervised_user.js index 27491fa..7ffa156 100644 --- a/chrome/browser/resources/md_user_manager/import_supervised_user.js +++ b/chrome/browser/resources/md_user_manager/import_supervised_user.js
@@ -50,11 +50,6 @@ supervisedUserIndex_: {type: Number, value: NO_USER_SELECTED} }, - /** override */ - ready: function() { - this.$.dialog.lastFocusableNode = this.$.cancel; - }, - /** * Displays the dialog. * @param {(!SignedInUser|undefined)} signedInUser @@ -72,20 +67,16 @@ this.signedInUser_ = signedInUser || null; if (this.signedInUser_) - this.$.dialog.open(); + this.$.dialog.showModal(); }, /** - * param {number} supervisedUserIndex Index of the selected supervised user. - * @private + * @param {number} supervisedUserIndex Index of the selected supervised user. * @return {boolean} Whether the 'Import' button should be disabled. + * @private */ isImportDisabled_: function(supervisedUserIndex) { - var disabled = supervisedUserIndex == NO_USER_SELECTED; - if (!disabled) { - this.$.dialog.lastFocusableNode = this.$.import; - } - return disabled; + return supervisedUserIndex == NO_USER_SELECTED; }, /** @@ -102,6 +93,11 @@ 'import', {supervisedUser: supervisedUser, signedInUser: this.signedInUser_}); } - } + }, + + /** @private */ + onCancelTap_: function() { + this.$.dialog.close(); + }, }); })();
diff --git a/chrome/browser/resources/md_user_manager/shared_styles.html b/chrome/browser/resources/md_user_manager/shared_styles.html index 698f0d85..7c9d1aa1 100644 --- a/chrome/browser/resources/md_user_manager/shared_styles.html +++ b/chrome/browser/resources/md_user_manager/shared_styles.html
@@ -69,15 +69,6 @@ --iron-overlay-backdrop-opacity: .8; } - /* TODO(mahmadi): Move this back to user_manager_dialog.html when it does - * not break the dialog */ - user-manager-dialog { - --paper-dialog: { - font-size: inherit; - line-height: initial; - }; - } - .product-logo { content: -webkit-image-set( url(../../../app/theme/default_100_percent/%DISTRIBUTION%/product_logo_name_22.png) 1x,
diff --git a/chrome/browser/resources/md_user_manager/user_manager_dialog.html b/chrome/browser/resources/md_user_manager/user_manager_dialog.html deleted file mode 100644 index ee48a85..0000000 --- a/chrome/browser/resources/md_user_manager/user_manager_dialog.html +++ /dev/null
@@ -1,71 +0,0 @@ -<link rel="import" href="/shared_styles.html"> -<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/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog-behavior/paper-dialog-behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog-behavior/paper-dialog-shared-styles.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> - -<dom-module id="user-manager-dialog"> - <template> - <style include="shared-styles paper-dialog-shared-styles iron-flex iron-flex-alignment iron-positioning"> - :host { - border-radius: 2px; - width: 512px; - } - - :host > ::content > *, - :host > ::content > *:first-child, - :host > ::content > *:last-child { - /* Overrides paper-dialog-shared-styles. */ - margin: 0; - padding: 0; - } - - #title-bar { - align-items: center; - border-bottom: var(--user-manager-separator-line); - min-height: 52px; - @apply(--user-manager-dialog-title-bar); - } - - #close { - --paper-icon-button: { - height: 40px; - padding: 10px; - width: 40px; - }; - -webkit-margin-end: 6px; - -webkit-margin-start: auto; - flex-shrink: 0; - } - - :host ::content .title { - -webkit-margin-end: 10px; - -webkit-margin-start: 16px; - font-size: 16px; - } - - :host ::content .body > * { - padding: 0 16px; - } - - :host ::content .body > .no-padding { - padding: 0; - } - - :host ::content .footer { - margin-top: 20px; - padding: 16px; - } - </style> - <div id="title-bar" class="horizontal justified layout"> - <content select=".title"></content> - <paper-icon-button icon="cr:close" id="close" dialog-dismiss> - </paper-icon-button> - </div> - <content select=".body"></content> - <content select=".footer"></content> - </template> - <script src="user_manager_dialog.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/md_user_manager/user_manager_dialog.js b/chrome/browser/resources/md_user_manager/user_manager_dialog.js deleted file mode 100644 index 31721ac..0000000 --- a/chrome/browser/resources/md_user_manager/user_manager_dialog.js +++ /dev/null
@@ -1,70 +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. - -/** - * @fileoverview 'user-manager-dialog' is a modal dialog for the user manager. - */ -Polymer({ - is: 'user-manager-dialog', - - behaviors: [Polymer.PaperDialogBehavior], - - properties: { - /** @override */ - noCancelOnOutsideClick: {type: Boolean, value: true}, - - /** @override */ - withBackdrop: {type: Boolean, value: true}, - - /** - * The first node that can receive focus. - * @type {!Node} - */ - firstFocusableNode: { - type: Object, - value: function() { - return this.$.close; - }, - observer: 'firstFocusableNodeChanged_' - }, - - /** - * The last node that can receive focus. - * @type {!Node} - */ - lastFocusableNode: { - type: Object, - value: function() { - return this.$.close; - }, - observer: 'lastFocusableNodeChanged_' - } - }, - - /** - * Returns the first and the last focusable elements in order to wrap the - * focus for the dialog in Polymer.PaperDialogBehavior. - * @override - * @type {!Array<!Node>} - */ - get _focusableNodes() { - return [this.firstFocusableNode, this.lastFocusableNode]; - }, - - /** - * Observer for firstFocusableNode. Updates __firstFocusableNode in - * Polymer.PaperDialogBehavior. - */ - firstFocusableNodeChanged_: function(newValue) { - this.__firstFocusableNode = newValue; - }, - - /** - * Observer for lastFocusableNodeChanged_. Updates __lastFocusableNode in - * Polymer.PaperDialogBehavior. - */ - lastFocusableNodeChanged_: function(newValue) { - this.__lastFocusableNode = newValue; - } -});
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index b5706ea..3c1661d 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html
@@ -7,8 +7,8 @@ </header> <include src="automatic_settings_reset_banner.html"> <if expr="chromeos"> - <link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> - <link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> + <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> + <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <include src="secondary_user_banner.html"> <section id="network-section-cros"> <div id="network-section-header" class="section-header">
diff --git a/chrome/browser/resources/options/compiled_resources2.gyp b/chrome/browser/resources/options/compiled_resources2.gyp index cd965d9c..a9a64f9 100644 --- a/chrome/browser/resources/options/compiled_resources2.gyp +++ b/chrome/browser/resources/options/compiled_resources2.gyp
@@ -18,7 +18,7 @@ '<(DEPTH)/third_party/jstemplate/util.js', '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', '<(DEPTH)/third_party/jstemplate/jstemplate.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_onc_types.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js', '<(DEPTH)/ui/webui/resources/js/action_link.js', '<(DEPTH)/ui/webui/resources/js/cr.js', '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', @@ -90,7 +90,7 @@ '<(DEPTH)/third_party/closure_compiler/externs/networking_private.js', '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', '<(DEPTH)/third_party/closure_compiler/externs/web_animations.js', - '<(DEPTH)/ui/webui/resources/cr_elements/network/cr_network_icon_externs.js', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js', 'options_bundle.js', ], },
diff --git a/chrome/browser/resources/settings/android_apps_page/android_apps_page.html b/chrome/browser/resources/settings/android_apps_page/android_apps_page.html index adc6a7a..0fed226 100644 --- a/chrome/browser/resources/settings/android_apps_page/android_apps_page.html +++ b/chrome/browser/resources/settings/android_apps_page/android_apps_page.html
@@ -20,34 +20,40 @@ <settings-animated-pages id="pages" section="androidApps" focus-config="[[focusConfig_]]"> <neon-animatable route-path="default"> - <div id="android-apps" class="settings-box two-line first" actionable - on-tap="onSubpageTap_"> - <div class="start"> - $i18n{androidAppsPageLabel} - <div class="secondary" id="secondaryText" - inner-h-t-m-l="[[i18nAdvanced('androidAppsSubtext')]]"> + <template is="dom-if" if="[[havePlayStoreApp]]" restamp> + <div id="android-apps" class="settings-box two-line first" actionable + on-tap="onSubpageTap_"> + <div class="start"> + $i18n{androidAppsPageLabel} + <div class="secondary" id="secondaryText" + inner-h-t-m-l="[[i18nAdvanced('androidAppsSubtext')]]"> + </div> </div> + <cr-policy-pref-indicator pref="[[prefs.arc.enabled]]" + icon-aria-label="$i18n{androidAppsPageTitle}"> + </cr-policy-pref-indicator> + <template is="dom-if" if="[[androidAppsInfo.playStoreEnabled]]"> + <button class="subpage-arrow" is="paper-icon-button-light" + aria-label="$i18n{androidAppsPageTitle}" + aria-describedby="secondaryText"> + </button> + </template> + <template is="dom-if" if="[[!androidAppsInfo.playStoreEnabled]]"> + <div class="separator"></div> + <paper-button id="enable" class="secondary-button" + disabled="[[isEnforced_(prefs.arc.enabled)]]" + on-tap="onEnableTap_" + aria-label="$i18n{androidAppsPageTitle}" + aria-describedby="secondaryText"> + $i18n{androidAppsEnable} + </paper-button> + </template> </div> - <cr-policy-pref-indicator pref="[[prefs.arc.enabled]]" - icon-aria-label="$i18n{androidAppsPageTitle}"> - </cr-policy-pref-indicator> - <template is="dom-if" if="[[androidAppsInfo_.playStoreEnabled]]"> - <button class="subpage-arrow" is="paper-icon-button-light" - aria-label="$i18n{androidAppsPageTitle}" - aria-describedby="secondaryText"> - </button> - </template> - <template is="dom-if" if="[[!androidAppsInfo_.playStoreEnabled]]"> - <div class="separator"></div> - <paper-button id="enable" class="secondary-button" - disabled="[[isEnforced_(prefs.arc.enabled)]]" - on-tap="onEnableTap_" - aria-label="$i18n{androidAppsPageTitle}" - aria-describedby="secondaryText"> - $i18n{androidAppsEnable} - </paper-button> - </template> - </div> + </template> + <template is="dom-if" if="[[!havePlayStoreApp]]" restamp> + <settings-android-settings-element> + </settings-android-settings-element> + </template> </neon-animatable> <template is="dom-if" route-path="/androidApps/details"> @@ -55,7 +61,7 @@ associated-control="[[$$('#android-apps')]]" page-title="$i18n{androidAppsPageLabel}"> <settings-android-apps-subpage - android-apps-info="[[androidAppsInfo_]]" prefs="{{prefs}}"> + android-apps-info="[[androidAppsInfo]]" prefs="{{prefs}}"> </settings-android-apps-subpage> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/android_apps_page/android_apps_page.js b/chrome/browser/resources/settings/android_apps_page/android_apps_page.js index 68ade2d..6260887 100644 --- a/chrome/browser/resources/settings/android_apps_page/android_apps_page.js +++ b/chrome/browser/resources/settings/android_apps_page/android_apps_page.js
@@ -19,8 +19,9 @@ notify: true, }, - /** @private {!AndroidAppsInfo|undefined} */ - androidAppsInfo_: Object, + havePlayStoreApp: Boolean, + + androidAppsInfo: Object, /** @private {!Map<string, string>} */ focusConfig_: { @@ -35,37 +36,6 @@ }, }, - /** @private {?settings.AndroidAppsBrowserProxy} */ - browserProxy_: null, - - /** @private {?WebUIListener} */ - listener_: null, - - /** @override */ - created: function() { - this.browserProxy_ = settings.AndroidAppsBrowserProxyImpl.getInstance(); - }, - - /** @override */ - attached: function() { - this.listener_ = cr.addWebUIListener( - 'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this)); - this.browserProxy_.requestAndroidAppsInfo(); - }, - - /** @override */ - detached: function() { - cr.removeWebUIListener(this.listener_); - }, - - /** - * @param {AndroidAppsInfo} info - * @private - */ - androidAppsInfoUpdate_: function(info) { - this.androidAppsInfo_ = info; - }, - /** * @param {Event} event * @private @@ -82,7 +52,7 @@ /** @private */ onSubpageTap_: function() { - if (this.androidAppsInfo_.playStoreEnabled) + if (this.androidAppsInfo.playStoreEnabled) settings.navigateTo(settings.Route.ANDROID_APPS_DETAILS); }, });
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 691cb34..bfedd2a 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
@@ -4,25 +4,21 @@ <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.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"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="android_apps_browser_proxy.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="android_settings_element.html"> <dom-module id="settings-android-apps-subpage"> <template> <style include="settings-shared"></style> - <div id="manageApps" class="settings-box first" - on-keydown="onManageAndroidAppsKeydown_" - on-tap="onManageAndroidAppsTap_" actionable - hidden="[[!androidAppsInfo.settingsAppAvailable]]"> - <div class="start"> - <div>$i18n{androidAppsManageApps}</div> - </div> - <button class="icon-external" is="paper-icon-button-light"> - </button> - </div> + <template is="dom-if" if="[[androidAppsInfo.settingsAppAvailable]]" restamp> + <settings-android-settings-element> + </settings-android-settings-element> + </template> <template is="dom-if" if="[[allowRemove_(prefs.arc.enabled.*)]]"> <div id="remove" class="settings-box" actionable on-tap="onRemoveTap_">
diff --git a/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.js b/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.js index bb987f74..ea9e855 100644 --- a/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.js +++ b/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.js
@@ -50,22 +50,6 @@ }, /** - * @param {Event} event - * @private - */ - onManageAndroidAppsKeydown_: function(event) { - if (event.key != 'Enter' && event.key != ' ') - return; - this.browserProxy_.showAndroidAppsSettings(true /** keyboardAction */); - event.stopPropagation(); - }, - - /** @private */ - onManageAndroidAppsTap_: function(event) { - this.browserProxy_.showAndroidAppsSettings(false /** keyboardAction */); - }, - - /** * @return {boolean} * @private */
diff --git a/chrome/browser/resources/settings/android_apps_page/android_settings_element.html b/chrome/browser/resources/settings/android_apps_page/android_settings_element.html new file mode 100644 index 0000000..17b6e86 --- /dev/null +++ b/chrome/browser/resources/settings/android_apps_page/android_settings_element.html
@@ -0,0 +1,24 @@ +<link rel="import" href="chrome://resources/html/polymer.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"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> +<link rel="import" href="../i18n_setup.html"> +<link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="android_apps_browser_proxy.html"> + +<dom-module id="settings-android-settings-element"> + <template> + <style include="settings-shared"></style> + <div id="manageApps" class="settings-box first" + on-keydown="onManageAndroidAppsKeydown_" + on-tap="onManageAndroidAppsTap_" actionable> + <div class="start"> + <div>$i18n{androidAppsManageApps}</div> + </div> + <button class="icon-external" is="paper-icon-button-light"> + </button> + </div> + </template> + <script src="android_settings_element.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/android_apps_page/android_settings_element.js b/chrome/browser/resources/settings/android_apps_page/android_settings_element.js new file mode 100644 index 0000000..bdac9c5 --- /dev/null +++ b/chrome/browser/resources/settings/android_apps_page/android_settings_element.js
@@ -0,0 +1,36 @@ +// 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. + +/** + * @fileoverview + * 'android-settings-element' is the element to open Android settings. + */ + +Polymer({ + is: 'settings-android-settings-element', + + /** @private {?settings.AndroidAppsBrowserProxy} */ + browserProxy_: null, + + /** @override */ + created: function() { + this.browserProxy_ = settings.AndroidAppsBrowserProxyImpl.getInstance(); + }, + + /** + * @param {Event} event + * @private + */ + onManageAndroidAppsKeydown_: function(event) { + if (event.key != 'Enter' && event.key != ' ') + return; + this.browserProxy_.showAndroidAppsSettings(true /** keyboardAction */); + event.stopPropagation(); + }, + + /** @private */ + onManageAndroidAppsTap_: function(event) { + this.browserProxy_.showAndroidAppsSettings(false /** keyboardAction */); + }, +}); \ No newline at end of file
diff --git a/chrome/browser/resources/settings/android_apps_page/compiled_resources2.gyp b/chrome/browser/resources/settings/android_apps_page/compiled_resources2.gyp index a80a158..548dae1 100644 --- a/chrome/browser/resources/settings/android_apps_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/android_apps_page/compiled_resources2.gyp
@@ -19,7 +19,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', '<(EXTERNS_GYP):settings_private', 'android_apps_browser_proxy', - ], + ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, {
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index afbd8cc..fcff6d2c 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -14,6 +14,7 @@ <link rel="import" href="../settings_vars_css.html"> <if expr="chromeos"> +<link rel="import" href="../android_apps_page/android_apps_browser_proxy.html"> <link rel="import" href="../android_apps_page/android_apps_page.html"> <link rel="import" href="../bluetooth_page/bluetooth_page.html"> <link rel="import" href="../device_page/device_page.html"> @@ -159,11 +160,13 @@ </template> <if expr="chromeos"> <template is="dom-if" - if="[[shouldShowAndroidApps_(showAndroidApps, pageVisibility)]]" + if="[[shouldShowAndroidApps_(showAndroidApps, androidAppsInfo, pageVisibility)]]" restamp> <settings-section page-title="$i18n{androidAppsPageTitle}" section="androidApps"> - <settings-android-apps-page prefs="{{prefs}}"> + <settings-android-apps-page prefs="{{prefs}}" + android-apps-info="[[androidAppsInfo]]" + have-play-store-app="[[havePlayStoreApp]]"> </settings-android-apps-page> </settings-section> </template>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js index 9fd3155e..fe8cc862 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -20,6 +20,11 @@ showAndroidApps: Boolean, + havePlayStoreApp: Boolean, + + /** @type {!AndroidAppsInfo|undefined} */ + androidAppsInfo: Object, + showChromeCleanup: { type: Boolean, value: function() { @@ -93,6 +98,13 @@ this.addEventListener('chrome-cleanup-dismissed', function(e) { this.showChromeCleanup = false; }.bind(this)); + + if (settings.AndroidAppsBrowserProxyImpl) { + cr.addWebUIListener( + 'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this)); + settings.AndroidAppsBrowserProxyImpl.getInstance() + .requestAndroidAppsInfo(); + } }, /** @@ -179,13 +191,32 @@ }, /** + * @param {!AndroidAppsInfo} info + * @private + */ + androidAppsInfoUpdate_: function(info) { + this.androidAppsInfo = info; + }, + + /** * @return {boolean} * @private */ shouldShowAndroidApps_: function() { var visibility = /** @type {boolean|undefined} */ ( this.get('pageVisibility.androidApps')); - return this.showAndroidApps && this.showPage_(visibility); + if (!this.showAndroidApps || !this.showPage_(visibility)) { + return false; + } + + // Section is invisible in case we don't have the Play Store app and + // settings app is not yet available. + if (!this.havePlayStoreApp && + (!this.androidAppsInfo || !this.androidAppsInfo.settingsAppAvailable)) { + return false; + } + + return true; }, /**
diff --git a/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp b/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp index 95174a4..ac834cf 100644 --- a/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp
@@ -8,6 +8,7 @@ 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', + '../android_apps_page/compiled_resources2.gyp:android_apps_browser_proxy', '../chrome_cleanup_page/compiled_resources2.gyp:chrome_cleanup_proxy', '../compiled_resources2.gyp:route', '../compiled_resources2.gyp:search_settings',
diff --git a/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp b/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp index 40301162..06972b3 100644 --- a/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp
@@ -8,7 +8,7 @@ 'dependencies': [ '../compiled_resources2.gyp:route', '../settings_page/compiled_resources2.gyp:settings_animated_pages', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', '<(EXTERNS_GYP):chrome_send', @@ -22,7 +22,7 @@ 'target_name': 'internet_config', 'dependencies': [ '../compiled_resources2.gyp:route', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', '<(EXTERNS_GYP):networking_private', @@ -34,7 +34,7 @@ 'target_name': 'internet_detail_page', 'dependencies': [ '../compiled_resources2.gyp:route', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -49,7 +49,7 @@ 'target_name': 'internet_known_networks_page', 'dependencies': [ '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(EXTERNS_GYP):networking_private', @@ -61,7 +61,7 @@ 'target_name': 'internet_subpage', 'dependencies': [ '../compiled_resources2.gyp:route', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -73,7 +73,7 @@ { 'target_name': 'network_apnlist', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, @@ -93,21 +93,21 @@ { 'target_name': 'network_ip_config', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'network_nameservers', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'network_property_list', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -120,7 +120,7 @@ '../compiled_resources2.gyp:route', '../controls/compiled_resources2.gyp:settings_checkbox', '../prefs/compiled_resources2.gyp:prefs_behavior', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -131,7 +131,7 @@ { 'target_name': 'network_proxy_input', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, @@ -143,7 +143,7 @@ 'target_name': 'network_siminfo', 'dependencies': [ '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_without_ink', '<(INTERFACES_GYP):networking_private_interface', @@ -153,7 +153,7 @@ { 'target_name': 'network_summary', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(INTERFACES_GYP):networking_private_interface', @@ -163,7 +163,7 @@ { 'target_name': 'network_summary_item', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -174,8 +174,8 @@ { 'target_name': 'tether_connection_dialog', 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', ],
diff --git a/chrome/browser/resources/settings/internet_page/internet_config.html b/chrome/browser/resources/settings/internet_page/internet_config.html index 8b8736a..92d222e 100644 --- a/chrome/browser/resources/settings/internet_page/internet_config.html +++ b/chrome/browser/resources/settings/internet_page/internet_config.html
@@ -1,5 +1,5 @@ -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 39b3a74..d7d2123a 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -1,9 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html">
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.html b/chrome/browser/resources/settings/internet_page/internet_page.html index 82c766ca..839f12b 100644 --- a/chrome/browser/resources/settings/internet_page/internet_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
diff --git a/chrome/browser/resources/settings/internet_page/internet_subpage.html b/chrome/browser/resources/settings/internet_page/internet_subpage.html index 5f20193..8fc5909 100644 --- a/chrome/browser/resources/settings/internet_page/internet_subpage.html +++ b/chrome/browser/resources/settings/internet_page/internet_subpage.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_list.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_list.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.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/iron-icon/iron-icon.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_apnlist.html b/chrome/browser/resources/settings/internet_page/network_apnlist.html index a425a62..2f72355 100644 --- a/chrome/browser/resources/settings/internet_page/network_apnlist.html +++ b/chrome/browser/resources/settings/internet_page/network_apnlist.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="../settings_vars_css.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_ip_config.html b/chrome/browser/resources/settings/internet_page/network_ip_config.html index fc0da65..f8fb2f9b 100644 --- a/chrome/browser/resources/settings/internet_page/network_ip_config.html +++ b/chrome/browser/resources/settings/internet_page/network_ip_config.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> <link rel="import" href="internet_shared_css.html"> <link rel="import" href="network_property_list.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_nameservers.html b/chrome/browser/resources/settings/internet_page/network_nameservers.html index a7178a8..a26ed36 100644 --- a/chrome/browser/resources/settings/internet_page/network_nameservers.html +++ b/chrome/browser/resources/settings/internet_page/network_nameservers.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input-container.html"> <link rel="import" href="../settings_vars_css.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.html b/chrome/browser/resources/settings/internet_page/network_property_list.html index 49d7c25..01a09c9 100644 --- a/chrome/browser/resources/settings/internet_page/network_property_list.html +++ b/chrome/browser/resources/settings/internet_page/network_property_list.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.html b/chrome/browser/resources/settings/internet_page/network_proxy.html index d9568a7..d6da26b 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html"> <link rel="import" href="chrome://resources/html/assert.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.html b/chrome/browser/resources/settings/internet_page/network_siminfo.html index d09ec27..e2849cc 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.html +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.html
@@ -1,7 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.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/polymer/v1_0/iron-a11y-keys/iron-a11y-keys.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_summary.html b/chrome/browser/resources/settings/internet_page/network_summary.html index 315a1043..f31a25c 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary.html +++ b/chrome/browser/resources/settings/internet_page/network_summary.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="network_summary_item.html">
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.html b/chrome/browser/resources/settings/internet_page/network_summary_item.html index b258d4ae..6a9295ee 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary_item.html +++ b/chrome/browser/resources/settings/internet_page/network_summary_item.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
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 b618dcbdc..9eb17a9 100644 --- a/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html +++ b/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="../icons.html"> <link rel="import" href="../route.html">
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.html b/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.html index 738fb92..fe28ea4 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.html
@@ -168,7 +168,8 @@ </button> </template> <template is="dom-if" if="[[!showDots_(item.metadata)]]"> - <button is="paper-icon-button-light" class="icon-external" + <button is="paper-icon-button-light" id="remoteCreditCardLink" + class="icon-external" on-tap="onRemoteEditCreditCardTap_" actionable></button> </template> </div>
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 e0fc22a..ef5d2bb 100644 --- a/chrome/browser/resources/settings/people_page/setup_pin_dialog.html +++ b/chrome/browser/resources/settings/people_page/setup_pin_dialog.html
@@ -51,8 +51,7 @@ <div id="pinKeyboardDiv" class="settings-box continuation"> <pin-keyboard id="pinKeyboard" on-pin-change="onPinChange_" on-submit="onPinSubmit_" value="{{pinKeyboardValue_}}" - has-error$="[[hasError_(problemMessage_, problemClass_)]]" - autofocus> + has-error$="[[hasError_(problemMessage_, problemClass_)]]"> <!-- Warning/error; only shown if title is hidden. --> <div id="problemDiv" class$="[[problemClass_]]" hidden="[[!problemMessage_]]" problem>
diff --git a/chrome/browser/resources/settings/people_page/setup_pin_dialog.js b/chrome/browser/resources/settings/people_page/setup_pin_dialog.js index ee0ce67..4056aab 100644 --- a/chrome/browser/resources/settings/people_page/setup_pin_dialog.js +++ b/chrome/browser/resources/settings/people_page/setup_pin_dialog.js
@@ -103,6 +103,7 @@ attached: function() { this.resetState_(); this.$.dialog.showModal(); + this.$.pinKeyboard.focus(); // Show the pin is too short error when first displaying the PIN dialog. this.problemClass_ = ProblemType.WARNING;
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html index 1f12c0e..bcf5d788 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.html +++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -46,6 +46,7 @@ <settings-basic-page prefs="{{prefs}}" page-visibility="[[pageVisibility]]" show-android-apps="[[showAndroidApps]]" + have-play-store-app="[[havePlayStoreApp]]" on-subpage-expand="onSubpageExpand_" in-search-mode="[[inSearchMode_]]" advanced-toggle-expanded="{{advancedToggleExpanded}}">
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index e42680c3..db5ed45 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -77,6 +77,8 @@ pageVisibility: Object, showAndroidApps: Boolean, + + havePlayStoreApp: Boolean, }, /** @override */
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 80a57d27..a8f79bf 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -1088,6 +1088,12 @@ type="chrome_html" preprocess="true" allowexternalscript="true" /> + <structure name="IDR_SETTINGS_ANDROID_SETTINGS_ELEMENT_HTML" + file="android_apps_page/android_settings_element.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_ANDROID_SETTINGS_ELEMENT_JS" + file="android_apps_page/android_settings_element.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_BLUETOOTH_DEVICE_DIALOG_HTML" file="bluetooth_page/bluetooth_device_dialog.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/settings_ui/compiled_resources2.gyp b/chrome/browser/resources/settings/settings_ui/compiled_resources2.gyp index 3b836f0..01b520ca 100644 --- a/chrome/browser/resources/settings/settings_ui/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/settings_ui/compiled_resources2.gyp
@@ -6,10 +6,10 @@ { 'target_name': 'settings_ui', 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/cr_drawer/compiled_resources2.gyp:cr_drawer', '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar', '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar_search_field', - '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_indicator_behavior', '../compiled_resources2.gyp:direction_delegate', '../compiled_resources2.gyp:global_scroll_target_behavior',
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html index d44dea12..05d56eb6 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -16,7 +16,7 @@ <link rel="import" href="../settings_vars_css.html"> <if expr="chromeos"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> </if> <dom-module id="settings-ui"> @@ -94,6 +94,7 @@ <template is="dom-if" id="drawerTemplate"> <settings-menu page-visibility="[[pageVisibility_]]" show-android-apps="[[showAndroidApps_]]" + have-play-store-app="[[havePlayStoreApp_]]" on-iron-activate="onIronActivate_" advanced-opened="{{advancedOpened_}}"> </settings-menu> @@ -108,6 +109,7 @@ toolbar-spinner-active="{{toolbarSpinnerActive_}}" page-visibility="[[pageVisibility_]]" show-android-apps="[[showAndroidApps_]]" + have-play-store-app="[[havePlayStoreApp_]]" advanced-toggle-expanded="{{advancedOpened_}}"> </settings-main> </div>
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index 279ebc7b..66db2641 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -60,6 +60,9 @@ showAndroidApps_: Boolean, /** @private */ + havePlayStoreApp_: Boolean, + + /** @private */ lastSearchQuery_: { type: String, value: '', @@ -159,6 +162,8 @@ this.showAndroidApps_ = loadTimeData.valueExists('androidAppsVisible') && loadTimeData.getBoolean('androidAppsVisible'); + this.havePlayStoreApp_ = loadTimeData.valueExists('havePlayStoreApp') && + loadTimeData.getBoolean('havePlayStoreApp'); this.addEventListener('show-container', function() { this.$.container.style.visibility = 'visible';
diff --git a/chrome/browser/resources/settings/site_settings/site_list.js b/chrome/browser/resources/settings/site_settings/site_list.js index eb5290fe..8fe62c5 100644 --- a/chrome/browser/resources/settings/site_settings/site_list.js +++ b/chrome/browser/resources/settings/site_settings/site_list.js
@@ -390,14 +390,20 @@ * @return {string} The site description. */ computeSiteDescription_: function(item) { - if (item.incognito && item.embeddingDisplayName.length > 0) { - return loadTimeData.getStringF( - 'embeddedIncognitoSite', item.embeddingDisplayName); + var displayName = ''; + if (item.embeddingOrigin) { + displayName = loadTimeData.getStringF( + 'embeddedOnHost', this.sanitizePort(item.embeddingOrigin)); + } else if (this.category == settings.ContentSettingsTypes.GEOLOCATION) { + displayName = loadTimeData.getString('embeddedOnAnyHost'); } - if (item.incognito) + if (item.incognito) { + if (displayName.length > 0) + return loadTimeData.getStringF('embeddedIncognitoSite', displayName); return loadTimeData.getString('incognitoSite'); - return item.embeddingDisplayName; + } + return displayName; }, /**
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js index 3b8f6442..de28654 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -95,22 +95,6 @@ }, /** - * Looks up the human-friendly embedder string to show in the UI. - * @param {string} embeddingOrigin The embedding origin to show. - * @param {string} category The category requesting it. - * @return {string} The string to show. - */ - getEmbedderString: function(embeddingOrigin, category) { - if (embeddingOrigin == '') { - if (category != settings.ContentSettingsTypes.GEOLOCATION) - return ''; - return loadTimeData.getStringF('embeddedOnHost', '*'); - } - return loadTimeData.getStringF( - 'embeddedOnHost', this.sanitizePort(embeddingOrigin)); - }, - - /** * Returns the icon to use for a given site. * @param {string} site The url of the site to fetch the icon for. * @return {string} The background-image style with the favicon. @@ -160,11 +144,6 @@ expandSiteException: function(exception) { var origin = exception.origin; var embeddingOrigin = exception.embeddingOrigin; - var embeddingDisplayName = ''; - if (origin != embeddingOrigin) { - embeddingDisplayName = - this.getEmbedderString(embeddingOrigin, this.category); - } var enforcement = ''; if (exception.source == 'extension' || exception.source == 'HostedApp' || @@ -179,7 +158,6 @@ origin: origin, displayName: exception.displayName, embeddingOrigin: embeddingOrigin, - embeddingDisplayName: embeddingDisplayName, incognito: exception.incognito, setting: exception.setting, enforcement: enforcement,
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js index e335cdf..acd83ba 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
@@ -22,7 +22,6 @@ * The site exception information passed form the C++ handler. * See also: SiteException. * @typedef {{embeddingOrigin: string, - * embeddingDisplayName: string, * incognito: boolean, * origin: string, * displayName: string, @@ -36,7 +35,6 @@ * See also: RawSiteException. * @typedef {{category: !settings.ContentSettingsTypes, * embeddingOrigin: string, - * embeddingDisplayName: string, * incognito: boolean, * origin: string, * displayName: string,
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_browsertest_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_browsertest_win.cc index 1695a3a..2954f7b 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_browsertest_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_browsertest_win.cc
@@ -79,8 +79,6 @@ class ChromeCleanerTagForResettingTest : public InProcessBrowserTest { public: void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature); } @@ -152,8 +150,6 @@ public ::testing::WithParamInterface<CleanupCompletionState> { public: void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - completion_state_ = GetParam(); ASSERT_TRUE(completion_state_ >= CleanupCompletionState::kNotAvailable && completion_state_ <= CleanupCompletionState::kInvalidValue);
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 866d8fd..146580c 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -13,6 +13,8 @@ #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" +#include "chrome/browser/signin/account_tracker_service_factory.h" +#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/common/pref_names.h" #include "components/browser_sync/profile_sync_service.h" @@ -20,6 +22,9 @@ #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/password_protection/password_protection_request.h" #include "components/safe_browsing_db/database_manager.h" +#include "components/signin/core/browser/account_info.h" +#include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/signin_manager.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" @@ -144,6 +149,29 @@ sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES); } +PasswordProtectionService::SyncAccountType +ChromePasswordProtectionService::GetSyncAccountType() { + DCHECK(profile_); + SigninManagerBase* signin_manager = + SigninManagerFactory::GetForProfileIfExists(profile_); + + if (!signin_manager) + return LoginReputationClientRequest::PasswordReuseEvent::NOT_SIGNED_IN; + + AccountInfo account_info = signin_manager->GetAuthenticatedAccountInfo(); + + if (account_info.account_id.empty() || account_info.hosted_domain.empty()) { + return LoginReputationClientRequest::PasswordReuseEvent::NOT_SIGNED_IN; + } + + // For gmail or googlemail account, the hosted_domain will always be + // kNoHostedDomainFound. + return account_info.hosted_domain == + std::string(AccountTrackerService::kNoHostedDomainFound) + ? LoginReputationClientRequest::PasswordReuseEvent::GMAIL + : LoginReputationClientRequest::PasswordReuseEvent::GSUITE; +} + void ChromePasswordProtectionService::ShowPhishingInterstitial( const GURL& phishing_url, const std::string& token,
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.h b/chrome/browser/safe_browsing/chrome_password_protection_service.h index adfd93e..6596b24 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.h +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.h
@@ -54,6 +54,8 @@ const std::string& token, content::WebContents* web_contents) override; + PasswordProtectionService::SyncAccountType GetSyncAccountType() override; + FRIEND_TEST_ALL_PREFIXES( ChromePasswordProtectionServiceTest, VerifyFinchControlForLowReputationPingSBEROnlyNoIncognito); @@ -65,6 +67,8 @@ FRIEND_TEST_ALL_PREFIXES( ChromePasswordProtectionServiceTest, VerifyFinchControlForLowReputationPingAllButNoIncognito); + FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceTest, + VerifyGetSyncAccountType); private: friend class MockChromePasswordProtectionService;
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index f496f390..f24d7cb 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -6,11 +6,24 @@ #include "base/memory/ref_counted.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/safe_browsing/ui_manager.h" +#include "chrome/browser/signin/account_fetcher_service_factory.h" +#include "chrome/browser/signin/account_tracker_service_factory.h" +#include "chrome/browser/signin/chrome_signin_client_factory.h" +#include "chrome/browser/signin/fake_account_fetcher_service_builder.h" +#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h" +#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" +#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/test_signin_client_builder.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/password_protection/password_protection_request.h" +#include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/fake_account_fetcher_service.h" +#include "components/signin/core/browser/signin_manager.h" +#include "components/signin/core/browser/signin_manager_base.h" #include "components/variations/variations_params_manager.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" @@ -19,9 +32,23 @@ namespace safe_browsing { namespace { + const char kPhishingURL[] = "http://phishing.com"; +const char kTestAccountID[] = "account_id"; +const char kTestEmail[] = "foo@example.com"; + +std::unique_ptr<KeyedService> SigninManagerBuild( + content::BrowserContext* context) { + Profile* profile = static_cast<Profile*>(context); + std::unique_ptr<SigninManagerBase> service(new SigninManagerBase( + ChromeSigninClientFactory::GetInstance()->GetForProfile(profile), + AccountTrackerServiceFactory::GetForProfile(profile))); + service->Initialize(NULL); + return std::move(service); } +} // namespace + class MockSafeBrowsingUIManager : public SafeBrowsingUIManager { public: explicit MockSafeBrowsingUIManager(SafeBrowsingService* service) @@ -110,6 +137,19 @@ ChromeRenderViewHostTestHarness::TearDown(); } + content::BrowserContext* CreateBrowserContext() override { + TestingProfile::Builder builder; + builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(), + BuildFakeProfileOAuth2TokenService); + builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(), + signin::BuildTestSigninClient); + builder.AddTestingFactory(SigninManagerFactory::GetInstance(), + SigninManagerBuild); + builder.AddTestingFactory(AccountFetcherServiceFactory::GetInstance(), + FakeAccountFetcherServiceBuilder::BuildForTests); + return builder.Build().release(); + } + // Sets up Finch trial feature parameters. void SetFeatureParams(const base::Feature& feature, const std::string& trial_name, @@ -149,6 +189,19 @@ service_->RequestFinished(request, false, std::move(response)); } + void SetUpSyncAccount(const std::string& hosted_domain) { + FakeAccountFetcherService* account_fetcher_service = + static_cast<FakeAccountFetcherService*>( + AccountFetcherServiceFactory::GetForProfile(profile())); + AccountTrackerService* account_tracker_service = + AccountTrackerServiceFactory::GetForProfile(profile()); + account_fetcher_service->FakeUserInfoFetchSuccess( + account_tracker_service->PickAccountIdForAccount(kTestAccountID, + kTestEmail), + kTestEmail, kTestAccountID, hosted_domain, "full_name", "given_name", + "locale", "http://picture.example.com/picture.jpg"); + } + protected: variations::testing::VariationParamsManager params_manager_; base::test::ScopedFeatureList scoped_feature_list_; @@ -441,4 +494,16 @@ RequestFinished(request_.get(), std::move(verdict_)); } +TEST_F(ChromePasswordProtectionServiceTest, VerifyGetSyncAccountType) { + SigninManagerBase* signin_manager = static_cast<SigninManagerBase*>( + SigninManagerFactory::GetForProfile(profile())); + signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); + SetUpSyncAccount(std::string(AccountTrackerService::kNoHostedDomainFound)); + EXPECT_EQ(LoginReputationClientRequest::PasswordReuseEvent::GMAIL, + service_->GetSyncAccountType()); + + SetUpSyncAccount("example.edu"); + EXPECT_EQ(LoginReputationClientRequest::PasswordReuseEvent::GSUITE, + service_->GetSyncAccountType()); +} } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc index 1eb450a..53b518d 100644 --- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc +++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
@@ -20,7 +20,8 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/sequenced_task_runner.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_traits.h" #include "components/safe_browsing/csd.pb.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/download_item.h" @@ -126,7 +127,7 @@ // Reads and parses a DownloadMetadata message from |metadata_path| into // |metadata|. -void ReadMetadataOnWorkerPool(const base::FilePath& metadata_path, +void ReadMetadataInBackground(const base::FilePath& metadata_path, DownloadMetadata* metadata) { using base::File; DCHECK(metadata); @@ -166,7 +167,7 @@ } // Writes |download_metadata| to |metadata_path|. -void WriteMetadataOnWorkerPool(const base::FilePath& metadata_path, +void WriteMetadataInBackground(const base::FilePath& metadata_path, DownloadMetadata* download_metadata) { MetadataWriteResult result = NUM_WRITE_RESULTS; std::string file_data; @@ -183,7 +184,7 @@ } // Deletes |metadata_path|. -void DeleteMetadataOnWorkerPool(const base::FilePath& metadata_path) { +void DeleteMetadataInBackground(const base::FilePath& metadata_path) { bool success = base::DeleteFile(metadata_path, false /* not recursive */); UMA_HISTOGRAM_BOOLEAN("SBIRS.DownloadMetadata.DeleteSuccess", success); } @@ -214,8 +215,7 @@ class DownloadMetadataManager::ManagerContext : public content::DownloadItem::Observer { public: - ManagerContext(const scoped_refptr<base::SequencedTaskRunner>& read_runner, - const scoped_refptr<base::SequencedTaskRunner>& write_runner, + ManagerContext(scoped_refptr<base::SequencedTaskRunner> task_runner, content::DownloadManager* download_manager); // Detaches this context from its owner. The owner must not access the context @@ -274,14 +274,14 @@ void CommitRequest(content::DownloadItem* item, std::unique_ptr<ClientDownloadRequest> request); - // Posts a task in the worker pool to read the metadata from disk. + // Posts a background task to read the metadata from disk. void ReadMetadata(); - // Posts a task in the worker pool to write the metadata to disk. + // Posts a background task to write the metadata to disk. void WriteMetadata(); - // Removes metadata for the context from memory and posts a task in the worker - // pool to delete it on disk. + // Removes metadata for the context from memory and posts a background task to + // delete it on disk. void RemoveMetadata(); // Clears the |pending_items_| mapping. @@ -300,11 +300,8 @@ // Updates the last opened time in the metadata and writes it to disk. void UpdateLastOpenedTime(const base::Time& last_opened_time); - // A task runner to which read tasks are posted. - scoped_refptr<base::SequencedTaskRunner> read_runner_; - - // A task runner to which write tasks are posted. - scoped_refptr<base::SequencedTaskRunner> write_runner_; + // A task runner to which IO tasks are posted. + const scoped_refptr<base::SequencedTaskRunner> task_runner_; // The path to the metadata file for this context. base::FilePath metadata_path_; @@ -340,22 +337,11 @@ // DownloadMetadataManager ----------------------------------------------------- -DownloadMetadataManager::DownloadMetadataManager( - const scoped_refptr<base::SequencedWorkerPool>& worker_pool) { - base::SequencedWorkerPool::SequenceToken token( - worker_pool->GetSequenceToken()); - // Do not block shutdown on reads since nothing will come of it. - read_runner_ = worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( - token, base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); - // Block shutdown on writes only if they've already begun. - write_runner_ = worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( - token, base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); -} - -DownloadMetadataManager::DownloadMetadataManager( - const scoped_refptr<base::SequencedTaskRunner>& task_runner) - : read_runner_(task_runner), write_runner_(task_runner) { -} +DownloadMetadataManager::DownloadMetadataManager() + : task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, + base::MayBlock()})) {} DownloadMetadataManager::~DownloadMetadataManager() { // Destruction may have taken place before managers have gone down. @@ -373,7 +359,7 @@ return; download_manager->AddObserver(this); contexts_[download_manager] = - new ManagerContext(read_runner_, write_runner_, download_manager); + new ManagerContext(task_runner_, download_manager); } void DownloadMetadataManager::SetRequest(content::DownloadItem* item, @@ -404,9 +390,9 @@ // Fire off a task to load the details and return them to the caller. DownloadMetadata* metadata = new DownloadMetadata(); - read_runner_->PostTaskAndReply( + task_runner_->PostTaskAndReply( FROM_HERE, - base::BindOnce(&ReadMetadataOnWorkerPool, + base::BindOnce(&ReadMetadataInBackground, GetMetadataPath(browser_context), metadata), base::BindOnce(&ReturnResults, callback, base::Passed(base::WrapUnique(metadata)))); @@ -438,11 +424,9 @@ // DownloadMetadataManager::ManagerContext ------------------------------------- DownloadMetadataManager::ManagerContext::ManagerContext( - const scoped_refptr<base::SequencedTaskRunner>& read_runner, - const scoped_refptr<base::SequencedTaskRunner>& write_runner, + scoped_refptr<base::SequencedTaskRunner> task_runner, content::DownloadManager* download_manager) - : read_runner_(read_runner), - write_runner_(write_runner), + : task_runner_(std::move(task_runner)), metadata_path_(GetMetadataPath(download_manager->GetBrowserContext())), state_(WAITING_FOR_LOAD), weak_factory_(this) { @@ -567,18 +551,18 @@ DownloadMetadata* metadata = new DownloadMetadata(); // Do not block shutdown on this read since nothing will come of it. - read_runner_->PostTaskAndReply( + task_runner_->PostTaskAndReply( FROM_HERE, - base::BindOnce(&ReadMetadataOnWorkerPool, metadata_path_, metadata), + base::BindOnce(&ReadMetadataInBackground, metadata_path_, metadata), base::BindOnce(&DownloadMetadataManager::ManagerContext::OnMetadataReady, weak_factory_.GetWeakPtr(), base::Passed(base::WrapUnique(metadata)))); } void DownloadMetadataManager::ManagerContext::WriteMetadata() { - write_runner_->PostTask( + task_runner_->PostTask( FROM_HERE, - base::BindOnce(&WriteMetadataOnWorkerPool, metadata_path_, + base::BindOnce(&WriteMetadataInBackground, metadata_path_, base::Owned(new DownloadMetadata(*download_metadata_)))); } @@ -592,8 +576,8 @@ } // Remove any metadata. download_metadata_.reset(); - write_runner_->PostTask( - FROM_HERE, base::BindOnce(&DeleteMetadataOnWorkerPool, metadata_path_)); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&DeleteMetadataInBackground, metadata_path_)); // Run callbacks (only present in case of a transition to LOAD_COMPLETE). RunCallbacks(); }
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h index 4c480d4cc..c666c24b 100644 --- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h +++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h
@@ -15,7 +15,6 @@ namespace base { class SequencedTaskRunner; -class SequencedWorkerPool; } namespace content { @@ -39,15 +38,7 @@ std::unique_ptr<ClientIncidentReport_DownloadDetails>)> GetDownloadDetailsCallback; - // Constructs a new instance for which disk IO operations will take place in - // |worker_pool|. - explicit DownloadMetadataManager( - const scoped_refptr<base::SequencedWorkerPool>& worker_pool); - - // Constructor that allows tests to provide a specific runner for - // asynchronous tasks. - explicit DownloadMetadataManager( - const scoped_refptr<base::SequencedTaskRunner>& task_runner); + DownloadMetadataManager(); ~DownloadMetadataManager() override; // Adds |download_manager| to the set observed by the metadata manager. @@ -82,11 +73,8 @@ typedef std::map<content::DownloadManager*, ManagerContext*> ManagerToContextMap; - // A task runner to which read tasks are posted. - scoped_refptr<base::SequencedTaskRunner> read_runner_; - - // A task runner to which write tasks are posted. - scoped_refptr<base::SequencedTaskRunner> write_runner_; + // A task runner to which IO tasks are posted. + const scoped_refptr<base::SequencedTaskRunner> task_runner_; // Contexts for each DownloadManager that has been added and has not yet // "gone down".
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc index 25a41a2..23b85b6 100644 --- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
@@ -15,7 +15,6 @@ #include "base/files/file_util.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" #include "chrome/test/base/testing_profile.h" #include "components/safe_browsing/csd.pb.h" #include "content/public/browser/browser_thread.h" @@ -23,6 +22,7 @@ #include "content/public/test/mock_download_item.h" #include "content/public/test/mock_download_manager.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.cc" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -79,9 +79,7 @@ // a DownloadManager. class MockDownloadMetadataManager : public DownloadMetadataManager { public: - MockDownloadMetadataManager( - const scoped_refptr<base::SequencedTaskRunner>& task_runner) - : DownloadMetadataManager(task_runner) {} + MockDownloadMetadataManager() = default; MOCK_METHOD1(GetDownloadManagerForBrowserContext, content::DownloadManager*(content::BrowserContext*)); @@ -106,11 +104,7 @@ protected: // Sets up a DownloadMetadataManager that will run tasks on the main test // thread. - DownloadMetadataManagerTestBase() - : manager_(scoped_refptr<base::SequencedTaskRunner>( - base::ThreadTaskRunnerHandle::Get())), - download_manager_(), - dm_observer_() {} + DownloadMetadataManagerTestBase() = default; // Returns the path to the test profile's DownloadMetadata file. base::FilePath GetMetadataPath() const { @@ -165,7 +159,7 @@ } // Runs all tasks posted to the test thread's message loop. - void RunAllTasks() { base::RunLoop().RunUntilIdle(); } + void RunAllTasks() { content::RunAllBlockingPoolTasksUntilIdle(); } // Adds a DownloadManager for the test profile. The DownloadMetadataManager's // observer is stashed for later use. Only call once per call to @@ -264,7 +258,7 @@ // The DownloadMetadataManager's content::DownloadManager::Observer. Captured // by download_manager_'s AddObserver action. - content::DownloadManager::Observer* dm_observer_; + content::DownloadManager::Observer* dm_observer_ = nullptr; }; // A parameterized test that exercises GetDownloadDetails. The parameters
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc index d0a150f..e95b976 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -20,7 +20,6 @@ #include "base/strings/string_util.h" #include "base/task_scheduler/post_task.h" #include "base/task_scheduler/task_traits.h" -#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" @@ -334,7 +333,6 @@ delayed_analysis_callbacks_( base::TimeDelta::FromMilliseconds(kDefaultCallbackIntervalMs), GetBackgroundTaskRunner()), - download_metadata_manager_(content::BrowserThread::GetBlockingPool()), receiver_weak_ptr_factory_(this), weak_ptr_factory_(this) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -422,7 +420,6 @@ this, &IncidentReportingService::OnCollationTimeout), delayed_analysis_callbacks_(delayed_task_interval, delayed_task_runner), - download_metadata_manager_(content::BrowserThread::GetBlockingPool()), receiver_weak_ptr_factory_(this), weak_ptr_factory_(this) { notification_registrar_.Add(this,
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h index ff996a4..15160c4eb 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -83,6 +83,7 @@ protected: friend class SafeBrowsingBlockingPageFactoryImpl; friend class SafeBrowsingBlockingPageTest; + friend class SafeBrowsingBlockingPageBrowserTest; friend class SafeBrowsingBlockingQuietPageFactoryImpl; friend class SafeBrowsingBlockingQuietPageTest; FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest,
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 1920c94..4107743 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -43,6 +43,7 @@ #include "components/safe_browsing_db/test_database_manager.h" #include "components/safe_browsing_db/util.h" #include "components/safe_browsing_db/v4_protocol_manager_util.h" +#include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/core/controller_client.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_interstitials/core/urls.h" @@ -58,6 +59,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_browser_thread.h" +#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" #include "net/cert/cert_verify_result.h" #include "net/cert/mock_cert_verifier.h" @@ -732,6 +734,28 @@ ->hit_report_sent(); } + // Helper method for LearnMore test below. Implemented as a test fixture + // method instead of in the test below because the whole test fixture class + // is friended by SafeBrowsingBlockingPage. + void MockHelpCenterUrl(InterstitialPage* interstitial_page) { + ASSERT_TRUE(https_server_.Start()); + scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate()); + net::CertVerifyResult verify_result; + verify_result.is_issued_by_known_root = true; + verify_result.verified_cert = cert; + verify_result.cert_status = 0; + mock_cert_verifier()->AddResultForCert(cert.get(), verify_result, net::OK); + + SafeBrowsingBlockingPage* sb_interstitial = + static_cast<SafeBrowsingBlockingPage*>( + interstitial_page->GetDelegateForTesting()); + security_interstitials::SecurityInterstitialControllerClient* client = + sb_interstitial->controller(); + + client->SetBaseHelpCenterUrlForTesting( + https_server_.GetURL("/title1.html")); + } + protected: TestThreatDetailsFactory details_factory_; @@ -798,12 +822,35 @@ IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, VisitWhitePaper) { SetupWarningAndNavigate(browser()); - EXPECT_EQ(VISIBLE, GetVisibility("whitepaper-link")); - EXPECT_TRUE(ClickAndWaitForDetach("whitepaper-link")); + EXPECT_EQ(1, browser()->tab_strip_model()->count()); + WebContents* interstitial_tab = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(interstitial_tab); - AssertNoInterstitial(false); // Assert the interstitial is gone - EXPECT_EQ(GetWhitePaperUrl(), - browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + EXPECT_EQ(VISIBLE, GetVisibility("whitepaper-link")); + content::TestNavigationObserver nav_observer(nullptr); + nav_observer.StartWatchingNewWebContents(); + EXPECT_TRUE(Click("whitepaper-link")); + + nav_observer.Wait(); + + EXPECT_EQ(2, browser()->tab_strip_model()->count()); + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); + + // Assert the interstitial is not present in the foreground tab. + AssertNoInterstitial(false); + + // Foreground tab displays the help center. + WebContents* new_tab = browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(new_tab); + EXPECT_EQ(GetWhitePaperUrl(), new_tab->GetURL()); + + // Interstitial should still display in the background tab. + browser()->tab_strip_model()->ActivateTabAt(0, true); + EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); + EXPECT_EQ(interstitial_tab, + browser()->tab_strip_model()->GetActiveWebContents()); + EXPECT_TRUE(YesInterstitial()); } IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, Proceed) { @@ -1112,17 +1159,35 @@ IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, LearnMore) { SetupWarningAndNavigate(browser()); - EXPECT_TRUE(ClickAndWaitForDetach("learn-more-link")); - AssertNoInterstitial(false); // Assert the interstitial is gone - // We are in the help page. - EXPECT_EQ( - GURL("https://support.google.com/chrome/answer/99020").GetWithEmptyPath(), - browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetURL() - .GetWithEmptyPath()); + WebContents* interstitial_tab = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(interstitial_tab); + + MockHelpCenterUrl(interstitial_tab->GetInterstitialPage()); + + EXPECT_EQ(1, browser()->tab_strip_model()->count()); + + content::TestNavigationObserver nav_observer(nullptr); + nav_observer.StartWatchingNewWebContents(); + SendCommand(security_interstitials::CMD_OPEN_HELP_CENTER); + nav_observer.Wait(); + + // A new tab has been opened. + EXPECT_EQ(2, browser()->tab_strip_model()->count()); + + // Interstitial does not display in the foreground tab. + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); + WebContents* new_tab = browser()->tab_strip_model()->GetWebContentsAt(1); + ASSERT_TRUE(new_tab); + EXPECT_FALSE(new_tab->ShowingInterstitialPage()); + + // Interstitial still displays in the background tab. + browser()->tab_strip_model()->ActivateTabAt(0, true); + EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); + EXPECT_EQ(interstitial_tab, + browser()->tab_strip_model()->GetActiveWebContents()); + EXPECT_TRUE(YesInterstitial()); } IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 307d627b..e0e0087 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -554,7 +554,6 @@ void TearDownOnMainThread() override { g_browser_process->safe_browsing_service()->ui_manager()->RemoveObserver( &observer_); - InProcessBrowserTest::TearDownOnMainThread(); } void SetUpInProcessBrowserTestFixture() override { @@ -1682,8 +1681,6 @@ } void TearDownInProcessBrowserTestFixture() override { - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); - sql::Connection db; base::FilePath cookie_path( SafeBrowsingService::GetCookieFilePathForTesting());
diff --git a/chrome/browser/safe_browsing/sandboxed_dmg_analyzer_mac.h b/chrome/browser/safe_browsing/sandboxed_dmg_analyzer_mac.h index 7aa69669..1455ebd 100644 --- a/chrome/browser/safe_browsing/sandboxed_dmg_analyzer_mac.h +++ b/chrome/browser/safe_browsing/sandboxed_dmg_analyzer_mac.h
@@ -10,7 +10,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "chrome/common/safe_archive_analyzer.mojom.h" +#include "chrome/common/safe_browsing/safe_archive_analyzer.mojom.h" #include "content/public/browser/utility_process_mojo_client.h" namespace safe_browsing {
diff --git a/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h b/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h index 0d476aa..a39a676 100644 --- a/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h +++ b/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h
@@ -10,8 +10,8 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "chrome/common/safe_archive_analyzer.mojom.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" +#include "chrome/common/safe_browsing/safe_archive_analyzer.mojom.h" #include "content/public/browser/utility_process_mojo_client.h" namespace safe_browsing {
diff --git a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc index 1d830578..faa7bed 100644 --- a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc +++ b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
@@ -72,7 +72,6 @@ void SetUpInProcessBrowserTestFixture() override { ASSERT_TRUE(test_server_.Start()); - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); } ImageFetcherImpl* CreateImageFetcher() { @@ -113,6 +112,7 @@ net::EmbeddedTestServer test_server_; TestImageFetcherDelegate delegate_; + private: DISALLOW_COPY_AND_ASSIGN(ImageFetcherImplBrowserTest); };
diff --git a/chrome/browser/sessions/OWNERS b/chrome/browser/sessions/OWNERS index 7d9a928..f66447ad 100644 --- a/chrome/browser/sessions/OWNERS +++ b/chrome/browser/sessions/OWNERS
@@ -2,7 +2,6 @@ per-file restore_on_startup_policy_handler*=atwilson@chromium.org -per-file session_restore_android*=dfalcantara@chromium.org per-file session_restore_android*=yfriedman@chromium.org per-file session_restore_android*=felipeg@chromium.org
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 596deefb..71d95be4 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -85,7 +85,6 @@ void SetUpCommandLine(base::CommandLine* command_line) override { // TODO(nkostylev): Investigate if we can remove this switch. command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests); - InProcessBrowserTest::SetUpCommandLine(command_line); } #endif
diff --git a/chrome/browser/signin/easy_unlock_service_factory.cc b/chrome/browser/signin/easy_unlock_service_factory.cc index 9c68aed2..5e54ddd 100644 --- a/chrome/browser/signin/easy_unlock_service_factory.cc +++ b/chrome/browser/signin/easy_unlock_service_factory.cc
@@ -84,6 +84,10 @@ int manifest_id = 0; #if defined(OS_CHROMEOS) + if (chromeos::ProfileHelper::IsLockScreenAppProfile( + Profile::FromBrowserContext(context))) { + return nullptr; + } if (chromeos::ProfileHelper::IsSigninProfile( Profile::FromBrowserContext(context))) { if (!context->IsOffTheRecord())
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.cc b/chrome/browser/ssl/chrome_expect_ct_reporter.cc index 9697c08..e569426 100644 --- a/chrome/browser/ssl/chrome_expect_ct_reporter.cc +++ b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
@@ -17,6 +17,7 @@ #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/common/chrome_features.h" +#include "net/cert/ct_serialization.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/report_sender.h" @@ -51,57 +52,42 @@ case net::ct::SignedCertificateTimestamp::SCT_EMBEDDED: return "embedded"; case net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION: - return "from-tls-extension"; + return "tls-extension"; case net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE: - return "from-ocsp-response"; - default: + return "ocsp"; + case net::ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX: NOTREACHED(); } return ""; } -void AddUnknownSCT( - const net::SignedCertificateTimestampAndStatus& sct_and_status, - base::ListValue* list) { +void AddSCT(const net::SignedCertificateTimestampAndStatus& sct, + base::ListValue* list) { std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue()); - list_item->SetString("origin", SCTOriginToString(sct_and_status.sct->origin)); - list->Append(std::move(list_item)); -} - -void AddInvalidSCT( - const net::SignedCertificateTimestampAndStatus& sct_and_status, - base::ListValue* list) { - std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue()); - list_item->SetString("origin", SCTOriginToString(sct_and_status.sct->origin)); - std::string log_id; - base::Base64Encode(sct_and_status.sct->log_id, &log_id); - list_item->SetString("id", log_id); - list->Append(std::move(list_item)); -} - -void AddValidSCT(const net::SignedCertificateTimestampAndStatus& sct_and_status, - base::ListValue* list) { - std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue()); - list_item->SetString("origin", SCTOriginToString(sct_and_status.sct->origin)); - - // The structure of the SCT object is defined in - // http://tools.ietf.org/html/rfc6962#section-4.1. - std::unique_ptr<base::DictionaryValue> sct(new base::DictionaryValue()); - sct->SetInteger("sct_version", sct_and_status.sct->version); - std::string log_id; - base::Base64Encode(sct_and_status.sct->log_id, &log_id); - sct->SetString("id", log_id); - base::TimeDelta timestamp = - sct_and_status.sct->timestamp - base::Time::UnixEpoch(); - sct->SetString("timestamp", base::Int64ToString(timestamp.InMilliseconds())); - std::string extensions; - base::Base64Encode(sct_and_status.sct->extensions, &extensions); - sct->SetString("extensions", extensions); - std::string signature; - base::Base64Encode(sct_and_status.sct->signature.signature_data, &signature); - sct->SetString("signature", signature); - - list_item->Set("sct", std::move(sct)); + // Chrome implements RFC6962, not 6962-bis, so the reports contain v1 SCTs. + list_item->SetInteger("version", 1); + std::string status; + switch (sct.status) { + case net::ct::SCT_STATUS_LOG_UNKNOWN: + status = "unknown"; + break; + case net::ct::SCT_STATUS_INVALID_SIGNATURE: + case net::ct::SCT_STATUS_INVALID_TIMESTAMP: + status = "invalid"; + break; + case net::ct::SCT_STATUS_OK: + status = "valid"; + break; + case net::ct::SCT_STATUS_NONE: + NOTREACHED(); + } + list_item->SetString("status", status); + list_item->SetString("source", SCTOriginToString(sct.sct->origin)); + std::string serialized_sct; + net::ct::EncodeSignedCertificateTimestamp(sct.sct, &serialized_sct); + std::string encoded_serialized_sct; + base::Base64Encode(serialized_sct, &encoded_serialized_sct); + list_item->SetString("serialized_sct", encoded_serialized_sct); list->Append(std::move(list_item)); } @@ -161,43 +147,26 @@ if (!base::FeatureList::IsEnabled(features::kExpectCTReporting)) return; - base::DictionaryValue report; - report.SetString("hostname", host_port_pair.host()); - report.SetInteger("port", host_port_pair.port()); - report.SetString("date-time", TimeToISO8601(base::Time::Now())); - report.SetString("effective-expiration-date", TimeToISO8601(expiration)); - report.Set("served-certificate-chain", - GetPEMEncodedChainAsList(served_certificate_chain)); - report.Set("validated-certificate-chain", - GetPEMEncodedChainAsList(validated_certificate_chain)); + base::DictionaryValue outer_report; + base::DictionaryValue* report = outer_report.SetDictionary( + "expect-ct-report", base::MakeUnique<base::DictionaryValue>()); + report->SetString("hostname", host_port_pair.host()); + report->SetInteger("port", host_port_pair.port()); + report->SetString("date-time", TimeToISO8601(base::Time::Now())); + report->SetString("effective-expiration-date", TimeToISO8601(expiration)); + report->Set("served-certificate-chain", + GetPEMEncodedChainAsList(served_certificate_chain)); + report->Set("validated-certificate-chain", + GetPEMEncodedChainAsList(validated_certificate_chain)); - std::unique_ptr<base::ListValue> unknown_scts(new base::ListValue()); - std::unique_ptr<base::ListValue> invalid_scts(new base::ListValue()); - std::unique_ptr<base::ListValue> valid_scts(new base::ListValue()); - + std::unique_ptr<base::ListValue> scts(new base::ListValue()); for (const auto& sct_and_status : signed_certificate_timestamps) { - switch (sct_and_status.status) { - case net::ct::SCT_STATUS_LOG_UNKNOWN: - AddUnknownSCT(sct_and_status, unknown_scts.get()); - break; - case net::ct::SCT_STATUS_INVALID_SIGNATURE: - case net::ct::SCT_STATUS_INVALID_TIMESTAMP: - AddInvalidSCT(sct_and_status, invalid_scts.get()); - break; - case net::ct::SCT_STATUS_OK: - AddValidSCT(sct_and_status, valid_scts.get()); - break; - default: - NOTREACHED(); - } + AddSCT(sct_and_status, scts.get()); } - - report.Set("unknown-scts", std::move(unknown_scts)); - report.Set("invalid-scts", std::move(invalid_scts)); - report.Set("valid-scts", std::move(valid_scts)); + report->Set("scts", std::move(scts)); std::string serialized_report; - if (!base::JSONWriter::Write(report, &serialized_report)) { + if (!base::JSONWriter::Write(outer_report, &serialized_report)) { LOG(ERROR) << "Failed to serialize Expect CT report"; return; }
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc index 776aec22..755444a 100644 --- a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc +++ b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
@@ -16,6 +16,7 @@ #include "base/values.h" #include "chrome/common/chrome_features.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "net/cert/ct_serialization.h" #include "net/cert/signed_certificate_timestamp_and_status.h" #include "net/test/cert_test_util.h" #include "net/test/test_data_directory.h" @@ -110,123 +111,75 @@ const std::string& origin_string) { if (origin_string == "embedded") return net::ct::SignedCertificateTimestamp::SCT_EMBEDDED; - if (origin_string == "from-tls-extension") + if (origin_string == "tls-extension") return net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION; - if (origin_string == "from-ocsp-response") + if (origin_string == "ocsp") return net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE; NOTREACHED(); return net::ct::SignedCertificateTimestamp::SCT_EMBEDDED; } -// Checks that an SCT |sct| appears (with the format determined by -// |status|) in |report_list|, a list of SCTs from an Expect CT -// report. |status| determines the format in that only certain fields -// are reported for certain verify statuses; SCTs from unknown logs -// contain very little information, for example, to avoid compromising -// privacy. -void FindSCTInReportList( - const scoped_refptr<net::ct::SignedCertificateTimestamp>& sct, - net::ct::SCTVerifyStatus status, +// Checks that an SCT |sct| appears with status |status| in |report_list|, a +// list of SCTs from an Expect-CT report. +::testing::AssertionResult FindSCTInReportList( + const scoped_refptr<net::ct::SignedCertificateTimestamp>& expected_sct, + net::ct::SCTVerifyStatus expected_status, const base::ListValue& report_list) { - bool found = false; - for (size_t i = 0; !found && i < report_list.GetSize(); i++) { + std::string expected_serialized_sct; + net::ct::EncodeSignedCertificateTimestamp(expected_sct, + &expected_serialized_sct); + + for (size_t i = 0; i < report_list.GetSize(); i++) { const base::DictionaryValue* report_sct; - ASSERT_TRUE(report_list.GetDictionary(i, &report_sct)); + if (!report_list.GetDictionary(i, &report_sct)) { + return ::testing::AssertionFailure() + << "Failed to get dictionary value from report SCT list"; + } - std::string origin; - ASSERT_TRUE(report_sct->GetString("origin", &origin)); + std::string serialized_sct; + EXPECT_TRUE(report_sct->GetString("serialized_sct", &serialized_sct)); + std::string decoded_serialized_sct; + EXPECT_TRUE(base::Base64Decode(serialized_sct, &decoded_serialized_sct)); + if (decoded_serialized_sct != expected_serialized_sct) + continue; - switch (status) { + std::string source; + EXPECT_TRUE(report_sct->GetString("source", &source)); + EXPECT_EQ(expected_sct->origin, SCTOriginStringToOrigin(source)); + + std::string report_status; + EXPECT_TRUE(report_sct->GetString("status", &report_status)); + switch (expected_status) { case net::ct::SCT_STATUS_LOG_UNKNOWN: - // SCTs from unknown logs only have an origin. - EXPECT_FALSE(report_sct->HasKey("sct")); - EXPECT_FALSE(report_sct->HasKey("id")); - if (SCTOriginStringToOrigin(origin) == sct->origin) - found = true; + EXPECT_EQ("unknown", report_status); break; - case net::ct::SCT_STATUS_INVALID_SIGNATURE: case net::ct::SCT_STATUS_INVALID_TIMESTAMP: { - // Invalid SCTs have a log id and an origin and nothing else. - EXPECT_FALSE(report_sct->HasKey("sct")); - std::string id_base64; - ASSERT_TRUE(report_sct->GetString("id", &id_base64)); - std::string id; - ASSERT_TRUE(base::Base64Decode(id_base64, &id)); - if (SCTOriginStringToOrigin(origin) == sct->origin && id == sct->log_id) - found = true; + EXPECT_EQ("invalid", report_status); break; } - case net::ct::SCT_STATUS_OK: { - // Valid SCTs have the full SCT. - const base::DictionaryValue* report_sct_object; - ASSERT_TRUE(report_sct->GetDictionary("sct", &report_sct_object)); - int version; - ASSERT_TRUE(report_sct_object->GetInteger("sct_version", &version)); - std::string id_base64; - ASSERT_TRUE(report_sct_object->GetString("id", &id_base64)); - std::string id; - ASSERT_TRUE(base::Base64Decode(id_base64, &id)); - std::string extensions_base64; - ASSERT_TRUE( - report_sct_object->GetString("extensions", &extensions_base64)); - std::string extensions; - ASSERT_TRUE(base::Base64Decode(extensions_base64, &extensions)); - std::string signature_data_base64; - ASSERT_TRUE( - report_sct_object->GetString("signature", &signature_data_base64)); - std::string signature_data; - ASSERT_TRUE(base::Base64Decode(signature_data_base64, &signature_data)); - - if (version == sct->version && - SCTOriginStringToOrigin(origin) == sct->origin && - id == sct->log_id && extensions == sct->extensions && - signature_data == sct->signature.signature_data) { - found = true; - } + EXPECT_EQ("valid", report_status); break; } - default: + case net::ct::SCT_STATUS_NONE: NOTREACHED(); } + return ::testing::AssertionSuccess(); } - EXPECT_TRUE(found); + + return ::testing::AssertionFailure() << "Failed to find SCT in report list"; } // Checks that all |expected_scts| appears in the given lists of SCTs // from an Expect CT report. void CheckReportSCTs( const net::SignedCertificateTimestampAndStatusList& expected_scts, - const base::ListValue& unknown_scts, - const base::ListValue& invalid_scts, - const base::ListValue& valid_scts) { - EXPECT_EQ( - expected_scts.size(), - unknown_scts.GetSize() + invalid_scts.GetSize() + valid_scts.GetSize()); + const base::ListValue& scts) { + EXPECT_EQ(expected_scts.size(), scts.GetSize()); for (const auto& expected_sct : expected_scts) { - switch (expected_sct.status) { - case net::ct::SCT_STATUS_LOG_UNKNOWN: - ASSERT_NO_FATAL_FAILURE(FindSCTInReportList( - expected_sct.sct, net::ct::SCT_STATUS_LOG_UNKNOWN, unknown_scts)); - break; - case net::ct::SCT_STATUS_INVALID_SIGNATURE: - ASSERT_NO_FATAL_FAILURE(FindSCTInReportList( - expected_sct.sct, net::ct::SCT_STATUS_INVALID_SIGNATURE, - invalid_scts)); - break; - case net::ct::SCT_STATUS_INVALID_TIMESTAMP: - ASSERT_NO_FATAL_FAILURE(FindSCTInReportList( - expected_sct.sct, net::ct::SCT_STATUS_INVALID_TIMESTAMP, - invalid_scts)); - break; - case net::ct::SCT_STATUS_OK: - ASSERT_NO_FATAL_FAILURE(FindSCTInReportList( - expected_sct.sct, net::ct::SCT_STATUS_OK, valid_scts)); - break; - default: - NOTREACHED(); - } + ASSERT_TRUE( + FindSCTInReportList(expected_sct.sct, expected_sct.status, scts)); } } @@ -242,8 +195,12 @@ ASSERT_TRUE(value); ASSERT_TRUE(value->IsType(base::Value::Type::DICTIONARY)); + base::DictionaryValue* outer_report_dict; + ASSERT_TRUE(value->GetAsDictionary(&outer_report_dict)); + base::DictionaryValue* report_dict; - ASSERT_TRUE(value->GetAsDictionary(&report_dict)); + ASSERT_TRUE( + outer_report_dict->GetDictionary("expect-ct-report", &report_dict)); std::string report_hostname; EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname)); @@ -269,16 +226,11 @@ ASSERT_NO_FATAL_FAILURE(CheckReportCertificateChain( ssl_info.cert, *report_validated_certificate_chain)); - const base::ListValue* report_unknown_scts = nullptr; - ASSERT_TRUE(report_dict->GetList("unknown-scts", &report_unknown_scts)); - const base::ListValue* report_invalid_scts = nullptr; - ASSERT_TRUE(report_dict->GetList("invalid-scts", &report_invalid_scts)); - const base::ListValue* report_valid_scts = nullptr; - ASSERT_TRUE(report_dict->GetList("valid-scts", &report_valid_scts)); + const base::ListValue* report_scts = nullptr; + ASSERT_TRUE(report_dict->GetList("scts", &report_scts)); - ASSERT_NO_FATAL_FAILURE(CheckReportSCTs( - ssl_info.signed_certificate_timestamps, *report_unknown_scts, - *report_invalid_scts, *report_valid_scts)); + ASSERT_NO_FATAL_FAILURE( + CheckReportSCTs(ssl_info.signed_certificate_timestamps, *report_scts)); } // A test network delegate that allows the user to specify a callback to @@ -457,38 +409,48 @@ // Append a variety of SCTs: two of each possible status, with a // mixture of different origins. + // The particular value of the log ID doesn't matter; it just has to be the + // correct length. + const unsigned char kTestLogId[] = { + 0xdf, 0x1c, 0x2e, 0xc1, 0x15, 0x00, 0x94, 0x52, 0x47, 0xa9, 0x61, + 0x68, 0x32, 0x5d, 0xdc, 0x5c, 0x79, 0x59, 0xe8, 0xf7, 0xc6, 0xd3, + 0x88, 0xfc, 0x00, 0x2e, 0x0b, 0xbd, 0x3f, 0x74, 0xd7, 0x01}; + const std::string log_id(reinterpret_cast<const char*>(kTestLogId), + sizeof(kTestLogId)); + // The values of the extensions and signature data don't matter + // either. However, each SCT has to be unique for the test expectation to be + // checked properly in CheckExpectCTReport(), so each SCT has a unique + // extensions value to make sure the serialized SCTs are unique. MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, - "unknown_log_id1", "extensions1", "signature1", now, + log_id, "extensions1", "signature1", now, net::ct::SCT_STATUS_LOG_UNKNOWN, &ssl_info.signed_certificate_timestamps); MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, - "unknown_log_id2", "extensions2", "signature2", now, + log_id, "extensions2", "signature2", now, net::ct::SCT_STATUS_LOG_UNKNOWN, &ssl_info.signed_certificate_timestamps); MakeTestSCTAndStatus( - net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, - "invalid_log_id1", "extensions1", "signature1", now, - net::ct::SCT_STATUS_INVALID_TIMESTAMP, + net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, log_id, + "extensions3", "signature1", now, net::ct::SCT_STATUS_INVALID_TIMESTAMP, &ssl_info.signed_certificate_timestamps); MakeTestSCTAndStatus( - net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, - "invalid_log_id1", "extensions1", "signature1", now, - net::ct::SCT_STATUS_INVALID_SIGNATURE, + net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, log_id, + "extensions4", "signature1", now, net::ct::SCT_STATUS_INVALID_SIGNATURE, &ssl_info.signed_certificate_timestamps); MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, - "invalid_log_id2", "extensions2", "signature2", now, + log_id, "extensions5", "signature2", now, net::ct::SCT_STATUS_INVALID_SIGNATURE, &ssl_info.signed_certificate_timestamps); MakeTestSCTAndStatus( - net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, - "valid_log_id1", "extensions1", "signature1", now, net::ct::SCT_STATUS_OK, + net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, log_id, + "extensions6", "signature1", now, net::ct::SCT_STATUS_OK, &ssl_info.signed_certificate_timestamps); MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, - "valid_log_id2", "extensions2", "signature2", now, + log_id, "extensions7", "signature2", now, net::ct::SCT_STATUS_OK, &ssl_info.signed_certificate_timestamps);
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index dbdefe17..a31095d 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -68,6 +68,7 @@ #include "components/policy/policy_constants.h" #include "components/prefs/testing_pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" +#include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/core/controller_client.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_state/core/security_state.h" @@ -140,6 +141,7 @@ using content::NavigationEntry; using content::SSLStatus; using content::WebContents; +using security_interstitials::SecurityInterstitialControllerClient; using web_modal::WebContentsModalDialogManager; const base::FilePath::CharType kDocRoot[] = @@ -710,6 +712,14 @@ ssl_config::prefs::kCertRevocationCheckingEnabled)); } + // Helper function for TestInterstitialLinksOpenInNewTab. Implemented as a + // test fixture method because the whole test fixture class is friended by + // SSLBlockingPage. + security_interstitials::SecurityInterstitialControllerClient* + GetControllerClientFromInterstitialPage(SSLBlockingPage* ssl_interstitial) { + return ssl_interstitial->controller(); + } + net::EmbeddedTestServer https_server_; net::EmbeddedTestServer https_server_expired_; net::EmbeddedTestServer https_server_mismatched_; @@ -3013,7 +3023,7 @@ content::RenderViewHost* interstitial_rvh = interstitial_page->GetMainFrame()->GetRenderViewHost(); int result = -1; - std::string javascript = + const std::string javascript = base::StringPrintf("window.domAutomationController.send(%d);", security_interstitials::CMD_PROCEED); ASSERT_TRUE(content::ExecuteScriptAndExtractInt( @@ -3048,7 +3058,7 @@ content::RenderViewHost* interstitial_rvh = interstitial_page->GetMainFrame()->GetRenderViewHost(); int result = -1; - std::string javascript = + const std::string javascript = base::StringPrintf("window.domAutomationController.send(%d);", security_interstitials::CMD_DONT_PROCEED); ASSERT_TRUE(content::ExecuteScriptAndExtractInt( @@ -3059,8 +3069,65 @@ EXPECT_EQ("about:blank", tab->GetVisibleURL().spec()); } +// Verifies that links in the interstitial open in a new tab. +// https://crbug.com/717616 +IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialLinksOpenInNewTab) { + ASSERT_TRUE(https_server_.Start()); + ASSERT_TRUE(https_server_expired_.Start()); + + WebContents* interstitial_tab = + browser()->tab_strip_model()->GetActiveWebContents(); + ui_test_utils::NavigateToURL( + browser(), https_server_expired_.GetURL("/ssl/google.html")); + content::WaitForInterstitialAttach( + browser()->tab_strip_model()->GetActiveWebContents()); + InterstitialPage* interstitial_page = interstitial_tab->GetInterstitialPage(); + ASSERT_TRUE( + content::WaitForRenderFrameReady(interstitial_page->GetMainFrame())); + CheckAuthenticationBrokenState(interstitial_tab, + net::CERT_STATUS_DATE_INVALID, + AuthState::SHOWING_INTERSTITIAL); + ASSERT_EQ(SSLBlockingPage::kTypeForTesting, + interstitial_page->GetDelegateForTesting()->GetTypeForTesting()); + + content::TestNavigationObserver nav_observer(nullptr); + nav_observer.StartWatchingNewWebContents(); + + SSLBlockingPage* ssl_interstitial = + static_cast<SSLBlockingPage*>(interstitial_page->GetDelegateForTesting()); + security_interstitials::SecurityInterstitialControllerClient* client = + GetControllerClientFromInterstitialPage(ssl_interstitial); + + // Mock out the help center URL so that our test will hit the test server + // instead of a real server. + // NOTE: The CMD_OPEN_HELP_CENTER code in + // components/security_interstitials/core/ssl_error_ui.cc ends up appending + // a path to whatever URL is passed to it. Since that path doesn't exist on + // our test server, this results in a 404. This is expected behavior, and + // things are still working as expected so long as the test passes! + const GURL mock_help_center_url = https_server_.GetURL("/title1.html"); + client->SetBaseHelpCenterUrlForTesting(mock_help_center_url); + + EXPECT_EQ(1, browser()->tab_strip_model()->count()); + + int result = -1; + const std::string javascript = + base::StringPrintf("window.domAutomationController.send(%d);", + security_interstitials::CMD_OPEN_HELP_CENTER); + ASSERT_TRUE(content::ExecuteScriptAndExtractInt( + interstitial_page->GetMainFrame(), javascript, &result)); + EXPECT_EQ(security_interstitials::CMD_OPEN_HELP_CENTER, result); + + nav_observer.Wait(); + + EXPECT_EQ(2, browser()->tab_strip_model()->count()); + WebContents* new_tab = browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(new_tab); + EXPECT_EQ(mock_help_center_url.host(), new_tab->GetURL().host()); +} + // Verifies that switching tabs, while showing interstitial page, will not -// affect the visibility of the interestitial. +// affect the visibility of the interstitial. // https://crbug.com/381439 IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) { ASSERT_TRUE(https_server_expired_.Start());
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index a4b0a7e..bbd058e 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -65,10 +65,12 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/page_navigator.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_switches.h" +#include "content/public/common/referrer.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" @@ -1040,6 +1042,26 @@ } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, + RendererDebugURL_NoLeakedThrottlePtrs) { + // We have checks in the throttle manager that we don't improperly leak + // activation state throttles. It would be nice to test things directly but it + // isn't very feasible right now without exposing a bunch of internal guts of + // the throttle manager. + // + // This test should crash the *browser process* with CHECK failures if the + // component is faulty. The CHECK assumes that the crash URL and other + // renderer debug URLs do not create a navigation throttle. See + // crbug.com/736658. + content::WindowedNotificationObserver observer( + content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, + content::NotificationService::AllSources()); + browser()->OpenURL(content::OpenURLParams( + GURL(content::kChromeUICrashURL), content::Referrer(), + WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); + observer.Wait(); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, NoConfiguration_AllowCreatingNewWindows) { base::HistogramTester tester; const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc index 8fefedc..842021e0 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -363,10 +363,13 @@ #if defined(OS_CHROMEOS) user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile_); - if (user) + if (user) { user_manager::UserManager::Get()->ChangeUserChildStatus(user, is_child); - else if (!chromeos::ProfileHelper::Get()->IsSigninProfile(profile_)) + } else if (!chromeos::ProfileHelper::Get()->IsSigninProfile(profile_) && + !chromeos::ProfileHelper::Get()->IsLockScreenAppProfile( + profile_)) { LOG(DFATAL) << "User instance not found while setting child account flag."; + } #endif }
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc index 097583f..c2309c2 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/supervised_user/child_accounts/child_account_service.h" #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/web_contents.h" #include "jni/ChildAccountService_jni.h" #include "ui/android/window_android.h" @@ -45,8 +44,7 @@ const std::string& email, const base::Callback<void(bool)>& callback) { ui::WindowAndroid* window_android = - content::ContentViewCore::FromWebContents(web_contents) - ->GetWindowAndroid(); + web_contents->GetNativeView()->GetWindowAndroid(); // Make a copy of the callback which can be passed as a pointer through // to Java.
diff --git a/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc index c52dae5f..efdba24 100644 --- a/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc +++ b/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc
@@ -58,7 +58,6 @@ ~SubframeTaskBrowserTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); content::IsolateAllSitesForTesting(command_line); }
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop.cc b/chrome/browser/thumbnails/simple_thumbnail_crop.cc index 918aecf5..9abdb02 100644 --- a/chrome/browser/thumbnails/simple_thumbnail_crop.cc +++ b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/thumbnails/simple_thumbnail_crop.h" -#include <algorithm> - #include "base/metrics/histogram_macros.h" #include "content/public/browser/browser_thread.h" #include "skia/ext/platform_canvas.h" @@ -46,10 +44,14 @@ if (bitmap.isNull() || bitmap.empty()) return; - SkBitmap thumbnail = CreateThumbnail( - bitmap, - ComputeTargetSizeAtMaximumScale(target_size_), - &context->clip_result); + DCHECK(context->clip_result != thumbnails::CLIP_RESULT_UNPROCESSED); + // TODO(treib): Getting the maximum supported scale here seems pointless - + // we only read back what GetCopySizeForThumbnail said. The max scale could + // only ever be smaller in the 1x -> 2x hack case (see + // GetCopySizeForThumbnail), but that seems like a bug - why would we scale + // on the CPU in that case? + SkBitmap thumbnail = + CreateThumbnail(bitmap, ComputeTargetSizeAtMaximumScale(target_size_)); context->score.boring_score = color_utils::CalculateBoringScore(thumbnail); context->score.good_clipping = @@ -60,21 +62,6 @@ callback.Run(*context.get(), thumbnail); } -SkBitmap SimpleThumbnailCrop::GetClippedBitmap(const SkBitmap& bitmap, - int desired_width, - int desired_height, - ClipResult* clip_result) { - gfx::Rect clipping_rect = - GetClippingRect(gfx::Size(bitmap.width(), bitmap.height()), - gfx::Size(desired_width, desired_height), - clip_result); - SkIRect src_rect = { clipping_rect.x(), clipping_rect.y(), - clipping_rect.right(), clipping_rect.bottom() }; - SkBitmap clipped_bitmap; - bitmap.extractSubset(&clipped_bitmap, src_rect); - return clipped_bitmap; -} - // RenderWidgetHostView::CopyFromSurface() can be costly especially when it is // necessary to read back the web contents image data from GPU. As the cost is // roughly proportional to the number of the copied pixels, the size of the @@ -151,32 +138,14 @@ // Creates a downsampled thumbnail from the given bitmap. // store. The returned bitmap will be isNull if there was an error creating it. SkBitmap SimpleThumbnailCrop::CreateThumbnail(const SkBitmap& bitmap, - const gfx::Size& desired_size, - ClipResult* clip_result) { + const gfx::Size& desired_size) { base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now(); - SkBitmap clipped_bitmap; - if (*clip_result == thumbnails::CLIP_RESULT_UNPROCESSED) { - // Clip the pixels that will commonly hold a scrollbar, which looks bad in - // thumbnails. - int scrollbar_size = gfx::scrollbar_size(); - SkIRect scrollbarless_rect = - { 0, 0, - std::max(1, bitmap.width() - scrollbar_size), - std::max(1, bitmap.height() - scrollbar_size) }; - SkBitmap bmp; - bitmap.extractSubset(&bmp, scrollbarless_rect); - - clipped_bitmap = GetClippedBitmap( - bmp, desired_size.width(), desired_size.height(), clip_result); - } else { - clipped_bitmap = bitmap; - } - // Need to resize it to the size we want, so downsample until it's // close, and let the caller make it the exact size if desired. + // TODO(treib): This is probably pointless, see TODO in ProcessBitmap. SkBitmap result = SkBitmapOperations::DownsampleByTwoUntilSize( - clipped_bitmap, desired_size.width(), desired_size.height()); + bitmap, desired_size.width(), desired_size.height()); LOCAL_HISTOGRAM_TIMES(kThumbnailHistogramName, base::TimeTicks::Now() - begin_compute_thumbnail);
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop.h b/chrome/browser/thumbnails/simple_thumbnail_crop.h index 3d96ccd..9440540 100644 --- a/chrome/browser/thumbnails/simple_thumbnail_crop.h +++ b/chrome/browser/thumbnails/simple_thumbnail_crop.h
@@ -28,16 +28,6 @@ const ConsumerCallback& callback, const SkBitmap& bitmap) override; - // Gets the clipped bitmap from |bitmap| per the aspect ratio of the - // desired width and the desired height. For instance, if the input - // bitmap is vertically long (ex. 400x900) and the desired size is - // square (ex. 100x100), the clipped bitmap will be the top half of the - // input bitmap (400x400). - // Statically exposed for use by tests only. - static SkBitmap GetClippedBitmap(const SkBitmap& bitmap, - int desired_width, - int desired_height, - thumbnails::ClipResult* clip_result); // Returns the size copied from the backing store. |thumbnail_size| is in // DIP, returned size in pixels. static gfx::Size GetCopySizeForThumbnail(ui::ScaleFactor scale_factor, @@ -57,8 +47,7 @@ private: static SkBitmap CreateThumbnail(const SkBitmap& bitmap, - const gfx::Size& desired_size, - ClipResult* clip_result); + const gfx::Size& desired_size); // The target size of the captured thumbnails, in DIPs. const gfx::Size target_size_;
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc b/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc index e321e58..f0512ce 100644 --- a/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc +++ b/chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc
@@ -21,86 +21,6 @@ typedef testing::Test SimpleThumbnailCropTest; -TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_TallerThanWide) { - // The input bitmap is vertically long. - gfx::Canvas canvas(gfx::Size(40, 90), 1.0f, true); - SkBitmap bitmap = canvas.GetBitmap(); - - // The desired size is square. - thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; - SkBitmap clipped_bitmap = SimpleThumbnailCrop::GetClippedBitmap( - bitmap, 10, 10, &clip_result); - // The clipped bitmap should be square. - EXPECT_EQ(40, clipped_bitmap.width()); - EXPECT_EQ(40, clipped_bitmap.height()); - // The input was taller than wide. - EXPECT_EQ(thumbnails::CLIP_RESULT_TALLER_THAN_WIDE, clip_result); -} - -TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_WiderThanTall) { - // The input bitmap is horizontally long. - gfx::Canvas canvas(gfx::Size(70, 40), 1.0f, true); - SkBitmap bitmap = canvas.GetBitmap(); - - // The desired size is square. - thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; - SkBitmap clipped_bitmap = SimpleThumbnailCrop::GetClippedBitmap( - bitmap, 10, 10, &clip_result); - // The clipped bitmap should be square. - EXPECT_EQ(40, clipped_bitmap.width()); - EXPECT_EQ(40, clipped_bitmap.height()); - // The input was wider than tall. - EXPECT_EQ(thumbnails::CLIP_RESULT_WIDER_THAN_TALL, clip_result); -} - -TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_TooWiderThanTall) { - // The input bitmap is horizontally very long. - gfx::Canvas canvas(gfx::Size(90, 40), 1.0f, true); - SkBitmap bitmap = canvas.GetBitmap(); - - // The desired size is square. - thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; - SkBitmap clipped_bitmap = SimpleThumbnailCrop::GetClippedBitmap( - bitmap, 10, 10, &clip_result); - // The clipped bitmap should be square. - EXPECT_EQ(40, clipped_bitmap.width()); - EXPECT_EQ(40, clipped_bitmap.height()); - // The input was wider than tall. - EXPECT_EQ(thumbnails::CLIP_RESULT_MUCH_WIDER_THAN_TALL, clip_result); -} - -TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_NotClipped) { - // The input bitmap is square. - gfx::Canvas canvas(gfx::Size(40, 40), 1.0f, true); - SkBitmap bitmap = canvas.GetBitmap(); - - // The desired size is square. - thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; - SkBitmap clipped_bitmap = SimpleThumbnailCrop::GetClippedBitmap( - bitmap, 10, 10, &clip_result); - // The clipped bitmap should be square. - EXPECT_EQ(40, clipped_bitmap.width()); - EXPECT_EQ(40, clipped_bitmap.height()); - // There was no need to clip. - EXPECT_EQ(thumbnails::CLIP_RESULT_NOT_CLIPPED, clip_result); -} - -TEST_F(SimpleThumbnailCropTest, GetClippedBitmap_NonSquareOutput) { - // The input bitmap is square. - gfx::Canvas canvas(gfx::Size(40, 40), 1.0f, true); - SkBitmap bitmap = canvas.GetBitmap(); - - // The desired size is horizontally long. - thumbnails::ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; - SkBitmap clipped_bitmap = SimpleThumbnailCrop::GetClippedBitmap( - bitmap, 20, 10, &clip_result); - // The clipped bitmap should have the same aspect ratio of the desired size. - EXPECT_EQ(40, clipped_bitmap.width()); - EXPECT_EQ(20, clipped_bitmap.height()); - // The input was taller than wide. - EXPECT_EQ(thumbnails::CLIP_RESULT_TALLER_THAN_WIDE, clip_result); -} - TEST_F(SimpleThumbnailCropTest, GetCanvasCopyInfo) { gfx::Size thumbnail_size(200, 120); gfx::Size expected_2x_size = gfx::ScaleToFlooredSize(thumbnail_size, 2.0);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 2087ff7..a91f1ba 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -544,6 +544,7 @@ "//components/renderer_context_menu", "//components/resources", "//components/safe_browsing/common:safe_browsing_prefs", + "//components/safe_browsing/web_ui", "//components/safe_json", "//components/search", "//components/search_engines", @@ -1415,12 +1416,14 @@ "ash/palette_delegate_chromeos.h", "ash/session_util.cc", "ash/session_util.h", + "ash/sort_windows_by_z_index.cc", "ash/system_tray_delegate_chromeos.cc", "ash/system_tray_delegate_chromeos.h", "ash/volume_controller.cc", "ash/volume_controller.h", "ash/vpn_list_forwarder.cc", "ash/vpn_list_forwarder.h", + "sort_windows_by_z_index.h", "views/ash/chrome_browser_main_extra_parts_ash.cc", "views/ash/chrome_browser_main_extra_parts_ash.h", "views/ash/tab_scrubber.cc",
diff --git a/chrome/browser/ui/android/bluetooth_chooser_android.cc b/chrome/browser/ui/android/bluetooth_chooser_android.cc index bb1408c..aabfc617 100644 --- a/chrome/browser/ui/android/bluetooth_chooser_android.cc +++ b/chrome/browser/ui/android/bluetooth_chooser_android.cc
@@ -11,7 +11,6 @@ #include "chrome/common/url_constants.h" #include "components/security_state/core/security_state.h" #include "components/url_formatter/elide_url.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/render_frame_host.h" #include "jni/BluetoothChooserDialog_jni.h" #include "ui/android/window_android.h" @@ -33,9 +32,7 @@ DCHECK(!origin.unique()); base::android::ScopedJavaLocalRef<jobject> window_android = - content::ContentViewCore::FromWebContents(web_contents_) - ->GetWindowAndroid() - ->GetJavaObject(); + web_contents_->GetNativeView()->GetWindowAndroid()->GetJavaObject(); SecurityStateTabHelper* helper = SecurityStateTabHelper::FromWebContents(web_contents_);
diff --git a/chrome/browser/ui/android/content_settings/OWNERS b/chrome/browser/ui/android/content_settings/OWNERS deleted file mode 100644 index 79becd2..0000000 --- a/chrome/browser/ui/android/content_settings/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -dfalcantara@chromium.org
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc index e920280..fc954f3d 100644 --- a/chrome/browser/ui/android/context_menu_helper.cc +++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/common/thumbnail_capturer.mojom.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/context_menu_params.h" @@ -25,6 +24,7 @@ #include "jni/ContextMenuParams_jni.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/WebKit/public/web/WebContextMenuData.h" +#include "ui/android/view_android.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" @@ -92,8 +92,9 @@ : web_contents_(web_contents) { JNIEnv* env = base::android::AttachCurrentThread(); java_obj_.Reset( - env, - Java_ContextMenuHelper_create(env, reinterpret_cast<long>(this)).obj()); + env, Java_ContextMenuHelper_create(env, reinterpret_cast<long>(this), + web_contents_->GetJavaWebContents()) + .obj()); DCHECK(!java_obj_.is_null()); } @@ -105,26 +106,14 @@ void ContextMenuHelper::ShowContextMenu( content::RenderFrameHost* render_frame_host, const content::ContextMenuParams& params) { - content::ContentViewCore* content_view_core = - content::ContentViewCore::FromWebContents(web_contents_); - - if (!content_view_core) - return; - - base::android::ScopedJavaLocalRef<jobject> jcontent_view_core( - content_view_core->GetJavaObject()); - - if (jcontent_view_core.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); context_menu_params_ = params; render_frame_id_ = render_frame_host->GetRoutingID(); render_process_id_ = render_frame_host->GetProcess()->GetID(); - + gfx::NativeView view = web_contents_->GetNativeView(); Java_ContextMenuHelper_showContextMenu( - env, java_obj_, jcontent_view_core, - ContextMenuHelper::CreateJavaContextMenuParams(params)); + env, java_obj_, ContextMenuHelper::CreateJavaContextMenuParams(params), + view->GetContainerView(), view->content_offset() * view->GetDipScale()); } void ContextMenuHelper::OnContextMenuClosed( @@ -235,7 +224,7 @@ // until there's either a connection error or a response. auto* thumbnail_capturer_proxy = thumbnail_capturer.get(); thumbnail_capturer_proxy->RequestThumbnailForContextNode( - 0, gfx::Size(max_dimen_px, max_dimen_px), + 0, gfx::Size(max_dimen_px, max_dimen_px), chrome::mojom::ImageFormat::PNG, base::Bind(retrieve_callback, base::Passed(&thumbnail_capturer), base::android::ScopedJavaGlobalRef<jobject>(env, jcallback))); }
diff --git a/chrome/browser/ui/android/infobars/OWNERS b/chrome/browser/ui/android/infobars/OWNERS index 83cd86f..eb3ed77 100644 --- a/chrome/browser/ui/android/infobars/OWNERS +++ b/chrome/browser/ui/android/infobars/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org mdjones@chromium.org per-file app_banner*=dominickn@chromium.org
diff --git a/chrome/browser/ui/android/tab_contents/OWNERS b/chrome/browser/ui/android/tab_contents/OWNERS index 810ce1b..33b82d6 100644 --- a/chrome/browser/ui/android/tab_contents/OWNERS +++ b/chrome/browser/ui/android/tab_contents/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org dtrainor@chromium.org # COMPONENT: UI>Browser>Mobile
diff --git a/chrome/browser/ui/android/tab_model/OWNERS b/chrome/browser/ui/android/tab_model/OWNERS index 810ce1b..33b82d6 100644 --- a/chrome/browser/ui/android/tab_model/OWNERS +++ b/chrome/browser/ui/android/tab_model/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org dtrainor@chromium.org # COMPONENT: UI>Browser>Mobile
diff --git a/chrome/browser/ui/android/usb_chooser_dialog_android.cc b/chrome/browser/ui/android/usb_chooser_dialog_android.cc index c1c50ccd..ebe196f 100644 --- a/chrome/browser/ui/android/usb_chooser_dialog_android.cc +++ b/chrome/browser/ui/android/usb_chooser_dialog_android.cc
@@ -22,7 +22,6 @@ #include "chrome/common/url_constants.h" #include "components/security_state/core/security_state.h" #include "components/url_formatter/elide_url.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "device/base/device_client.h" @@ -84,9 +83,7 @@ // Create (and show) the UsbChooser dialog. base::android::ScopedJavaLocalRef<jobject> window_android = - content::ContentViewCore::FromWebContents(web_contents) - ->GetWindowAndroid() - ->GetJavaObject(); + web_contents->GetNativeView()->GetWindowAndroid()->GetJavaObject(); JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> origin_string = base::android::ConvertUTF16ToJavaString(
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc b/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc index af15bcc4..f0b07cdc 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc
@@ -42,8 +42,10 @@ std::unique_ptr<KeyedService> AppListSyncableServiceFactory::BuildInstanceFor( content::BrowserContext* browser_context) { Profile* profile = static_cast<Profile*>(browser_context); - if (chromeos::ProfileHelper::IsSigninProfile(profile)) - return NULL; + if (chromeos::ProfileHelper::IsSigninProfile(profile) || + chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { + return nullptr; + } VLOG(1) << "BuildInstanceFor: " << profile->GetDebugName() << " (" << profile << ")"; return base::MakeUnique<AppListSyncableService>(
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index c01cff01..4c5465b 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -637,6 +637,7 @@ case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: { Profile* profile = content::Details<Profile>(details).ptr(); if (!chromeos::ProfileHelper::IsSigninProfile(profile) && + !chromeos::ProfileHelper::IsLockScreenAppProfile(profile) && !profile->IsGuestSession() && !profile->IsSupervised()) { // Start the error notifier services to show auth/sync notifications. SigninErrorNotifierFactory::GetForProfile(profile);
diff --git a/chrome/browser/ui/ash/ime_controller_client.cc b/chrome/browser/ui/ash/ime_controller_client.cc index cd34faf..8d9cdc6 100644 --- a/chrome/browser/ui/ash/ime_controller_client.cc +++ b/chrome/browser/ui/ash/ime_controller_client.cc
@@ -88,15 +88,16 @@ state->SwitchToPreviousInputMethod(); } -void ImeControllerClient::SwitchImeById(const std::string& id) { +void ImeControllerClient::SwitchImeById(const std::string& id, + bool show_message) { InputMethodManager::State* state = input_method_manager_->GetActiveIMEState().get(); if (state) - state->ChangeInputMethod(id, true /* show_message */); + state->ChangeInputMethod(id, show_message); } -void ImeControllerClient::ActivateImeProperty(const std::string& key) { - NOTIMPLEMENTED(); +void ImeControllerClient::ActivateImeMenuItem(const std::string& key) { + input_method_manager_->ActivateInputMethodMenuItem(key); } // chromeos::input_method::InputMethodManager::Observer:
diff --git a/chrome/browser/ui/ash/ime_controller_client.h b/chrome/browser/ui/ash/ime_controller_client.h index e83f379..18f4789b 100644 --- a/chrome/browser/ui/ash/ime_controller_client.h +++ b/chrome/browser/ui/ash/ime_controller_client.h
@@ -37,8 +37,8 @@ // ash::mojom::ImeControllerClient: void SwitchToNextIme() override; void SwitchToPreviousIme() override; - void SwitchImeById(const std::string& id) override; - void ActivateImeProperty(const std::string& key) override; + void SwitchImeById(const std::string& id, bool show_message) override; + void ActivateImeMenuItem(const std::string& key) override; // chromeos::input_method::InputMethodManager::Observer: void InputMethodChanged(chromeos::input_method::InputMethodManager* manager,
diff --git a/chrome/browser/ui/ash/ime_controller_client_unittest.cc b/chrome/browser/ui/ash/ime_controller_client_unittest.cc index e4d74e4..3043a47 100644 --- a/chrome/browser/ui/ash/ime_controller_client_unittest.cc +++ b/chrome/browser/ui/ash/ime_controller_client_unittest.cc
@@ -63,6 +63,7 @@ bool show_message) override { ++change_input_method_count_; current_ime_id_ = input_method_id; + last_show_message_ = show_message; } std::unique_ptr<std::vector<InputMethodDescriptor>> GetActiveInputMethods() const override { @@ -94,6 +95,7 @@ int next_input_method_count_ = 0; int previous_input_method_count_ = 0; int change_input_method_count_ = 0; + bool last_show_message_ = false; protected: friend base::RefCounted<InputMethodManager::State>; @@ -118,6 +120,10 @@ void RemoveImeMenuObserver(ImeMenuObserver* observer) override { ++remove_menu_observer_count_; } + void ActivateInputMethodMenuItem(const std::string& key) override { + last_activate_menu_item_key_ = key; + } + InputMethodUtil* GetInputMethodUtil() override { return &util_; } scoped_refptr<InputMethodManager::State> GetActiveIMEState() override { return state_; @@ -128,6 +134,7 @@ int remove_observer_count_ = 0; int add_menu_observer_count_ = 0; int remove_menu_observer_count_ = 0; + std::string last_activate_menu_item_key_; FakeInputMethodDelegate delegate_; InputMethodUtil util_; @@ -297,9 +304,21 @@ TEST_F(ImeControllerClientTest, SwitchImeById) { ImeControllerClient client(&input_method_manager_); - client.SwitchImeById("ime2"); + client.SwitchImeById("id2", true /* show_message */); EXPECT_EQ(1, input_method_manager_.state_->change_input_method_count_); - EXPECT_EQ("ime2", input_method_manager_.state_->current_ime_id_); + EXPECT_EQ("id2", input_method_manager_.state_->current_ime_id_); + EXPECT_TRUE(input_method_manager_.state_->last_show_message_); + + client.SwitchImeById("id1", false /* show_message */); + EXPECT_EQ(2, input_method_manager_.state_->change_input_method_count_); + EXPECT_EQ("id1", input_method_manager_.state_->current_ime_id_); + EXPECT_FALSE(input_method_manager_.state_->last_show_message_); +} + +TEST_F(ImeControllerClientTest, ActivateImeMenuItem) { + ImeControllerClient client(&input_method_manager_); + client.ActivateImeMenuItem("key1"); + EXPECT_EQ("key1", input_method_manager_.last_activate_menu_item_key_); } } // namespace
diff --git a/chrome/browser/ui/ash/sort_windows_by_z_index.cc b/chrome/browser/ui/ash/sort_windows_by_z_index.cc new file mode 100644 index 0000000..909bef9f --- /dev/null +++ b/chrome/browser/ui/ash/sort_windows_by_z_index.cc
@@ -0,0 +1,67 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/sort_windows_by_z_index.h" + +#include <utility> + +#include "ash/shell.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/containers/flat_set.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/stl_util.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "ui/aura/window.h" +#include "ui/aura/window_tracker.h" + +namespace ui { + +namespace { + +// Append windows in |windows| that are descendant of |root_window| to +// |sorted_windows| in z-order, from topmost to bottommost. +void AppendDescendantsSortedByZIndex( + const aura::Window* root_window, + const base::flat_set<aura::Window*>& windows, + std::vector<aura::Window*>* sorted_windows) { + const aura::Window::Windows& children = root_window->children(); + for (auto it = children.rbegin(); it != children.rend(); ++it) { + aura::Window* window = *it; + if (base::ContainsKey(windows, window)) { + sorted_windows->push_back(window); + // Skip children of |window| since a window in |windows| is not expected + // to be the parent of another window in |windows|. + } else { + AppendDescendantsSortedByZIndex(window, windows, sorted_windows); + } + } +} + +void DoSortWindowsByZIndex(std::unique_ptr<aura::WindowTracker> window_tracker, + SortWindowsByZIndexCallback callback) { + const base::flat_set<aura::Window*> windows(window_tracker->windows(), + base::KEEP_FIRST_OF_DUPES); + std::vector<aura::Window*> sorted_windows; + for (aura::Window* root_window : ash::Shell::GetAllRootWindows()) + AppendDescendantsSortedByZIndex(root_window, windows, &sorted_windows); + DCHECK_EQ(windows.size(), sorted_windows.size()); + std::move(callback).Run(sorted_windows); +} + +} // namespace + +void SortWindowsByZIndex(const std::vector<aura::Window*>& windows, + SortWindowsByZIndexCallback callback) { + auto window_tracker = base::MakeUnique<aura::WindowTracker>(); + for (aura::Window* window : windows) + window_tracker->Add(window); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&DoSortWindowsByZIndex, std::move(window_tracker), + std::move(callback))); +} + +} // namespace ui
diff --git a/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc b/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc index f7370c91..57111b5 100644 --- a/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc +++ b/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc
@@ -76,8 +76,6 @@ } void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - ON_CALL(media_router_, RegisterMediaSinksObserver(_)) .WillByDefault(Invoke( this, &SystemTrayTrayCastMediaRouterChromeOSTest::CaptureSink)); @@ -89,7 +87,6 @@ void TearDownInProcessBrowserTestFixture() override { CastConfigClientMediaRouter::SetMediaRouterForTest(nullptr); - InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); } media_router::MockMediaRouter media_router_;
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc index 32b950ac..660542236 100644 --- a/chrome/browser/ui/browser_command_controller_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -38,8 +38,6 @@ ~BrowserCommandControllerBrowserTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); - #if defined(OS_CHROMEOS) command_line->AppendSwitch( chromeos::switches::kIgnoreUserProfileMappingForTests);
diff --git a/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm b/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm index ff8e7ccf..1c3a87f 100644 --- a/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm +++ b/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm
@@ -50,8 +50,6 @@ // Make sure the task manager is closed (if any). chrome::HideTaskManager(); ASSERT_FALSE(GetTaskManagerMac()); - - InProcessBrowserTest::TearDownOnMainThread(); } TaskManagerMac* GetTaskManagerMac() const {
diff --git a/chrome/browser/ui/profile_error_browsertest.cc b/chrome/browser/ui/profile_error_browsertest.cc index 3de37298..09c2333e 100644 --- a/chrome/browser/ui/profile_error_browsertest.cc +++ b/chrome/browser/ui/profile_error_browsertest.cc
@@ -58,8 +58,6 @@ } void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - // Skip showing the error message box in order to avoid freezing the main // thread. chrome::internal::g_should_skip_message_box_for_test = true;
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc index bb2db92c..a3b0bf6 100644 --- a/chrome/browser/ui/search/local_ntp_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -381,8 +381,6 @@ } void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - will_create_browser_context_services_subscription_ = BrowserContextDependencyManager::GetInstance() ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
diff --git a/chrome/browser/ui/sort_windows_by_z_index.h b/chrome/browser/ui/sort_windows_by_z_index.h new file mode 100644 index 0000000..436ab3d --- /dev/null +++ b/chrome/browser/ui/sort_windows_by_z_index.h
@@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_SORT_WINDOWS_BY_Z_INDEX_H_ +#define CHROME_BROWSER_UI_SORT_WINDOWS_BY_Z_INDEX_H_ + +#include <vector> + +#include "base/callback_forward.h" +#include "ui/gfx/native_widget_types.h" + +namespace ui { + +using SortWindowsByZIndexCallback = + base::OnceCallback<void(std::vector<gfx::NativeWindow>)>; + +// Returns a list with the windows in |windows| sorted by z-index, from topmost +// to bottommost, via an asynchronous call to |callback| on the current +// sequence. Windows from |windows| that have been deleted by the time +// |callback| runs won't be part of the sorted list. +// +// TODO(fdoray): Implement this on all platforms. https://crbug.com/731145 +void SortWindowsByZIndex(const std::vector<gfx::NativeWindow>& windows, + SortWindowsByZIndexCallback callback); + +} // namespace ui + +#endif // CHROME_BROWSER_UI_SORT_WINDOWS_BY_Z_INDEX_H_
diff --git a/chrome/browser/ui/sort_windows_by_z_index_browsertest.cc b/chrome/browser/ui/sort_windows_by_z_index_browsertest.cc new file mode 100644 index 0000000..6b3c8239 --- /dev/null +++ b/chrome/browser/ui/sort_windows_by_z_index_browsertest.cc
@@ -0,0 +1,60 @@ +// 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/ui/sort_windows_by_z_index.h" + +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/containers/flat_set.h" +#include "base/run_loop.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/test/base/in_process_browser_test.h" + +using SortWindowsByZIndexBrowserTest = InProcessBrowserTest; + +IN_PROC_BROWSER_TEST_F(SortWindowsByZIndexBrowserTest, SortWindowsByZIndex) { + Browser* browser1 = BrowserList::GetInstance()->GetLastActive(); + chrome::NewWindow(browser1); + Browser* browser2 = BrowserList::GetInstance()->GetLastActive(); + EXPECT_NE(browser1, browser2); + chrome::NewWindow(browser1); + Browser* browser3 = BrowserList::GetInstance()->GetLastActive(); + EXPECT_NE(browser1, browser3); + EXPECT_NE(browser2, browser3); + chrome::NewWindow(browser1); + Browser* browser4 = BrowserList::GetInstance()->GetLastActive(); + EXPECT_NE(browser1, browser4); + EXPECT_NE(browser2, browser4); + EXPECT_NE(browser3, browser4); + + gfx::NativeWindow window1 = browser1->window()->GetNativeWindow(); + gfx::NativeWindow window2 = browser2->window()->GetNativeWindow(); + gfx::NativeWindow window3 = browser3->window()->GetNativeWindow(); + gfx::NativeWindow window4 = browser4->window()->GetNativeWindow(); + + std::vector<gfx::NativeWindow> expected_sorted_windows{window4, window3, + window2, window1}; + + bool callback_did_run = false; + ui::SortWindowsByZIndex( + {window1, window3, window2, window4}, + base::BindOnce( + [](std::vector<gfx::NativeWindow> expected_sorted_windows, + bool* callback_did_run, + std::vector<gfx::NativeWindow> sorted_windows) { + EXPECT_EQ(expected_sorted_windows, sorted_windows); + *callback_did_run = true; + }, + std::move(expected_sorted_windows), + base::Unretained(&callback_did_run))); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(callback_did_run); +}
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index f7ef4d0..d0390d3 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -861,7 +861,6 @@ class SupervisedUserBrowserCreatorTest : public InProcessBrowserTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII(switches::kSupervisedUserId, "asdf"); } };
diff --git a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc index 97a9cc7..a7af7ad 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc
@@ -199,7 +199,6 @@ void TearDownOnMainThread() override { test_body_has_run_ = true; - InProcessBrowserTest::TearDownOnMainThread(); } void TearDown() override {
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc index e517f94..53b590fd 100644 --- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc +++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc
@@ -22,7 +22,6 @@ void SetUpCommandLine(base::CommandLine* command_line) override { // Force the first-run flow to trigger autoimport. - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kForceFirstRun); }
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.cc b/chrome/browser/ui/tab_contents/core_tab_helper.cc index ac3e496..4ed2cee3 100644 --- a/chrome/browser/ui/tab_contents/core_tab_helper.cc +++ b/chrome/browser/ui/tab_contents/core_tab_helper.cc
@@ -119,6 +119,7 @@ thumbnail_capturer_proxy->RequestThumbnailForContextNode( kImageSearchThumbnailMinSize, gfx::Size(kImageSearchThumbnailMaxWidth, kImageSearchThumbnailMaxHeight), + chrome::mojom::ImageFormat::JPEG, base::Bind(&CoreTabHelper::DoSearchByImageInNewTab, weak_factory_.GetWeakPtr(), base::Passed(&thumbnail_capturer), src_url));
diff --git a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc index 5c0e839..4b1ddd4 100644 --- a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
@@ -33,12 +33,10 @@ ~ArcAppUninstallDialogViewBrowserTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); arc::SetArcAvailableCommandLineForTesting(command_line); } void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); ArcSessionManager::DisableUIForTesting(); ArcAuthNotification::DisableForTesting(); } @@ -89,7 +87,6 @@ void TearDownOnMainThread() override { ArcSessionManager::Get()->Shutdown(); - InProcessBrowserTest::TearDownOnMainThread(); } // Ensures the ArcAppDialogView is destoryed.
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.cc b/chrome/browser/ui/views/frame/test_with_browser_view.cc index 9fae7b4..b600ed2 100644 --- a/chrome/browser/ui/views/frame/test_with_browser_view.cc +++ b/chrome/browser/ui/views/frame/test_with_browser_view.cc
@@ -5,11 +5,11 @@ #include "chrome/browser/ui/views/frame/test_with_browser_view.h" #include "base/memory/ptr_util.h" -#include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" #include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/search_engines/chrome_template_url_service_client.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" @@ -82,6 +82,7 @@ #endif testing_io_thread_state_.reset(new chrome::TestingIOThreadState()); BrowserWithTestWindowTest::SetUp(); + predictor_db_.reset(new predictors::PredictorDatabase(GetProfile())); browser_view_ = static_cast<BrowserView*>(browser()->window()); } @@ -99,6 +100,7 @@ content::RunAllPendingInMessageLoop(content::BrowserThread::DB); BrowserWithTestWindowTest::TearDown(); testing_io_thread_state_.reset(); + predictor_db_.reset(); #if defined(OS_CHROMEOS) chromeos::input_method::Shutdown(); #endif
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.h b/chrome/browser/ui/views/frame/test_with_browser_view.h index db73a693..d091378 100644 --- a/chrome/browser/ui/views/frame/test_with_browser_view.h +++ b/chrome/browser/ui/views/frame/test_with_browser_view.h
@@ -14,6 +14,10 @@ class TestingIOThreadState; } +namespace predictors { +class PredictorDatabase; +} + class BrowserView; class ScopedTestingLocalState; @@ -37,6 +41,7 @@ private: BrowserView* browser_view_; // Not owned. std::unique_ptr<ScopedTestingLocalState> local_state_; + std::unique_ptr<predictors::PredictorDatabase> predictor_db_; std::unique_ptr<chrome::TestingIOThreadState> testing_io_thread_state_; DISALLOW_COPY_AND_ASSIGN(TestWithBrowserView);
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc index a442c39..8a09efc 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" +#include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/test/base/in_process_browser_test.h" @@ -139,3 +140,26 @@ } } #endif // OS_CHROMEOS + +class ZoomBubbleDialogTest : public DialogBrowserTest { + public: + ZoomBubbleDialogTest() {} + + // DialogBrowserTest: + void ShowDialog(const std::string& name) override { + BrowserView* browser_view = static_cast<BrowserView*>(browser()->window()); + content::WebContents* web_contents = browser_view->GetActiveWebContents(); + ZoomBubbleView::ShowBubble(web_contents, gfx::Point(), + ZoomBubbleView::USER_GESTURE); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ZoomBubbleDialogTest); +}; + +// Test that calls ShowDialog("default"). Interactive when run via +// browser_tests --gtest_filter=BrowserDialogTest.Invoke --interactive +// --dialog=ZoomBubbleDialogTest.InvokeDialog_default +IN_PROC_BROWSER_TEST_F(ZoomBubbleDialogTest, InvokeDialog_default) { + RunDialog(); +}
diff --git a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc index abd4fcbb1..dd177e67 100644 --- a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc
@@ -40,6 +40,10 @@ ContactInfoEditorViewController::~ContactInfoEditorViewController() {} +bool ContactInfoEditorViewController::IsEditingExistingItem() { + return !!profile_to_edit_; +} + std::vector<EditorField> ContactInfoEditorViewController::GetFieldDefinitions() { std::vector<EditorField> fields; @@ -162,8 +166,9 @@ } bool ContactInfoEditorViewController::ContactInfoValidationDelegate:: - IsValidTextfield(views::Textfield* textfield) { - return ValidateTextfield(textfield, nullptr); + IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) { + return ValidateTextfield(textfield, error_message); } bool ContactInfoEditorViewController::ContactInfoValidationDelegate:: @@ -232,7 +237,7 @@ } bool ContactInfoEditorViewController::ContactInfoValidationDelegate:: - IsValidCombobox(views::Combobox* combobox) { + IsValidCombobox(views::Combobox* combobox, base::string16* error_message) { // This UI doesn't contain any comboboxes. NOTREACHED(); return true;
diff --git a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h index 1d10660d..8a000707 100644 --- a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h +++ b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.h
@@ -36,6 +36,7 @@ ~ContactInfoEditorViewController() override; // EditorViewController: + bool IsEditingExistingItem() override; std::vector<EditorField> GetFieldDefinitions() override; base::string16 GetInitialValueForType( autofill::ServerFieldType type) override; @@ -73,8 +74,10 @@ // ValidationDelegate: bool ShouldFormat() override; base::string16 Format(const base::string16& text) override; - bool IsValidTextfield(views::Textfield* textfield) override; - bool IsValidCombobox(views::Combobox* combobox) override; + bool IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) override; + bool IsValidCombobox(views::Combobox* combobox, + base::string16* error_message) override; bool TextfieldValueChanged(views::Textfield* textfield, bool was_blurred) override; bool ComboboxValueChanged(views::Combobox* combobox) override;
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index 6cb6c1e..7b55d15 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -80,17 +80,25 @@ app_locale_(app_locale), initially_valid_(initially_valid) {} - bool IsValidTextfield(views::Textfield* textfield) override { + bool IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) override { NOTREACHED(); return true; } - bool IsValidCombobox(views::Combobox* combobox) override { + bool IsValidCombobox(views::Combobox* combobox, + base::string16* error_message) override { // View will have no parent if it's not been attached yet. Use initial // validity state. views::View* view_parent = combobox->parent(); - if (!view_parent) + if (!view_parent) { + *error_message = + initially_valid_ + ? base::string16() + : l10n_util::GetStringUTF16( + IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED); return initially_valid_; + } // Get the combined date from the month and year dropdowns. views::Combobox* month_combobox = static_cast<views::Combobox*>( @@ -109,6 +117,10 @@ month_combobox->SetInvalid(is_expired); year_combobox->SetInvalid(is_expired); + *error_message = + is_expired ? l10n_util::GetStringUTF16( + IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED) + : base::string16(); return !is_expired; } @@ -119,12 +131,10 @@ } bool ComboboxValueChanged(views::Combobox* combobox) override { - bool is_valid = IsValidCombobox(combobox); + base::string16 error_message; + bool is_valid = IsValidCombobox(combobox, &error_message); controller_->DisplayErrorMessageForField( - autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, - is_valid ? base::string16() - : l10n_util::GetStringUTF16( - IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED)); + autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, error_message); return is_valid; } @@ -235,7 +245,8 @@ CreditCardEditorViewController::CreateCustomFieldView( autofill::ServerFieldType type, views::View** focusable_field, - bool* valid) { + bool* valid, + base::string16* error_message) { DCHECK_EQ(type, autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); std::unique_ptr<views::View> view = base::MakeUnique<views::View>(); @@ -268,7 +279,7 @@ EditorField::LengthHint::HINT_SHORT, /*required=*/true, EditorField::ControlType::COMBOBOX}; std::unique_ptr<ValidatingCombobox> month_combobox = - CreateComboboxForField(tmp_month); + CreateComboboxForField(tmp_month, error_message); *focusable_field = month_combobox.get(); combobox_layout->AddView(month_combobox.release(), 1, 1, views::GridLayout::FILL, views::GridLayout::FILL, @@ -280,7 +291,7 @@ EditorField::LengthHint::HINT_SHORT, /*required=*/true, EditorField::ControlType::COMBOBOX}; std::unique_ptr<ValidatingCombobox> year_combobox = - CreateComboboxForField(tmp_year); + CreateComboboxForField(tmp_year, error_message); combobox_layout->AddView(year_combobox.release(), 1, 1, views::GridLayout::FILL, views::GridLayout::FILL, 0, kInputFieldHeight); @@ -316,6 +327,10 @@ return button_view; } +bool CreditCardEditorViewController::IsEditingExistingItem() { + return !!credit_card_to_edit_; +} + std::vector<EditorField> CreditCardEditorViewController::GetFieldDefinitions() { bool is_server_card = IsEditingServerCard(); return std::vector<EditorField>{ @@ -612,13 +627,14 @@ } bool CreditCardEditorViewController::CreditCardValidationDelegate:: - IsValidTextfield(views::Textfield* textfield) { - return ValidateValue(textfield->text(), nullptr); + IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) { + return ValidateValue(textfield->text(), error_message); } bool CreditCardEditorViewController::CreditCardValidationDelegate:: - IsValidCombobox(views::Combobox* combobox) { - return ValidateCombobox(combobox, nullptr); + IsValidCombobox(views::Combobox* combobox, base::string16* error_message) { + return ValidateCombobox(combobox, error_message); } bool CreditCardEditorViewController::CreditCardValidationDelegate::
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h index 51a85901..a83064d 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h
@@ -51,9 +51,11 @@ std::unique_ptr<views::View> CreateCustomFieldView( autofill::ServerFieldType type, views::View** focusable_field, - bool* valid) override; + bool* valid, + base::string16* error_message) override; std::unique_ptr<views::View> CreateExtraViewForField( autofill::ServerFieldType type) override; + bool IsEditingExistingItem() override; std::vector<EditorField> GetFieldDefinitions() override; base::string16 GetInitialValueForType( autofill::ServerFieldType type) override; @@ -89,8 +91,10 @@ // ValidationDelegate: bool ShouldFormat() override; base::string16 Format(const base::string16& text) override; - bool IsValidTextfield(views::Textfield* textfield) override; - bool IsValidCombobox(views::Combobox* combobox) override; + bool IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) override; + bool IsValidCombobox(views::Combobox* combobox, + base::string16* error_message) override; bool TextfieldValueChanged(views::Textfield* textfield, bool was_blurred) override; bool ComboboxValueChanged(views::Combobox* combobox) override;
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc index aaa7505..3b326e4 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc
@@ -496,6 +496,10 @@ GetComboboxValue(autofill::CREDIT_CARD_EXP_MONTH)); EXPECT_EQ(base::ASCIIToUTF16("2017"), GetComboboxValue(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)); + // Should show as expired when the editor opens. + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED), + GetErrorLabelForType(autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR)); views::Combobox* combobox = static_cast<views::Combobox*>( dialog_view()->GetViewByID(EditorViewController::GetInputFieldViewId( @@ -562,6 +566,10 @@ ClickOnChildInListViewAndWait(/*child_index=*/0, /*num_children=*/1, DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW); + // Proper error shown. + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_BILLING_ADDRESS_REQUIRED), + GetErrorLabelForType(autofill::ADDRESS_BILLING_LINE1)); + // Fixing the billing address. SelectBillingAddress(billing_profile.guid()); @@ -595,7 +603,69 @@ } IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardEditorTest, - ChangeCardHolderName) { + EditingCardWithoutCardholderName) { + autofill::CreditCard card = autofill::test::GetCreditCard(); + autofill::AutofillProfile billing_profile(autofill::test::GetFullProfile()); + AddAutofillProfile(billing_profile); + card.set_billing_address_id(billing_profile.guid()); + // Clear the name. + card.SetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), + base::string16(), "en-US"); + AddCreditCard(card); + + InvokePaymentRequestUI(); + + // One instrument is available, but it's not selected. + PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); + EXPECT_EQ(1U, request->state()->available_instruments().size()); + EXPECT_EQ(nullptr, request->state()->selected_instrument()); + + OpenPaymentMethodScreen(); + + ResetEventObserver(DialogEvent::CREDIT_CARD_EDITOR_OPENED); + ClickOnChildInListViewAndWait(/*child_index=*/0, /*num_children=*/1, + DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW); + + // Proper error shown. + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE), + GetErrorLabelForType(autofill::CREDIT_CARD_NAME_FULL)); + + // Fixing the name. + SetEditorTextfieldValue(base::ASCIIToUTF16("Bob Newname"), + autofill::CREDIT_CARD_NAME_FULL); + + // Verifying the data is in the DB. + autofill::PersonalDataManager* personal_data_manager = GetDataManager(); + personal_data_manager->AddObserver(&personal_data_observer_); + + ResetEventObserver(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION); + + // Wait until the web database has been updated and the notification sent. + base::RunLoop data_loop; + EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()) + .WillOnce(QuitMessageLoop(&data_loop)); + ClickOnDialogViewAndWait(DialogViewID::EDITOR_SAVE_BUTTON); + data_loop.Run(); + + EXPECT_EQ(1u, personal_data_manager->GetCreditCards().size()); + autofill::CreditCard* credit_card = + personal_data_manager->GetCreditCards()[0]; + EXPECT_EQ(base::ASCIIToUTF16("Bob Newname"), + credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL)); + // It retains other properties. + EXPECT_EQ(card.guid(), credit_card->guid()); + EXPECT_EQ(base::ASCIIToUTF16("4111111111111111"), credit_card->number()); + EXPECT_EQ(billing_profile.guid(), credit_card->billing_address_id()); + + // Still have one instrument, but now it's selected. + EXPECT_EQ(1U, request->state()->available_instruments().size()); + EXPECT_EQ(request->state()->available_instruments().back().get(), + request->state()->selected_instrument()); +} + +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardEditorTest, + ChangeCardholderName) { autofill::AutofillProfile billing_profile(autofill::test::GetFullProfile()); AddAutofillProfile(billing_profile); autofill::CreditCard card = autofill::test::GetCreditCard();
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.cc b/chrome/browser/ui/views/payments/editor_view_controller.cc index 9cc4fa1b..1c83e1d 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/editor_view_controller.cc
@@ -66,6 +66,8 @@ type); error_label->SetEnabledColor(error_label->GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_AlertSeverityHigh)); + error_label->SetMultiLine(true); + error_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); view->AddChildView(error_label.release()); return view; @@ -87,23 +89,7 @@ void EditorViewController::DisplayErrorMessageForField( autofill::ServerFieldType type, const base::string16& error_message) { - const auto& label_view_it = error_labels_.find(type); - DCHECK(label_view_it != error_labels_.end()); - - if (error_message.empty()) { - label_view_it->second->RemoveAllChildViews(/*delete_children=*/true); - } else { - if (!label_view_it->second->has_children()) { - // If there was no error label view, add it. - label_view_it->second->AddChildView( - CreateErrorLabelView(error_message, type).release()); - } else { - // The error view is the only child, and has a Label as only child itself. - static_cast<views::Label*>( - label_view_it->second->child_at(0)->child_at(0)) - ->SetText(error_message); - } - } + AddOrUpdateErrorMessageForField(type, error_message); RelayoutPane(); } @@ -120,7 +106,8 @@ std::unique_ptr<views::View> EditorViewController::CreateCustomFieldView( autofill::ServerFieldType type, views::View** focusable_field, - bool* valid) { + bool* valid, + base::string16* error_message) { return nullptr; } @@ -201,16 +188,24 @@ } std::unique_ptr<ValidatingCombobox> -EditorViewController::CreateComboboxForField(const EditorField& field) { +EditorViewController::CreateComboboxForField(const EditorField& field, + base::string16* error_message) { + std::unique_ptr<ValidationDelegate> delegate = + CreateValidationDelegate(field); + ValidationDelegate* delegate_ptr = delegate.get(); std::unique_ptr<ValidatingCombobox> combobox = base::MakeUnique<ValidatingCombobox>(GetComboboxModelForType(field.type), - CreateValidationDelegate(field)); - base::string16 initial_value = GetInitialValueForType(field.type); + std::move(delegate)); combobox->SetAccessibleName(field.label); - if (!initial_value.empty()) { + + base::string16 initial_value = GetInitialValueForType(field.type); + if (!initial_value.empty()) combobox->SelectValue(initial_value); - combobox->SetInvalid(!combobox->IsValid()); + if (IsEditingExistingItem()) { + combobox->SetInvalid( + !delegate_ptr->IsValidCombobox(combobox.get(), error_message)); } + // Using autofill field type as a view ID. combobox->set_id(GetInputFieldViewId(field.type)); combobox->set_listener(this); @@ -361,22 +356,29 @@ field.required ? field.label + base::ASCIIToUTF16("*") : field.label); label->SetMultiLine(true); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); layout->AddView(label.release()); views::View* focusable_field = nullptr; constexpr int kInputFieldHeight = 28; + base::string16 error_message; switch (field.control_type) { case EditorField::ControlType::TEXTFIELD: case EditorField::ControlType::TEXTFIELD_NUMBER: { - ValidatingTextfield* text_field = - new ValidatingTextfield(CreateValidationDelegate(field)); - // Set the initial value and validity state. + std::unique_ptr<ValidationDelegate> validation_delegate = + CreateValidationDelegate(field); + ValidationDelegate* delegate_ptr = validation_delegate.get(); + base::string16 initial_value = GetInitialValueForType(field.type); + ValidatingTextfield* text_field = + new ValidatingTextfield(std::move(validation_delegate)); + // Set the initial value and validity state. text_field->SetText(initial_value); text_field->SetAccessibleName(field.label); - *valid = text_field->IsValid(); - if (!initial_value.empty()) + *valid = IsEditingExistingItem() && + delegate_ptr->IsValidTextfield(text_field, &error_message); + if (IsEditingExistingItem()) text_field->SetInvalid(!(*valid)); if (field.control_type == EditorField::ControlType::TEXTFIELD_NUMBER) @@ -394,7 +396,7 @@ } case EditorField::ControlType::COMBOBOX: { std::unique_ptr<ValidatingCombobox> combobox = - CreateComboboxForField(field); + CreateComboboxForField(field, &error_message); focusable_field = combobox.get(); *valid = combobox->IsValid(); @@ -407,8 +409,8 @@ case EditorField::ControlType::CUSTOMFIELD: { // Custom field view will now be owned by |row|. And it must be valid // since the derived class specified a custom view for this field. - std::unique_ptr<views::View> field_view = - CreateCustomFieldView(field.type, &focusable_field, valid); + std::unique_ptr<views::View> field_view = CreateCustomFieldView( + field.type, &focusable_field, valid, &error_message); DCHECK(field_view); layout->AddView(field_view.release(), 1, 1, views::GridLayout::FILL, @@ -438,6 +440,9 @@ base::MakeUnique<views::View>(); error_label_view->SetLayoutManager(new views::FillLayout); error_labels_[field.type] = error_label_view.get(); + if (IsEditingExistingItem() && !error_message.empty()) + AddOrUpdateErrorMessageForField(field.type, error_message); + layout->AddView(error_label_view.release()); // Bottom padding for the row. @@ -463,4 +468,26 @@ return widest_column_width; } +void EditorViewController::AddOrUpdateErrorMessageForField( + autofill::ServerFieldType type, + const base::string16& error_message) { + const auto& label_view_it = error_labels_.find(type); + DCHECK(label_view_it != error_labels_.end()); + + if (error_message.empty()) { + label_view_it->second->RemoveAllChildViews(/*delete_children=*/true); + } else { + if (!label_view_it->second->has_children()) { + // If there was no error label view, add it. + label_view_it->second->AddChildView( + CreateErrorLabelView(error_message, type).release()); + } else { + // The error view is the only child, and has a Label as only child itself. + static_cast<views::Label*>( + label_view_it->second->child_at(0)->child_at(0)) + ->SetText(error_message); + } + } +} + } // namespace payments
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.h b/chrome/browser/ui/views/payments/editor_view_controller.h index fbe836d..42b2476 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.h +++ b/chrome/browser/ui/views/payments/editor_view_controller.h
@@ -115,16 +115,21 @@ // default focus within the custom view. |valid| should be set to the initial // validity state of the custom view. If a custom view requires model // validation, it should be tracked in |text_fields_| or |comboboxes_| (e.g., - // by using CreateComboboxForField). + // by using CreateComboboxForField). |error_message| should be set to the + // error message for the whole custom view, if applicable. It's possible this + // message will only be shown in certain circumstances by the + // EditorViewController. virtual std::unique_ptr<views::View> CreateCustomFieldView( autofill::ServerFieldType type, views::View** focusable_field, - bool* valid); + bool* valid, + base::string16* error_message); // Create an extra view to go to the right of the field with |type|, which // can either be a textfield, combobox, or custom view. virtual std::unique_ptr<views::View> CreateExtraViewForField( autofill::ServerFieldType type); - + // Returns whether the editor is editing an existing item. + virtual bool IsEditingExistingItem() = 0; // Returns the field definitions used to build the UI. virtual std::vector<EditorField> GetFieldDefinitions() = 0; virtual base::string16 GetInitialValueForType( @@ -160,9 +165,12 @@ views::View* GetFirstFocusedView() override; // Will create a combobox according to the |field| definition. Will also keep - // track of this field to populate the edited model on save. + // track of this field to populate the edited model on save. Fills + // |error_message| with an error message about this field's data, if + // appropriate. std::unique_ptr<ValidatingCombobox> CreateComboboxForField( - const EditorField& field); + const EditorField& field, + base::string16* error_message); private: // views::TextfieldController: @@ -187,6 +195,9 @@ // |size| type. int ComputeWidestExtraViewWidth(EditorField::LengthHint size); + void AddOrUpdateErrorMessageForField(autofill::ServerFieldType type, + const base::string16& error_message); + // Used to remember the association between the input field UI element and the // original field definition. The ValidatingTextfield* and ValidatingCombobox* // are owned by their parent view, this only keeps a reference that is good as
diff --git a/chrome/browser/ui/views/payments/error_message_view_controller.cc b/chrome/browser/ui/views/payments/error_message_view_controller.cc index ff91628..426e2698 100644 --- a/chrome/browser/ui/views/payments/error_message_view_controller.cc +++ b/chrome/browser/ui/views/payments/error_message_view_controller.cc
@@ -62,6 +62,7 @@ label->SetEnabledColor(label->GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_AlertSeverityHigh)); label->SetMultiLine(true); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); content_view->AddChildView(label.release()); }
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc index c1fed0e4..890788af 100644 --- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc +++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -89,6 +89,9 @@ label_text->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); amount_text->set_id(static_cast<int>(amount_label_id)); amount_text->SetMultiLine(true); + // The amount is formatted by the browser (and not provided by the website) so + // it can be aligned to left. + amount_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); amount_text->SetAllowCharacterBreak(true); std::unique_ptr<views::View> amount_wrapper = base::MakeUnique<views::View>();
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index d09dd2a..a9c1cf5 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -177,6 +177,7 @@ layout->StartRow(0, 0); std::unique_ptr<views::Label> name_label = CreateMediumLabel(section_name); name_label->SetMultiLine(true); + name_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); layout->AddView(name_label.release()); if (content_view) { @@ -231,6 +232,7 @@ std::unique_ptr<views::Label> amount_label = bold ? CreateBoldLabel(amount) : base::MakeUnique<views::Label>(amount); amount_label->SetMultiLine(true); + amount_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); amount_label->SetAllowCharacterBreak(true); item_amount_layout->StartRow(0, 0);
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc index a0ae9f3..dcd0b80 100644 --- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc +++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -200,6 +200,7 @@ label->set_id( static_cast<int>(DialogViewID::SHIPPING_ADDRESS_SECTION_HEADER_LABEL)); label->SetMultiLine(true); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); if (!spec()->selected_shipping_option_error().empty()) { auto warning_icon = base::MakeUnique<views::ImageView>();
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc index 7a546ae..c8623b9 100644 --- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
@@ -63,6 +63,10 @@ ShippingAddressEditorViewController::~ShippingAddressEditorViewController() {} +bool ShippingAddressEditorViewController::IsEditingExistingItem() { + return !!profile_to_edit_; +} + std::vector<EditorField> ShippingAddressEditorViewController::GetFieldDefinitions() { return editor_fields_; @@ -497,14 +501,15 @@ } bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: - IsValidTextfield(views::Textfield* textfield) { - return ValidateValue(textfield->text(), nullptr); + IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) { + return ValidateValue(textfield->text(), error_message); } bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: - IsValidCombobox(views::Combobox* combobox) { + IsValidCombobox(views::Combobox* combobox, base::string16* error_message) { return ValidateValue(combobox->GetTextForRow(combobox->selected_index()), - nullptr); + error_message); } bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate::
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h index 250e956..5bd6ddc 100644 --- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h +++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
@@ -46,6 +46,7 @@ ~ShippingAddressEditorViewController() override; // EditorViewController: + bool IsEditingExistingItem() override; std::vector<EditorField> GetFieldDefinitions() override; base::string16 GetInitialValueForType( autofill::ServerFieldType type) override; @@ -74,8 +75,10 @@ // ValidationDelegate: bool ShouldFormat() override; base::string16 Format(const base::string16& text) override; - bool IsValidTextfield(views::Textfield* textfield) override; - bool IsValidCombobox(views::Combobox* combobox) override; + bool IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) override; + bool IsValidCombobox(views::Combobox* combobox, + base::string16* error_message) override; bool TextfieldValueChanged(views::Textfield* textfield, bool was_blurred) override; bool ComboboxValueChanged(views::Combobox* combobox) override;
diff --git a/chrome/browser/ui/views/payments/validating_combobox.cc b/chrome/browser/ui/views/payments/validating_combobox.cc index e2622427..8527ac8f 100644 --- a/chrome/browser/ui/views/payments/validating_combobox.cc +++ b/chrome/browser/ui/views/payments/validating_combobox.cc
@@ -48,7 +48,8 @@ } bool ValidatingCombobox::IsValid() { - return delegate_->IsValidCombobox(this); + base::string16 unused; + return delegate_->IsValidCombobox(this, &unused); } void ValidatingCombobox::Validate() {
diff --git a/chrome/browser/ui/views/payments/validating_textfield.cc b/chrome/browser/ui/views/payments/validating_textfield.cc index efce2f2..04c21a2 100644 --- a/chrome/browser/ui/views/payments/validating_textfield.cc +++ b/chrome/browser/ui/views/payments/validating_textfield.cc
@@ -43,7 +43,8 @@ } bool ValidatingTextfield::IsValid() { - return delegate_->IsValidTextfield(this); + base::string16 unused; + return delegate_->IsValidTextfield(this, &unused); } void ValidatingTextfield::Validate() {
diff --git a/chrome/browser/ui/views/payments/validating_textfield_unittest.cc b/chrome/browser/ui/views/payments/validating_textfield_unittest.cc index 001261a4..1b39248 100644 --- a/chrome/browser/ui/views/payments/validating_textfield_unittest.cc +++ b/chrome/browser/ui/views/payments/validating_textfield_unittest.cc
@@ -30,16 +30,22 @@ // ValidationDelegate: bool TextfieldValueChanged(views::Textfield* textfield, bool was_blurred) override { - return !was_blurred || IsValidTextfield(textfield); + base::string16 unused; + return !was_blurred || IsValidTextfield(textfield, &unused); } bool ComboboxValueChanged(views::Combobox* combobox) override { - return IsValidCombobox(combobox); + base::string16 unused; + return IsValidCombobox(combobox, &unused); } - bool IsValidTextfield(views::Textfield* textfield) override { + bool IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) override { // We really don't like textfields with more than 5 characters in them. return textfield->text().size() <= 5u; } - bool IsValidCombobox(views::Combobox* combobox) override { return true; } + bool IsValidCombobox(views::Combobox* combobox, + base::string16* error_message) override { + return true; + } void ComboboxModelChanged(views::Combobox* combobox) override {} private:
diff --git a/chrome/browser/ui/views/payments/validation_delegate.h b/chrome/browser/ui/views/payments/validation_delegate.h index 96cafdfc..9687b1a3 100644 --- a/chrome/browser/ui/views/payments/validation_delegate.h +++ b/chrome/browser/ui/views/payments/validation_delegate.h
@@ -23,8 +23,10 @@ virtual base::string16 Format(const base::string16& text); // Only the delegate knows how to validate the input fields. - virtual bool IsValidTextfield(views::Textfield* textfield) = 0; - virtual bool IsValidCombobox(views::Combobox* combobox) = 0; + virtual bool IsValidTextfield(views::Textfield* textfield, + base::string16* error_message) = 0; + virtual bool IsValidCombobox(views::Combobox* combobox, + base::string16* error_message) = 0; // Notifications to let delegate react to input field changes and also let // caller know if the new values are valid. |was_blurred| indicates if the
diff --git a/chrome/browser/ui/views/task_manager_view_browsertest.cc b/chrome/browser/ui/views/task_manager_view_browsertest.cc index c45a7fd7..debe502 100644 --- a/chrome/browser/ui/views/task_manager_view_browsertest.cc +++ b/chrome/browser/ui/views/task_manager_view_browsertest.cc
@@ -52,8 +52,6 @@ chrome::HideTaskManager(); content::RunAllPendingInMessageLoop(); ASSERT_FALSE(GetView()); - - InProcessBrowserTest::TearDownOnMainThread(); } TaskManagerView* GetView() const {
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index cb9cb951..baced5d 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -74,6 +74,8 @@ #include "components/favicon_base/select_favicon_frames.h" #include "components/history/core/browser/history_types.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/web_ui/constants.h" +#include "components/safe_browsing/web_ui/safe_browsing_ui.h" #include "components/signin/core/common/profile_management_switches.h" #include "components/signin/core/common/signin_features.h" #include "content/public/browser/web_contents.h" @@ -368,6 +370,8 @@ return &NewWebUI<ProfilerUI>; if (url.host() == chrome::kChromeUIQuotaInternalsHost) return &NewWebUI<QuotaInternalsUI>; + if (url.host() == safe_browsing::kChromeUISafeBrowsingHost) + return &NewWebUI<SafeBrowsingUI>; if (url.host() == chrome::kChromeUISignInInternalsHost) return &NewWebUI<SignInInternalsUI>; if (url.host_piece() == chrome::kChromeUISuggestionsHost)
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index b20cb02..c7dc893a 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -141,8 +141,6 @@ &CoreOobeHandler::HandleEnableLargeCursor); AddCallback("enableVirtualKeyboard", &CoreOobeHandler::HandleEnableVirtualKeyboard); - AddCallback("setForceDisableVirtualKeyboard", - &CoreOobeHandler::HandleSetForceDisableVirtualKeyboard); AddCallback("enableScreenMagnifier", &CoreOobeHandler::HandleEnableScreenMagnifier); AddCallback("enableSpokenFeedback", @@ -304,19 +302,6 @@ AccessibilityManager::Get()->EnableVirtualKeyboard(enabled); } -void CoreOobeHandler::HandleSetForceDisableVirtualKeyboard(bool disable) { - scoped_keyboard_disabler_.SetForceDisableVirtualKeyboard(disable); - - if (disable) { - keyboard::KeyboardController* controller = - keyboard::KeyboardController::GetInstance(); - if (controller) { - controller->HideKeyboard( - keyboard::KeyboardController::HIDE_REASON_AUTOMATIC); - } - } -} - void CoreOobeHandler::HandleEnableScreenMagnifier(bool enabled) { // TODO(nkostylev): Add support for partial screen magnifier. DCHECK(MagnificationManager::Get());
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h index c81057a..77b9f38c 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
@@ -18,7 +18,6 @@ #include "chrome/browser/chromeos/login/version_info_updater.h" #include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h" #include "ui/events/event_source.h" -#include "ui/keyboard/scoped_keyboard_disabler.h" namespace base { class ListValue; @@ -108,7 +107,6 @@ void HandleEnableLargeCursor(bool enabled); void HandleEnableHighContrast(bool enabled); void HandleEnableVirtualKeyboard(bool enabled); - void HandleSetForceDisableVirtualKeyboard(bool disable); void HandleEnableScreenMagnifier(bool enabled); void HandleEnableSpokenFeedback(bool /* enabled */); void HandleInitialized(); @@ -162,8 +160,6 @@ DemoModeDetector demo_mode_detector_; - keyboard::ScopedKeyboardDisabler scoped_keyboard_disabler_; - DISALLOW_COPY_AND_ASSIGN(CoreOobeHandler); };
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index c296ffb..88d1809 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -351,9 +351,13 @@ params.SetString("gaiaUrl", eafe_url); params.SetString("gaiaPath", eafe_path); } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kCrosGaiaApiV1)) { params.SetString("chromeOSApiVersion", "1"); + } else if (use_easy_bootstrap_) { + // Easy bootstrap is not v2-compatible + params.SetString("chromeOSApiVersion", "1"); } frame_state_ = FRAME_STATE_LOADING;
diff --git a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h index cbf0652..e47f871a 100644 --- a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h +++ b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h
@@ -13,7 +13,7 @@ namespace network_element { // Adds the strings needed for network elements to |html_source|. String ids -// correspond to matching ids in ui/webui/resources/cr_elements/network/. +// correspond to ids in ui/webui/resources/cr_elements/chromeos/network/. void AddLocalizedStrings(content::WebUIDataSource* html_source); } // namespace network_element
diff --git a/chrome/browser/ui/webui/conflicts_handler.cc b/chrome/browser/ui/webui/conflicts_handler.cc index b6bb36ec..3343a6e 100644 --- a/chrome/browser/ui/webui/conflicts_handler.cc +++ b/chrome/browser/ui/webui/conflicts_handler.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/webui/conflicts_handler.h" +#include <memory> +#include <utility> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/strings/string16.h" @@ -24,6 +27,9 @@ } void ConflictsHandler::HandleRequestModuleList(const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + CHECK(args->GetString(0, &module_list_callback_id_)); + // The request is handled asynchronously, and will callback via // OnScanCompleted on completion. auto* model = EnumerateModulesModel::GetInstance(); @@ -61,7 +67,8 @@ results.Set("moduleList", std::move(list)); results.SetString("modulesTableTitle", table_title); - web_ui()->CallJavascriptFunctionUnsafe("returnModuleList", results); + AllowJavascript(); + ResolveJavascriptCallback(base::Value(module_list_callback_id_), results); } void ConflictsHandler::OnScanCompleted() {
diff --git a/chrome/browser/ui/webui/conflicts_handler.h b/chrome/browser/ui/webui/conflicts_handler.h index 1b7cfae..389ef1a 100644 --- a/chrome/browser/ui/webui/conflicts_handler.h +++ b/chrome/browser/ui/webui/conflicts_handler.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_WEBUI_CONFLICTS_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_CONFLICTS_HANDLER_H_ +#include <string> + #include "base/macros.h" #include "base/scoped_observer.h" #include "chrome/browser/win/enumerate_modules_model.h" @@ -31,6 +33,8 @@ ScopedObserver<EnumerateModulesModel, EnumerateModulesModel::Observer> observer_; + std::string module_list_callback_id_; + DISALLOW_COPY_AND_ASSIGN(ConflictsHandler); };
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index 7605395c..6e712e0 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -126,7 +126,8 @@ }; #endif -SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents) { +SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents, + bool is_superfish) { // Random parameters for SSL blocking page. int cert_error = net::ERR_CERT_CONTAINS_ERRORS; GURL request_url("https://example.com"); @@ -169,7 +170,7 @@ options_mask |= security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT; return SSLBlockingPage::Create( web_contents, cert_error, ssl_info, request_url, options_mask, - time_triggered_, nullptr, false /* is superfish */, + time_triggered_, nullptr, is_superfish, base::Callback<void(content::CertificateRequestResultType)>()); } @@ -413,7 +414,12 @@ std::unique_ptr<content::InterstitialPageDelegate> interstitial_delegate; std::string html; if (base::StartsWith(path, "ssl", base::CompareCase::SENSITIVE)) { - interstitial_delegate.reset(CreateSSLBlockingPage(web_contents)); + interstitial_delegate.reset( + CreateSSLBlockingPage(web_contents, false /* is superfish */)); + } else if (base::StartsWith(path, "superfish-ssl", + base::CompareCase::SENSITIVE)) { + interstitial_delegate.reset( + CreateSSLBlockingPage(web_contents, true /* is superfish */)); } else if (base::StartsWith(path, "safebrowsing", base::CompareCase::SENSITIVE)) { interstitial_delegate.reset(CreateSafeBrowsingBlockingPage(web_contents));
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc index 9147c8d..bc4f800 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
@@ -52,6 +52,11 @@ "Privacy error"); } +IN_PROC_BROWSER_TEST_F(InterstitialUITest, SuperfishInterstitial) { + TestInterstitial(GURL("chrome://interstitials/superfish-ssl"), + "Privacy error"); +} + IN_PROC_BROWSER_TEST_F(InterstitialUITest, PinnedCertInterstitial) { TestInterstitial(GURL("chrome://interstitials/ssl?type=hpkp_failure"), "Privacy error");
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index 0b2364d8..8a5b7f958 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -595,7 +595,7 @@ base::Bind(&base::DoNothing), nullptr); CleanupAfterUninstall(); } else { - GetExtensionUninstallDialog()->ConfirmUninstall( + CreateExtensionUninstallDialog()->ConfirmUninstall( extension, extensions::UNINSTALL_REASON_USER_INITIATED, extensions::UNINSTALL_SOURCE_CHROME_APPS_PAGE); } @@ -856,16 +856,13 @@ } extensions::ExtensionUninstallDialog* -AppLauncherHandler::GetExtensionUninstallDialog() { - if (!extension_uninstall_dialog_.get()) { - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); - extension_uninstall_dialog_.reset( - extensions::ExtensionUninstallDialog::Create( - extension_service_->profile(), - browser->window()->GetNativeWindow(), - this)); - } +AppLauncherHandler::CreateExtensionUninstallDialog() { + Browser* browser = + chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); + extension_uninstall_dialog_.reset( + extensions::ExtensionUninstallDialog::Create( + extension_service_->profile(), browser->window()->GetNativeWindow(), + this)); return extension_uninstall_dialog_.get(); }
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h index e808463..6bf2f834 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
@@ -165,7 +165,7 @@ // Returns the ExtensionUninstallDialog object for this class, creating it if // needed. - extensions::ExtensionUninstallDialog* GetExtensionUninstallDialog(); + extensions::ExtensionUninstallDialog* CreateExtensionUninstallDialog(); // Continuation for installing a bookmark app after favicon lookup. void OnFaviconForApp(std::unique_ptr<AppInstallInfo> install_info,
diff --git a/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc b/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc index 80e5953..be244e81 100644 --- a/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc +++ b/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc
@@ -28,7 +28,6 @@ : public InProcessBrowserTest { public: void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kForceFirstRun); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc index 51e85cb..fccd102 100644 --- a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
@@ -71,9 +71,12 @@ std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue); info->SetBoolean("playStoreEnabled", arc::IsArcPlayStoreEnabledForProfile(profile_)); + const ArcAppListPrefs* arc_apps_pref = ArcAppListPrefs::Get(profile_); + // TODO(khmel): Inverstigate why in some browser tests + // playStoreEnabled is true but arc_apps_pref is not set. info->SetBoolean( "settingsAppAvailable", - ArcAppListPrefs::Get(profile_)->IsRegistered(arc::kSettingsAppId)); + arc_apps_pref && arc_apps_pref->IsRegistered(arc::kSettingsAppId)); return info; }
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 c6fe9e83..a4c4006 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
@@ -43,6 +43,7 @@ #include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h" #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h" #include "chromeos/chromeos_switches.h" +#include "components/arc/arc_util.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "ui/display/display_switches.h" @@ -302,7 +303,9 @@ void AddAndroidAppStrings(content::WebUIDataSource* html_source) { LocalizedString localized_strings[] = { - {"androidAppsPageTitle", IDS_SETTINGS_ANDROID_APPS_TITLE}, + {"androidAppsPageTitle", arc::IsPlayStoreAvailable() + ? IDS_SETTINGS_ANDROID_APPS_TITLE + : IDS_SETTINGS_ANDROID_SETTINGS_TITLE}, {"androidAppsPageLabel", IDS_SETTINGS_ANDROID_APPS_LABEL}, {"androidAppsEnable", IDS_SETTINGS_ANDROID_APPS_ENABLE}, {"androidAppsManageApps", IDS_SETTINGS_ANDROID_APPS_MANAGE_APPS}, @@ -1715,7 +1718,8 @@ {"cookiePlural", IDS_SETTINGS_COOKIES_PLURAL_COOKIES}, {"cookieServiceWorker", IDS_SETTINGS_COOKIES_SERVICE_WORKER}, {"cookieSingular", IDS_SETTINGS_COOKIES_SINGLE_COOKIE}, - {"embeddedOnHost", IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST}, + {"embeddedOnAnyHost", IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_ANY_HOST}, + {"embeddedOnHost", IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_HOST}, {"editSiteTitle", IDS_SETTINGS_EDIT_SITE_TITLE}, {"appCacheManifest", IDS_SETTINGS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL}, {"cacheStorageLastModified",
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index eb0fb47..f9cf6dd 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -204,10 +204,18 @@ chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); html_source->AddBoolean("fingerprintUnlockEnabled", chromeos::quick_unlock::IsFingerprintEnabled()); - html_source->AddBoolean("androidAppsVisible", - arc::IsArcAllowedForProfile(profile) && - !arc::IsArcOptInVerificationDisabled() && - arc::IsPlayStoreAvailable()); + + // We have 2 variants of Android apps settings. Default case, when the Play + // Store app exists we show expandable section that allows as to + // enable/disable the Play Store and link to Android settings which is + // available once settings app is registered in the system. + // For AOSP images we don't have the Play Store app. In last case we Android + // apps settings consists only from root link to Android settings and only + // visible once settings app is registered. + const bool androidAppsVisible = arc::IsArcAllowedForProfile(profile) && + !arc::IsArcOptInVerificationDisabled(); + html_source->AddBoolean("androidAppsVisible", androidAppsVisible); + html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable()); // TODO(mash): Support Chrome power settings in Mash. crbug.com/644348 bool enable_power_settings = !ash_util::IsRunningInMash();
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc index 1c9fdf9..61c0d0e 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc
@@ -461,8 +461,6 @@ InlineLoginHelperBrowserTest() {} void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - will_create_browser_context_services_subscription_ = BrowserContextDependencyManager::GetInstance() ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
diff --git a/chrome/browser/ui/webui/signin/md_user_manager_ui.cc b/chrome/browser/ui/webui/signin/md_user_manager_ui.cc index e7fbef7..4b58961 100644 --- a/chrome/browser/ui/webui/signin/md_user_manager_ui.cc +++ b/chrome/browser/ui/webui/signin/md_user_manager_ui.cc
@@ -97,10 +97,6 @@ source->AddResourcePath("supervised_user_learn_more.js", IDR_MD_SUPERVISED_USER_LEARN_MORE_JS); source->AddResourcePath("user_manager.js", IDR_MD_USER_MANAGER_JS); - source->AddResourcePath("user_manager_dialog.html", - IDR_MD_USER_MANAGER_DIALOG_HTML); - source->AddResourcePath("user_manager_dialog.js", - IDR_MD_USER_MANAGER_DIALOG_JS); source->AddResourcePath("user_manager_pages.html", IDR_MD_USER_MANAGER_PAGES_HTML); source->AddResourcePath("user_manager_pages.js",
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc index 7539e22..ff194a9 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
@@ -36,7 +36,6 @@ ~WindowSizerTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); // Make screens sufficiently wide to host 2 browsers side by side. command_line->AppendSwitchASCII("ash-host-window-bounds", "600x600,601+0-600x600");
diff --git a/chrome/browser/usb/usb_browsertest.cc b/chrome/browser/usb/usb_browsertest.cc index 5f555e9..7a0737f 100644 --- a/chrome/browser/usb/usb_browsertest.cc +++ b/chrome/browser/usb/usb_browsertest.cc
@@ -8,8 +8,10 @@ #include "base/command_line.h" #include "base/memory/ref_counted.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/usb/usb_chooser_context_factory.h" #include "chrome/browser/usb/usb_chooser_controller.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -94,63 +96,163 @@ void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( switches::kEnableExperimentalWebPlatformFeatures); - InProcessBrowserTest::SetUpCommandLine(command_line); } void SetUpOnMainThread() override { embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); ASSERT_TRUE(embedded_test_server()->Start()); - device_client_.reset(new MockDeviceClient()); - scoped_refptr<MockUsbDevice> mock_device( - new MockUsbDevice(0, 0, "Test Manufacturer", "Test Device", "123456")); - device_client_->usb_service()->AddDevice(mock_device); + AddMockDevice("123456"); + + // Force the UsbChooserContext to be created before the test begins. This + // ensures that it is created before any instances of DeviceManagerImpl and + // thus may expose ordering bugs not normally encountered. + UsbChooserContextFactory::GetForProfile(browser()->profile()); + + ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("localhost", "/simple_page.html")); + + RenderFrameHost* render_frame_host = + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); + EXPECT_THAT(render_frame_host->GetLastCommittedOrigin().Serialize(), + testing::StartsWith("http://localhost:")); + render_frame_host->GetInterfaceRegistry()->AddInterface( + base::Bind(&FakeChooserService::Create, render_frame_host)); + } + + void AddMockDevice(const std::string& serial_number) { + DCHECK(!mock_device_); + mock_device_ = base::MakeRefCounted<MockUsbDevice>( + 0, 0, "Test Manufacturer", "Test Device", serial_number); + device_client_->usb_service()->AddDevice(mock_device_); + } + + void RemoveMockDevice() { + DCHECK(mock_device_); + device_client_->usb_service()->RemoveDevice(mock_device_); + mock_device_ = nullptr; } private: std::unique_ptr<MockDeviceClient> device_client_; + scoped_refptr<MockUsbDevice> mock_device_; }; IN_PROC_BROWSER_TEST_F(WebUsbTest, RequestAndGetDevices) { - ui_test_utils::NavigateToURL( - browser(), - embedded_test_server()->GetURL("localhost", "/simple_page.html")); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - RenderFrameHost* render_frame_host = web_contents->GetMainFrame(); - EXPECT_THAT(render_frame_host->GetLastCommittedOrigin().Serialize(), - testing::StartsWith("http://localhost:")); - render_frame_host->GetInterfaceRegistry()->AddInterface( - base::Bind(&FakeChooserService::Create, render_frame_host)); - - std::string result; - EXPECT_TRUE(content::ExecuteScriptAndExtractString( + int int_result; + EXPECT_TRUE(content::ExecuteScriptAndExtractInt( web_contents, "navigator.usb.getDevices()" " .then(devices => {" - " domAutomationController.send(devices.length.toString());" - " });", - &result)); - EXPECT_EQ("0", result); + " domAutomationController.send(devices.length);" + " });", + &int_result)); + EXPECT_EQ(0, int_result); + std::string result; EXPECT_TRUE(content::ExecuteScriptAndExtractString( web_contents, "navigator.usb.requestDevice({ filters: [ { vendorId: 0 } ] })" " .then(device => {" " domAutomationController.send(device.serialNumber);" - " });", + " });", &result)); EXPECT_EQ("123456", result); - EXPECT_TRUE(content::ExecuteScriptAndExtractString( + EXPECT_TRUE(content::ExecuteScriptAndExtractInt( web_contents, "navigator.usb.getDevices()" " .then(devices => {" - " domAutomationController.send(devices.length.toString());" - " });", + " domAutomationController.send(devices.length);" + " });", + &int_result)); + EXPECT_EQ(1, int_result); +} + +IN_PROC_BROWSER_TEST_F(WebUsbTest, AddRemoveDevice) { + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents, + "navigator.usb.requestDevice({ filters: [ { vendorId: 0 } ] })" + " .then(device => {" + " domAutomationController.send(device.serialNumber);" + " });" + + "var deviceAdded = null;" + "navigator.usb.addEventListener('connect', e => {" + " deviceAdded = e.device;" + "});" + + "var deviceRemoved = null;" + "navigator.usb.addEventListener('disconnect', e => {" + " deviceRemoved = e.device;" + "});", &result)); - EXPECT_EQ("1", result); + EXPECT_EQ("123456", result); + + RemoveMockDevice(); + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents, + "if (deviceRemoved === null) {" + " domAutomationController.send('null');" + "} else {" + " domAutomationController.send(deviceRemoved.serialNumber);" + "}", + &result)); + EXPECT_EQ("123456", result); + + AddMockDevice("123456"); + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents, + "if (deviceAdded === null) {" + " domAutomationController.send('null');" + "} else {" + " domAutomationController.send(deviceAdded.serialNumber);" + "}", + &result)); + EXPECT_EQ("123456", result); +} + +IN_PROC_BROWSER_TEST_F(WebUsbTest, AddRemoveDeviceEphemeral) { + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Replace the default mock device with one that has no serial number. + RemoveMockDevice(); + AddMockDevice(""); + + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents, + "navigator.usb.requestDevice({ filters: [ { vendorId: 0 } ] })" + " .then(device => {" + " domAutomationController.send(device.serialNumber);" + " });" + + "var deviceRemoved = null;" + "navigator.usb.addEventListener('disconnect', e => {" + " deviceRemoved = e.device;" + "});", + &result)); + EXPECT_EQ("", result); + + RemoveMockDevice(); + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents, + "if (deviceRemoved === null) {" + " domAutomationController.send('null');" + "} else {" + " domAutomationController.send(deviceRemoved.serialNumber);" + "}", + &result)); + EXPECT_EQ("", result); } } // namespace
diff --git a/chrome/browser/usb/usb_chooser_context.cc b/chrome/browser/usb/usb_chooser_context.cc index ce0e3bc..bd90f11 100644 --- a/chrome/browser/usb/usb_chooser_context.cc +++ b/chrome/browser/usb/usb_chooser_context.cc
@@ -194,7 +194,8 @@ object.HasKey(kSerialNumberKey); } -void UsbChooserContext::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { +void UsbChooserContext::OnDeviceRemovedCleanup( + scoped_refptr<UsbDevice> device) { for (auto& map_entry : ephemeral_devices_) map_entry.second.erase(device->guid()); }
diff --git a/chrome/browser/usb/usb_chooser_context.h b/chrome/browser/usb/usb_chooser_context.h index c3ef423..29801ec 100644 --- a/chrome/browser/usb/usb_chooser_context.h +++ b/chrome/browser/usb/usb_chooser_context.h
@@ -56,7 +56,7 @@ bool IsValidObject(const base::DictionaryValue& object) override; // device::UsbService::Observer implementation. - void OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) override; + void OnDeviceRemovedCleanup(scoped_refptr<device::UsbDevice> device) override; bool is_incognito_; std::map<std::pair<GURL, GURL>, std::set<std::string>> ephemeral_devices_;
diff --git a/chrome/browser/web_bluetooth_browsertest.cc b/chrome/browser/web_bluetooth_browsertest.cc index 1319519..fa8ab9d 100644 --- a/chrome/browser/web_bluetooth_browsertest.cc +++ b/chrome/browser/web_bluetooth_browsertest.cc
@@ -37,7 +37,6 @@ // https://crbug.com/507419 command_line->AppendSwitch( switches::kEnableExperimentalWebPlatformFeatures); - InProcessBrowserTest::SetUpCommandLine(command_line); } void SetUpOnMainThread() override {
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index be73029..292f4761 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -107,7 +107,6 @@ "chrome_content_client_constants.cc", "chrome_isolated_world_ids.h", "chrome_result_codes.h", - "chrome_utility_messages.h", "common_message_generator.cc", "common_message_generator.h", "common_param_traits.cc", @@ -239,6 +238,7 @@ "//components/policy:generated", "//components/policy/core/common", "//components/prefs", + "//components/safe_browsing/web_ui:constants", "//components/signin/core/common", "//components/signin/core/common:signin_features", "//components/strings", @@ -683,7 +683,7 @@ } if (safe_browsing_mode == 1) { - sources += [ "safe_archive_analyzer.mojom" ] + sources += [ "safe_browsing/safe_archive_analyzer.mojom" ] } public_deps = [
diff --git a/chrome/common/DEPS b/chrome/common/DEPS index 655033b..c60be853 100644 --- a/chrome/common/DEPS +++ b/chrome/common/DEPS
@@ -25,6 +25,7 @@ "+components/policy/core/common", "+components/printing/common", "+components/safe_browsing/csd.pb.h", + "+components/safe_browsing/web_ui/constants.h", "+components/signin/core/common", "+components/translate/core/common", "+components/url_formatter",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 25534a5c..28d3183 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -292,7 +292,7 @@ // Enables the pref service. See https://crbug.com/654988. const base::Feature kPrefService{"PrefService", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; #if defined(OS_CHROMEOS) // The lock screen will be preloaded so it is instantly available when the user
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 4f5ce400..3f0fa05 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -227,11 +227,6 @@ const char kDisableExtensionsHttpThrottling[] = "disable-extensions-http-throttling"; -// Disable the behavior that the second click on a launcher item (the click when -// the item is already active) minimizes the item. -const char kDisableMinimizeOnSecondLauncherItemClick[] = - "disable-minimize-on-second-launcher-item-click"; - // Disable auto-reload of error pages if offline. const char kDisableOfflineAutoReload[] = "disable-offline-auto-reload"; @@ -399,12 +394,6 @@ // (see SettingsWindowEnabled() below). const char kEnableSettingsWindow[] = "enable-settings-window"; -// Enable the Site Engagement Eviction Policy which evicts temporary storage -// using the site engagement service. Implicitly enables the site engagement -// service. -const char kEnableSiteEngagementEvictionPolicy[] = - "enable-site-engagement-eviction-policy"; - // Enables the site settings all sites list and site details pages in the Chrome // settings UI. const char kEnableSiteSettings[] = "enable-site-settings"; @@ -536,9 +525,6 @@ // Marks a renderer as an Instant process. const char kInstantProcess[] = "instant-process"; -// The URL for the interests API. -const char kInterestsURL[] = "interests-url"; - // Used for testing - keeps browser alive after last browser window closes. const char kKeepAliveForTest[] = "keep-alive-for-test"; @@ -861,9 +847,6 @@ // Enables Contextual Search. const char kEnableContextualSearch[] = "enable-contextual-search"; -// Enables chrome hosted mode for Android. -const char kEnableHostedMode[] = "enable-hosted-mode"; - // Enables a hung renderer InfoBar allowing the user to close or wait on // unresponsive web content. const char kEnableHungRendererInfoBar[] = "enable-hung-renderer-infobar"; @@ -1050,20 +1033,12 @@ // Runs un-installation steps that were done by chrome first-run. const char kUninstall[] = "uninstall"; -// Requests that Chrome launch the Metro viewer process via the given appid -// (which is assumed to be registered as default browser) and synchronously -// connect to it. -const char kViewerLaunchViaAppId[] = "viewer-launch-via-appid"; - // Causes the process to run as a watcher process. const char kWatcherProcess[] = "watcher"; // Enables custom-drawing the titlebar and tabstrip background so that it's not // a garish #FFFFFF like it is by default on Windows 10. const char kWindows10CustomTitlebar[] = "windows10-custom-titlebar"; - -// Indicates that chrome was launched to service a search request in Windows 8. -const char kWindows8Search[] = "windows8-search"; #endif // defined(OS_WIN) #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 36c3868..dd1d5121 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -81,7 +81,6 @@ extern const char kDisableExtensionsExcept[]; extern const char kDisableExtensionsFileAccessCheck[]; extern const char kDisableExtensionsHttpThrottling[]; -extern const char kDisableMinimizeOnSecondLauncherItemClick[]; extern const char kDisableOfflineAutoReload[]; extern const char kDisableOfflineAutoReloadVisibleOnly[]; extern const char kDisablePermissionActionReporting[]; @@ -126,7 +125,6 @@ extern const char kEnableProfiling[]; extern const char kEnablePushApiBackgroundMode[]; extern const char kEnableSettingsWindow[]; -extern const char kEnableSiteEngagementEvictionPolicy[]; extern const char kEnableSiteSettings[]; extern const char kEnableSupervisedUserManagedBookmarksFolder[]; extern const char kEnableTabAudioMuting[]; @@ -156,7 +154,6 @@ extern const char kInstallChromeApp[]; extern const char kInstallSupervisedUserWhitelists[]; extern const char kInstantProcess[]; -extern const char kInterestsURL[]; extern const char kKeepAliveForTest[]; extern const char kKioskMode[]; extern const char kKioskModePrinting[]; @@ -246,7 +243,6 @@ extern const char kDisableContextualSearch[]; extern const char kEnableAccessibilityTabSwitcher[]; extern const char kEnableContextualSearch[]; -extern const char kEnableHostedMode[]; extern const char kEnableHungRendererInfoBar[]; extern const char kForceShowUpdateMenuBadge[]; extern const char kForceShowUpdateMenuItem[]; @@ -311,10 +307,8 @@ extern const char kPrefetchArgumentWatcher[]; extern const char kShowIcons[]; extern const char kUninstall[]; -extern const char kViewerLaunchViaAppId[]; extern const char kWatcherProcess[]; extern const char kWindows10CustomTitlebar[]; -extern const char kWindows8Search[]; #endif // defined(OS_WIN) #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
diff --git a/chrome/common/common_message_generator.h b/chrome/common/common_message_generator.h index 27e54c7..fc776be8 100644 --- a/chrome/common/common_message_generator.h +++ b/chrome/common/common_message_generator.h
@@ -4,7 +4,6 @@ // Multiply-included file, hence no include guard. -#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/common_param_traits_macros.h" #include "chrome/common/mac/app_shim_messages.h" #include "chrome/common/prerender_messages.h" @@ -34,3 +33,7 @@ #if BUILDFLAG(ENABLE_WEBRTC) #include "chrome/common/media/webrtc_logging_messages.h" #endif + +#if defined(FULL_SAFE_BROWSING) +#include "chrome/common/safe_browsing/safe_archive_analyzer_param_traits.h" +#endif
diff --git a/chrome/common/safe_browsing/BUILD.gn b/chrome/common/safe_browsing/BUILD.gn index fb98a0b..b75bb1d 100644 --- a/chrome/common/safe_browsing/BUILD.gn +++ b/chrome/common/safe_browsing/BUILD.gn
@@ -42,6 +42,7 @@ "protobuf_message_read_macros.h", "protobuf_message_size_macros.h", "protobuf_message_write_macros.h", + "safe_archive_analyzer_param_traits.h", "zip_analyzer.cc", "zip_analyzer.h", ]
diff --git a/chrome/common/safe_browsing/OWNERS b/chrome/common/safe_browsing/OWNERS index a044ef7..5c8681db 100644 --- a/chrome/common/safe_browsing/OWNERS +++ b/chrome/common/safe_browsing/OWNERS
@@ -12,3 +12,10 @@ # For security review of IPC-to-protobuf bridge. per-file *protobuf_message*.h=set noparent per-file *protobuf_message*.h=file://ipc/SECURITY_OWNERS + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_param_traits*.*=set noparent +per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chrome/common/safe_archive_analyzer.mojom b/chrome/common/safe_browsing/safe_archive_analyzer.mojom similarity index 100% rename from chrome/common/safe_archive_analyzer.mojom rename to chrome/common/safe_browsing/safe_archive_analyzer.mojom
diff --git a/chrome/common/safe_archive_analyzer.typemap b/chrome/common/safe_browsing/safe_archive_analyzer.typemap similarity index 72% rename from chrome/common/safe_archive_analyzer.typemap rename to chrome/common/safe_browsing/safe_archive_analyzer.typemap index 567ef61..c27b709 100644 --- a/chrome/common/safe_archive_analyzer.typemap +++ b/chrome/common/safe_browsing/safe_archive_analyzer.typemap
@@ -2,11 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//chrome/common/safe_archive_analyzer.mojom" +mojom = "//chrome/common/safe_browsing/safe_archive_analyzer.mojom" public_headers = [ "//chrome/common/safe_browsing/zip_analyzer.h" ] -traits_headers = [ "//chrome/common/chrome_utility_messages.h" ] +traits_headers = + [ "//chrome/common/safe_browsing/safe_archive_analyzer_param_traits.h" ] deps = [ "//chrome/common/safe_browsing:proto",
diff --git a/chrome/common/chrome_utility_messages.h b/chrome/common/safe_browsing/safe_archive_analyzer_param_traits.h similarity index 91% rename from chrome/common/chrome_utility_messages.h rename to chrome/common/safe_browsing/safe_archive_analyzer_param_traits.h index a60c443..cab667f2 100644 --- a/chrome/common/chrome_utility_messages.h +++ b/chrome/common/safe_browsing/safe_archive_analyzer_param_traits.h
@@ -2,21 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Multiply-included message file, so no include guard. +// Multiply-included param traits file, so no include guard. -// TODO(noel): rename this file to a param traits variant for the full safe -// browsing feature, and remove all remaining #include of this file. +#if !defined(FULL_SAFE_BROWSING) +#error FULL_SAFE_BROWSING should be defined. +#endif -#include "build/build_config.h" -#include "ipc/ipc_message_macros.h" - -#if defined(FULL_SAFE_BROWSING) #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/ipc_protobuf_message_macros.h" #include "chrome/common/safe_browsing/protobuf_message_param_traits.h" -#endif +#include "ipc/ipc_message_macros.h" -#if defined(FULL_SAFE_BROWSING) IPC_ENUM_TRAITS_VALIDATE( safe_browsing::ClientDownloadRequest_DownloadType, safe_browsing::ClientDownloadRequest_DownloadType_IsValid(value)) @@ -96,4 +92,3 @@ IPC_STRUCT_TRAITS_MEMBER(archived_binary) IPC_STRUCT_TRAITS_MEMBER(archived_archive_filenames) IPC_STRUCT_TRAITS_END() -#endif // FULL_SAFE_BROWSING
diff --git a/chrome/common/thumbnail_capturer.mojom b/chrome/common/thumbnail_capturer.mojom index 71bf82c2..9fc1651 100644 --- a/chrome/common/thumbnail_capturer.mojom +++ b/chrome/common/thumbnail_capturer.mojom
@@ -6,13 +6,20 @@ import "ui/gfx/geometry/mojo/geometry.mojom"; +enum ImageFormat { + JPEG, + PNG, +}; + interface ThumbnailCapturer { - // Requests a JPEG encoded thumbnail of the image selected by the most - // recently opened context menu. If no image is selected or there's an error - // capturing a thumbnail, |thumbnail_data| will be empty. If the image area is - // larger than |thumbnail_min_area_pixels| it will be downscaled to fit within + // Requests an encoded thumbnail of the image selected by the most recently + // opened context menu. The encoding format is specified as a parameter. If + // no image is selected or there's an error capturing a thumbnail, + // |thumbnail_data| will be empty. If the image area is larger than + // |thumbnail_min_area_pixels| it will be downscaled to fit within // |thumbnail_max_size_pixels|. RequestThumbnailForContextNode(int32 thumbnail_min_area_pixels, - gfx.mojom.Size thumbnail_max_size_pixels) + gfx.mojom.Size thumbnail_max_size_pixels, + ImageFormat image_format) => (array<uint8> thumbnail_data, gfx.mojom.Size original_size); };
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 43f5492..1a4b7422 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "build/build_config.h" #include "chrome/common/features.h" +#include "components/safe_browsing/web_ui/constants.h" #include "content/public/common/url_constants.h" #include "extensions/features/features.h" #include "media/media_features.h" @@ -669,6 +670,7 @@ kChromeUISignInInternalsHost, kChromeUISiteEngagementHost, kChromeUINTPTilesInternalsHost, + safe_browsing::kChromeUISafeBrowsingHost, kChromeUISuggestionsHost, kChromeUISupervisedUserInternalsHost, kChromeUISyncInternalsHost,
diff --git a/chrome/installer/util/google_update_util.cc b/chrome/installer/util/google_update_util.cc index 95eb1e3..3d9aef5 100644 --- a/chrome/installer/util/google_update_util.cc +++ b/chrome/installer/util/google_update_util.cc
@@ -8,20 +8,13 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "base/process/kill.h" #include "base/process/launch.h" #include "base/strings/string16.h" #include "base/time/time.h" -#include "base/win/registry.h" -#include "base/win/scoped_handle.h" #include "base/win/win_util.h" -#include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/google_update_settings.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/installation_state.h" -#include "chrome/installer/util/product.h" - -using base::win::RegKey; namespace google_update { @@ -29,55 +22,6 @@ const int kGoogleUpdateTimeoutMs = 20 * 1000; -// Returns true if Google Update is present at the given level. -bool IsGoogleUpdatePresent(bool system_install) { - // Using the existence of version key in the registry to decide. - return GoogleUpdateSettings::GetGoogleUpdateVersion(system_install).IsValid(); -} - -// Returns GoogleUpdateSetup.exe's executable path at specified level. -// or an empty path if none is found. -base::FilePath GetGoogleUpdateSetupExe(bool system_install) { - const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - RegKey update_key; - - if (update_key.Open(root_key, kRegPathGoogleUpdate, KEY_QUERY_VALUE) == - ERROR_SUCCESS) { - base::string16 path_str; - base::string16 version_str; - if ((update_key.ReadValue(kRegPathField, &path_str) == ERROR_SUCCESS) && - (update_key.ReadValue(kRegGoogleUpdateVersion, &version_str) == - ERROR_SUCCESS)) { - return base::FilePath(path_str).DirName().Append(version_str). - Append(kGoogleUpdateSetupExe); - } - } - return base::FilePath(); -} - -// If Google Update is present at system-level, sets |cmd_string| to the command -// line to install Google Update at user-level and returns true. -// Otherwise, clears |cmd_string| and returns false. -bool GetUserLevelGoogleUpdateInstallCommandLine(base::string16* cmd_string) { - cmd_string->clear(); - base::FilePath google_update_setup( - GetGoogleUpdateSetupExe(true)); // system-level. - if (!google_update_setup.empty()) { - base::CommandLine cmd(google_update_setup); - // Appends "/install runtime=true&needsadmin=false /silent /nomitag". - // NB: /nomitag needs to be at the end. - // Constants are found in code.google.com/p/omaha/common/const_cmd_line.h. - cmd.AppendArg("/install"); - // The "&" can be used in base::LaunchProcess() without quotation - // (this is problematic only if run from command prompt). - cmd.AppendArg("runtime=true&needsadmin=false"); - cmd.AppendArg("/silent"); - cmd.AppendArg("/nomitag"); - *cmd_string = cmd.GetCommandLineString(); - } - return !cmd_string->empty(); -} - // Launches command |cmd_string|, and waits for |timeout| milliseconds before // timing out. To wait indefinitely, one can set // |timeout| to be base::TimeDelta::FromMilliseconds(INFINITE). @@ -107,29 +51,6 @@ } // namespace -bool EnsureUserLevelGoogleUpdatePresent() { - VLOG(0) << "Ensuring Google Update is present at user-level."; - - bool success = false; - if (IsGoogleUpdatePresent(false)) { - success = true; - } else { - base::string16 cmd_string; - if (!GetUserLevelGoogleUpdateInstallCommandLine(&cmd_string)) { - LOG(ERROR) << "Cannot find Google Update at system-level."; - // Ideally we should return false. However, this case should not be - // encountered by regular users, and developers (who often installs - // Chrome without Google Update) may be unduly impeded by this case. - // Therefore we return true. - success = true; - } else { - success = LaunchProcessAndWaitWithTimeout(cmd_string, - base::TimeDelta::FromMilliseconds(INFINITE)); - } - } - return success; -} - bool UninstallGoogleUpdate(bool system_install) { bool success = false; base::string16 cmd_string(
diff --git a/chrome/installer/util/google_update_util.h b/chrome/installer/util/google_update_util.h index 97edfada..dca4cd13 100644 --- a/chrome/installer/util/google_update_util.h +++ b/chrome/installer/util/google_update_util.h
@@ -7,13 +7,6 @@ namespace google_update { -// If user-level Google Update is absent, calls the system-level -// GoogleUpdateSetup.exe to install it, and waits until it finishes. -// Returns true if already installed, installed successfully, or -// if Google Update is not present at system-level. -// Returns false if the installation fails. -bool EnsureUserLevelGoogleUpdatePresent(); - // Tell Google Update that an uninstall has taken place. This gives it a chance // to uninstall itself straight away if no more products are installed on the // system rather than waiting for the next time the scheduled task runs.
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index 7b13a72..a7b6ecc 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -45,6 +45,7 @@ #include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/codec/jpeg_codec.h" +#include "ui/gfx/codec/png_codec.h" #include "ui/gfx/geometry/size_f.h" #include "url/gurl.h" @@ -72,6 +73,10 @@ // the refresh delay is less than this value (in seconds). static const double kLocationChangeIntervalInSeconds = 10; +// For the context menu, we want to keep transparency as is instead of +// replacing transparent pixels with black ones +static const bool kDiscardTransparencyForContextMenu = false; + namespace { // If the source image is null or occupies less area than @@ -194,6 +199,7 @@ void ChromeRenderFrameObserver::RequestThumbnailForContextNode( int32_t thumbnail_min_area_pixels, const gfx::Size& thumbnail_max_size_pixels, + chrome::mojom::ImageFormat image_format, const RequestThumbnailForContextNodeCallback& callback) { WebNode context_node = render_frame()->GetWebFrame()->ContextMenuNode(); SkBitmap thumbnail; @@ -219,8 +225,19 @@ std::vector<uint8_t> thumbnail_data; constexpr int kDefaultQuality = 90; std::vector<unsigned char> data; - if (gfx::JPEGCodec::Encode(bitmap, kDefaultQuality, &data)) { - thumbnail_data.swap(data); + + switch (image_format) { + case chrome::mojom::ImageFormat::PNG: + if (gfx::PNGCodec::EncodeBGRASkBitmap( + bitmap, kDiscardTransparencyForContextMenu, &data)) { + thumbnail_data.swap(data); + break; + } + case chrome::mojom::ImageFormat::JPEG: + if (gfx::JPEGCodec::Encode(bitmap, kDefaultQuality, &data)) { + thumbnail_data.swap(data); + break; + } } callback.Run(thumbnail_data, original_size);
diff --git a/chrome/renderer/chrome_render_frame_observer.h b/chrome/renderer/chrome_render_frame_observer.h index 24da7f6..5ec1af9f 100644 --- a/chrome/renderer/chrome_render_frame_observer.h +++ b/chrome/renderer/chrome_render_frame_observer.h
@@ -55,6 +55,7 @@ void RequestThumbnailForContextNode( int32_t thumbnail_min_area_pixels, const gfx::Size& thumbnail_max_size_pixels, + chrome::mojom::ImageFormat image_format, const RequestThumbnailForContextNodeCallback& callback) override; // Mojo handlers.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4baf8eb..588faf7 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2029,6 +2029,7 @@ "../browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc", "../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc", "../browser/ui/ash/volume_controller_browsertest.cc", + "../browser/ui/sort_windows_by_z_index_browsertest.cc", "../browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc", ] deps += [
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 2b2612b5..a53f85b 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -40,6 +40,7 @@ "javatests/src/org/chromium/chrome/test/util/browser/suggestions/ContentSuggestionsTestUtils.java", "javatests/src/org/chromium/chrome/test/util/browser/suggestions/DummySuggestionsEventReporter.java", "javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java", + "javatests/src/org/chromium/chrome/test/util/browser/suggestions/SuggestionsDependenciesRule.java", "javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java", "javatests/src/org/chromium/chrome/test/util/browser/RecyclerViewTestUtils.java", "javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java",
diff --git a/chrome/test/android/OWNERS b/chrome/test/android/OWNERS index 05f86d3..666390f 100644 --- a/chrome/test/android/OWNERS +++ b/chrome/test/android/OWNERS
@@ -1,6 +1,5 @@ aelias@chromium.org boliu@chromium.org -dfalcantara@chromium.org dtrainor@chromium.org jbudorick@chromium.org mariakhomenko@chromium.org
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java index e2fe630..7413ce1 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/SuggestionsBottomSheetTestRule.java
@@ -6,28 +6,28 @@ import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.registerCategory; -import org.chromium.chrome.browser.suggestions.SuggestionsBottomSheetContent; import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; +import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; /** * Junit4 rule for tests testing suggestions on the Chrome Home bottom sheet. + * @deprecated Use {@link BottomSheetTestRule} directly for general Chrome setup and + * {@link SuggestionsDependenciesRule} for dependencies setup. */ +@Deprecated public class SuggestionsBottomSheetTestRule extends BottomSheetTestRule { - @Override - protected void beforeStartingActivity() { + /** + * Initialises the test dependency factory with dummy data for the bottom sheet tests. + * @deprecated To be removed or refactored (see http://crrev.com/c/541442/). Use + * {@link SuggestionsDependenciesRule} directly in the meantime. + */ + @Deprecated + public void initDependencies(SuggestionsDependenciesRule.TestFactory testFactory) { FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource(); registerCategory(suggestionsSource, /* category = */ 42, /* count = */ 5); - SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(suggestionsSource); - SuggestionsBottomSheetContent.setEventReporterForTesting( - new DummySuggestionsEventReporter()); - super.beforeStartingActivity(); - } + testFactory.suggestionsSource = suggestionsSource; - @Override - protected void afterActivityFinished() { - super.afterActivityFinished(); - SuggestionsBottomSheetContent.setSuggestionsSourceForTesting(null); - SuggestionsBottomSheetContent.setEventReporterForTesting(null); + testFactory.eventReporter = new DummySuggestionsEventReporter(); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java index 5bb1f7e..6770ad8 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java
@@ -208,6 +208,9 @@ } @Override + public void onDestroy() {} + + @Override public int[] getCategories() { int[] result = new int[mCategories.size()]; int index = 0;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/SuggestionsDependenciesRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/SuggestionsDependenciesRule.java new file mode 100644 index 0000000..f98f83c --- /dev/null +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/SuggestionsDependenciesRule.java
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.test.util.browser.suggestions; + +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.chrome.browser.favicon.LargeIconBridge; +import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.suggestions.MostVisitedSites; +import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory; +import org.chromium.chrome.browser.suggestions.SuggestionsEventReporter; + +/** + * Rule that allows mocking native dependencies of the suggestions package. + * + * The Factory members to override should be set before the main test rule is called to initialise + * the test activity. + * + * @see SuggestionsDependencyFactory + */ +public class SuggestionsDependenciesRule extends TestWatcher { + private TestFactory mFactory; + + public TestFactory getFactory() { + return mFactory; + } + + @Override + protected void starting(Description description) { + mFactory = new TestFactory(); + SuggestionsDependencyFactory.setInstanceForTesting(mFactory); + } + + @Override + protected void finished(Description description) { + SuggestionsDependencyFactory.setInstanceForTesting(null); + } + + /** + * SuggestionsDependencyFactory that exposes and allows modifying the instances to be injected. + */ + // TODO(dgn): Warning emitted while all the exposed fields are not used, this should become + // unnecessary as we start using the rule. + @SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD") + public static class TestFactory extends SuggestionsDependencyFactory { + public SuggestionsSource suggestionsSource; + public MostVisitedSites mostVisitedSites; + public LargeIconBridge largeIconBridge; + public SuggestionsEventReporter eventReporter; + + @Override + public SuggestionsSource createSuggestionSource(Profile profile) { + if (suggestionsSource != null) return suggestionsSource; + return super.createSuggestionSource(profile); + } + + @Override + public SuggestionsEventReporter createEventReporter() { + if (eventReporter != null) return eventReporter; + return super.createEventReporter(); + } + + @Override + public MostVisitedSites createMostVisitedSites(Profile profile) { + if (mostVisitedSites != null) return mostVisitedSites; + return super.createMostVisitedSites(profile); + } + + @Override + public LargeIconBridge createLargeIconBridge(Profile profile) { + if (largeIconBridge != null) return largeIconBridge; + return new LargeIconBridge(profile); + } + } +}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/OWNERS b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/OWNERS deleted file mode 100644 index 79becd2..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -dfalcantara@chromium.org
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc index a55f440..e4f55f8e 100644 --- a/chrome/test/base/testing_profile_manager.cc +++ b/chrome/test/base/testing_profile_manager.cc
@@ -70,7 +70,8 @@ // Create a path for the profile based on the name. base::FilePath profile_path(profiles_dir_.GetPath()); #if defined(OS_CHROMEOS) - if (profile_name != chrome::kInitialProfile) { + if (profile_name != chrome::kInitialProfile && + profile_name != chromeos::ProfileHelper::GetLockScreenAppProfileName()) { profile_path = profile_path.Append(chromeos::ProfileHelper::Get()->GetUserProfileDir( chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(
diff --git a/chrome/test/chromedriver/OWNERS b/chrome/test/chromedriver/OWNERS index 543fcb9e..9d982eb3 100644 --- a/chrome/test/chromedriver/OWNERS +++ b/chrome/test/chromedriver/OWNERS
@@ -2,4 +2,5 @@ johnchen@chromium.org # backup reviewer +jbudorick@chromium.org stgao@chromium.org
diff --git a/chrome/test/chromedriver/chrome/adb_impl.cc b/chrome/test/chromedriver/chrome/adb_impl.cc index a60d8bc..c592328 100644 --- a/chrome/test/chromedriver/chrome/adb_impl.cc +++ b/chrome/test/chromedriver/chrome/adb_impl.cc
@@ -230,9 +230,9 @@ const std::string& command, std::string* response) { scoped_refptr<ResponseBuffer> response_buffer = new ResponseBuffer; VLOG(1) << "Sending adb command: " << command; - io_task_runner_->PostTask( - FROM_HERE, - base::Bind(&ExecuteCommandOnIOThread, command, response_buffer, port_)); + io_task_runner_->PostTask(FROM_HERE, + base::BindOnce(&ExecuteCommandOnIOThread, command, + response_buffer, port_)); Status status = response_buffer->GetResponse( response, base::TimeDelta::FromSeconds(30)); if (status.IsOk()) {
diff --git a/chrome/test/chromedriver/commands.cc b/chrome/test/chromedriver/commands.cc index 1c36f9a02..da702814 100644 --- a/chrome/test/chromedriver/commands.cc +++ b/chrome/test/chromedriver/commands.cc
@@ -71,7 +71,8 @@ } thread->task_runner()->PostTask( - FROM_HERE, base::Bind(&SetThreadLocalSession, base::Passed(&session))); + FROM_HERE, + base::BindOnce(&SetThreadLocalSession, base::Passed(&session))); session_thread_map ->insert(std::make_pair(new_id, make_linked_ptr(thread.release()))); init_session_cmd.Run(params, new_id, callback); @@ -209,11 +210,10 @@ if (!session) { cmd_task_runner->PostTask( FROM_HERE, - base::Bind(callback_on_cmd, - Status(return_ok_without_session ? kOk : kNoSuchSession), - base::Passed(std::unique_ptr<base::Value>()), - std::string(), - false)); + base::BindOnce(callback_on_cmd, + Status(return_ok_without_session ? kOk : kNoSuchSession), + base::Passed(std::unique_ptr<base::Value>()), + std::string(), false)); return; } @@ -289,9 +289,8 @@ } cmd_task_runner->PostTask( - FROM_HERE, - base::Bind(callback_on_cmd, status, base::Passed(&value), session->id, - session->w3c_compliant)); + FROM_HERE, base::BindOnce(callback_on_cmd, status, base::Passed(&value), + session->id, session->w3c_compliant)); if (session->quit) { SetThreadLocalSession(std::unique_ptr<Session>()); @@ -316,12 +315,13 @@ callback.Run(status, std::unique_ptr<base::Value>(), session_id, false); } else { iter->second->task_runner()->PostTask( - FROM_HERE, base::Bind(&ExecuteSessionCommandOnSessionThread, - command_name, command, return_ok_without_session, - base::Passed(base::WrapUnique(params.DeepCopy())), - base::ThreadTaskRunnerHandle::Get(), callback, - base::Bind(&TerminateSessionThreadOnCommandThread, - session_thread_map, session_id))); + FROM_HERE, + base::BindOnce(&ExecuteSessionCommandOnSessionThread, command_name, + command, return_ok_without_session, + base::Passed(base::WrapUnique(params.DeepCopy())), + base::ThreadTaskRunnerHandle::Get(), callback, + base::Bind(&TerminateSessionThreadOnCommandThread, + session_thread_map, session_id))); } }
diff --git a/chrome/test/chromedriver/commands_unittest.cc b/chrome/test/chromedriver/commands_unittest.cc index 5c5af31..c765fc2 100644 --- a/chrome/test/chromedriver/commands_unittest.cc +++ b/chrome/test/chromedriver/commands_unittest.cc
@@ -231,7 +231,7 @@ std::string id("id"); thread->task_runner()->PostTask( FROM_HERE, - base::Bind(&internal::CreateSessionOnSessionThreadForTesting, id)); + base::BindOnce(&internal::CreateSessionOnSessionThreadForTesting, id)); map[id] = thread; base::DictionaryValue params; @@ -719,7 +719,7 @@ std::string id("id"); thread->task_runner()->PostTask( FROM_HERE, - base::Bind(&internal::CreateSessionOnSessionThreadForTesting, id)); + base::BindOnce(&internal::CreateSessionOnSessionThreadForTesting, id)); map[id] = thread; @@ -810,7 +810,7 @@ std::string id("id"); thread->task_runner()->PostTask( FROM_HERE, - base::Bind(&internal::CreateSessionOnSessionThreadForTesting, id)); + base::BindOnce(&internal::CreateSessionOnSessionThreadForTesting, id)); map[id] = thread; // In SuccessNotifyingCommandListenersBeforeCommand, we verified BeforeCommand @@ -818,8 +818,8 @@ // verify this again, so we can just add |listener| with PostTask. auto listener = base::MakeUnique<FailingCommandListener>(); thread->task_runner()->PostTask( - FROM_HERE, base::Bind(&AddListenerToSessionIfSessionExists, - base::Passed(&listener))); + FROM_HERE, base::BindOnce(&AddListenerToSessionIfSessionExists, + base::Passed(&listener))); base::DictionaryValue params; // The command should never be executed if BeforeCommand fails for a listener. @@ -838,5 +838,5 @@ run_loop.Run(); thread->task_runner()->PostTask(FROM_HERE, - base::Bind(&VerifySessionWasDeleted)); + base::BindOnce(&VerifySessionWasDeleted)); }
diff --git a/chrome/test/chromedriver/net/net_util.cc b/chrome/test/chromedriver/net/net_util.cc index 66cd616..b117d378 100644 --- a/chrome/test/chromedriver/net/net_util.cc +++ b/chrome/test/chromedriver/net/net_util.cc
@@ -35,8 +35,8 @@ bool Fetch() { getter_->GetNetworkTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&SyncUrlFetcher::FetchOnIOThread, base::Unretained(this))); + FROM_HERE, base::BindOnce(&SyncUrlFetcher::FetchOnIOThread, + base::Unretained(this))); event_.Wait(); return success_; }
diff --git a/chrome/test/chromedriver/net/net_util_unittest.cc b/chrome/test/chromedriver/net/net_util_unittest.cc index 256d96b..91ae6e2 100644 --- a/chrome/test/chromedriver/net/net_util_unittest.cc +++ b/chrome/test/chromedriver/net/net_util_unittest.cc
@@ -40,8 +40,8 @@ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); io_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&FetchUrlTest::InitOnIO, base::Unretained(this), &event)); + FROM_HERE, base::BindOnce(&FetchUrlTest::InitOnIO, + base::Unretained(this), &event)); event.Wait(); } @@ -49,8 +49,8 @@ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); io_thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&FetchUrlTest::DestroyServerOnIO, - base::Unretained(this), &event)); + FROM_HERE, base::BindOnce(&FetchUrlTest::DestroyServerOnIO, + base::Unretained(this), &event)); event.Wait(); }
diff --git a/chrome/test/chromedriver/net/port_server_unittest.cc b/chrome/test/chromedriver/net/port_server_unittest.cc index c43f693..bd3681bc 100644 --- a/chrome/test/chromedriver/net/port_server_unittest.cc +++ b/chrome/test/chromedriver/net/port_server_unittest.cc
@@ -132,8 +132,8 @@ base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&RunServerOnThread, path, response, &listen_event, request)); + FROM_HERE, base::BindOnce(&RunServerOnThread, path, response, + &listen_event, request)); ASSERT_TRUE(listen_event.TimedWait(base::TimeDelta::FromSeconds(5))); }
diff --git a/chrome/test/chromedriver/net/sync_websocket_impl.cc b/chrome/test/chromedriver/net/sync_websocket_impl.cc index 71f364e..eecba9b 100644 --- a/chrome/test/chromedriver/net/sync_websocket_impl.cc +++ b/chrome/test/chromedriver/net/sync_websocket_impl.cc
@@ -56,9 +56,8 @@ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); context_getter_->GetNetworkTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&SyncWebSocketImpl::Core::ConnectOnIO, - this, url, &success, &event)); + FROM_HERE, base::BindOnce(&SyncWebSocketImpl::Core::ConnectOnIO, this, + url, &success, &event)); event.Wait(); return success; } @@ -68,9 +67,8 @@ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); context_getter_->GetNetworkTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&SyncWebSocketImpl::Core::SendOnIO, - this, message, &success, &event)); + FROM_HERE, base::BindOnce(&SyncWebSocketImpl::Core::SendOnIO, this, + message, &success, &event)); event.Wait(); return success; }
diff --git a/chrome/test/chromedriver/net/test_http_server.cc b/chrome/test/chromedriver/net/test_http_server.cc index 1999d26..45a48f8 100644 --- a/chrome/test/chromedriver/net/test_http_server.cc +++ b/chrome/test/chromedriver/net/test_http_server.cc
@@ -42,8 +42,8 @@ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&TestHttpServer::StartOnServerThread, - base::Unretained(this), &success, &event)); + FROM_HERE, base::BindOnce(&TestHttpServer::StartOnServerThread, + base::Unretained(this), &success, &event)); event.Wait(); return success; } @@ -54,8 +54,8 @@ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&TestHttpServer::StopOnServerThread, - base::Unretained(this), &event)); + FROM_HERE, base::BindOnce(&TestHttpServer::StopOnServerThread, + base::Unretained(this), &event)); event.Wait(); thread_.Stop(); }
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc index 7df71ce8..8f940fa 100644 --- a/chrome/test/chromedriver/server/chromedriver_server.cc +++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -134,8 +134,8 @@ const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, const HttpResponseSenderFunc& send_response_on_io_func, std::unique_ptr<net::HttpServerResponseInfo> response) { - io_task_runner->PostTask( - FROM_HERE, base::Bind(send_response_on_io_func, base::Passed(&response))); + io_task_runner->PostTask(FROM_HERE, base::BindOnce(send_response_on_io_func, + base::Passed(&response))); } void HandleRequestOnCmdThread( @@ -165,10 +165,10 @@ const net::HttpServerRequestInfo& request, const HttpResponseSenderFunc& send_response_func) { cmd_task_runner->PostTask( - FROM_HERE, base::Bind(handle_request_on_cmd_func, request, - base::Bind(&SendResponseOnCmdThread, - base::ThreadTaskRunnerHandle::Get(), - send_response_func))); + FROM_HERE, base::BindOnce(handle_request_on_cmd_func, request, + base::Bind(&SendResponseOnCmdThread, + base::ThreadTaskRunnerHandle::Get(), + send_response_func))); } base::LazyInstance<base::ThreadLocalPointer<HttpServer>>::DestructorAtExit @@ -211,9 +211,9 @@ io_thread.task_runner()->PostTask( FROM_HERE, - base::Bind(&StartServerOnIOThread, port, allow_remote, - base::Bind(&HandleRequestOnIOThread, cmd_loop.task_runner(), - handle_request_func))); + base::BindOnce(&StartServerOnIOThread, port, allow_remote, + base::Bind(&HandleRequestOnIOThread, + cmd_loop.task_runner(), handle_request_func))); // Run the command loop. This loop is quit after the response for a shutdown // request is posted to the IO loop. After the command loop quits, a task // is posted to the IO loop to stop the server. Lastly, the IO thread is @@ -221,7 +221,7 @@ // This assumes the response is sent synchronously as part of the IO task. cmd_run_loop.Run(); io_thread.task_runner()->PostTask(FROM_HERE, - base::Bind(&StopServerOnIOThread)); + base::BindOnce(&StopServerOnIOThread)); } } // namespace
diff --git a/chrome/test/chromedriver/session_commands_unittest.cc b/chrome/test/chromedriver/session_commands_unittest.cc index 6ed5954..9c5312a 100644 --- a/chrome/test/chromedriver/session_commands_unittest.cc +++ b/chrome/test/chromedriver/session_commands_unittest.cc
@@ -21,7 +21,7 @@ #include "chrome/test/chromedriver/session.h" #include "testing/gtest/include/gtest/gtest.h" -TEST(SessionCommandTest, FileUpload) { +TEST(SessionCommandsTest, FileUpload) { Session session("id"); base::DictionaryValue params; std::unique_ptr<base::Value> value;
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index e73db7a..f7b81d7 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -173,6 +173,10 @@ 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePage', # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1149 'ChromeDriverTests.testShouldAllowTheUserToSwitchToAnIFrameAndRemainFocusedOnIt', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1857 + 'TakesScreenshotTest.testShouldCaptureScreenshot', + 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePageAfterSwitching', + 'TakesScreenshotTest.testShouldCaptureScreenshotAtIFramePageAfterSwitching', ] _SPECIFIC_OS_REVISION_NEGATIVE_FILTER = {}
diff --git a/chrome/test/data/chromeos/liblouis_nacl/test.js b/chrome/test/data/chromeos/liblouis_nacl/test.js index 142773b..7391034 100644 --- a/chrome/test/data/chromeos/liblouis_nacl/test.js +++ b/chrome/test/data/chromeos/liblouis_nacl/test.js
@@ -71,7 +71,8 @@ }, function testTranslateString() { - rpc('Translate', { 'table_names': TABLE_NAME, 'text': TEXT}, + rpc('Translate', { 'table_names': TABLE_NAME, 'text': TEXT, + form_type_map: []}, pass(expectSuccessReply(function(reply) { chrome.test.assertEq(CELLS, reply['cells']); }))); @@ -82,7 +83,8 @@ // letter 'T' should be translated to 3 cells in US English grade 2 // braille (dots 56, 6, 2345). function testTranslateGrade2SingleCapital() { - rpc('Translate', { 'table_names': CONTRACTED_TABLE_NAME, 'text': 'T'}, + rpc('Translate', { 'table_names': CONTRACTED_TABLE_NAME, 'text': 'T', + form_type_map: []}, pass(expectSuccessReply(function(reply) { chrome.test.assertEq('30201e', reply['cells']); })));
diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/reset_all_advertisements/manifest.json b/chrome/test/data/extensions/api_test/bluetooth_low_energy/reset_all_advertisements/manifest.json new file mode 100644 index 0000000..60a6fa2 --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/reset_all_advertisements/manifest.json
@@ -0,0 +1,18 @@ +{ + "manifest_version": 2, + "name": "Test the Bluetooth Low Energy resetAdvertising API", + "version": "1.0", + "app": { + "background": { + "scripts": ["runtest.js"] + } + }, + "kiosk_only": true, + "kiosk_enabled": true, + "bluetooth": { + "low_energy": true, + "peripheral": true, + "uuids": ["1234"] + }, + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqbc71rRrqz+62pGVmZGDzTK8P4IHTTyN4jBLBJasDTrRllQp4Pb6INnSr08HQM3aaZMYKWkAJTm4gbCDNzvHfIZMAMY6OZfnm0eqiZnxFFgKgIzdr4Z/EyAXVd1Rm1JKhncde2S/U3zWStDb5iYfWZJBIiWVT98q7cW6sstsMOmrHAIAKCzK+mzycFptlRWzAf+8NR9bq1jNZe+h1kJBgY0xnVlGZm+NIhZd/Ke8Y+G2vM4rtuDvp5971HVV294HD28hWbsoOqBf85gPa6tKE57FhLomi/aJVBVBiCfHExXjK1hB2QeM/r7e8P//ZZPoYszSzHJVBw/heRLFOMezIwIDAQAB" +}
diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/reset_all_advertisements/runtest.js b/chrome/test/data/extensions/api_test/bluetooth_low_energy/reset_all_advertisements/runtest.js new file mode 100644 index 0000000..972acbd --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/reset_all_advertisements/runtest.js
@@ -0,0 +1,52 @@ +// 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. + +var kAdvertisement = { + type: 'broadcast', + serviceUuids: ['value1', 'value2'], + manufacturerData: [ + {id: 321, data: [1, 2, 3]}, + {id: 567, data: [8, 2, 3]} + ], + solicitUuids: ['value3', 'value4'], + serviceData: [ + {uuid: 'uuid8', data: [1, 2, 3]}, + {uuid: 'uuid36', data: [8, 2, 3]} + ] +}; + +var registeredAdvertisements = []; + +chrome.test.runTests([ + function registerFirstAdvertisement() { + chrome.bluetoothLowEnergy.registerAdvertisement( + kAdvertisement, + chrome.test.callbackPass(function(id) { + chrome.test.assertTrue(!!id); + registeredAdvertisements.push(id); + })); + }, + + function registerSecondAdvertisement() { + chrome.bluetoothLowEnergy.registerAdvertisement( + kAdvertisement, + chrome.test.callbackPass(function(id) { + chrome.test.assertTrue(!!id); + chrome.test.assertEq(-1, registeredAdvertisements.indexOf(id)); + registeredAdvertisements.push(id); + })); + }, + + function resetAdvertising() { + chrome.bluetoothLowEnergy.resetAdvertising(chrome.test.callbackPass()); + }, + + function unregisterFails() { + registeredAdvertisements.forEach(function(id) { + chrome.bluetoothLowEnergy.unregisterAdvertisement( + id, + chrome.test.callbackFail("This advertisement does not exist")); + }); + } +]);
diff --git a/chrome/test/data/extensions/api_test/native_bindings/extension/background.js b/chrome/test/data/extensions/api_test/native_bindings/extension/background.js index 0b6fc9d..560cecf 100644 --- a/chrome/test/data/extensions/api_test/native_bindings/extension/background.js +++ b/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
@@ -124,7 +124,11 @@ }, function testLastError() { chrome.runtime.setUninstallURL('chrome://newtab', function() { - chrome.test.assertLastError('Invalid URL: "chrome://newtab".'); + var expectedError = 'Invalid URL: "chrome://newtab".'; + chrome.test.assertLastError(expectedError); + // Explicitly also test the old extension.lastError property. + chrome.test.assertTrue(!!chrome.extension.lastError); + chrome.test.assertEq(expectedError, chrome.extension.lastError.message); chrome.test.succeed(); }); },
diff --git a/chrome/test/data/favicon/pushstate_with_manifest.html b/chrome/test/data/favicon/pushstate_with_manifest.html new file mode 100644 index 0000000..7df9c45 --- /dev/null +++ b/chrome/test/data/favicon/pushstate_with_manifest.html
@@ -0,0 +1,12 @@ +<html> +<head> +<link rel="manifest" href="manifest.json"/> +<script> +window.onload = function() { + setTimeout(function() { + history.pushState("", "", "#pushState"); + }, 0); +} +</script> +</head> +</html>
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_network_indicator_tests.js b/chrome/test/data/webui/cr_elements/cr_policy_network_indicator_tests.js index e8d4a607..8e9890a 100644 --- a/chrome/test/data/webui/cr_elements/cr_policy_network_indicator_tests.js +++ b/chrome/test/data/webui/cr_elements/cr_policy_network_indicator_tests.js
@@ -10,6 +10,9 @@ /** @type {!PaperTooltipElement|undefined} */ var tooltip; + // Prevent 'Cannot read property of undefined' errors in cr_onc_types.js. + chrome.networkingPrivate = {}; + setup(function() { PolymerTest.clearBody();
diff --git a/chrome/test/data/webui/md_bookmarks/command_manager_test.js b/chrome/test/data/webui/md_bookmarks/command_manager_test.js index 47c5563..f4672d1e 100644 --- a/chrome/test/data/webui/md_bookmarks/command_manager_test.js +++ b/chrome/test/data/webui/md_bookmarks/command_manager_test.js
@@ -264,6 +264,7 @@ test('cannot edit unmodifiable nodes', function() { // Cannot edit root folders. var items = new Set(['1']); + store.data.selection.items = items; assertFalse(commandManager.canExecute(Command.EDIT, items)); assertFalse(commandManager.canExecute(Command.DELETE, items)); @@ -273,6 +274,14 @@ items = new Set(['12']); assertFalse(commandManager.canExecute(Command.EDIT, items)); assertFalse(commandManager.canExecute(Command.DELETE, items)); + + commandManager.openCommandMenuAtPosition(0, 0); + var commandItem = {}; + commandManager.root.querySelectorAll('.dropdown-item').forEach(element => { + commandItem[element.getAttribute('command')] = element; + }); + MockInteractions.tap(commandItem[Command.EDIT]); + commandManager.assertLastCommand(null); }); });
diff --git a/chrome/test/data/webui/md_user_manager/control_bar_tests.js b/chrome/test/data/webui/md_user_manager/control_bar_tests.js index edb5527..46950c6 100644 --- a/chrome/test/data/webui/md_user_manager/control_bar_tests.js +++ b/chrome/test/data/webui/md_user_manager/control_bar_tests.js
@@ -82,6 +82,9 @@ teardown(function(done) { controlBarElement.remove(); + if (errorDialogElement.$.dialog.open) + errorDialogElement.$.dialog.close(); + // Allow asynchronous tasks to finish. setTimeout(done); }); @@ -95,7 +98,7 @@ Polymer.dom.flush(); // The dialog is visible. - assertTrue(errorDialogElement.$.dialog.opened); + assertTrue(errorDialogElement.$.dialog.open); }); }); @@ -108,7 +111,7 @@ Polymer.dom.flush(); // The error dialog is visible. - assertTrue(errorDialogElement.$.dialog.opened); + assertTrue(errorDialogElement.$.dialog.open); }); });
diff --git a/chrome/test/data/webui/md_user_manager/import_supervised_user_tests.js b/chrome/test/data/webui/md_user_manager/import_supervised_user_tests.js index dc6b3c3..8e21ecc 100644 --- a/chrome/test/data/webui/md_user_manager/import_supervised_user_tests.js +++ b/chrome/test/data/webui/md_user_manager/import_supervised_user_tests.js
@@ -32,13 +32,13 @@ test('Dialog does not show if no signed-in user is provided', function() { // The dialog is initially not visible. - assertFalse(importElement.$.dialog.opened); + assertFalse(importElement.$.dialog.open); importElement.show(undefined, []); Polymer.dom.flush(); // The dialog is still not visible. - assertFalse(importElement.$.dialog.opened); + assertFalse(importElement.$.dialog.open); }); test('Can import supervised user', function() { @@ -61,20 +61,20 @@ event.detail.supervisedUser.name == 'supervised user 2') { Polymer.dom.flush(); // The dialog is no longer visible. - assertFalse(importElement.$.dialog.opened); + assertFalse(importElement.$.dialog.open); resolve(); } }); // The dialog is initially not visible. - assertFalse(importElement.$.dialog.opened); + assertFalse(importElement.$.dialog.open); importElement.show(signedInUser, supervisedUsers); Polymer.dom.flush(); // The dialog becomes visible. - assertTrue(importElement.$.dialog.opened); + assertTrue(importElement.$.dialog.open); // The correct message is displayed. assertEquals(loadTimeData.getString('supervisedUserImportText'),
diff --git a/chrome/test/data/webui/print_preview/native_layer_stub.js b/chrome/test/data/webui/print_preview/native_layer_stub.js index 23e223e..495d224 100644 --- a/chrome/test/data/webui/print_preview/native_layer_stub.js +++ b/chrome/test/data/webui/print_preview/native_layer_stub.js
@@ -98,8 +98,14 @@ }, /** @override */ - print: function() { - this.methodCalled('print'); + print: function( + destination, printTicketStore, cloudPrintInterface, documentInfo) { + this.methodCalled('print', { + destination: destination, + printTicketStore: printTicketStore, + cloudPrintInterface: cloudPrintInterface, + documentInfo: documentInfo, + }); return Promise.resolve(); },
diff --git a/chrome/test/data/webui/print_preview/print_preview_tests.js b/chrome/test/data/webui/print_preview/print_preview_tests.js index b952e2f..e06412d9 100644 --- a/chrome/test/data/webui/print_preview/print_preview_tests.js +++ b/chrome/test/data/webui/print_preview/print_preview_tests.js
@@ -145,6 +145,31 @@ } /** + * Get the default media size for |device|. + * @param {!print_preview.PrinterCapabilitiesResponse} device + * @return {{width_microns: number, + * height_microns: number}} The width and height of the default + * media. + */ + function getDefaultMediaSize(device) { + var size = device.capabilities.printer.media_size.option.find( + function(opt) { return opt.is_default; }); + return { width_microns: size.width_microns, + height_microns: size.height_microns }; + } + + /** + * Get the default page orientation for |device|. + * @param {!print_preview.PrinterCapabilitiesResponse} device + * @return {string} The default orientation. + */ + function getDefaultOrientation(device) { + return device.capabilities.printer.page_orientation.option.find( + function(opt) { return opt.is_default; }).type; + } + + + /** * @param {string} printerId * @return {!Object} */ @@ -1288,8 +1313,8 @@ return d.id == 'BarDevice'; }); - nativeLayer.setLocalDestinationCapabilities( - getCddTemplate('BarDevice')); + var barDevice = getCddTemplate('BarDevice'); + nativeLayer.setLocalDestinationCapabilities(barDevice); printPreview.destinationStore_.selectDestination(barDestination); return nativeLayer.whenCalled('getPrinterCapabilities', 'BarDevice') @@ -1304,7 +1329,31 @@ expectFalse(printButton.disabled); printButton.click(); // This should result in a call to print. - return nativeLayer.whenCalled('print'); + return nativeLayer.whenCalled('print').then( + /** + * @param {{destination: !print_preview.Destination, + * printTicketStore: !print_preview.PrintTicketStore, + * cloudPrintInterface: print_preview + * .CloudPrintInterface, + * documentInfo: print_preview.DocumentInfo}} args + * The arguments that print() was called with. + */ + function(args) { + // Sanity check some printing argument values. + var printTicketStore = args.printTicketStore; + expectEquals(barDevice.printerId, args.destination.id); + expectEquals( + getDefaultOrientation(barDevice) == 'LANDSCAPE', + printTicketStore.landscape.getValue()); + expectEquals(1, printTicketStore.copies.getValueAsNumber()); + var mediaDefault = getDefaultMediaSize(barDevice); + expectEquals( + mediaDefault.width_microns, + printTicketStore.mediaSize.getValue().width_microns); + expectEquals( + mediaDefault.height_microns, + printTicketStore.mediaSize.getValue().height_microns); + }); }); }); });
diff --git a/chrome/test/data/webui/settings/android_apps_page_test.js b/chrome/test/data/webui/settings/android_apps_page_test.js index ccc51f0..53ef87f 100644 --- a/chrome/test/data/webui/settings/android_apps_page_test.js +++ b/chrome/test/data/webui/settings/android_apps_page_test.js
@@ -2,49 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** - * @constructor - * @implements {settings.AndroidAppsBrowserProxy} - * @extends {TestBrowserProxy} - */ -function TestAndroidAppsBrowserProxy() { - TestBrowserProxy.call(this, [ - 'requestAndroidAppsInfo', - 'showAndroidAppsSettings', - ]); -} - -TestAndroidAppsBrowserProxy.prototype = { - __proto__: TestBrowserProxy.prototype, - - /** @override */ - requestAndroidAppsInfo: function() { - this.methodCalled('requestAndroidAppsInfo'); - this.setAndroidAppsState(false, false); - }, - - /** override */ - showAndroidAppsSettings: function(keyboardAction) { - this.methodCalled('showAndroidAppsSettings'); - }, - - setAndroidAppsState: function(playStoreEnabled, settingsAppAvailable) { - // We need to make sure to pass a new object here, otherwise the property - // change event may not get fired in the listener. - var appsInfo = { - playStoreEnabled: playStoreEnabled, - settingsAppAvailable: settingsAppAvailable, - }; - cr.webUIListenerCallback('android-apps-info-update', appsInfo); - }, -}; - /** @type {?SettingsAndroidAppsPageElement} */ var androidAppsPage = null; /** @type {?TestAndroidAppsBrowserProxy} */ var androidAppsBrowserProxy = null; +var setAndroidAppsState = function(playStoreEnabled, settingsAppAvailable) { + var appsInfo = { + playStoreEnabled: playStoreEnabled, + settingsAppAvailable: settingsAppAvailable, + }; + androidAppsPage.androidAppsInfo = appsInfo; + Polymer.dom.flush(); +} + suite('AndroidAppsPageTests', function() { setup(function() { androidAppsBrowserProxy = new TestAndroidAppsBrowserProxy(); @@ -59,15 +31,15 @@ androidAppsPage.remove(); }); + teardown(function() { + androidAppsPage.remove(); + }); + suite('Main Page', function() { setup(function() { + androidAppsPage.havePlayStoreApp = true; androidAppsPage.prefs = {arc: {enabled: {value: false}}}; - Polymer.dom.flush(); - - return androidAppsBrowserProxy.whenCalled('requestAndroidAppsInfo') - .then(function() { - androidAppsBrowserProxy.setAndroidAppsState(false, false); - }); + setAndroidAppsState(false, false); }); test('Enable', function() { @@ -79,8 +51,7 @@ Polymer.dom.flush(); assertTrue(androidAppsPage.prefs.arc.enabled.value); - androidAppsBrowserProxy.setAndroidAppsState(true, false); - Polymer.dom.flush(); + setAndroidAppsState(true, false); assertTrue(!!androidAppsPage.$$('.subpage-arrow')); }); }); @@ -102,32 +73,42 @@ } setup(function() { + androidAppsPage.havePlayStoreApp = true; androidAppsPage.prefs = {arc: {enabled: {value: true}}}; - return androidAppsBrowserProxy.whenCalled('requestAndroidAppsInfo') - .then(function() { - settings.navigateTo(settings.Route.ANDROID_APPS); - androidAppsBrowserProxy.setAndroidAppsState(true, false); - MockInteractions.tap(androidAppsPage.$$('#android-apps')); - Polymer.dom.flush(); - subpage = androidAppsPage.$$('settings-android-apps-subpage'); - assertTrue(!!subpage); - }); + setAndroidAppsState(true, false); + settings.navigateTo(settings.Route.ANDROID_APPS); + MockInteractions.tap(androidAppsPage.$$('#android-apps')); + Polymer.dom.flush(); + subpage = androidAppsPage.$$('settings-android-apps-subpage'); + assertTrue(!!subpage); }); test('Sanity', function() { assertTrue(!!subpage.$$('#remove')); - assertTrue(!!subpage.$$('#manageApps')); + assertTrue(!subpage.$$('settings-android-settings-element')); }); test('ManageAppsUpdate', function() { - var manageApps = subpage.$$('#manageApps'); - assertTrue(manageApps.hidden); - androidAppsBrowserProxy.setAndroidAppsState(true, true); + assertTrue(!subpage.$$('settings-android-settings-element')); + setAndroidAppsState(true, true); + assertTrue(!!subpage.$$('settings-android-settings-element')); + assertTrue(!!subpage.$$('settings-android-settings-element'). + $$('#manageApps')); + setAndroidAppsState(true, false); + assertTrue(!subpage.$$('settings-android-settings-element')); + }); + + test('ManageAppsOpenReqest', function() { + setAndroidAppsState(true, true); + var button = subpage.$$('settings-android-settings-element'). + $$('#manageApps'); + assertTrue(!!button); + var promise = androidAppsBrowserProxy.whenCalled( + 'showAndroidAppsSettings'); + // MockInteractions.tap does not work here due style is not updated. + button.click(); Polymer.dom.flush(); - assertFalse(manageApps.hidden); - androidAppsBrowserProxy.setAndroidAppsState(true, false); - Polymer.dom.flush(); - assertTrue(manageApps.hidden); + return promise; }); test('Disable', function() { @@ -147,8 +128,7 @@ test('HideOnDisable', function() { assertEquals(settings.getCurrentRoute(), settings.Route.ANDROID_APPS_DETAILS); - androidAppsBrowserProxy.setAndroidAppsState(false, false); - Polymer.dom.flush(); + setAndroidAppsState(false, false); return whenPopState().then(function() { assertEquals(settings.getCurrentRoute(), settings.Route.ANDROID_APPS); @@ -160,6 +140,7 @@ var subpage; setup(function() { + androidAppsPage.havePlayStoreApp = true; androidAppsPage.prefs = { arc: { enabled: { @@ -168,20 +149,46 @@ } } }; - return androidAppsBrowserProxy.whenCalled('requestAndroidAppsInfo') - .then(function() { - androidAppsBrowserProxy.setAndroidAppsState(true, true); - MockInteractions.tap(androidAppsPage.$$('#android-apps')); - Polymer.dom.flush(); - subpage = androidAppsPage.$$('settings-android-apps-subpage'); - assertTrue(!!subpage); - }); + setAndroidAppsState(true, true); + MockInteractions.tap(androidAppsPage.$$('#android-apps')); + Polymer.dom.flush(); + subpage = androidAppsPage.$$('settings-android-apps-subpage'); + assertTrue(!!subpage); }); test('Sanity', function() { Polymer.dom.flush(); - assertTrue(!!subpage.$$('#manageApps')); assertFalse(!!subpage.$$('#remove')); + assertTrue(!!subpage.$$('settings-android-settings-element')); + assertTrue(!!subpage.$$('settings-android-settings-element'). + $$('#manageApps')); }); }); + + suite('NoPlayStore', function() { + setup(function() { + androidAppsPage.havePlayStoreApp = false; + androidAppsPage.prefs = {arc: {enabled: {value: true}}}; + setAndroidAppsState(true, true); + }); + + test('Sanity', function() { + assertTrue(!!androidAppsPage.$$('settings-android-settings-element')); + assertTrue(!!androidAppsPage.$$('settings-android-settings-element'). + $$("#manageApps")); + }); + + test('ManageAppsOpenReqest', function() { + var button = androidAppsPage.$$('settings-android-settings-element'). + $$('#manageApps'); + assertTrue(!!button); + var promise = androidAppsBrowserProxy.whenCalled( + 'showAndroidAppsSettings'); + // MockInteractions.tap does not work here due style is not updated. + button.click(); + Polymer.dom.flush(); + return promise; + }); + }); + });
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 0a3201e..3e7c3660 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1661,6 +1661,7 @@ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ ROOT_PATH + 'ui/webui/resources/js/promise_resolver.js', '../test_browser_proxy.js', + 'test_android_apps_browser_proxy.js', 'android_apps_page_test.js', ]), };
diff --git a/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js b/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js index 1f22859..48ba81b 100644 --- a/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js +++ b/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js
@@ -204,12 +204,10 @@ test('verifyCreditCardCount', function() { var section = self.createAutofillSection_([], []); - assertTrue(!!section); var creditCardList = section.$.creditCardList; assertTrue(!!creditCardList); - // +1 for the template element. - assertEquals(1, creditCardList.children.length); + assertEquals(0, creditCardList.querySelectorAll('.list-item').length); assertFalse(section.$.noCreditCardsLabel.hidden); assertTrue(section.$.creditCardsHeading.hidden); @@ -227,11 +225,10 @@ var section = self.createAutofillSection_([], creditCards); - assertTrue(!!section); var creditCardList = section.$.creditCardList; assertTrue(!!creditCardList); - // +1 for the template element. - assertEquals(creditCards.length + 1, creditCardList.children.length); + assertEquals(creditCards.length, + creditCardList.querySelectorAll('.list-item').length); assertTrue(section.$.noCreditCardsLabel.hidden); assertFalse(section.$.creditCardsHeading.hidden); @@ -433,6 +430,86 @@ MockInteractions.tap(creditCardDialog.$.cancelButton); }); }); + + test('verifyLocalCreditCardMenu', function() { + var creditCard = FakeDataMaker.creditCardEntry(); + + // When credit card is local, |isCached| will be undefined. + creditCard.metadata.isLocal = true; + creditCard.metadata.isCached = undefined; + + var section = self.createAutofillSection_([], [creditCard]); + var creditCardList = section.$.creditCardList; + assertTrue(!!creditCardList); + assertEquals(1, creditCardList.querySelectorAll('.list-item').length); + var row = creditCardList.children[0]; + + // Local credit cards will show the overflow menu. + assertFalse(!!row.querySelector('#remoteCreditCardLink')); + var menuButton = row.querySelector('#creditCardMenu'); + assertTrue(!!menuButton); + + menuButton.click(); + Polymer.dom.flush(); + + var menu = section.$.creditCardSharedMenu; + + // Menu should have 2 options. + assertFalse(menu.querySelector('#menuEditCreditCard').hidden); + assertFalse(menu.querySelector('#menuRemoveCreditCard').hidden); + assertTrue(menu.querySelector('#menuClearCreditCard').hidden); + + menu.close(); + Polymer.dom.flush(); + }); + + test('verifyCachedCreditCardMenu', function() { + var creditCard = FakeDataMaker.creditCardEntry(); + + creditCard.metadata.isLocal = false; + creditCard.metadata.isCached = true; + + var section = self.createAutofillSection_([], [creditCard]); + var creditCardList = section.$.creditCardList; + assertTrue(!!creditCardList); + assertEquals(1, creditCardList.querySelectorAll('.list-item').length); + var row = creditCardList.children[0]; + + // Cached remote CCs will show overflow menu. + assertFalse(!!row.querySelector('#remoteCreditCardLink')); + var menuButton = row.querySelector('#creditCardMenu'); + assertTrue(!!menuButton); + + menuButton.click(); + Polymer.dom.flush(); + + var menu = section.$.creditCardSharedMenu; + + // Menu should have 2 options. + assertFalse(menu.querySelector('#menuEditCreditCard').hidden); + assertTrue(menu.querySelector('#menuRemoveCreditCard').hidden); + assertFalse(menu.querySelector('#menuClearCreditCard').hidden); + + menu.close(); + Polymer.dom.flush(); + }); + + test('verifyNotCachedCreditCardMenu', function() { + var creditCard = FakeDataMaker.creditCardEntry(); + + creditCard.metadata.isLocal = false; + creditCard.metadata.isCached = false; + + var section = self.createAutofillSection_([], [creditCard]); + var creditCardList = section.$.creditCardList; + assertTrue(!!creditCardList); + assertEquals(1, creditCardList.querySelectorAll('.list-item').length); + var row = creditCardList.children[0]; + + // No overflow menu when not cached. + assertTrue(!!row.querySelector('#remoteCreditCardLink')); + assertFalse(!!row.querySelector('#creditCardMenu')); + }); }); mocha.run(); @@ -454,7 +531,6 @@ test('verifyNoAddresses', function() { var section = self.createAutofillSection_([], []); - assertTrue(!!section); var addressList = section.$.addressList; assertTrue(!!addressList); @@ -475,11 +551,10 @@ var section = self.createAutofillSection_(addresses, []); - assertTrue(!!section); var addressList = section.$.addressList; assertTrue(!!addressList); - // +1 for the template element. - assertEquals(addresses.length + 1, addressList.children.length); + assertEquals(addresses.length, + addressList.querySelectorAll('.list-item').length); assertTrue(section.$.noAddressesLabel.hidden); }); @@ -512,7 +587,7 @@ var addressList = section.$.addressList; var row = addressList.children[0]; assertTrue(!!row); - var menuButton = row.querySelector('#addressMenu') + var menuButton = row.querySelector('#addressMenu'); assertTrue(!!menuButton); var outlinkButton = row.querySelector('button.icon-external'); assertFalse(!!outlinkButton); @@ -525,7 +600,7 @@ var addressList = section.$.addressList; var row = addressList.children[0]; assertTrue(!!row); - var menuButton = row.querySelector('#addressMenu') + var menuButton = row.querySelector('#addressMenu'); assertFalse(!!menuButton); var outlinkButton = row.querySelector('button.icon-external'); assertTrue(!!outlinkButton);
diff --git a/chrome/test/data/webui/settings/site_list_tests.js b/chrome/test/data/webui/settings/site_list_tests.js index 3f12cbe..a7c5336 100644 --- a/chrome/test/data/webui/settings/site_list_tests.js +++ b/chrome/test/data/webui/settings/site_list_tests.js
@@ -63,7 +63,7 @@ exceptions: { plugins: [ { - embeddingOrigin: 'http://foo-block.com', + embeddingOrigin: '', origin: 'http://foo-block.com', setting: 'block', source: 'policy',
diff --git a/chrome/test/data/webui/settings/test_android_apps_browser_proxy.js b/chrome/test/data/webui/settings/test_android_apps_browser_proxy.js new file mode 100644 index 0000000..4bbcf0d --- /dev/null +++ b/chrome/test/data/webui/settings/test_android_apps_browser_proxy.js
@@ -0,0 +1,40 @@ +// 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. + +/** + * @constructor + * @implements {settings.AndroidAppsBrowserProxy} + * @extends {TestBrowserProxy} + */ +function TestAndroidAppsBrowserProxy() { + TestBrowserProxy.call(this, [ + 'requestAndroidAppsInfo', + 'showAndroidAppsSettings', + ]); +} + +TestAndroidAppsBrowserProxy.prototype = { + __proto__: TestBrowserProxy.prototype, + + /** @override */ + requestAndroidAppsInfo: function() { + this.methodCalled('requestAndroidAppsInfo'); + this.setAndroidAppsState(false, false); + }, + + /** override */ + showAndroidAppsSettings: function(keyboardAction) { + this.methodCalled('showAndroidAppsSettings'); + }, + + setAndroidAppsState: function(playStoreEnabled, settingsAppAvailable) { + // We need to make sure to pass a new object here, otherwise the property + // change event may not get fired in the listener. + var appsInfo = { + playStoreEnabled: playStoreEnabled, + settingsAppAvailable: settingsAppAvailable, + }; + cr.webUIListenerCallback('android-apps-info-update', appsInfo); + }, +};
diff --git a/chrome/typemaps.gni b/chrome/typemaps.gni index 539ad98..90e24de9 100644 --- a/chrome/typemaps.gni +++ b/chrome/typemaps.gni
@@ -4,6 +4,6 @@ typemaps = [ "//chrome/common/instant.typemap", - "//chrome/common/safe_archive_analyzer.typemap", + "//chrome/common/safe_browsing/safe_archive_analyzer.typemap", "//chrome/common/shell_handler_win.typemap", ]
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 4c711c6b..83cbd2da 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -62,8 +62,8 @@ #endif #if defined(FULL_SAFE_BROWSING) -#include "chrome/common/safe_archive_analyzer.mojom.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" +#include "chrome/common/safe_browsing/safe_archive_analyzer.mojom.h" #include "chrome/common/safe_browsing/zip_analyzer.h" #if defined(OS_MACOSX) #include "chrome/utility/safe_browsing/mac/dmg_analyzer.h"
diff --git a/chrome/utility/image_writer/image_writer_handler.cc b/chrome/utility/image_writer/image_writer_handler.cc index 437f50c..bec9ea1 100644 --- a/chrome/utility/image_writer/image_writer_handler.cc +++ b/chrome/utility/image_writer/image_writer_handler.cc
@@ -35,7 +35,7 @@ extensions::mojom::RemovableStorageWriterClientPtr client) { client_ = std::move(client); client_.set_connection_error_handler( - base::Bind(&ImageWriterHandler::Cancel, base::Unretained(this))); + base::BindOnce(&ImageWriterHandler::Cancel, base::Unretained(this))); base::FilePath target_device = device; const bool test_mode = IsTestDevice(device); @@ -70,7 +70,7 @@ extensions::mojom::RemovableStorageWriterClientPtr client) { client_ = std::move(client); client_.set_connection_error_handler( - base::Bind(&ImageWriterHandler::Cancel, base::Unretained(this))); + base::BindOnce(&ImageWriterHandler::Cancel, base::Unretained(this))); base::FilePath target_device = device; const bool test_mode = IsTestDevice(device);
diff --git a/chrome/utility/media_galleries/ipc_data_source.cc b/chrome/utility/media_galleries/ipc_data_source.cc index 6d1778d..908d511 100644 --- a/chrome/utility/media_galleries/ipc_data_source.cc +++ b/chrome/utility/media_galleries/ipc_data_source.cc
@@ -37,8 +37,9 @@ DCHECK(data_source_thread_checker_.CalledOnValidThread()); utility_task_runner_->PostTask( - FROM_HERE, base::Bind(&IPCDataSource::ReadBlob, base::Unretained(this), - destination, callback, position, size)); + FROM_HERE, + base::BindOnce(&IPCDataSource::ReadBlob, base::Unretained(this), + destination, callback, position, size)); } bool IPCDataSource::GetSize(int64_t* size_out) { @@ -72,8 +73,8 @@ media_data_source_->ReadBlob( position, clamped_size, - base::Bind(&IPCDataSource::ReadDone, base::Unretained(this), destination, - callback)); + base::BindOnce(&IPCDataSource::ReadDone, base::Unretained(this), + destination, callback)); } void IPCDataSource::ReadDone(uint8_t* destination,
diff --git a/chrome/utility/media_galleries/media_metadata_parser.cc b/chrome/utility/media_galleries/media_metadata_parser.cc index 236ad2a..455e68b 100644 --- a/chrome/utility/media_galleries/media_metadata_parser.cc +++ b/chrome/utility/media_galleries/media_metadata_parser.cc
@@ -146,10 +146,11 @@ CHECK(media_thread_->Start()); media_thread_->task_runner()->PostTaskAndReply( - FROM_HERE, base::Bind(&ParseAudioVideoMetadata, source_.get(), - get_attached_images_, metadata, images), - base::Bind(&FinishParseAudioVideoMetadata, callback, - base::Owned(metadata), base::Owned(images))); + FROM_HERE, + base::BindOnce(&ParseAudioVideoMetadata, source_.get(), + get_attached_images_, metadata, images), + base::BindOnce(&FinishParseAudioVideoMetadata, callback, + base::Owned(metadata), base::Owned(images))); } } // namespace metadata
diff --git a/chrome/utility/profile_import_handler.cc b/chrome/utility/profile_import_handler.cc index f76f2ba0..2aa3674a7 100644 --- a/chrome/utility/profile_import_handler.cc +++ b/chrome/utility/profile_import_handler.cc
@@ -59,8 +59,9 @@ *localized_strings, ThreadSafeProfileImportObserverPtr::Create(std::move(observer))); import_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&Importer::StartImport, importer_, - source_profile, items, base::RetainedRef(bridge_))); + FROM_HERE, + base::BindOnce(&Importer::StartImport, importer_, source_profile, items, + base::RetainedRef(bridge_))); } void ProfileImportHandler::CancelImport() {
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index 08cbad2c..93f65e7 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -481,6 +481,15 @@ } if (is_android) { + generate_jni_registration("cast_shell_jni_registration") { + target = ":cast_shell_apk" + output = "$root_gen_dir/chromecast/android/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] + } android_assets("cast_shell_apk_assets") { assert(v8_use_external_startup_data)
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn index 1d29974..321a3d2 100644 --- a/chromecast/android/BUILD.gn +++ b/chromecast/android/BUILD.gn
@@ -27,6 +27,7 @@ deps = [ ":platform_jni_loader", "//base", + "//chromecast:cast_shell_jni_registration", "//chromecast:cast_shell_lib", "//chromecast:chromecast_features", "//chromecast/app",
diff --git a/chromecast/app/android/cast_jni_loader.cc b/chromecast/app/android/cast_jni_loader.cc index 79a32fe..73b829bb 100644 --- a/chromecast/app/android/cast_jni_loader.cc +++ b/chromecast/app/android/cast_jni_loader.cc
@@ -6,6 +6,7 @@ #include "base/android/library_loader/library_loader_hooks.h" #include "base/bind.h" #include "chromecast/android/cast_jni_registrar.h" +#include "chromecast/android/cast_shell_jni_registration.h" #include "chromecast/android/platform_jni_loader.h" #include "chromecast/app/cast_main_delegate.h" #include "chromecast/browser/android/jni_registrar.h" @@ -42,6 +43,12 @@ JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); + if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) { + return -1; + } + + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) || !NativeInit()) { return -1;
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc index 9b446e0..b6af3b5 100644 --- a/chromeos/components/tether/initializer.cc +++ b/chromeos/components/tether/initializer.cc
@@ -64,17 +64,16 @@ NetworkConnectionHandler* network_connection_handler) { if (!device::BluetoothAdapterFactory::IsBluetoothSupported()) { PA_LOG(WARNING) << "Bluetooth is not supported on this device; cannot " - << "initialize tether feature."; + << "initialize Tether feature."; return; } if (instance_) { - PA_LOG(WARNING) << "Tether initialization was triggered when the feature " - << "had already been initialized; exiting initialization " - << "early."; + // The Tether feature has already been initialized. No need to do anything. return; } + PA_LOG(INFO) << "Initializing Tether feature."; instance_ = new Initializer(cryptauth_service, std::move(notification_presenter), pref_service, token_service, network_state_handler,
diff --git a/chromeos/components/tether/initializer.h b/chromeos/components/tether/initializer.h index db1449f..a1b6944 100644 --- a/chromeos/components/tether/initializer.h +++ b/chromeos/components/tether/initializer.h
@@ -56,7 +56,8 @@ // Initializes the Tether Chrome OS component. class Initializer : public OAuth2TokenService::Observer { public: - // Initializes the tether feature. + // Initializes the tether feature. If the feature has already been + // initialized, this function is a no-op. static void Init( cryptauth::CryptAuthService* cryptauth_service, std::unique_ptr<NotificationPresenter> notification_presenter,
diff --git a/chromeos/dbus/blocking_method_caller_unittest.cc b/chromeos/dbus/blocking_method_caller_unittest.cc index d62f787..3ffa197 100644 --- a/chromeos/dbus/blocking_method_caller_unittest.cc +++ b/chromeos/dbus/blocking_method_caller_unittest.cc
@@ -61,7 +61,7 @@ // Set an expectation so mock_proxy's CallMethodAndBlock() will use // CreateMockProxyResponse() to return responses. EXPECT_CALL(*mock_proxy_.get(), - MockCallMethodAndBlockWithErrorDetails(_, _, _)) + CallMethodAndBlockWithErrorDetails(_, _, _)) .WillRepeatedly( Invoke(this, &BlockingMethodCallerTest::CreateMockProxyResponse)); @@ -91,9 +91,10 @@ private: // Returns a response for the given method call. Used to implement // CallMethodAndBlock() for |mock_proxy_|. - dbus::Response* CreateMockProxyResponse(dbus::MethodCall* method_call, - int timeout_ms, - dbus::ScopedDBusError* error) { + std::unique_ptr<dbus::Response> CreateMockProxyResponse( + dbus::MethodCall* method_call, + int timeout_ms, + dbus::ScopedDBusError* error) { if (method_call->GetInterface() == "org.chromium.TestInterface" && method_call->GetMember() == "Echo") { dbus::MessageReader reader(method_call); @@ -103,12 +104,12 @@ dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); writer.AppendString(text_message); - return response.release(); + return response; } } LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); - return NULL; + return nullptr; } };
diff --git a/chromeos/dbus/services/service_provider_test_helper.cc b/chromeos/dbus/services/service_provider_test_helper.cc index 6a3488d..27981ed 100644 --- a/chromeos/dbus/services/service_provider_test_helper.cc +++ b/chromeos/dbus/services/service_provider_test_helper.cc
@@ -21,8 +21,7 @@ namespace chromeos { -ServiceProviderTestHelper::ServiceProviderTestHelper() - : response_received_(false) { +ServiceProviderTestHelper::ServiceProviderTestHelper() { if (!base::MessageLoop::current()) message_loop_.reset(new base::MessageLoop()); } @@ -58,17 +57,17 @@ // |mock_exported_object_|. mock_object_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(), service_name, service_path); - // |mock_object_proxy_|'s MockCallMethodAndBlock() will use - // MockCallMethodAndBlock() to return responses. + // |mock_object_proxy_|'s CallMethodAndBlock() will use CallMethodAndBlock() + // to return responses. EXPECT_CALL(*mock_object_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(ResultOf(std::mem_fun(&dbus::MethodCall::GetInterface), interface_name), ResultOf(std::mem_fun(&dbus::MethodCall::GetMember), exported_method_name)), _)) .WillOnce( - Invoke(this, &ServiceProviderTestHelper::MockCallMethodAndBlock)); + Invoke(this, &ServiceProviderTestHelper::CallMethodAndBlock)); service_provider->Start(mock_exported_object_.get()); } @@ -118,7 +117,7 @@ method_callback_ = method_callback; } -dbus::Response* ServiceProviderTestHelper::MockCallMethodAndBlock( +std::unique_ptr<dbus::Response> ServiceProviderTestHelper::CallMethodAndBlock( dbus::MethodCall* method_call, Unused) { // Set the serial number to non-zero, so @@ -127,14 +126,15 @@ // Run the callback captured in MockExportMethod(). In addition to returning // a response that the caller will ignore, this will send a signal, which // will be received by |on_signal_callback_|. + std::unique_ptr<dbus::Response> response; method_callback_.Run(method_call, base::Bind(&ServiceProviderTestHelper::OnResponse, - base::Unretained(this))); + base::Unretained(this), &response)); // Check for a response. - if (!response_received_) + if (!response) base::RunLoop().Run(); // Return response. - return response_.release(); + return response; } void ServiceProviderTestHelper::MockConnectToSignal( @@ -155,9 +155,9 @@ } void ServiceProviderTestHelper::OnResponse( + std::unique_ptr<dbus::Response>* out_response, std::unique_ptr<dbus::Response> response) { - response_ = std::move(response); - response_received_ = true; + *out_response = std::move(response); if (base::RunLoop::IsRunningOnCurrentThread()) base::MessageLoop::current()->QuitWhenIdle(); }
diff --git a/chromeos/dbus/services/service_provider_test_helper.h b/chromeos/dbus/services/service_provider_test_helper.h index e6429cdc..caccb66 100644 --- a/chromeos/dbus/services/service_provider_test_helper.h +++ b/chromeos/dbus/services/service_provider_test_helper.h
@@ -70,7 +70,7 @@ dbus::ExportedObject::OnExportedCallback on_exported_callback); // Calls exported method and waits for a response for |mock_object_proxy_|. - dbus::Response* MockCallMethodAndBlock( + std::unique_ptr<dbus::Response> CallMethodAndBlock( dbus::MethodCall* method_call, ::testing::Unused); @@ -85,7 +85,8 @@ void MockSendSignal(dbus::Signal* signal); // Receives a response and makes it available to MockCallMethodAndBlock(). - void OnResponse(std::unique_ptr<dbus::Response> response); + void OnResponse(std::unique_ptr<dbus::Response>* out_response, + std::unique_ptr<dbus::Response> response); scoped_refptr<dbus::MockBus> mock_bus_; scoped_refptr<dbus::MockExportedObject> mock_exported_object_; @@ -93,8 +94,6 @@ dbus::ExportedObject::MethodCallCallback method_callback_; dbus::ObjectProxy::SignalCallback on_signal_callback_; std::unique_ptr<base::MessageLoop> message_loop_; - bool response_received_; - std::unique_ptr<dbus::Response> response_; }; } // namespace chromeos
diff --git a/chromeos/printing/printer_configuration.h b/chromeos/printing/printer_configuration.h index 2ed1130..44e7a52 100644 --- a/chromeos/printing/printer_configuration.h +++ b/chromeos/printing/printer_configuration.h
@@ -87,14 +87,23 @@ description_ = description; } + // Returns the |manufacturer| of the printer. + // DEPRECATED(skau@chromium.org): Use make_and_model() instead. const std::string& manufacturer() const { return manufacturer_; } void set_manufacturer(const std::string& manufacturer) { manufacturer_ = manufacturer; } + // Returns the |model| of the printer. + // DEPRECATED(skau@chromium.org): Use make_and_model() instead. const std::string& model() const { return model_; } void set_model(const std::string& model) { model_ = model; } + const std::string& make_and_model() const { return make_and_model_; } + void set_make_and_model(const std::string& make_and_model) { + make_and_model_ = make_and_model; + } + const std::string& uri() const { return uri_; } void set_uri(const std::string& uri) { uri_ = uri; } @@ -130,11 +139,19 @@ std::string description_; // The manufacturer of the printer, e.g. HP + // DEPRECATED(skau@chromium.org): Migrating to make_and_model. This is kept + // for backward compatibility until migration is complete. std::string manufacturer_; // The model of the printer, e.g. OfficeJet 415 + // DEPRECATED(skau@chromium.org): Migrating to make_and_model. This is kept + // for backward compatibility until migration is complete. std::string model_; + // The manufactuer and model of the printer in one string. e.g. HP OfficeJet + // 415. + std::string make_and_model_; + // The full path for the printer. Suitable for configuration in CUPS. // Contains protocol, hostname, port, and queue. std::string uri_;
diff --git a/chromeos/printing/printer_translator.cc b/chromeos/printing/printer_translator.cc index c723664..7f7499a 100644 --- a/chromeos/printing/printer_translator.cc +++ b/chromeos/printing/printer_translator.cc
@@ -65,6 +65,12 @@ if (value.GetString(kModel, &model)) printer->set_model(model); + std::string make_and_model = manufacturer; + if (!manufacturer.empty() && !model.empty()) + make_and_model.append(" "); + make_and_model.append(model); + printer->set_make_and_model(make_and_model); + std::string uuid; if (value.GetString(kUUID, &uuid)) printer->set_uuid(uuid);
diff --git a/chromeos/printing/printer_translator_unittest.cc b/chromeos/printing/printer_translator_unittest.cc index 16995ef..0723be1 100644 --- a/chromeos/printing/printer_translator_unittest.cc +++ b/chromeos/printing/printer_translator_unittest.cc
@@ -19,11 +19,13 @@ const char kHash[] = "ABCDEF123456"; const char kName[] = "Chrome Super Printer"; const char kDescription[] = "first star on the left"; -const char kMake[] = "Chrome"; -const char kModel[] = "Inktastic Laser Magic"; const char kUri[] = "ipp://printy.domain.co:555/ipp/print"; const char kUUID[] = "UUID-UUID-UUID"; +const char kMake[] = "Chrome"; +const char kModel[] = "Inktastic Laser Magic"; +const char kMakeAndModel[] = "Chrome Inktastic Laser Magic"; + const base::Time kTimestamp = base::Time::FromInternalValue(445566); // PpdReference test data @@ -118,6 +120,7 @@ EXPECT_EQ(kDescription, printer->description()); EXPECT_EQ(kMake, printer->manufacturer()); EXPECT_EQ(kModel, printer->model()); + EXPECT_EQ(kMakeAndModel, printer->make_and_model()); EXPECT_EQ(kUri, printer->uri()); EXPECT_EQ(kUUID, printer->uuid()); EXPECT_EQ(kTimestamp, printer->last_updated()); @@ -126,5 +129,37 @@ printer->ppd_reference().effective_make_and_model); } +TEST(PrinterTranslatorTest, RecommendedPrinterToPrinterBlankManufacturer) { + base::DictionaryValue preference; + preference.SetString("id", kHash); + preference.SetString("display_name", kName); + preference.SetString("model", kModel); + preference.SetString("uri", kUri); + preference.SetString("ppd_resource.effective_model", kEffectiveMakeAndModel); + + std::unique_ptr<Printer> printer = + RecommendedPrinterToPrinter(preference, kTimestamp); + EXPECT_TRUE(printer); + + EXPECT_EQ(kModel, printer->model()); + EXPECT_EQ(kModel, printer->make_and_model()); +} + +TEST(PrinterTranslatorTest, RecommendedPrinterToPrinterBlankModel) { + base::DictionaryValue preference; + preference.SetString("id", kHash); + preference.SetString("display_name", kName); + preference.SetString("manufacturer", kMake); + preference.SetString("uri", kUri); + preference.SetString("ppd_resource.effective_model", kEffectiveMakeAndModel); + + std::unique_ptr<Printer> printer = + RecommendedPrinterToPrinter(preference, kTimestamp); + EXPECT_TRUE(printer); + + EXPECT_EQ(kMake, printer->manufacturer()); + EXPECT_EQ(kMake, printer->make_and_model()); +} + } // namespace printing } // namespace chromeos
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 09cfefc22..a63c720 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1016,8 +1016,10 @@ // Will log quality metrics for each FormStructure based on the presence of // autocomplete attributes, if available. - for (FormStructure* cur_form : queried_forms) - cur_form->LogQualityMetricsBasedOnAutocomplete(); + for (FormStructure* cur_form : queried_forms) { + cur_form->LogQualityMetricsBasedOnAutocomplete( + form_interactions_ukm_logger_.get()); + } // Forward form structures to the password generation manager to detect // account creation forms.
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc index 9bce1ca..c076cdf 100644 --- a/components/autofill/core/browser/autofill_metrics.cc +++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -19,6 +19,7 @@ #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/form_data.h" #include "components/ukm/public/ukm_entry_builder.h" @@ -49,6 +50,18 @@ const char kUKMFormSubmittedEntryName[] = "Autofill.AutofillFormSubmitted"; const char kUKMAutofillFormSubmittedStateMetricName[] = "AutofillFormSubmittedState"; +// |UkmEntry| for capturing field type prediction quality. +const char kUKMFieldTypeEntryName[] = "Autofill.FieldTypeValidation"; +const char kUKMFieldFillStatusEntryName[] = "Autofill.FieldFillStatus"; +const char kUKMFormSignatureMetricName[] = "FormSignature"; +const char kUKMFieldSignatureMetricName[] = "FieldSignature"; +const char kUKMValidationEventMetricName[] = "ValidationEvent"; +const char kUKMPredictionSourceMetricName[] = "PredictionSource"; +const char kUKMPredictedTypeMetricName[] = "PredictedType"; +const char kUKMActualTypeMetricName[] = "ActualType"; +const char kUKMWasSuggestionShownMetricName[] = "WasSuggestionShown"; +const char kUKMWasPreviouslyAutofilledMetricName[] = "WasPreviouslyAutofilled"; + } // namespace internal namespace autofill { @@ -277,6 +290,23 @@ histogram->AddTime(duration); } +const char* GetQualityMetricPredictionSource( + AutofillMetrics::QualityMetricPredictionSource source) { + switch (source) { + default: + case AutofillMetrics::PREDICTION_SOURCE_UNKNOWN: + NOTREACHED(); + return "Unknown"; + + case AutofillMetrics::PREDICTION_SOURCE_HEURISTIC: + return "Heuristic"; + case AutofillMetrics::PREDICTION_SOURCE_SERVER: + return "Server"; + case AutofillMetrics::PREDICTION_SOURCE_OVERALL: + return "Overall"; + } +} + const char* GetQualityMetricTypeSuffix( AutofillMetrics::QualityMetricType metric_type) { switch (metric_type) { @@ -339,17 +369,19 @@ } // Logs field type prediction quality metrics. The primary histogram name is -// constructed based on |source| The field-specific histogram name also factors -// possible and predicted field types (|possible_types| and |predicted_type|, -// respectively). May log a suffixed version of the metric depending on -// |metric_type|. +// constructed based on |prediction_source| The field-specific histogram names +// also incorporates the possible and predicted types for |field|. A suffix may +// be appended to the metric name, depending on |metric_type|. void LogPredictionQualityMetrics( - const base::StringPiece& source, - const ServerFieldTypeSet& possible_types, + AutofillMetrics::QualityMetricPredictionSource prediction_source, ServerFieldType predicted_type, + AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, AutofillMetrics::QualityMetricType metric_type) { // Generate histogram names. - const char* const suffix = GetQualityMetricTypeSuffix(metric_type); + const char* source = GetQualityMetricPredictionSource(prediction_source); + const char* suffix = GetQualityMetricTypeSuffix(metric_type); std::string raw_data_histogram = base::JoinString({"Autofill.FieldPrediction.", source, suffix}, ""); std::string aggregate_histogram = base::JoinString( @@ -357,6 +389,13 @@ std::string type_specific_histogram = base::JoinString( {"Autofill.FieldPredictionQuality.ByFieldType.", source, suffix}, ""); + const ServerFieldTypeSet& possible_types = + metric_type == AutofillMetrics::TYPE_AUTOCOMPLETE_BASED + ? ServerFieldTypeSet{AutofillType(field.html_type(), + field.html_mode()) + .GetStorableType()} + : field.possible_types(); + // Get the best type classification we can for the field. ServerFieldType actual_type = GetActualFieldType(possible_types, predicted_type); @@ -369,6 +408,10 @@ UMA_HISTOGRAM_SPARSE_SLOWLY(raw_data_histogram, (predicted_type << 16) | actual_type); + form_interactions_ukm_logger->LogFieldType( + form.form_signature(), field.GetFieldSignature(), prediction_source, + metric_type, predicted_type, actual_type); + // NO_SERVER_DATA is the equivalent of predicting UNKNOWN. if (predicted_type == NO_SERVER_DATA) predicted_type = UNKNOWN_TYPE; @@ -664,27 +707,35 @@ } void AutofillMetrics::LogHeuristicPredictionQualityMetrics( - const ServerFieldTypeSet& possible_types, - ServerFieldType predicted_type, - AutofillMetrics::QualityMetricType metric_type) { - LogPredictionQualityMetrics("Heuristic", possible_types, predicted_type, - metric_type); + FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, + QualityMetricType metric_type) { + LogPredictionQualityMetrics( + PREDICTION_SOURCE_HEURISTIC, + AutofillType(field.heuristic_type()).GetStorableType(), + form_interactions_ukm_logger, form, field, metric_type); } void AutofillMetrics::LogServerPredictionQualityMetrics( - const ServerFieldTypeSet& possible_types, - ServerFieldType predicted_type, - AutofillMetrics::QualityMetricType metric_type) { - LogPredictionQualityMetrics("Server", possible_types, predicted_type, - metric_type); + FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, + QualityMetricType metric_type) { + LogPredictionQualityMetrics( + PREDICTION_SOURCE_SERVER, + AutofillType(field.server_type()).GetStorableType(), + form_interactions_ukm_logger, form, field, metric_type); } void AutofillMetrics::LogOverallPredictionQualityMetrics( - const ServerFieldTypeSet& possible_types, - ServerFieldType predicted_type, - AutofillMetrics::QualityMetricType metric_type) { - LogPredictionQualityMetrics("Overall", possible_types, predicted_type, - metric_type); + FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, + QualityMetricType metric_type) { + LogPredictionQualityMetrics( + PREDICTION_SOURCE_OVERALL, field.Type().GetStorableType(), + form_interactions_ukm_logger, form, field, metric_type); } // static @@ -1324,6 +1375,65 @@ MillisecondsSinceFormParsed()); } +void AutofillMetrics::FormInteractionsUkmLogger::LogFieldFillStatus( + const FormStructure& form, + const AutofillField& field, + QualityMetricType metric_type) { + if (!CanLog()) + return; + + if (source_id_ == -1) + GetNewSourceID(); + + std::unique_ptr<ukm::UkmEntryBuilder> builder = + ukm_recorder_->GetEntryBuilder(source_id_, + internal::kUKMFieldFillStatusEntryName); + builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName, + MillisecondsSinceFormParsed()); + builder->AddMetric(internal::kUKMFormSignatureMetricName, + static_cast<int64_t>(form.form_signature())); + builder->AddMetric(internal::kUKMFieldSignatureMetricName, + static_cast<int64_t>(field.GetFieldSignature())); + builder->AddMetric(internal::kUKMValidationEventMetricName, + static_cast<int64_t>(metric_type)); + builder->AddMetric(internal::kUKMIsAutofilledMetricName, + static_cast<int64_t>(field.is_autofilled)); + builder->AddMetric(internal::kUKMWasPreviouslyAutofilledMetricName, + static_cast<int64_t>(field.previously_autofilled())); +} + +void AutofillMetrics::FormInteractionsUkmLogger::LogFieldType( + FormSignature form_signature, + FieldSignature field_signature, + QualityMetricPredictionSource prediction_source, + QualityMetricType metric_type, + ServerFieldType predicted_type, + ServerFieldType actual_type) { + if (!CanLog()) + return; + + if (source_id_ == -1) + GetNewSourceID(); + + std::unique_ptr<ukm::UkmEntryBuilder> builder = + ukm_recorder_->GetEntryBuilder(source_id_, + internal::kUKMFieldTypeEntryName); + builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName, + MillisecondsSinceFormParsed()); + builder->AddMetric(internal::kUKMFormSignatureMetricName, + static_cast<int64_t>(form_signature)); + builder->AddMetric(internal::kUKMFieldSignatureMetricName, + static_cast<int64_t>(field_signature)); + builder->AddMetric(internal::kUKMValidationEventMetricName, + static_cast<int64_t>(metric_type)); + builder->AddMetric(internal::kUKMPredictionSourceMetricName, + static_cast<int64_t>(prediction_source)); + builder->AddMetric(internal::kUKMPredictedTypeMetricName, + static_cast<int64_t>(predicted_type)); + builder->AddMetric(internal::kUKMActualTypeMetricName, + static_cast<int64_t>(actual_type)); +} + void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted( AutofillFormSubmittedState state) { if (!CanLog()) @@ -1361,7 +1471,10 @@ AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed() const { DCHECK(!form_parsed_timestamp_.is_null()); - return (base::TimeTicks::Now() - form_parsed_timestamp_).InMilliseconds(); + // Use the pinned timestamp as the current time if it's set. + base::TimeTicks now = + pinned_timestamp_.is_null() ? base::TimeTicks::Now() : pinned_timestamp_; + return (now - form_parsed_timestamp_).InMilliseconds(); } void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() { @@ -1369,4 +1482,17 @@ ukm_recorder_->UpdateSourceURL(source_id_, url_); } +AutofillMetrics::UkmTimestampPin::UkmTimestampPin( + FormInteractionsUkmLogger* logger) + : logger_(logger) { + DCHECK(logger_); + DCHECK(!logger_->has_pinned_timestamp()); + logger_->set_pinned_timestamp(base::TimeTicks::Now()); +} + +AutofillMetrics::UkmTimestampPin::~UkmTimestampPin() { + DCHECK(logger_->has_pinned_timestamp()); + logger_->set_pinned_timestamp(base::TimeTicks()); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h index 9e63c96..29203efc 100644 --- a/components/autofill/core/browser/autofill_metrics.h +++ b/components/autofill/core/browser/autofill_metrics.h
@@ -11,7 +11,6 @@ #include <vector> #include "base/macros.h" -#include "base/strings/string_piece_forward.h" #include "base/time/time.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_profile.h" @@ -19,6 +18,7 @@ #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/form_field_data.h" +#include "components/autofill/core/common/signatures_util.h" #include "components/ukm/public/ukm_recorder.h" namespace internal { @@ -69,6 +69,19 @@ // |UkmEntry| for |AutofillFormSubmittedState|. extern const char kUKMFormSubmittedEntryName[]; extern const char kUKMAutofillFormSubmittedStateMetricName[]; + +// |UkmEntry| for capturing field fill status and type prediction quality. +extern const char kUKMFieldTypeEntryName[]; +extern const char kUKMFieldFillStatusEntryName[]; +extern const char kUKMFormSignatureMetricName[]; +extern const char kUKMFieldSignatureMetricName[]; +extern const char kUKMValidationEventMetricName[]; +extern const char kUKMPredictionSourceMetricName[]; +extern const char kUKMPredictedTypeMetricName[]; +extern const char kUKMActualTypeMetricName[]; +extern const char kUKMWasSuggestionShownMetricName[]; +extern const char kUKMWasPreviouslyAutofilledMetricName[]; + } // namespace internal namespace autofill { @@ -411,6 +424,14 @@ NUM_FIELD_TYPE_QUALITY_METRICS }; + enum QualityMetricPredictionSource { + PREDICTION_SOURCE_UNKNOWN, // Not used. The prediction source is unknown. + PREDICTION_SOURCE_HEURISTIC, // Local heuristic field-type prediction. + PREDICTION_SOURCE_SERVER, // Crowd-sourced server field type prediction. + PREDICTION_SOURCE_OVERALL, // Overall field-type prediction seen by user. + NUM_QUALITY_METRIC_SOURCES + }; + enum QualityMetricType { TYPE_SUBMISSION = 0, // Logged based on user's submitted data. TYPE_NO_SUBMISSION, // Logged based on user's entered data. @@ -697,6 +718,9 @@ public: explicit FormInteractionsUkmLogger(ukm::UkmRecorder* ukm_recorder); + bool has_pinned_timestamp() const { return !pinned_timestamp_.is_null(); } + void set_pinned_timestamp(base::TimeTicks t) { pinned_timestamp_ = t; } + const GURL& url() const { return url_; } void OnFormsParsed(const GURL& url); @@ -707,6 +731,15 @@ void LogSelectedMaskedServerCard(); void LogDidFillSuggestion(int record_type); void LogTextFieldDidChange(const AutofillField& field); + void LogFieldFillStatus(const FormStructure& form, + const AutofillField& field, + QualityMetricType metric_type); + void LogFieldType(FormSignature form_signature, + FieldSignature field_signature, + QualityMetricPredictionSource prediction_source, + QualityMetricType metric_type, + ServerFieldType predicted_type, + ServerFieldType actual_type); void LogFormSubmitted(AutofillFormSubmittedState state); // We initialize |url_| with the form's URL when we log the first form @@ -723,6 +756,20 @@ ukm::SourceId source_id_ = -1; GURL url_; base::TimeTicks form_parsed_timestamp_; + base::TimeTicks pinned_timestamp_; + }; + + // Utility class to pin the timestamp used by the FormInteractionsUkmLogger + // while an instance of this class is in scope. Pinned timestamps cannot be + // nested. + class UkmTimestampPin { + public: + UkmTimestampPin(FormInteractionsUkmLogger* logger); + ~UkmTimestampPin(); + + private: + FormInteractionsUkmLogger* const logger_; + DISALLOW_IMPLICIT_CONSTRUCTORS(UkmTimestampPin); }; // |upload_decision_metrics| is a bitmask of |CardUploadDecisionMetric|. @@ -749,16 +796,19 @@ static void LogDeveloperEngagementMetric(DeveloperEngagementMetric metric); static void LogHeuristicPredictionQualityMetrics( - const ServerFieldTypeSet& possible_types, - ServerFieldType predicted_type, + FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, QualityMetricType metric_type); static void LogServerPredictionQualityMetrics( - const ServerFieldTypeSet& possible_types, - ServerFieldType predicted_type, + FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, QualityMetricType metric_type); static void LogOverallPredictionQualityMetrics( - const ServerFieldTypeSet& possible_types, - ServerFieldType predicted_type, + FormInteractionsUkmLogger* form_interactions_ukm_logger, + const FormStructure& form, + const AutofillField& field, QualityMetricType metric_type); static void LogServerQueryMetric(ServerQueryMetric metric);
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index 30543c4..1405395 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -59,6 +59,9 @@ namespace autofill { namespace { +using ExpectedUkmMetrics = + std::vector<std::vector<std::pair<const char*, int64_t>>>; + class TestPersonalDataManager : public PersonalDataManager { public: TestPersonalDataManager() @@ -343,14 +346,14 @@ } void VerifyDeveloperEngagementUkm( + const ukm::TestUkmRecorder& ukm_recorder, const FormData& form, - const ukm::TestUkmRecorder* ukm_recorder, const std::vector<int64_t>& expected_metric_values) { - const ukm::mojom::UkmEntry* entry = ukm_recorder->GetEntryForEntryName( + const ukm::mojom::UkmEntry* entry = ukm_recorder.GetEntryForEntryName( internal::kUKMDeveloperEngagementEntryName); ASSERT_NE(nullptr, entry); const ukm::UkmSource* source = - ukm_recorder->GetSourceForSourceId(entry->source_id); + ukm_recorder.GetSourceForSourceId(entry->source_id); ASSERT_NE(nullptr, source); EXPECT_EQ(form.origin, source->url()); @@ -374,20 +377,18 @@ rhs.first == internal::kUKMMillisecondsSinceFormParsedMetricName)); } -void VerifyFormInteractionUkm( - const FormData& form, - const ukm::TestUkmRecorder* ukm_recorder, - const char* event_name, - const std::vector<std::vector<std::pair<const char*, int64_t>>>& - expected_metrics) { +void VerifyFormInteractionUkm(const ukm::TestUkmRecorder& ukm_recorder, + const FormData& form, + const char* event_name, + const ExpectedUkmMetrics& expected_metrics) { size_t expected_metrics_index = 0; - for (size_t i = 0; i < ukm_recorder->entries_count(); ++i) { - const ukm::mojom::UkmEntry* entry = ukm_recorder->GetEntry(i); + for (size_t i = 0; i < ukm_recorder.entries_count(); ++i) { + const ukm::mojom::UkmEntry* entry = ukm_recorder.GetEntry(i); if (entry->event_hash != base::HashMetricName(event_name)) continue; const ukm::UkmSource* source = - ukm_recorder->GetSourceForSourceId(entry->source_id); + ukm_recorder.GetSourceForSourceId(entry->source_id); ASSERT_NE(nullptr, source); EXPECT_EQ(form.origin, source->url()); @@ -399,15 +400,68 @@ } } -void VerifySubmitFormUkm(const FormData& form, - const ukm::TestUkmRecorder* ukm_recorder, +void VerifySubmitFormUkm(const ukm::TestUkmRecorder& ukm_recorder, + const FormData& form, AutofillMetrics::AutofillFormSubmittedState state) { VerifyFormInteractionUkm( - form, ukm_recorder, internal::kUKMFormSubmittedEntryName, + ukm_recorder, form, internal::kUKMFormSubmittedEntryName, {{{internal::kUKMAutofillFormSubmittedStateMetricName, state}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); } +void AppendFieldFillStatusUkm(const FormData& form, + ExpectedUkmMetrics* expected_metrics) { + int64_t form_signature = static_cast<int64_t>(CalculateFormSignature(form)); + int64_t metric_type = static_cast<int64_t>(AutofillMetrics::TYPE_SUBMISSION); + for (const FormFieldData& field : form.fields) { + int64_t field_signature = + static_cast<int64_t>(CalculateFieldSignatureForField(field)); + expected_metrics->push_back( + {{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, + {internal::kUKMFormSignatureMetricName, form_signature}, + {internal::kUKMFieldSignatureMetricName, field_signature}, + {internal::kUKMValidationEventMetricName, metric_type}, + {internal::kUKMIsAutofilledMetricName, field.is_autofilled ? 1 : 0}, + {internal::kUKMWasPreviouslyAutofilledMetricName, 0}}); + } +} + +void AppendFieldTypeUkm(const FormData& form, + const std::vector<ServerFieldType>& heuristic_types, + const std::vector<ServerFieldType>& server_types, + const std::vector<ServerFieldType>& actual_types, + ExpectedUkmMetrics* expected_metrics) { + ASSERT_EQ(heuristic_types.size(), form.fields.size()); + ASSERT_EQ(server_types.size(), form.fields.size()); + ASSERT_EQ(actual_types.size(), form.fields.size()); + int64_t form_signature = static_cast<int64_t>(CalculateFormSignature(form)); + int64_t metric_type = static_cast<int64_t>(AutofillMetrics::TYPE_SUBMISSION); + std::vector<int64_t> prediction_sources{ + AutofillMetrics::PREDICTION_SOURCE_HEURISTIC, + AutofillMetrics::PREDICTION_SOURCE_SERVER, + AutofillMetrics::PREDICTION_SOURCE_OVERALL}; + for (size_t i = 0; i < form.fields.size(); ++i) { + const FormFieldData& field = form.fields[i]; + int64_t field_signature = + static_cast<int64_t>(CalculateFieldSignatureForField(field)); + for (int64_t source : prediction_sources) { + int64_t predicted_type = static_cast<int64_t>( + (source == AutofillMetrics::PREDICTION_SOURCE_SERVER + ? server_types + : heuristic_types)[i]); + int64_t actual_type = static_cast<int64_t>(actual_types[i]); + expected_metrics->push_back( + {{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, + {internal::kUKMFormSignatureMetricName, form_signature}, + {internal::kUKMFieldSignatureMetricName, field_signature}, + {internal::kUKMValidationEventMetricName, metric_type}, + {internal::kUKMPredictionSourceMetricName, source}, + {internal::kUKMPredictedTypeMetricName, predicted_type}, + {internal::kUKMActualTypeMetricName, actual_type}}); + } + } +} + } // namespace // This is defined in the autofill_metrics.cc implementation file. @@ -809,7 +863,7 @@ form.origin = GURL("http://example.com/form.html"); form.action = GURL("http://example.com/submit.html"); - std::vector<ServerFieldType> heuristic_types, server_types; + std::vector<ServerFieldType> heuristic_types, server_types, actual_types; AutofillField field; // Add a first name field, that is predicted correctly. @@ -818,6 +872,7 @@ form.fields.push_back(field); heuristic_types.push_back(NAME_FIRST); server_types.push_back(NAME_FIRST); + actual_types.push_back(NAME_FIRST); // Add a last name field, that is predicted correctly. test::CreateTestFormField("last", "last", ValueForType(NAME_LAST), "test", @@ -825,6 +880,7 @@ form.fields.push_back(field); heuristic_types.push_back(NAME_LAST); server_types.push_back(NAME_LAST); + actual_types.push_back(NAME_LAST); // Add an empty or unknown field, that is predicted as per the test params. test::CreateTestFormField("Unknown", "Unknown", @@ -833,6 +889,12 @@ heuristic_types.push_back(predicted_type); server_types.push_back(predicted_type == UNKNOWN_TYPE ? NO_SERVER_DATA : predicted_type); + // Resolve any field type ambiguity. + if (actual_field_type == AMBIGUOUS_TYPE) { + if (predicted_type == COMPANY_NAME || predicted_type == NAME_MIDDLE) + actual_field_type = predicted_type; + } + actual_types.push_back(actual_field_type); // Simulate having seen this form on page load. autofill_manager_->AddSeenForm(form, heuristic_types, server_types); @@ -841,11 +903,12 @@ base::HistogramTester histogram_tester; autofill_manager_->SubmitForm(form, TimeTicks::Now()); - // Resolve any field type ambiguity. - if (actual_field_type == AMBIGUOUS_TYPE) { - if (predicted_type == COMPANY_NAME || predicted_type == NAME_MIDDLE) - actual_field_type = predicted_type; - } + ExpectedUkmMetrics expected_ukm_metrics; + AppendFieldTypeUkm(form, heuristic_types, server_types, actual_types, + &expected_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldTypeEntryName, + expected_ukm_metrics); // Validate the total samples and the crossed (predicted-to-actual) samples. for (const auto& source : prediction_sources) { @@ -1790,7 +1853,7 @@ ASSERT_EQ(1U, test_ukm_recorder_.entries_count()); ASSERT_EQ(1U, test_ukm_recorder_.sources_count()); VerifyDeveloperEngagementUkm( - form, &test_ukm_recorder_, + test_ukm_recorder_, form, {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS}); } } @@ -1840,7 +1903,7 @@ ASSERT_EQ(1U, test_ukm_recorder_.entries_count()); ASSERT_EQ(1U, test_ukm_recorder_.sources_count()); VerifyDeveloperEngagementUkm( - form, &test_ukm_recorder_, + test_ukm_recorder_, form, {AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS}); } } @@ -1872,7 +1935,7 @@ ASSERT_EQ(1U, test_ukm_recorder_.entries_count()); ASSERT_EQ(1U, test_ukm_recorder_.sources_count()); - VerifyDeveloperEngagementUkm(form, &test_ukm_recorder_, + VerifyDeveloperEngagementUkm(test_ukm_recorder_, form, {AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT}); test_ukm_recorder_.Purge(); } @@ -1887,7 +1950,7 @@ autofill_manager_->Reset(); VerifyDeveloperEngagementUkm( - form, &test_ukm_recorder_, + test_ukm_recorder_, form, {AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS, AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT}); } @@ -2160,7 +2223,7 @@ } VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionsShownEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NAME_FULL}, {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, @@ -2173,14 +2236,14 @@ // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to // |autofill_manager_->FillOrPreviewForm|. VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionFilledEntryName, {{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}, {{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); // Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState| // because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|. - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -2271,7 +2334,7 @@ } VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionsShownEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, {internal::kUKMHeuristicTypeMetricName, ADDRESS_HOME_STATE}, {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, @@ -2284,14 +2347,14 @@ // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to // |autofill_manager_->FillOrPreviewForm|. VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionFilledEntryName, {{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}, {{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); // Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState| // because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|. - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -3002,7 +3065,7 @@ "Autofill.FormEvents.CreditCard", AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -3026,12 +3089,12 @@ AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionsShownEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NUMBER}, {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, {internal::kUKMServerTypeMetricName, CREDIT_CARD_NUMBER}}}); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -3058,10 +3121,10 @@ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionFilledEntryName, {{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -3089,10 +3152,10 @@ AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionFilledEntryName, {{{internal::kUKMRecordTypeMetricName, CreditCard::FULL_SERVER_CARD}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -3122,14 +3185,14 @@ 1); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionFilledEntryName, {{{internal::kUKMRecordTypeMetricName, CreditCard::MASKED_SERVER_CARD}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, + test_ukm_recorder_, form, internal::kUKMSelectedMaskedServerCardEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -3155,7 +3218,7 @@ autofill_manager_->SubmitForm(form, TimeTicks::Now()); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMFormSubmittedEntryName, + test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, {{{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); @@ -3163,7 +3226,7 @@ autofill_manager_->SubmitForm(form, TimeTicks::Now()); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMFormSubmittedEntryName, + test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, {{{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}, @@ -3255,12 +3318,12 @@ 0); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionsShownEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NUMBER}, {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, {internal::kUKMServerTypeMetricName, CREDIT_CARD_NUMBER}}}); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } } @@ -3735,7 +3798,7 @@ "Autofill.FormEvents.Address", AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); - VerifySubmitFormUkm(form, &test_ukm_recorder_, + VerifySubmitFormUkm(test_ukm_recorder_, form, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); } @@ -4258,13 +4321,17 @@ base::HistogramTester histogram_tester; autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); histogram_tester.ExpectTotalCount("Autofill.FormSubmittedState", 0); + + EXPECT_EQ(1U, test_ukm_recorder_.entries_count()); + EXPECT_EQ(1U, test_ukm_recorder_.sources_count()); + + VerifyDeveloperEngagementUkm( + test_ukm_recorder_, form, + {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS}); } - std::vector<std::vector<std::pair<const char*, int64_t>>> - expected_form_submission_ukm_metrics = { - {{internal::kUKMAutofillFormSubmittedStateMetricName, - AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}, - {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}; + ExpectedUkmMetrics expected_form_submission_ukm_metrics; + ExpectedUkmMetrics expected_field_fill_status_ukm_metrics; // No data entered in the form. { @@ -4277,16 +4344,18 @@ EXPECT_EQ(1, user_action_tester.GetActionCount( "Autofill_FormSubmitted_NonFillable")); - // Expect an entry for |DeveloperEngagement| and an entry for form - // interactions. Both entries are for the same URL. - ASSERT_EQ(2U, test_ukm_recorder_.entries_count()); - ASSERT_EQ(2U, test_ukm_recorder_.sources_count()); - VerifyDeveloperEngagementUkm( - form, &test_ukm_recorder_, - {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + expected_form_submission_ukm_metrics.push_back( + {{internal::kUKMAutofillFormSubmittedStateMetricName, + AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}, + {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } // Non fillable form. @@ -4308,9 +4377,14 @@ {{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } // Fill in the third field. @@ -4334,9 +4408,15 @@ AutofillMetrics:: FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } // Autofilled none with suggestions shown. @@ -4352,18 +4432,24 @@ "Autofill_FormSubmitted_FilledNone_SuggestionsShown")); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionsShownEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, {internal::kUKMHeuristicTypeMetricName, PHONE_HOME_WHOLE_NUMBER}, {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, {internal::kUKMServerTypeMetricName, NO_SERVER_DATA}}}); + expected_form_submission_ukm_metrics.push_back( {{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } // Mark one of the fields as autofilled. @@ -4385,9 +4471,14 @@ {{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } // Mark all of the fillable fields as autofilled. @@ -4410,9 +4501,14 @@ {{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } // Clear out the third field's value. @@ -4434,9 +4530,14 @@ {{internal::kUKMAutofillFormSubmittedStateMetricName, AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}); - VerifyFormInteractionUkm(form, &test_ukm_recorder_, + VerifyFormInteractionUkm(test_ukm_recorder_, form, internal::kUKMFormSubmittedEntryName, expected_form_submission_ukm_metrics); + + AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics); + VerifyFormInteractionUkm(test_ukm_recorder_, form, + internal::kUKMFieldFillStatusEntryName, + expected_field_fill_status_ukm_metrics); } } @@ -4547,12 +4648,12 @@ autofill_manager_->Reset(); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMInteractedWithFormEntryName, + test_ukm_recorder_, form, internal::kUKMInteractedWithFormEntryName, {{{internal::kUKMIsForCreditCardMetricName, false}, {internal::kUKMLocalRecordTypeCountMetricName, 0}, {internal::kUKMServerRecordTypeCountMetricName, 0}}}); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionsShownEntryName, {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}, {internal::kUKMHeuristicTypeMetricName, PHONE_HOME_WHOLE_NUMBER}, {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, @@ -4562,13 +4663,13 @@ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED}, {internal::kUKMServerTypeMetricName, NO_SERVER_DATA}}}); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName, + test_ukm_recorder_, form, internal::kUKMSuggestionFilledEntryName, {{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}, {{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE}, {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}}); VerifyFormInteractionUkm( - form, &test_ukm_recorder_, internal::kUKMTextFieldDidChangeEntryName, + test_ukm_recorder_, form, internal::kUKMTextFieldDidChangeEntryName, {{{internal::kUKMFieldTypeGroupMetricName, NAME}, {internal::kUKMHeuristicTypeMetricName, NAME_FULL}, {internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 4319c23..7beba16 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -696,6 +696,9 @@ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger, bool did_show_suggestions, bool observed_submission) const { + // Use the same timestamp on UKM Metrics generated within this method's scope. + AutofillMetrics::UkmTimestampPin timestamp_pin(form_interactions_ukm_logger); + size_t num_detected_field_types = 0; size_t num_edited_autofilled_fields = 0; bool did_autofill_all_possible_fields = true; @@ -710,40 +713,31 @@ for (size_t i = 0; i < field_count(); ++i) { auto* const field = this->field(i); - // No further logging for password fields. Those are primarily related to a - // different feature code path, and so make more sense to track outside of - // this metric. - if (field->form_control_type == "password") - continue; - if (IsUPIVirtualPaymentAddress(field->value)) { AutofillMetrics::LogUserHappinessMetric( AutofillMetrics::USER_DID_ENTER_UPI_VPA); } + + form_interactions_ukm_logger->LogFieldFillStatus(*this, *field, + metric_type); + + AutofillMetrics::LogHeuristicPredictionQualityMetrics( + form_interactions_ukm_logger, *this, *field, metric_type); + AutofillMetrics::LogServerPredictionQualityMetrics( + form_interactions_ukm_logger, *this, *field, metric_type); + AutofillMetrics::LogOverallPredictionQualityMetrics( + form_interactions_ukm_logger, *this, *field, metric_type); // We count fields that were autofilled but later modified, regardless of // whether the data now in the field is recognized. if (field->previously_autofilled()) num_edited_autofilled_fields++; - // Aliases for the field types predicted by heuristics, server and overall. - ServerFieldType heuristic_type = - AutofillType(field->heuristic_type()).GetStorableType(); - ServerFieldType server_type = - AutofillType(field->server_type()).GetStorableType(); - ServerFieldType predicted_type = field->Type().GetStorableType(); - const ServerFieldTypeSet& field_types = field->possible_types(); DCHECK(!field_types.empty()); - - AutofillMetrics::LogHeuristicPredictionQualityMetrics( - field_types, heuristic_type, metric_type); - AutofillMetrics::LogServerPredictionQualityMetrics(field_types, server_type, - metric_type); - AutofillMetrics::LogOverallPredictionQualityMetrics( - field_types, predicted_type, metric_type); - - if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE)) + if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE)) { + DCHECK_EQ(field_types.size(), 1u); continue; + } ++num_detected_field_types; if (field->is_autofilled) @@ -813,21 +807,18 @@ } } -void FormStructure::LogQualityMetricsBasedOnAutocomplete() const { +void FormStructure::LogQualityMetricsBasedOnAutocomplete( + AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) + const { const AutofillMetrics::QualityMetricType metric_type = AutofillMetrics::TYPE_AUTOCOMPLETE_BASED; for (const auto& field : fields_) { if (field->html_type() != HTML_TYPE_UNSPECIFIED && field->html_type() != HTML_TYPE_UNRECOGNIZED) { - // The type inferred by the autocomplete attribute. - ServerFieldTypeSet actual_field_type_set{ - AutofillType(field->html_type(), field->html_mode()) - .GetStorableType()}; - AutofillMetrics::LogHeuristicPredictionQualityMetrics( - actual_field_type_set, field->heuristic_type(), metric_type); + form_interactions_ukm_logger, *this, *field, metric_type); AutofillMetrics::LogServerPredictionQualityMetrics( - actual_field_type_set, field->server_type(), metric_type); + form_interactions_ukm_logger, *this, *field, metric_type); } } }
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index 52fd9fb..c70a23a8 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -147,7 +147,9 @@ // Log the quality of the heuristics and server predictions for this form // structure, if autocomplete attributes are present on the fields (they are // used as golden truths). - void LogQualityMetricsBasedOnAutocomplete() const; + void LogQualityMetricsBasedOnAutocomplete( + AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) + const; // Classifies each field in |fields_| based upon its |autocomplete| attribute, // if the attribute is available. The association is stored into the field's
diff --git a/components/cast_channel/cast_channel_enum.h b/components/cast_channel/cast_channel_enum.h index 1ccf670..c1f7f2bb 100644 --- a/components/cast_channel/cast_channel_enum.h +++ b/components/cast_channel/cast_channel_enum.h
@@ -22,7 +22,7 @@ NONE, CONNECTING, OPEN, - CLOSING, + CLOSING, // TODO(zhaobin): Remove this value because it is unused. CLOSED, };
diff --git a/components/cast_channel/cast_socket.cc b/components/cast_channel/cast_socket.cc index c4b2def..86adf57 100644 --- a/components/cast_channel/cast_socket.cc +++ b/components/cast_channel/cast_socket.cc
@@ -136,8 +136,9 @@ // would result in re-entrancy. CloseInternal(); - if (!connect_callback_.is_null()) - base::ResetAndReturn(&connect_callback_).Run(ChannelError::UNKNOWN); + for (auto& connect_callback : connect_callbacks_) + connect_callback.Run(channel_id_, ChannelError::UNKNOWN); + connect_callbacks_.clear(); } ReadyState CastSocketImpl::ready_state() const { @@ -240,20 +241,36 @@ transport_ = std::move(transport); } -void CastSocketImpl::Connect(base::Callback<void(ChannelError)> callback) { +void CastSocketImpl::Connect(const OnOpenCallback& callback) { + switch (ready_state_) { + case ReadyState::NONE: + connect_callbacks_.push_back(callback); + Connect(); + break; + case ReadyState::CONNECTING: + connect_callbacks_.push_back(callback); + break; + case ReadyState::OPEN: + callback.Run(channel_id_, ChannelError::NONE); + break; + case ReadyState::CLOSED: + callback.Run(channel_id_, ChannelError::CONNECT_ERROR); + break; + default: + NOTREACHED() << "Unknown ReadyState: " + << ReadyStateToString(ready_state_); + } +} + +void CastSocketImpl::Connect() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); VLOG_WITH_CONNECTION(1) << "Connect readyState = " << ReadyStateToString(ready_state_); + DCHECK_EQ(ReadyState::NONE, ready_state_); DCHECK_EQ(ConnectionState::START_CONNECT, connect_state_); delegate_ = base::MakeUnique<CastSocketMessageDelegate>(this); - if (ready_state_ != ReadyState::NONE) { - callback.Run(ChannelError::CONNECT_ERROR); - return; - } - - connect_callback_ = callback; SetReadyState(ReadyState::CONNECTING); SetConnectState(ConnectionState::TCP_CONNECT); @@ -532,7 +549,7 @@ void CastSocketImpl::DoConnectCallback() { VLOG(1) << "DoConnectCallback (error_state = " << ChannelErrorToString(error_state_) << ")"; - if (connect_callback_.is_null()) { + if (connect_callbacks_.empty()) { DLOG(FATAL) << "Connection callback invoked multiple times."; return; } @@ -550,7 +567,9 @@ CloseInternal(); } - base::ResetAndReturn(&connect_callback_).Run(error_state_); + for (auto& connect_callback : connect_callbacks_) + connect_callback.Run(channel_id_, error_state_); + connect_callbacks_.clear(); } void CastSocketImpl::Close(const net::CompletionCallback& callback) {
diff --git a/components/cast_channel/cast_socket.h b/components/cast_channel/cast_socket.h index 00c4e50..e51d26f2 100644 --- a/components/cast_channel/cast_socket.h +++ b/components/cast_channel/cast_socket.h
@@ -56,6 +56,9 @@ // Public interface of the CastSocket class. class CastSocket { public: + using OnOpenCallback = + base::Callback<void(int channel_id, ChannelError error_state)>; + class Observer { public: virtual ~Observer() {} @@ -82,7 +85,7 @@ // If the CastSocket is destroyed while the connection is pending, |callback| // will be invoked with CHANNEL_ERROR_UNKNOWN. In this case, invoking // |callback| must not result in any re-entrancy behavior. - virtual void Connect(base::Callback<void(ChannelError)> callback) = 0; + virtual void Connect(const OnOpenCallback& callback) = 0; // Closes the channel if not already closed. On completion, the channel will // be in READY_STATE_CLOSED. @@ -167,7 +170,7 @@ ~CastSocketImpl() override; // CastSocket interface. - void Connect(base::Callback<void(ChannelError)> callback) override; + void Connect(const OnOpenCallback& callback) override; CastTransport* transport() const override; void Close(const net::CompletionCallback& callback) override; const net::IPEndPoint& ip_endpoint() const override; @@ -228,6 +231,8 @@ // capability must not have a certificate with audio only policy. bool VerifyChannelPolicy(const AuthResult& result); + void Connect(); + private: FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestConnectAuthMessageCorrupted); FRIEND_TEST_ALL_PREFIXES(CastSocketTest, @@ -354,8 +359,8 @@ // Reply received from the receiver to a challenge request. std::unique_ptr<CastMessage> challenge_reply_; - // Callback invoked when the socket is connected or fails to connect. - base::Callback<void(ChannelError)> connect_callback_; + // Callbacks invoked when the socket is connected or fails to connect. + std::vector<OnOpenCallback> connect_callbacks_; // Callback invoked by |connect_timeout_timer_| to cancel the connection. base::CancelableClosure connect_timeout_callback_;
diff --git a/components/cast_channel/cast_socket_service.cc b/components/cast_channel/cast_socket_service.cc index 5da94186..6bdeae3 100644 --- a/components/cast_channel/cast_socket_service.cc +++ b/components/cast_channel/cast_socket_service.cc
@@ -5,17 +5,33 @@ #include "components/cast_channel/cast_socket_service.h" #include "base/memory/ptr_util.h" +#include "components/cast_channel/cast_socket.h" +#include "components/cast_channel/logger.h" #include "content/public/browser/browser_thread.h" using content::BrowserThread; +namespace { +// Connect timeout for connect calls. +const int kConnectTimeoutSecs = 10; + +// Ping interval +const int kPingIntervalInSecs = 5; + +// Liveness timeout for connect calls, in milliseconds. If no message is +// received from the receiver during kConnectLivenessTimeoutSecs, it is +// considered gone. +const int kConnectLivenessTimeoutSecs = kPingIntervalInSecs * 2; +} // namespace + namespace cast_channel { int CastSocketService::last_channel_id_ = 0; CastSocketService::CastSocketService() : RefcountedKeyedService( - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) { + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)), + logger_(new Logger()) { DETACH_FROM_THREAD(thread_checker_); } @@ -23,13 +39,19 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } -int CastSocketService::AddSocket(std::unique_ptr<CastSocket> socket) { +scoped_refptr<Logger> CastSocketService::GetLogger() { + return logger_; +} + +CastSocket* CastSocketService::AddSocket(std::unique_ptr<CastSocket> socket) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(socket); int id = ++last_channel_id_; socket->set_id(id); + + auto* socket_ptr = socket.get(); sockets_.insert(std::make_pair(id, std::move(socket))); - return id; + return socket_ptr; } std::unique_ptr<CastSocket> CastSocketService::RemoveSocket(int channel_id) { @@ -52,6 +74,60 @@ return socket_it == sockets_.end() ? nullptr : socket_it->second.get(); } +CastSocket* CastSocketService::GetSocket( + const net::IPEndPoint& ip_endpoint) const { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + auto it = std::find_if( + sockets_.begin(), sockets_.end(), + [&ip_endpoint]( + const std::pair<const int, std::unique_ptr<CastSocket>>& pair) { + return pair.second->ip_endpoint() == ip_endpoint; + }); + return it == sockets_.end() ? nullptr : it->second.get(); +} + +int CastSocketService::OpenSocket(const net::IPEndPoint& ip_endpoint, + net::NetLog* net_log, + const base::TimeDelta& connect_timeout, + const base::TimeDelta& liveness_timeout, + const base::TimeDelta& ping_interval, + uint64_t device_capabilities, + const CastSocket::OnOpenCallback& open_cb, + CastSocket::Observer* observer) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(observer); + auto* socket = GetSocket(ip_endpoint); + + if (!socket) { + // If cast socket does not exist. + if (socket_for_test_) { + socket = AddSocket(std::move(socket_for_test_)); + } else { + socket = new CastSocketImpl(ip_endpoint, net_log, connect_timeout, + liveness_timeout, ping_interval, logger_, + device_capabilities); + AddSocket(base::WrapUnique(socket)); + } + } + + socket->AddObserver(observer); + socket->Connect(open_cb); + return socket->id(); +} + +int CastSocketService::OpenSocket(const net::IPEndPoint& ip_endpoint, + net::NetLog* net_log, + const CastSocket::OnOpenCallback& open_cb, + CastSocket::Observer* observer) { + auto connect_timeout = base::TimeDelta::FromSeconds(kConnectTimeoutSecs); + auto ping_interval = base::TimeDelta::FromSeconds(kPingIntervalInSecs); + auto liveness_timeout = + base::TimeDelta::FromSeconds(kConnectLivenessTimeoutSecs); + return OpenSocket(ip_endpoint, net_log, connect_timeout, liveness_timeout, + ping_interval, CastDeviceCapability::NONE, open_cb, + observer); +} + CastSocket::Observer* CastSocketService::GetObserver(const std::string& id) { auto it = socket_observer_map_.find(id); return it == socket_observer_map_.end() ? nullptr : it->second.get(); @@ -65,6 +141,11 @@ return observer_ptr; } +void CastSocketService::SetSocketForTest( + std::unique_ptr<cast_channel::CastSocket> socket_for_test) { + socket_for_test_ = std::move(socket_for_test); +} + void CastSocketService::ShutdownOnUIThread() {} } // namespace cast_channel
diff --git a/components/cast_channel/cast_socket_service.h b/components/cast_channel/cast_socket_service.h index 54cd715d..eea0aee 100644 --- a/components/cast_channel/cast_socket_service.h +++ b/components/cast_channel/cast_socket_service.h
@@ -24,9 +24,12 @@ public: CastSocketService(); - // Adds |socket| to |sockets_| and returns the new channel_id. Takes ownership - // of |socket|. - int AddSocket(std::unique_ptr<CastSocket> socket); + // Returns a pointer to the Logger member variable. + scoped_refptr<cast_channel::Logger> GetLogger(); + + // Adds |socket| to |sockets_| and returns raw pointer of |socket|. Takes + // ownership of |socket|. + CastSocket* AddSocket(std::unique_ptr<CastSocket> socket); // Removes the CastSocket corresponding to |channel_id| from the // CastSocketRegistry. Returns nullptr if no such CastSocket exists. @@ -36,6 +39,44 @@ // otherwise. CastSocket* GetSocket(int channel_id) const; + CastSocket* GetSocket(const net::IPEndPoint& ip_endpoint) const; + + // Opens cast socket with |ip_endpoint| and invokes |open_cb| when opening + // operation finishes. If cast socket with |ip_endpoint| already exists, + // invoke |open_cb| directly with existing socket's channel ID. + // Parameters: + // |ip_endpoint|: IP address and port of the remote host. + // |net_log|: Log of socket events. + // |connect_timeout|: Connection timeout interval. + // |liveness_timeout|: Liveness timeout for connect calls. + // |ping_interval|: Ping interval. + // |logger|: Log of cast channel events. + // |device_capabilities|: Device capabilities. + // |open_cb|: OnOpenCallback invoked when cast socket is opened. + // |observer|: Observer handles messages and errors on newly opened socket. + // Does not take ownership of |observer|. + int OpenSocket(const net::IPEndPoint& ip_endpoint, + net::NetLog* net_log, + const base::TimeDelta& connect_timeout, + const base::TimeDelta& liveness_timeout, + const base::TimeDelta& ping_interval, + uint64_t device_capabilities, + const CastSocket::OnOpenCallback& open_cb, + CastSocket::Observer* observer); + + // Opens cast socket with |ip_endpoint| and invokes |open_cb| when opening + // operation finishes. If cast socket with |ip_endpoint| already exists, + // invoke |open_cb| directly with existing socket's channel ID. + // |ip_endpoint|: IP address and port of the remote host. + // |net_log|: Log of socket events. + // |open_cb|: OnOpenCallback invoked when cast socket is opened. + // |observer|: Observer handles messages and errors on newly opened socket. + // Does not take ownership of |observer|. + int OpenSocket(const net::IPEndPoint& ip_endpoint, + net::NetLog* net_log, + const CastSocket::OnOpenCallback& open_cb, + CastSocket::Observer* observer); + // Returns an observer corresponding to |id|. CastSocket::Observer* GetObserver(const std::string& id); @@ -45,6 +86,9 @@ const std::string& id, std::unique_ptr<CastSocket::Observer> observer); + // Allow test to inject a mock cast socket. + void SetSocketForTest(std::unique_ptr<CastSocket> socket_for_test); + private: ~CastSocketService() override; @@ -63,6 +107,10 @@ std::map<std::string, std::unique_ptr<CastSocket::Observer>> socket_observer_map_; + scoped_refptr<cast_channel::Logger> logger_; + + std::unique_ptr<CastSocket> socket_for_test_; + THREAD_CHECKER(thread_checker_); DISALLOW_COPY_AND_ASSIGN(CastSocketService);
diff --git a/components/cast_channel/cast_socket_service_unittest.cc b/components/cast_channel/cast_socket_service_unittest.cc index 53141c7..ca4f9307 100644 --- a/components/cast_channel/cast_socket_service_unittest.cc +++ b/components/cast_channel/cast_socket_service_unittest.cc
@@ -3,13 +3,20 @@ // found in the LICENSE file. #include "components/cast_channel/cast_socket_service.h" +#include "base/test/mock_callback.h" #include "components/cast_channel/cast_test_util.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; +using testing::DoAll; +using testing::Invoke; +using testing::Return; +using testing::ReturnRef; using testing::SaveArg; +using testing::WithArgs; namespace cast_channel { @@ -19,40 +26,35 @@ : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), cast_socket_service_(new CastSocketService()) {} + CastSocket* AddSocket(std::unique_ptr<CastSocket> socket) { + return cast_socket_service_->AddSocket(std::move(socket)); + } + + void TearDown() override { cast_socket_service_ = nullptr; } + protected: content::TestBrowserThreadBundle thread_bundle_; scoped_refptr<CastSocketService> cast_socket_service_; + base::MockCallback<CastSocket::OnOpenCallback> mock_on_open_callback_; + MockCastSocketObserver mock_observer_; }; TEST_F(CastSocketServiceTest, TestAddSocket) { - int channel_id_1 = 0; auto socket1 = base::MakeUnique<MockCastSocket>(); - EXPECT_CALL(*socket1, set_id(_)).WillOnce(SaveArg<0>(&channel_id_1)); + auto* socket_ptr1 = AddSocket(std::move(socket1)); + EXPECT_NE(0, socket_ptr1->id()); - int channel_id = cast_socket_service_->AddSocket(std::move(socket1)); - EXPECT_EQ(channel_id_1, channel_id); - EXPECT_NE(0, channel_id_1); - - int channel_id_2 = 0; auto socket2 = base::MakeUnique<MockCastSocket>(); - EXPECT_CALL(*socket2, set_id(_)).WillOnce(SaveArg<0>(&channel_id_2)); + auto* socket_ptr2 = AddSocket(std::move(socket2)); + EXPECT_NE(socket_ptr1->id(), socket_ptr2->id()); - auto* socket_ptr = socket2.get(); - channel_id = cast_socket_service_->AddSocket(std::move(socket2)); - EXPECT_EQ(channel_id_2, channel_id); - EXPECT_NE(channel_id_1, channel_id_2); + auto removed_socket = cast_socket_service_->RemoveSocket(socket_ptr2->id()); + EXPECT_EQ(socket_ptr2, removed_socket.get()); - auto removed_socket = cast_socket_service_->RemoveSocket(channel_id); - EXPECT_EQ(socket_ptr, removed_socket.get()); - - int channel_id_3 = 0; auto socket3 = base::MakeUnique<MockCastSocket>(); - EXPECT_CALL(*socket3, set_id(_)).WillOnce(SaveArg<0>(&channel_id_3)); - - channel_id = cast_socket_service_->AddSocket(std::move(socket3)); - EXPECT_EQ(channel_id_3, channel_id); - EXPECT_NE(channel_id_1, channel_id_3); - EXPECT_NE(channel_id_2, channel_id_3); + auto* socket_ptr3 = AddSocket(std::move(socket3)); + EXPECT_NE(socket_ptr1->id(), socket_ptr3->id()); + EXPECT_NE(socket_ptr2->id(), socket_ptr3->id()); } TEST_F(CastSocketServiceTest, TestRemoveAndGetSocket) { @@ -63,13 +65,32 @@ EXPECT_FALSE(socket); auto mock_socket = base::MakeUnique<MockCastSocket>(); - EXPECT_CALL(*mock_socket, set_id(_)); - auto* mock_socket_ptr = mock_socket.get(); - channel_id = cast_socket_service_->AddSocket(std::move(mock_socket)); + auto* mock_socket_ptr = AddSocket(std::move(mock_socket)); + channel_id = mock_socket_ptr->id(); EXPECT_EQ(mock_socket_ptr, cast_socket_service_->GetSocket(channel_id)); + socket = cast_socket_service_->RemoveSocket(channel_id); EXPECT_TRUE(socket); } +TEST_F(CastSocketServiceTest, TestOpenChannel) { + auto* mock_socket = new MockCastSocket(); + auto ip_endpoint = CreateIPEndPointForTest(); + mock_socket->SetIPEndpoint(ip_endpoint); + cast_socket_service_->SetSocketForTest(base::WrapUnique(mock_socket)); + + EXPECT_CALL(*mock_socket, Connect(_)) + .WillOnce( + WithArgs<0>(Invoke([&](const CastSocket::OnOpenCallback& callback) { + callback.Run(mock_socket->id(), ChannelError::NONE); + }))); + EXPECT_CALL(mock_on_open_callback_, Run(_, ChannelError::NONE)); + EXPECT_CALL(*mock_socket, AddObserver(_)); + + cast_socket_service_->OpenSocket(ip_endpoint, nullptr /* net_log */, + mock_on_open_callback_.Get(), + &mock_observer_); +} + } // namespace cast_channel
diff --git a/components/cast_channel/cast_socket_unittest.cc b/components/cast_channel/cast_socket_unittest.cc index d0d2461c..bc4ae28 100644 --- a/components/cast_channel/cast_socket_unittest.cc +++ b/components/cast_channel/cast_socket_unittest.cc
@@ -158,7 +158,8 @@ public: CompleteHandler() {} MOCK_METHOD1(OnCloseComplete, void(int result)); - MOCK_METHOD1(OnConnectComplete, void(ChannelError error_state)); + MOCK_METHOD2(OnConnectComplete, + void(int channel_id, ChannelError error_state)); MOCK_METHOD1(OnWriteComplete, void(int result)); MOCK_METHOD1(OnReadComplete, void(int result)); @@ -356,7 +357,7 @@ SendMessage(EqualsProto(challenge_proto), _)) .WillOnce(PostCompletionCallbackTask<1>(net::OK)); EXPECT_CALL(*socket_->GetMockTransport(), Start()); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::NONE)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::NONE)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -432,7 +433,7 @@ SendMessage(EqualsProto(challenge_proto), _)) .WillOnce(PostCompletionCallbackTask<1>(net::OK)); EXPECT_CALL(*socket_->GetMockTransport(), Start()); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::TRANSPORT_ERROR)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::TRANSPORT_ERROR)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -457,7 +458,7 @@ socket_->SetupTcpConnect(net::ASYNC, net::ERR_FAILED); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_ERROR)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_ERROR)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -472,7 +473,7 @@ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::ERR_FAILED); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_ERROR)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_ERROR)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -485,7 +486,7 @@ TEST_F(CastSocketTest, TestConnectTcpTimeoutError) { CreateCastSocketSecure(); socket_->SetupTcpConnectUnresponsive(); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_TIMEOUT)); EXPECT_CALL(*observer_, OnError(_, ChannelError::CONNECT_TIMEOUT)); socket_->AddObserver(observer_.get()); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, @@ -505,7 +506,7 @@ TEST_F(CastSocketTest, TestConnectTcpSocketTimeoutError) { CreateCastSocketSecure(); socket_->SetupTcpConnect(net::SYNCHRONOUS, net::ERR_CONNECTION_TIMED_OUT); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_TIMEOUT)); EXPECT_CALL(*observer_, OnError(_, ChannelError::CONNECT_TIMEOUT)); socket_->AddObserver(observer_.get()); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, @@ -525,7 +526,8 @@ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK); socket_->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::AUTHENTICATION_ERROR)); + EXPECT_CALL(handler_, + OnConnectComplete(_, ChannelError::AUTHENTICATION_ERROR)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -541,7 +543,8 @@ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK); socket_->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::AUTHENTICATION_ERROR)); + EXPECT_CALL(handler_, + OnConnectComplete(_, ChannelError::AUTHENTICATION_ERROR)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -559,7 +562,7 @@ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK); socket_->SetupSslConnect(net::SYNCHRONOUS, net::ERR_CONNECTION_TIMED_OUT); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_TIMEOUT)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -577,7 +580,7 @@ socket_->SetupTcpConnect(net::ASYNC, net::OK); socket_->SetupSslConnect(net::ASYNC, net::ERR_CONNECTION_TIMED_OUT); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_TIMEOUT)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -597,7 +600,7 @@ SendMessage(EqualsProto(CreateAuthChallenge()), _)) .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET)); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CAST_SOCKET_ERROR)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CAST_SOCKET_ERROR)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -634,7 +637,7 @@ .WillOnce(PostCompletionCallbackTask<1>(net::OK)); socket_->AddReadResult(net::SYNCHRONOUS, net::ERR_FAILED); EXPECT_CALL(*observer_, OnError(_, ChannelError::CAST_SOCKET_ERROR)); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CAST_SOCKET_ERROR)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CAST_SOCKET_ERROR)); EXPECT_CALL(*socket_->GetMockTransport(), Start()); socket_->AddObserver(observer_.get()); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, @@ -660,7 +663,8 @@ EXPECT_CALL(*socket_->GetMockTransport(), SendMessage(EqualsProto(challenge_proto), _)) .WillOnce(PostCompletionCallbackTask<1>(net::OK)); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::AUTHENTICATION_ERROR)); + EXPECT_CALL(handler_, + OnConnectComplete(_, ChannelError::AUTHENTICATION_ERROR)); EXPECT_CALL(*socket_->GetMockTransport(), Start()); socket_->AddObserver(observer_.get()); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, @@ -698,7 +702,7 @@ EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str)); socket_->AddWriteResultForData(net::ASYNC, test_message_str); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::NONE)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::NONE)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -740,7 +744,7 @@ EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str)); socket_->AddWriteResultForData(net::SYNCHRONOUS, test_message_str); - EXPECT_CALL(handler_, OnConnectComplete(ChannelError::NONE)); + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::NONE)); socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, base::Unretained(&handler_))); RunPendingTasks(); @@ -775,4 +779,45 @@ delegate.OnError(cast_channel::ChannelError::CONNECT_ERROR); } +TEST_F(CastSocketTest, TestOpenChannelConnectingSocket) { + CreateCastSocketSecure(); + socket_->SetupTcpConnectUnresponsive(); + socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, + base::Unretained(&handler_))); + RunPendingTasks(); + + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_TIMEOUT)) + .Times(2); + socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, + base::Unretained(&handler_))); + socket_->TriggerTimeout(); + RunPendingTasks(); +} + +TEST_F(CastSocketTest, TestOpenChannelConnectedSocket) { + CreateCastSocketSecure(); + socket_->SetupTcpConnect(net::ASYNC, net::OK); + socket_->SetupSslConnect(net::ASYNC, net::OK); + + HandleAuthHandshake(); + + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::NONE)); + socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, + base::Unretained(&handler_))); +} + +TEST_F(CastSocketTest, TestOpenChannelClosedSocket) { + CreateCastSocketSecure(); + socket_->SetupTcpConnect(net::ASYNC, net::ERR_FAILED); + + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_ERROR)); + socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, + base::Unretained(&handler_))); + RunPendingTasks(); + + EXPECT_CALL(handler_, OnConnectComplete(_, ChannelError::CONNECT_ERROR)); + socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, + base::Unretained(&handler_))); +} + } // namespace cast_channel
diff --git a/components/cast_channel/cast_test_util.cc b/components/cast_channel/cast_test_util.cc index 76c5640..36efe11 100644 --- a/components/cast_channel/cast_test_util.cc +++ b/components/cast_channel/cast_test_util.cc
@@ -29,7 +29,12 @@ MockCastSocketObserver::MockCastSocketObserver() {} MockCastSocketObserver::~MockCastSocketObserver() {} -MockCastSocket::MockCastSocket() : mock_transport_(new MockCastTransport()) {} +MockCastSocket::MockCastSocket() + : channel_id_(0), + error_state_(ChannelError::NONE), + keep_alive_(false), + audio_only_(false), + mock_transport_(new MockCastTransport()) {} MockCastSocket::~MockCastSocket() {} net::IPEndPoint CreateIPEndPointForTest() {
diff --git a/components/cast_channel/cast_test_util.h b/components/cast_channel/cast_test_util.h index 7ad0646..66bac563 100644 --- a/components/cast_channel/cast_test_util.h +++ b/components/cast_channel/cast_test_util.h
@@ -69,23 +69,40 @@ MockCastSocket(); ~MockCastSocket() override; - MOCK_METHOD1(Connect, void(base::Callback<void(ChannelError)> callback)); + MOCK_METHOD1(Connect, void(const OnOpenCallback& callback)); MOCK_METHOD1(Close, void(const net::CompletionCallback& callback)); - MOCK_CONST_METHOD0(ip_endpoint, const net::IPEndPoint&()); - MOCK_CONST_METHOD0(id, int()); - MOCK_METHOD1(set_id, void(int id)); MOCK_CONST_METHOD0(ready_state, ReadyState()); - MOCK_CONST_METHOD0(error_state, ChannelError()); - MOCK_CONST_METHOD0(keep_alive, bool(void)); - MOCK_CONST_METHOD0(audio_only, bool(void)); - MOCK_METHOD1(SetErrorState, void(ChannelError error_state)); MOCK_METHOD1(AddObserver, void(Observer* observer)); - CastTransport* transport() const override { return mock_transport_.get(); } + const net::IPEndPoint& ip_endpoint() const override { return ip_endpoint_; } + void SetIPEndpoint(const net::IPEndPoint& ip_endpoint) { + ip_endpoint_ = ip_endpoint; + } + int id() const override { return channel_id_; } + void set_id(int id) override { channel_id_ = id; } + + ChannelError error_state() const override { return error_state_; } + void SetErrorState(ChannelError error_state) override { + error_state_ = error_state; + } + + bool keep_alive() const override { return keep_alive_; } + void SetKeepAlive(bool keep_alive) { keep_alive_ = keep_alive; } + + bool audio_only() const override { return audio_only_; } + void SetAudioOnly(bool audio_only) { audio_only_ = audio_only; } + + CastTransport* transport() const override { return mock_transport_.get(); } MockCastTransport* mock_transport() const { return mock_transport_.get(); } private: + net::IPEndPoint ip_endpoint_; + int channel_id_; + ChannelError error_state_; + bool keep_alive_; + bool audio_only_; + std::unique_ptr<MockCastTransport> mock_transport_; std::unique_ptr<Observer> observer_;
diff --git a/components/components_strings.grd b/components/components_strings.grd index 9b42f89..d29cca9 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -206,6 +206,7 @@ <part file="pdf_strings.grdp" /> <part file="physical_web_ui_strings.grdp" /> <part file="policy_strings.grdp" /> + <part file="safe_browsing_strings.grdp" /> <part file="security_interstitials_strings.grdp" /> <part file="security_state_strings.grdp" /> <part file="ssl_errors_strings.grdp" />
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index 5e727a3..fe36337 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -25,6 +25,16 @@ jni_package = "cronet" } +generate_jni_registration("cronet_jni_registration") { + target = ":cronet_sample_apk" + output = "$root_gen_dir/components/cronet/android/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] +} + java_cpp_enum("effective_connection_type_java") { sources = [ "//net/nqe/effective_connection_type.h", @@ -165,6 +175,7 @@ deps = [ ":cronet_android_cert_proto", ":cronet_jni_headers", + ":cronet_jni_registration", ":cronet_version_header", "//base", "//base/third_party/dynamic_annotations", @@ -476,6 +487,7 @@ testonly = true sources = [ "test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java", + "test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java", "test/src/org/chromium/net/CronetTestUtil.java", "test/src/org/chromium/net/MockCertVerifier.java", "test/src/org/chromium/net/MockUrlRequestJobFactory.java", @@ -501,6 +513,8 @@ "test/cronet_test_util.h", "test/cronet_url_request_context_config_test.cc", "test/cronet_url_request_context_config_test.h", + "test/experimental_options_test.cc", + "test/experimental_options_test.h", "test/mock_cert_verifier.cc", "test/mock_cert_verifier.h", "test/mock_url_request_job_factory.cc", @@ -529,6 +543,9 @@ ] include_dirs = [ _cronet_version_header_include_dir ] + + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + configs += [ "//build/config/android:hide_all_but_jni" ] } android_resources("cronet_test_apk_resources") { @@ -999,6 +1016,7 @@ "$root_out_dir/lib.java/base/base_java_test_support.jar", "$root_out_dir/lib.java/components/cronet/android/cronet_javatests.jar", "$root_out_dir/lib.java/components/cronet/android/cronet_test_apk_java.jar", + "$root_out_dir/lib.java/net/android/embedded_test_server_aidl_java.jar", "$root_out_dir/lib.java/net/android/net_java.jar", "$root_out_dir/lib.java/net/android/net_java_test_support.jar", "$root_out_dir/lib.java/url/url_java.jar", @@ -1027,6 +1045,7 @@ ":cronet_test_apk_java", "//base:base_java", "//base:base_java_test_support", + "//net/android:embedded_test_server_aidl_java", "//net/android:net_java", "//net/android:net_java_test_support", "//third_party/netty4:netty_all_java",
diff --git a/components/cronet/android/api/build.xml b/components/cronet/android/api/build.xml index fced897..b0d10bb7 100644 --- a/components/cronet/android/api/build.xml +++ b/components/cronet/android/api/build.xml
@@ -2,7 +2,7 @@ <target name="doc" description="generate documentation"> <javadoc destdir="${doc.dir}" overview="${overview}" - bootclasspath="../../../../third_party/android_tools/sdk/platforms/android-25/android.jar:../../../../third_party/android_tools/sdk/extras/android/support/annotations/android-support-annotations.jar:${lib.java.dir}/cronet_javadoc_classpath.jar" + bootclasspath="../../../../third_party/android_tools/sdk/platforms/android-26/android.jar:../../../../third_party/android_tools/sdk/extras/android/support/annotations/android-support-annotations.jar:${lib.java.dir}/cronet_javadoc_classpath.jar" docletpath="../../../../buildtools/android/doclava/jsilver.jar:../../../../buildtools/android/doclava/doclava.jar" > <fileset dir="${source.dir}">
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc index 72c416e..b7aa07a 100644 --- a/components/cronet/android/cronet_library_loader.cc +++ b/components/cronet/android/cronet_library_loader.cc
@@ -19,6 +19,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/statistics_recorder.h" #include "components/cronet/android/cronet_bidirectional_stream_adapter.h" +#include "components/cronet/android/cronet_jni_registration.h" #include "components/cronet/android/cronet_upload_data_stream_adapter.h" #include "components/cronet/android/cronet_url_request_adapter.h" #include "components/cronet/android/cronet_url_request_context_adapter.h" @@ -84,6 +85,11 @@ jint CronetOnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); + if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) { + return -1; + } + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. if (!RegisterJNI(env) || !NativeInit()) { return -1; }
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc index c8b2ea2..e2b6068 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.cc +++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -38,6 +38,7 @@ #include "components/cronet/android/cert/proto/cert_verification.pb.h" #include "components/cronet/android/cronet_library_loader.h" #include "components/cronet/histogram_manager.h" +#include "components/cronet/host_cache_persistence_manager.h" #include "components/cronet/url_request_context_config.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_filter.h" @@ -115,8 +116,12 @@ static base::LazyInstance<NetLogWithNetworkChangeEvents>::Leaky g_net_log = LAZY_INSTANCE_INITIALIZER; -const char kHttpServerProperties[] = "net.http_server_properties"; -const char kNetworkQualities[] = "net.network_qualities"; +// Name of the pref used for host cache persistence. +const char kHostCachePref[] = "net.host_cache"; +// Name of the pref used for HTTP server properties persistence. +const char kHttpServerPropertiesPref[] = "net.http_server_properties"; +// Name of the pref used for NQE persistence. +const char kNetworkQualitiesPref[] = "net.network_qualities"; // Current version of disk storage. const int32_t kStorageVersion = 1; // Version number used when the version of disk storage is unknown. @@ -131,7 +136,7 @@ : public net::HttpServerPropertiesManager::PrefDelegate { public: explicit PrefServiceAdapter(PrefService* pref_service) - : pref_service_(pref_service), path_(kHttpServerProperties) { + : pref_service_(pref_service), path_(kHttpServerPropertiesPref) { pref_change_registrar_.Init(pref_service_); } @@ -181,7 +186,7 @@ void SetDictionaryValue(const base::DictionaryValue& value) override { DCHECK(thread_checker_.CalledOnValidThread()); - pref_service_->Set(kNetworkQualities, value); + pref_service_->Set(kNetworkQualitiesPref, value); if (lossy_prefs_writing_task_posted_) return; @@ -204,7 +209,8 @@ std::unique_ptr<base::DictionaryValue> GetDictionaryValue() override { DCHECK(thread_checker_.CalledOnValidThread()); UMA_HISTOGRAM_EXACT_LINEAR("NQE.Prefs.ReadCount", 1, 2); - return pref_service_->GetDictionary(kNetworkQualities)->CreateDeepCopy(); + return pref_service_->GetDictionary(kNetworkQualitiesPref) + ->CreateDeepCopy(); } private: @@ -644,19 +650,23 @@ std::unique_ptr<PrefFilter>()); context_builder.SetFileTaskRunner(GetFileThread()->task_runner()); - // Set up HttpServerPropertiesManager. + // Register prefs and set up the PrefService. PrefServiceFactory factory; factory.set_user_prefs(json_pref_store_); scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple()); - registry->RegisterDictionaryPref(kHttpServerProperties, + registry->RegisterDictionaryPref(kHttpServerPropertiesPref, base::MakeUnique<base::DictionaryValue>()); if (config->enable_network_quality_estimator) { // Use lossy prefs to limit the overhead of reading/writing the prefs. - registry->RegisterDictionaryPref(kNetworkQualities, + registry->RegisterDictionaryPref(kNetworkQualitiesPref, PrefRegistry::LOSSY_PREF); } + if (config->enable_host_cache_persistence) { + registry->RegisterListPref(kHostCachePref); + } pref_service_ = factory.Create(registry.get()); + // Set up the HttpServerPropertiesManager. std::unique_ptr<net::HttpServerPropertiesManager> http_server_properties_manager(new net::HttpServerPropertiesManager( new PrefServiceAdapter(pref_service_.get()), @@ -710,6 +720,17 @@ context_ = context_builder.Build(); + // Set up host cache persistence if it's enabled. Happens after building the + // URLRequestContext to get access to the HostCache. + if (pref_service_ && config->enable_host_cache_persistence) { + net::HostCache* host_cache = context_->host_resolver()->GetHostCache(); + host_cache_persistence_manager_ = + base::MakeUnique<HostCachePersistenceManager>( + host_cache, pref_service_.get(), kHostCachePref, + base::TimeDelta::FromMilliseconds( + config->host_cache_persistence_delay_ms)); + } + context_->set_check_cleartext_permitted(true); context_->set_enable_brotli(config->enable_brotli);
diff --git a/components/cronet/android/cronet_url_request_context_adapter.h b/components/cronet/android/cronet_url_request_context_adapter.h index 0a94920..c02bad0 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.h +++ b/components/cronet/android/cronet_url_request_context_adapter.h
@@ -42,6 +42,7 @@ } // namespace net namespace cronet { +class HostCachePersistenceManager; class TestUtil; struct URLRequestContextConfig; @@ -220,7 +221,7 @@ std::unique_ptr<net::FileNetLogObserver> net_log_file_observer_; // |pref_service_| should outlive the HttpServerPropertiesManager owned by - // |context_|. + // |context_| and the HostCachePersistenceManager. std::unique_ptr<PrefService> pref_service_; std::unique_ptr<net::URLRequestContext> context_; std::unique_ptr<net::ProxyConfigService> proxy_config_service_; @@ -250,6 +251,11 @@ std::unique_ptr<net::NetworkQualitiesPrefsManager> network_qualities_prefs_manager_; + // Manages reading and writing the HostCache pref when persistence is enabled. + // Must be destroyed before |context_| (because it owns the HostResolverImpl, + // which owns the HostCache) and |pref_service_|. + std::unique_ptr<HostCachePersistenceManager> host_cache_persistence_manager_; + // Java object that owns this CronetURLRequestContextAdapter. base::android::ScopedJavaGlobalRef<jobject> jcronet_url_request_context_;
diff --git a/components/cronet/android/test/cronet_test_jni.cc b/components/cronet/android/test/cronet_test_jni.cc index 7f4b219..851f6ef 100644 --- a/components/cronet/android/test/cronet_test_jni.cc +++ b/components/cronet/android/test/cronet_test_jni.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "cronet_test_util.h" #include "cronet_url_request_context_config_test.h" +#include "experimental_options_test.h" #include "mock_cert_verifier.h" #include "mock_url_request_job_factory.h" #include "native_test_server.h" @@ -31,6 +32,7 @@ cronet::TestUploadDataStreamHandlerRegisterJni}, {"CronetUrlRequestContextConfigTest", cronet::RegisterCronetUrlRequestContextConfigTest}, + {"ExperimentalOptionsTest", cronet::RegisterExperimentalOptionsTest}, {"CronetTestUtil", cronet::TestUtil::Register}, };
diff --git a/components/cronet/android/test/experimental_options_test.cc b/components/cronet/android/test/experimental_options_test.cc new file mode 100644 index 0000000..e33fabf --- /dev/null +++ b/components/cronet/android/test/experimental_options_test.cc
@@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/cronet/android/test/experimental_options_test.h" + +#include <jni.h> + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/time/time.h" +#include "components/cronet/android/test/cronet_test_util.h" +#include "jni/ExperimentalOptionsTest_jni.h" +#include "net/base/address_family.h" +#include "net/base/net_errors.h" +#include "net/dns/host_cache.h" +#include "net/dns/host_resolver.h" +#include "net/url_request/url_request_context.h" + +using base::android::JavaParamRef; + +namespace cronet { + +namespace { +void WriteToHostCacheOnNetworkThread(jlong jcontext_adapter, + const std::string& address_string) { + net::URLRequestContext* context = + TestUtil::GetURLRequestContext(jcontext_adapter); + net::HostCache* cache = context->host_resolver()->GetHostCache(); + net::HostCache::Key key("host-cache-test-host", + net::ADDRESS_FAMILY_UNSPECIFIED, 0); + net::IPAddress address; + CHECK(address.AssignFromIPLiteral(address_string)); + net::AddressList address_list = + net::AddressList::CreateFromIPAddress(address, 0); + net::HostCache::Entry entry(net::OK, address_list); + cache->Set(key, entry, base::TimeTicks::Now(), + base::TimeDelta::FromSeconds(1)); +} +} // namespace + +static void WriteToHostCache(JNIEnv* env, + const JavaParamRef<jclass>& jcaller, + jlong jcontext_adapter, + const JavaParamRef<jstring>& jaddress) { + TestUtil::RunAfterContextInit( + jcontext_adapter, + base::Bind(&WriteToHostCacheOnNetworkThread, jcontext_adapter, + base::android::ConvertJavaStringToUTF8(env, jaddress))); +} + +bool RegisterExperimentalOptionsTest(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +} // namespace cronet
diff --git a/components/cronet/android/test/experimental_options_test.h b/components/cronet/android/test/experimental_options_test.h new file mode 100644 index 0000000..95ee724 --- /dev/null +++ b/components/cronet/android/test/experimental_options_test.h
@@ -0,0 +1,16 @@ +// 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_CRONET_ANDROID_TEST_EXPERIMENTAL_OPTIONS_TEST_H_ +#define COMPONENTS_CRONET_ANDROID_TEST_EXPERIMENTAL_OPTIONS_TEST_H_ + +#include <jni.h> + +namespace cronet { + +bool RegisterExperimentalOptionsTest(JNIEnv* env); + +} // namespace cronet + +#endif // COMPONENTS_CRONET_ANDROID_TEST_EXPERIMENTAL_OPTIONS_TEST_H_
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java index 3509479..ce11e10 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
@@ -10,16 +10,21 @@ import org.chromium.base.Log; import org.chromium.base.PathUtils; +import org.chromium.base.annotations.JNINamespace; import org.chromium.base.test.util.Feature; +import org.chromium.net.impl.CronetUrlRequestContext; +import org.chromium.net.test.EmbeddedTestServer; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.URL; /** * Tests for experimental options. */ +@JNINamespace("cronet") public class ExperimentalOptionsTest extends CronetTestBase { private static final String TAG = ExperimentalOptionsTest.class.getSimpleName(); private ExperimentalCronetEngine.Builder mBuilder; @@ -135,4 +140,62 @@ } return false; } + + @MediumTest + @Feature({"Cronet"}) + @OnlyRunNativeCronet + // Tests that basic Cronet functionality works when host cache persistence is enabled, and that + // persistence works. + public void testHostCachePersistence() throws Exception { + EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(getContext()); + + String realUrl = testServer.getURL("/echo?status=200"); + URL javaUrl = new URL(realUrl); + String realHost = javaUrl.getHost(); + int realPort = javaUrl.getPort(); + String testHost = "host-cache-test-host"; + String testUrl = new URL("http", testHost, realPort, javaUrl.getPath()).toString(); + + mBuilder.setStoragePath(getTestStorage(getContext())); + + // Set a short delay so the pref gets written quickly. + JSONObject staleDns = new JSONObject() + .put("enable", true) + .put("delay_ms", 0) + .put("allow_other_network", true) + .put("persist_to_disk", true) + .put("persist_delay_ms", 0); + JSONObject experimentalOptions = new JSONObject().put("StaleDNS", staleDns); + mBuilder.setExperimentalOptions(experimentalOptions.toString()); + CronetUrlRequestContext context = (CronetUrlRequestContext) mBuilder.build(); + + // Create a HostCache entry for "host-cache-test-host". + nativeWriteToHostCache(context.getUrlRequestContextAdapter(), realHost); + + // Do a request for the test URL to make sure it's cached. + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder builder = + context.newUrlRequestBuilder(testUrl, callback, callback.getExecutor()); + UrlRequest urlRequest = builder.build(); + urlRequest.start(); + callback.blockForDone(); + assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); + + // Shut down the context, persisting contents to disk, and build a new one. + context.shutdown(); + context = (CronetUrlRequestContext) mBuilder.build(); + + // Use the test URL without creating a new cache entry first. It should use the persisted + // one. + callback = new TestUrlRequestCallback(); + builder = context.newUrlRequestBuilder(testUrl, callback, callback.getExecutor()); + urlRequest = builder.build(); + urlRequest.start(); + callback.blockForDone(); + assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); + } + + // Sets a host cache entry with hostname "host-cache-test-host" and an AddressList containing + // the provided address. + private static native void nativeWriteToHostCache(long adapter, String address); }
diff --git a/components/cronet/ios/Cronet.h b/components/cronet/ios/Cronet.h index cd8483b..920cace 100644 --- a/components/cronet/ios/Cronet.h +++ b/components/cronet/ios/Cronet.h
@@ -22,7 +22,7 @@ /// Enum of Cronet NSError codes. NS_ENUM(NSInteger){ - CRNErrorInvalidArgument = 1001, + CRNErrorInvalidArgument = 1001, CRNErrorUnsupportedConfig = 1002, }; /// The corresponding value is a String object that contains the name of
diff --git a/components/cronet/ios/Cronet.mm b/components/cronet/ios/Cronet.mm index 9c827d2..e7cc88b 100644 --- a/components/cronet/ios/Cronet.mm +++ b/components/cronet/ios/Cronet.mm
@@ -38,6 +38,9 @@ base::LazyInstance<std::unique_ptr<cronet::CronetEnvironment>>::Leaky gChromeNet = LAZY_INSTANCE_INITIALIZER; +// TODO(lilyhoughton) make these independent across Cronet instances, i.e.: +// refresh them on shutdown, and add tests to make sure the defaults are +// sane. BOOL gHttp2Enabled = YES; BOOL gQuicEnabled = NO; cronet::URLRequestContextConfig::HttpCacheType gHttpCache = @@ -52,9 +55,10 @@ base::LazyInstance<std::unique_ptr<CronetHttpProtocolHandlerDelegate>>::Leaky gHttpProtocolHandlerDelegate = LAZY_INSTANCE_INITIALIZER; NSURLCache* gPreservedSharedURLCache = nil; -BOOL gEnableTestCertVerifierForTesting = FALSE; +BOOL gEnableTestCertVerifierForTesting = NO; std::unique_ptr<net::CertVerifier> gMockCertVerifier; NSString* gAcceptLanguages = nil; +BOOL gEnablePKPBypassForLocalTrustAnchors = YES; // CertVerifier, which allows any certificates for testing. class TestCertVerifier : public net::CertVerifier { @@ -229,6 +233,14 @@ error:(NSError**)outError { [self checkNotStarted]; + // Pinning a key only makes sense if pin bypassing has been disabled + if (gEnablePKPBypassForLocalTrustAnchors) { + *outError = + [self createUnsupportedConfigurationError: + @"Cannot pin keys while public key pinning is bypassed"]; + return NO; + } + auto pkp = base::MakeUnique<cronet::URLRequestContextConfig::Pkp>( base::SysNSStringToUTF8(host), includeSubdomains, base::Time::FromCFAbsoluteTime( @@ -254,6 +266,10 @@ return YES; } ++ (void)setEnablePublicKeyPinningBypassForLocalTrustAnchors:(BOOL)enable { + gEnablePKPBypassForLocalTrustAnchors = enable; +} + + (void)startInternal { std::string user_agent = base::SysNSStringToUTF8(gUserAgent); @@ -271,6 +287,9 @@ gChromeNet.Get()->set_ssl_key_log_file_name( base::SysNSStringToUTF8(gSslKeyLogFileName)); gChromeNet.Get()->set_pkp_list(std::move(gPkpList)); + gChromeNet.Get() + ->set_enable_public_key_pinning_bypass_for_local_trust_anchors( + gEnablePKPBypassForLocalTrustAnchors); for (const auto& quicHint : gQuicHints) { gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port, quicHint->alternate_port); @@ -412,12 +431,30 @@ if (reason) { errorDictionary[NSLocalizedFailureReasonErrorKey] = reason; } - return [self createCronetErrorWith:CRNErrorInvalidArgument - userInfo:errorDictionary]; + return [self createCronetErrorWithCode:CRNErrorInvalidArgument + userInfo:errorDictionary]; } -+ (NSError*)createCronetErrorWith:(int)errorCode - userInfo:(NSDictionary*)userInfo { ++ (NSError*)createUnsupportedConfigurationError:(NSString*)contradiction { + NSMutableDictionary* errorDictionary = + [[NSMutableDictionary alloc] initWithDictionary:@{ + NSLocalizedDescriptionKey : @"Unsupported configuration", + NSLocalizedRecoverySuggestionErrorKey : + @"Try disabling Public Key Pinning Bypass before pinning keys.", + NSLocalizedFailureReasonErrorKey : @"Pinning public keys while local " + @"anchor bypass is enabled is " + @"currently not supported.", + }]; + if (contradiction) { + errorDictionary[NSLocalizedFailureReasonErrorKey] = contradiction; + } + + return [self createCronetErrorWithCode:CRNErrorUnsupportedConfig + userInfo:errorDictionary]; +} + ++ (NSError*)createCronetErrorWithCode:(int)errorCode + userInfo:(NSDictionary*)userInfo { return [NSError errorWithDomain:CRNCronetErrorDomain code:errorCode userInfo:userInfo];
diff --git a/components/cronet/ios/cronet_environment.h b/components/cronet/ios/cronet_environment.h index 8363025..8f4adc7 100644 --- a/components/cronet/ios/cronet_environment.h +++ b/components/cronet/ios/cronet_environment.h
@@ -105,6 +105,11 @@ void set_pkp_list(PkpVector pkp_list) { pkp_list_ = std::move(pkp_list); } + void set_enable_public_key_pinning_bypass_for_local_trust_anchors( + bool enable) { + enable_pkp_bypass_for_local_trust_anchors_ = enable; + } + // Returns the URLRequestContext associated with this object. net::URLRequestContext* GetURLRequestContext() const; @@ -162,6 +167,7 @@ bool user_agent_partial_; std::unique_ptr<net::NetLog> net_log_; std::unique_ptr<net::WriteToFileNetLogObserver> net_log_observer_; + bool enable_pkp_bypass_for_local_trust_anchors_; DISALLOW_COPY_AND_ASSIGN(CronetEnvironment); };
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm index be5ee3c..1e04229 100644 --- a/components/cronet/ios/cronet_environment.mm +++ b/components/cronet/ios/cronet_environment.mm
@@ -222,7 +222,8 @@ http_cache_(URLRequestContextConfig::HttpCacheType::DISK), user_agent_(user_agent), user_agent_partial_(user_agent_partial), - net_log_(new net::NetLog) {} + net_log_(new net::NetLog), + enable_pkp_bypass_for_local_trust_anchors_(true) {} void CronetEnvironment::Start() { // Threads setup. @@ -349,7 +350,11 @@ main_context_ = context_builder.Build(); - // Iterate through PKP configuration for every host. + main_context_->transport_security_state() + ->SetEnablePublicKeyPinningBypassForLocalTrustAnchors( + enable_pkp_bypass_for_local_trust_anchors_); + + // Iterate trhough PKP configuration for every host. for (const auto& pkp : config->pkp_list) { // Add the host pinning. main_context_->transport_security_state()->AddHPKP(
diff --git a/components/cronet/ios/test/cronet_pkp_test.mm b/components/cronet/ios/test/cronet_pkp_test.mm index 962a54ec1..79a9706b 100644 --- a/components/cronet/ios/test/cronet_pkp_test.mm +++ b/components/cronet/ios/test/cronet_pkp_test.mm
@@ -78,6 +78,7 @@ NSData* hash, BOOL include_subdomains, NSDate* expiration_date) { + [Cronet setEnablePublicKeyPinningBypassForLocalTrustAnchors:NO]; NSSet* hashes = [NSSet setWithObject:hash]; NSError* error; BOOL success = [Cronet addPublicKeyPinsForHost:host @@ -141,6 +142,21 @@ ASSERT_NO_FATAL_FAILURE(sendRequestAndAssertResult(request_url_, kSuccess)); } +TEST_F(PkpTest, TestBypass) { + [Cronet setEnablePublicKeyPinningBypassForLocalTrustAnchors:YES]; + + NSSet* hashes = [NSSet setWithObject:NonMatchingHash()]; + NSError* error; + BOOL success = [Cronet addPublicKeyPinsForHost:server_host_ + pinHashes:hashes + includeSubdomains:kExcludeSubdomains + expirationDate:(NSDate*)kDistantFuture + error:&error]; + + EXPECT_FALSE(success); + EXPECT_EQ([error code], CRNErrorUnsupportedConfig); +} + // Tests the case when the pin hash does not match and the client accesses the // subdomain of the configured PKP host with includeSubdomains flag set to true. // The client is expected to receive the error response.
diff --git a/components/cronet/ios/test/cronet_test_base.h b/components/cronet/ios/test/cronet_test_base.h index 770b980b..8735f07 100644 --- a/components/cronet/ios/test/cronet_test_base.h +++ b/components/cronet/ios/test/cronet_test_base.h
@@ -17,6 +17,7 @@ + (void)shutdownForTesting; + (void)setMockCertVerifierForTesting: (std::unique_ptr<net::CertVerifier>)certVerifier; ++ (void)setEnablePublicKeyPinningBypassForLocalTrustAnchors:(BOOL)enable; @end // NSURLSessionDataDelegate delegate implementation used by the tests to
diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc index e4b4a773..432fb1eb 100644 --- a/components/cronet/url_request_context_config.cc +++ b/components/cronet/url_request_context_config.cc
@@ -73,6 +73,12 @@ // Name of boolean to allow stale DNS results from other networks to be used on // the current network. const char kStaleDnsAllowOtherNetwork[] = "allow_other_network"; +// Name of boolean to enable persisting the DNS cache to disk. +const char kStaleDnsPersist[] = "persist_to_disk"; +// Name of integer minimum time in milliseconds between writes to disk for DNS +// cache persistence. Default value is one minute. Only relevant if +// "persist_to_disk" is true. +const char kStaleDnsPersistTimer[] = "persist_delay_ms"; // Rules to override DNS resolution. Intended for testing. // See explanation of format in net/dns/mapped_host_resolver.h. @@ -292,6 +298,12 @@ &allow_other_network)) { stale_dns_options.allow_other_network = allow_other_network; } + bool persist; + if (stale_dns_args->GetBoolean(kStaleDnsPersist, &persist)) + enable_host_cache_persistence = persist; + int persist_timer; + if (stale_dns_args->GetInteger(kStaleDnsPersistTimer, &persist_timer)) + host_cache_persistence_delay_ms = persist_timer; } } else if (it.key() == kHostResolverRulesFieldTrialName) { const base::DictionaryValue* host_resolver_rules_args = nullptr;
diff --git a/components/cronet/url_request_context_config.h b/components/cronet/url_request_context_config.h index 7b13833..51eb80b6 100644 --- a/components/cronet/url_request_context_config.h +++ b/components/cronet/url_request_context_config.h
@@ -167,6 +167,13 @@ // The list of public key pins. std::vector<std::unique_ptr<Pkp>> pkp_list; + // Enable DNS cache persistence. + bool enable_host_cache_persistence = false; + + // Minimum time in milliseconds between writing the HostCache contents to + // prefs. Only relevant when |enable_host_cache_persistence| is true. + int host_cache_persistence_delay_ms = 60000; + // Experimental options that are recognized by the config parser. std::unique_ptr<base::DictionaryValue> effective_experimental_options = nullptr;
diff --git a/components/cryptauth/cryptauth_device_manager.cc b/components/cryptauth/cryptauth_device_manager.cc index 0fa6a82..a12def4 100644 --- a/components/cryptauth/cryptauth_device_manager.cc +++ b/components/cryptauth/cryptauth_device_manager.cc
@@ -297,6 +297,14 @@ return true; } +std::unique_ptr<SyncSchedulerImpl> CreateSyncScheduler( + SyncScheduler::Delegate* delegate) { + return base::MakeUnique<SyncSchedulerImpl>( + delegate, base::TimeDelta::FromHours(kRefreshPeriodHours), + base::TimeDelta::FromMinutes(kDeviceSyncBaseRecoveryPeriodMinutes), + kDeviceSyncMaxJitterRatio, "CryptAuth DeviceSync"); +} + } // namespace CryptAuthDeviceManager::CryptAuthDeviceManager( @@ -308,6 +316,7 @@ client_factory_(std::move(client_factory)), gcm_manager_(gcm_manager), pref_service_(pref_service), + scheduler_(CreateSyncScheduler(this)), weak_ptr_factory_(this) { UpdateUnlockKeysFromPrefs(); } @@ -349,7 +358,6 @@ prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure) || last_successful_sync.is_null(); - scheduler_ = CreateSyncScheduler(); scheduler_->Start(elapsed_time_since_last_sync, is_recovering_from_failure ? SyncScheduler::Strategy::AGGRESSIVE_RECOVERY @@ -474,13 +482,6 @@ observer.OnSyncFinished(SyncResult::FAILURE, DeviceChangeResult::UNCHANGED); } -std::unique_ptr<SyncScheduler> CryptAuthDeviceManager::CreateSyncScheduler() { - return base::MakeUnique<SyncSchedulerImpl>( - this, base::TimeDelta::FromHours(kRefreshPeriodHours), - base::TimeDelta::FromMinutes(kDeviceSyncBaseRecoveryPeriodMinutes), - kDeviceSyncMaxJitterRatio, "CryptAuth DeviceSync"); -} - void CryptAuthDeviceManager::OnResyncMessage() { ForceSyncNow(INVOCATION_REASON_SERVER_INITIATED); }
diff --git a/components/cryptauth/cryptauth_device_manager.h b/components/cryptauth/cryptauth_device_manager.h index a728f24..af57063 100644 --- a/components/cryptauth/cryptauth_device_manager.h +++ b/components/cryptauth/cryptauth_device_manager.h
@@ -119,8 +119,9 @@ // use this constructor outside of tests. CryptAuthDeviceManager(); - // Creates a new SyncScheduler instance. Exposed for testing. - virtual std::unique_ptr<SyncScheduler> CreateSyncScheduler(); + void SetSyncSchedulerForTest(std::unique_ptr<SyncScheduler> sync_scheduler) { + scheduler_ = std::move(sync_scheduler); + } private: // CryptAuthGCMManager::Observer:
diff --git a/components/cryptauth/cryptauth_device_manager_unittest.cc b/components/cryptauth/cryptauth_device_manager_unittest.cc index fa1f146..0c6ae094 100644 --- a/components/cryptauth/cryptauth_device_manager_unittest.cc +++ b/components/cryptauth/cryptauth_device_manager_unittest.cc
@@ -297,23 +297,20 @@ gcm_manager, pref_service), scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()), - weak_sync_scheduler_factory_(scoped_sync_scheduler_.get()) {} + weak_sync_scheduler_factory_(scoped_sync_scheduler_) { + SetSyncSchedulerForTest(base::WrapUnique(scoped_sync_scheduler_)); + } ~TestCryptAuthDeviceManager() override {} - std::unique_ptr<SyncScheduler> CreateSyncScheduler() override { - EXPECT_TRUE(scoped_sync_scheduler_); - return std::move(scoped_sync_scheduler_); - } - base::WeakPtr<MockSyncScheduler> GetSyncScheduler() { return weak_sync_scheduler_factory_.GetWeakPtr(); } private: // Ownership is passed to |CryptAuthDeviceManager| super class when - // |CreateSyncScheduler()| is called. - std::unique_ptr<MockSyncScheduler> scoped_sync_scheduler_; + // SetSyncSchedulerForTest() is called. + MockSyncScheduler* scoped_sync_scheduler_; // Stores the pointer of |scoped_sync_scheduler_| after ownership is passed to // the super class.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc index b7683d29..3812a8d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc
@@ -40,6 +40,10 @@ int64_t original_bytes_; }; +// Hostname used for the other bucket which consists of chrome-services traffic. +// This should be in sync with the same in DataReductionSiteBreakdownView.java +const char kOtherHostName[] = "Other"; + // static const void* DataUseUserDataBytes::kUserDataKey = &DataUseUserDataBytes::kUserDataKey; @@ -84,16 +88,14 @@ data_use_measurement::DataUse* data_use) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (data_use->traffic_type() != - data_use_measurement::DataUse::TrafficType::USER_TRAFFIC) { - return; - } - if (!request.url().SchemeIs(url::kHttpsScheme) && !request.url().SchemeIs(url::kHttpScheme)) { return; } + if (request.GetTotalReceivedBytes() <= 0) + return; + int64_t network_bytes = request.GetTotalReceivedBytes(); DataReductionProxyRequestType request_type = GetDataReductionProxyRequestType( request, data_reduction_proxy_io_data_->configurator()->GetProxyConfig(), @@ -105,7 +107,9 @@ request, request_type == VIA_DATA_REDUCTION_PROXY, data_reduction_proxy_io_data_->lofi_decider()); - if (!data_use->url().is_valid()) { + if (data_use->traffic_type() == + data_use_measurement::DataUse::TrafficType::USER_TRAFFIC && + !data_use->url().is_valid()) { // URL will be empty until pageload navigation commits. Save the data use of // these mainframe, subresource, redirected requests in user data until // then. @@ -120,7 +124,11 @@ } } else { data_reduction_proxy_io_data_->UpdateDataUseForHost( - network_bytes, original_bytes, data_use->url().HostNoBrackets()); + network_bytes, original_bytes, + data_use->traffic_type() == + data_use_measurement::DataUse::TrafficType::USER_TRAFFIC + ? data_use->url().HostNoBrackets() + : kOtherHostName); } }
diff --git a/components/exo/layer_tree_frame_sink_holder.cc b/components/exo/layer_tree_frame_sink_holder.cc index a71950a..f7920103 100644 --- a/components/exo/layer_tree_frame_sink_holder.cc +++ b/components/exo/layer_tree_frame_sink_holder.cc
@@ -45,6 +45,14 @@ release_callbacks_[id] = callback; } +int LayerTreeFrameSinkHolder::AllocateResourceId() { + return next_resource_id_++; +} + +base::WeakPtr<LayerTreeFrameSinkHolder> LayerTreeFrameSinkHolder::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + //////////////////////////////////////////////////////////////////////////////// // cc::LayerTreeFrameSinkClient overrides:
diff --git a/components/exo/layer_tree_frame_sink_holder.h b/components/exo/layer_tree_frame_sink_holder.h index cb16cdd7..60dd085 100644 --- a/components/exo/layer_tree_frame_sink_holder.h +++ b/components/exo/layer_tree_frame_sink_holder.h
@@ -33,12 +33,10 @@ bool HasReleaseCallbackForResource(cc::ResourceId id); void SetResourceReleaseCallback(cc::ResourceId id, const cc::ReleaseCallback& callback); + int AllocateResourceId(); + base::WeakPtr<LayerTreeFrameSinkHolder> GetWeakPtr(); - cc::LayerTreeFrameSink* GetLayerTreeFrameSink() { return frame_sink_.get(); } - - base::WeakPtr<LayerTreeFrameSinkHolder> GetWeakPtr() { - return weak_factory_.GetWeakPtr(); - } + cc::LayerTreeFrameSink* frame_sink() { return frame_sink_.get(); } // Overridden from cc::LayerTreeFrameSinkClient: void SetBeginFrameSource(cc::BeginFrameSource* source) override; @@ -65,6 +63,9 @@ Surface* surface_; std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_; + // The next resource id the buffer is attached to. + int next_resource_id_ = 1; + base::WeakPtrFactory<LayerTreeFrameSinkHolder> weak_factory_; DISALLOW_COPY_AND_ASSIGN(LayerTreeFrameSinkHolder);
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 5184110..4f6ab06 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -447,8 +447,8 @@ if (current_begin_frame_ack_.sequence_number != cc::BeginFrameArgs::kInvalidFrameNumber) { if (!current_begin_frame_ack_.has_damage) { - layer_tree_frame_sink_holder_->GetLayerTreeFrameSink() - ->DidNotProduceFrame(current_begin_frame_ack_); + layer_tree_frame_sink_holder_->frame_sink()->DidNotProduceFrame( + current_begin_frame_ack_); } current_begin_frame_ack_.sequence_number = cc::BeginFrameArgs::kInvalidFrameNumber; @@ -744,7 +744,8 @@ void Surface::UpdateResource(bool client_usage) { if (current_buffer_.buffer() && current_buffer_.buffer()->ProduceTransferableResource( - layer_tree_frame_sink_holder_.get(), next_resource_id_++, + layer_tree_frame_sink_holder_.get(), + layer_tree_frame_sink_holder_->AllocateResourceId(), state_.only_visible_on_secure_output, client_usage, ¤t_resource_)) { current_resource_has_alpha_ = @@ -859,7 +860,7 @@ } frame.render_pass_list.push_back(std::move(render_pass)); - layer_tree_frame_sink_holder_->GetLayerTreeFrameSink()->SubmitCompositorFrame( + layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame( std::move(frame)); }
diff --git a/components/exo/surface.h b/components/exo/surface.h index 6c9fa64c..c6037f0 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -304,9 +304,6 @@ std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_; - // The next resource id the buffer will be attached to. - int next_resource_id_ = 1; - // The damage region to schedule paint for when Commit() is called. SkRegion pending_damage_;
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn index 55aae92..4a851040 100644 --- a/components/exo/wayland/BUILD.gn +++ b/components/exo/wayland/BUILD.gn
@@ -58,10 +58,7 @@ ] if (use_ozone) { - deps += [ - "//third_party/mesa:wayland_drm_protocol", - "//third_party/wayland-protocols:linux_dmabuf_protocol", - ] + deps += [ "//third_party/wayland-protocols:linux_dmabuf_protocol" ] configs += [ ":libdrm" ] if (is_chromeos) {
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index d477e07c..cbc0be7 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -84,7 +84,6 @@ #if defined(USE_OZONE) #include <drm_fourcc.h> #include <linux-dmabuf-unstable-v1-server-protocol.h> -#include <wayland-drm-server-protocol.h> #if defined(OS_CHROMEOS) #include "ui/base/ime/chromeos/ime_keyboard.h" #include "ui/base/ime/chromeos/input_method_manager.h" @@ -482,128 +481,6 @@ #if defined(USE_OZONE) //////////////////////////////////////////////////////////////////////////////// -// wl_drm_interface: - -const struct drm_supported_format { - uint32_t drm_format; - gfx::BufferFormat buffer_format; -} drm_supported_formats[] = { - {WL_DRM_FORMAT_RGB565, gfx::BufferFormat::BGR_565}, - {WL_DRM_FORMAT_XBGR8888, gfx::BufferFormat::RGBX_8888}, - {WL_DRM_FORMAT_ABGR8888, gfx::BufferFormat::RGBA_8888}, - {WL_DRM_FORMAT_XRGB8888, gfx::BufferFormat::BGRX_8888}, - {WL_DRM_FORMAT_ARGB8888, gfx::BufferFormat::BGRA_8888}, - {WL_DRM_FORMAT_NV12, gfx::BufferFormat::YUV_420_BIPLANAR}, - {WL_DRM_FORMAT_YVU420, gfx::BufferFormat::YVU_420}}; - -void drm_authenticate(wl_client* client, wl_resource* resource, uint32_t id) { - wl_drm_send_authenticated(resource); -} - -void drm_create_buffer(wl_client* client, - wl_resource* resource, - uint32_t id, - uint32_t name, - int32_t width, - int32_t height, - uint32_t stride, - uint32_t format) { - wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_NAME, - "GEM names are not supported"); -} - -void drm_create_planar_buffer(wl_client* client, - wl_resource* resource, - uint32_t id, - uint32_t name, - int32_t width, - int32_t height, - uint32_t format, - int32_t offset0, - int32_t stride0, - int32_t offset1, - int32_t stride1, - int32_t offset2, - int32_t stride3) { - wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_NAME, - "GEM names are not supported"); -} - -void drm_create_prime_buffer(wl_client* client, - wl_resource* resource, - uint32_t id, - int32_t name, - int32_t width, - int32_t height, - uint32_t format, - int32_t offset0, - int32_t stride0, - int32_t offset1, - int32_t stride1, - int32_t offset2, - int32_t stride2) { - const auto* supported_format = - std::find_if(drm_supported_formats, - drm_supported_formats + arraysize(drm_supported_formats), - [format](const drm_supported_format& supported_format) { - return supported_format.drm_format == format; - }); - if (supported_format == - (drm_supported_formats + arraysize(drm_supported_formats))) { - wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_FORMAT, - "invalid format 0x%x", format); - return; - } - - std::vector<gfx::NativePixmapPlane> planes; - planes.emplace_back(stride0, offset0, 0, 0); - planes.emplace_back(stride1, offset1, 0, 0); - planes.emplace_back(stride2, offset2, 0, 0); - std::vector<base::ScopedFD> fds; - - size_t num_planes = - gfx::NumberOfPlanesForBufferFormat(supported_format->buffer_format); - planes.resize(num_planes); - fds.push_back(base::ScopedFD(name)); - - std::unique_ptr<Buffer> buffer = - GetUserDataAs<Display>(resource)->CreateLinuxDMABufBuffer( - gfx::Size(width, height), supported_format->buffer_format, planes, - std::move(fds)); - if (!buffer) { - wl_resource_post_no_memory(resource); - return; - } - - wl_resource* buffer_resource = - wl_resource_create(client, &wl_buffer_interface, 1, id); - - buffer->set_release_callback(base::Bind(&HandleBufferReleaseCallback, - base::Unretained(buffer_resource))); - - SetImplementation(buffer_resource, &buffer_implementation, std::move(buffer)); -} - -const struct wl_drm_interface drm_implementation = { - drm_authenticate, drm_create_buffer, drm_create_planar_buffer, - drm_create_prime_buffer}; - -const uint32_t drm_version = 2; - -void bind_drm(wl_client* client, void* data, uint32_t version, uint32_t id) { - wl_resource* resource = wl_resource_create( - client, &wl_drm_interface, std::min(version, drm_version), id); - - wl_resource_set_implementation(resource, &drm_implementation, data, nullptr); - - if (version >= 2) - wl_drm_send_capabilities(resource, WL_DRM_CAPABILITY_PRIME); - - for (const auto& supported_format : drm_supported_formats) - wl_drm_send_format(resource, supported_format.drm_format); -} - -//////////////////////////////////////////////////////////////////////////////// // linux_buffer_params_interface: const struct dmabuf_supported_format { @@ -4094,8 +3971,6 @@ compositor_version, display_, bind_compositor); wl_global_create(wl_display_.get(), &wl_shm_interface, 1, display_, bind_shm); #if defined(USE_OZONE) - wl_global_create(wl_display_.get(), &wl_drm_interface, drm_version, display_, - bind_drm); wl_global_create(wl_display_.get(), &zwp_linux_dmabuf_v1_interface, 2, display_, bind_linux_dmabuf); #endif
diff --git a/components/favicon/content/content_favicon_driver.cc b/components/favicon/content/content_favicon_driver.cc index ece84e5..09b45ef 100644 --- a/components/favicon/content/content_favicon_driver.cc +++ b/components/favicon/content/content_favicon_driver.cc
@@ -210,7 +210,9 @@ return; favicon_urls_.reset(); - manifest_url_ = GURL(); + + if (!navigation_handle->IsSameDocument()) + manifest_url_ = GURL(); content::ReloadType reload_type = navigation_handle->GetReloadType(); if (reload_type == content::ReloadType::NONE || IsOffTheRecord())
diff --git a/components/feature_engagement_tracker/public/feature_constants.cc b/components/feature_engagement_tracker/public/feature_constants.cc index d372beca..d9669ba 100644 --- a/components/feature_engagement_tracker/public/feature_constants.cc +++ b/components/feature_engagement_tracker/public/feature_constants.cc
@@ -13,19 +13,21 @@ base::FEATURE_DISABLED_BY_DEFAULT}; #if defined(OS_ANDROID) -const base::Feature kIPHDataSaverPreviewFeature{ - "IPH_DataSaverPreview", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHDataSaverDetailFeature{ "IPH_DataSaverDetail", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kIPHDownloadPageFeature{"IPH_DownloadPage", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHDataSaverPreviewFeature{ + "IPH_DataSaverPreview", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHDownloadHomeFeature{"IPH_DownloadHome", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif // OS_ANDROID +const base::Feature kIPHDownloadPageFeature{"IPH_DownloadPage", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // defined(OS_ANDROID) -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) +const base::Feature kIPHIncognitoWindowFeature{ + "IPH_IncognitoWindow", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHNewTabFeature{"IPH_NewTab", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif // OS_WIN +#endif // defined(OS_WIN) || defined(OS_LINUX) } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/public/feature_constants.h b/components/feature_engagement_tracker/public/feature_constants.h index 2c4cc38..baf93f3 100644 --- a/components/feature_engagement_tracker/public/feature_constants.h +++ b/components/feature_engagement_tracker/public/feature_constants.h
@@ -20,15 +20,16 @@ // should also be declared in: // org.chromium.components.feature_engagement_tracker.FeatureConstants. #if defined(OS_ANDROID) -extern const base::Feature kIPHDataSaverPreviewFeature; extern const base::Feature kIPHDataSaverDetailFeature; -extern const base::Feature kIPHDownloadPageFeature; +extern const base::Feature kIPHDataSaverPreviewFeature; extern const base::Feature kIPHDownloadHomeFeature; -#endif // OS_ANDROID +extern const base::Feature kIPHDownloadPageFeature; +#endif // defined(OS_ANDROID) -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) +extern const base::Feature kIPHIncognitoWindowFeature; extern const base::Feature kIPHNewTabFeature; -#endif // OS_WIN +#endif // defined(OS_WIN) || defined(OS_LINUX) } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/public/feature_list.cc b/components/feature_engagement_tracker/public/feature_list.cc index aa9a67a..976ff40 100644 --- a/components/feature_engagement_tracker/public/feature_list.cc +++ b/components/feature_engagement_tracker/public/feature_list.cc
@@ -15,14 +15,15 @@ const base::Feature* kAllFeatures[] = { &kIPHDummyFeature, // Ensures non-empty array for all platforms. #if defined(OS_ANDROID) - &kIPHDataSaverPreviewFeature, &kIPHDataSaverDetailFeature, - &kIPHDownloadPageFeature, + &kIPHDataSaverPreviewFeature, &kIPHDownloadHomeFeature, -#endif // OS_ANDROID -#if defined(OS_WIN) + &kIPHDownloadPageFeature, +#endif // defined(OS_ANDROID) +#if defined(OS_WIN) || defined(OS_LINUX) + &kIPHIncognitoWindowFeature, &kIPHNewTabFeature, -#endif // OS_WIN +#endif // defined(OS_WIN) || defined(OS_LINUX) }; } // namespace
diff --git a/components/feature_engagement_tracker/public/feature_list.h b/components/feature_engagement_tracker/public/feature_list.h index 78642ddb..cdb15d0 100644 --- a/components/feature_engagement_tracker/public/feature_list.h +++ b/components/feature_engagement_tracker/public/feature_list.h
@@ -45,14 +45,15 @@ // Defines a flags_ui::FeatureEntry::FeatureParam for each feature. DEFINE_VARIATION_PARAM(kIPHDummyFeature, "IPH_Dummy"); #if defined(OS_ANDROID) -DEFINE_VARIATION_PARAM(kIPHDataSaverPreviewFeature, "IPH_DataSaverPreview"); DEFINE_VARIATION_PARAM(kIPHDataSaverDetailFeature, "IPH_DataSaverDetail"); -DEFINE_VARIATION_PARAM(kIPHDownloadPageFeature, "IPH_DownloadPage"); +DEFINE_VARIATION_PARAM(kIPHDataSaverPreviewFeature, "IPH_DataSaverPreview"); DEFINE_VARIATION_PARAM(kIPHDownloadHomeFeature, "IPH_DownloadHome"); -#endif // OS_ANDROID -#if defined(OS_WIN) +DEFINE_VARIATION_PARAM(kIPHDownloadPageFeature, "IPH_DownloadPage"); +#endif // defined(OS_ANDROID) +#if defined(OS_WIN) || defined(OS_LINUX) +DEFINE_VARIATION_PARAM(kIPHIncognitoWindowFeature, "IPH_IncognitoWindow"); DEFINE_VARIATION_PARAM(kIPHNewTabFeature, "IPH_NewTab"); -#endif // OS_WIN +#endif // defined(OS_WIN) || defined(OS_LINUX) } // namespace @@ -62,11 +63,12 @@ constexpr flags_ui::FeatureEntry::FeatureVariation kIPHDemoModeChoiceVariations[] = { #if defined(OS_ANDROID) - VARIATION_ENTRY(kIPHDataSaverPreviewFeature), VARIATION_ENTRY(kIPHDataSaverDetailFeature), - VARIATION_ENTRY(kIPHDownloadPageFeature), + VARIATION_ENTRY(kIPHDataSaverPreviewFeature), VARIATION_ENTRY(kIPHDownloadHomeFeature), -#elif defined(OS_WIN) + VARIATION_ENTRY(kIPHDownloadPageFeature), +#elif defined(OS_WIN) || defined(OS_LINUX) + VARIATION_ENTRY(kIPHIncognitoWindowFeature), VARIATION_ENTRY(kIPHNewTabFeature), #else VARIATION_ENTRY(kIPHDummyFeature), // Ensures non-empty array.
diff --git a/components/offline_pages/core/prefetch/BUILD.gn b/components/offline_pages/core/prefetch/BUILD.gn index 4604e9c4..b45caac 100644 --- a/components/offline_pages/core/prefetch/BUILD.gn +++ b/components/offline_pages/core/prefetch/BUILD.gn
@@ -61,6 +61,7 @@ "//components/ntp_snippets", "//components/offline_pages/core", "//components/offline_pages/core:switches", + "//components/variations:variations", "//components/version_info", "//google_apis", "//net:net", @@ -120,6 +121,7 @@ "prefetch_network_request_factory_impl_unittest.cc", "prefetch_request_fetcher_unittest.cc", "prefetch_request_operation_response_unittest.cc", + "prefetch_server_urls_unittest.cc", "suggested_articles_observer_unittest.cc", ] @@ -131,6 +133,7 @@ "//components/offline_pages/core", "//components/offline_pages/core:switches", "//components/offline_pages/core:test_support", + "//components/variations:test_support", "//components/version_info:channel", "//net:test_support", "//testing/gmock",
diff --git a/components/offline_pages/core/prefetch/DEPS b/components/offline_pages/core/prefetch/DEPS index 5214a88..2bebfd7 100644 --- a/components/offline_pages/core/prefetch/DEPS +++ b/components/offline_pages/core/prefetch/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/download/public", "+google_apis", + "+components/variations", "+components/gcm_driver", "+components/ntp_snippets", "+components/version_info",
diff --git a/components/offline_pages/core/prefetch/prefetch_server_urls.cc b/components/offline_pages/core/prefetch/prefetch_server_urls.cc index 84135e6ba..fc430b1d 100644 --- a/components/offline_pages/core/prefetch/prefetch_server_urls.cc +++ b/components/offline_pages/core/prefetch/prefetch_server_urls.cc
@@ -4,17 +4,18 @@ #include "components/offline_pages/core/prefetch/prefetch_server_urls.h" +#include "components/offline_pages/core/offline_page_feature.h" +#include "components/variations/variations_associated_data.h" #include "google_apis/google_api_keys.h" #include "net/base/url_util.h" namespace offline_pages { +const char kPrefetchServer[] = "https://offlinepages-pa.googleapis.com/"; + namespace { -const char kPrefetchServer[] = "https://offlinepages-pa.googleapis.com/"; -const char kPrefetchStagingServer[] = - "https://staging-offlinepages-pa.sandbox.googleapis.com/"; - +const char kOfflinePagesBackend[] = "offline_pages_backend"; const char kGeneratePageBundleRequestURLPath[] = "v1:GeneratePageBundle"; const char kGetOperationLeadingURLPath[] = "v1/"; const char kDownloadLeadingURLPath[] = "v1/media/"; @@ -25,14 +26,20 @@ const char kAltKeyName[] = "alt"; const char kAltKeyValueForDownload[] = "media"; -GURL GetServerURLForPath(const std::string& url_path, - version_info::Channel channel) { - bool is_stable_channel = channel == version_info::Channel::STABLE; - GURL server_url(is_stable_channel ? kPrefetchServer : kPrefetchStagingServer); +GURL GetServerURL() { + GURL endpoint(variations::GetVariationParamValueByFeature( + offline_pages::kPrefetchingOfflinePagesFeature, kOfflinePagesBackend)); + // |is_valid| returns false for bad URLs and also for empty URLs. + return endpoint.is_valid() && endpoint.SchemeIsCryptographic() + ? endpoint + : GURL(kPrefetchServer); +} + +GURL GetServerURLForPath(const std::string& url_path) { GURL::Replacements replacements; replacements.SetPathStr(url_path); - return server_url.ReplaceComponents(replacements); + return GetServerURL().ReplaceComponents(replacements); } GURL AppendApiKeyToURL(const GURL& url, version_info::Channel channel) { @@ -45,22 +52,21 @@ } // namespace GURL GeneratePageBundleRequestURL(version_info::Channel channel) { - GURL server_url = - GetServerURLForPath(kGeneratePageBundleRequestURLPath, channel); + GURL server_url = GetServerURLForPath(kGeneratePageBundleRequestURLPath); return AppendApiKeyToURL(server_url, channel); } GURL GetOperationRequestURL(const std::string& name, version_info::Channel channel) { std::string url_path = kGetOperationLeadingURLPath + name; - GURL server_url = GetServerURLForPath(url_path, channel); + GURL server_url = GetServerURLForPath(url_path); return AppendApiKeyToURL(server_url, channel); } GURL PrefetchDownloadURL(const std::string& download_location, version_info::Channel channel) { std::string url_path = kDownloadLeadingURLPath + download_location; - GURL server_url = GetServerURLForPath(url_path, channel); + GURL server_url = GetServerURLForPath(url_path); server_url = net::AppendQueryParameter(server_url, kAltKeyName, kAltKeyValueForDownload);
diff --git a/components/offline_pages/core/prefetch/prefetch_server_urls.h b/components/offline_pages/core/prefetch/prefetch_server_urls.h index 626b4684..bf83ac6 100644 --- a/components/offline_pages/core/prefetch/prefetch_server_urls.h +++ b/components/offline_pages/core/prefetch/prefetch_server_urls.h
@@ -11,6 +11,8 @@ namespace offline_pages { +extern const char kPrefetchServer[]; + // Returns the URL to send a request to generate page bundle. GURL GeneratePageBundleRequestURL(version_info::Channel channel);
diff --git a/components/offline_pages/core/prefetch/prefetch_server_urls_unittest.cc b/components/offline_pages/core/prefetch/prefetch_server_urls_unittest.cc new file mode 100644 index 0000000..02fc66b9 --- /dev/null +++ b/components/offline_pages/core/prefetch/prefetch_server_urls_unittest.cc
@@ -0,0 +1,67 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/prefetch/prefetch_server_urls.h" + +#include "components/offline_pages/core/offline_page_feature.h" +#include "components/variations/variations_params_manager.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace offline_pages { + +namespace { +const char kTestOfflinePagesSuggestionsServerEndpoint[] = + "https://test-offlinepages-pa.sandbox.googleapis.com/"; +const char kInvalidServerEndpoint[] = "^__^"; +const char kInvalidSchemeServerEndpoint[] = + "http://test-offlinepages-pa.sandbox.googleapis.com/"; +} // namespace + +class PrefetchServerURLsTest : public testing::Test { + public: + PrefetchServerURLsTest() = default; + ~PrefetchServerURLsTest() override = default; + void SetTestingServerEndpoint(const std::string& server_config); + + private: + variations::testing::VariationParamsManager params_manager_; +}; + +void PrefetchServerURLsTest::SetTestingServerEndpoint( + const std::string& server_config) { + params_manager_.ClearAllVariationParams(); + params_manager_.SetVariationParamsWithFeatureAssociations( + kPrefetchingOfflinePagesFeature.name, + {{"offline_pages_backend", server_config}}, + {kPrefetchingOfflinePagesFeature.name}); +} + +TEST_F(PrefetchServerURLsTest, TestVariationsConfig) { + GURL default_server(kPrefetchServer); + GURL request_url = + GeneratePageBundleRequestURL(version_info::Channel::UNKNOWN); + EXPECT_EQ(default_server.host(), request_url.host()); + EXPECT_TRUE(request_url.SchemeIsCryptographic()); + + // Test reset to a valid, HTTPS URL. + SetTestingServerEndpoint(kTestOfflinePagesSuggestionsServerEndpoint); + request_url = GeneratePageBundleRequestURL(version_info::Channel::UNKNOWN); + EXPECT_EQ("test-offlinepages-pa.sandbox.googleapis.com", request_url.host()); + EXPECT_TRUE(request_url.SchemeIsCryptographic()); + + // Test other variations of invalid URLS. + // First, a completely bogus endpoint. + SetTestingServerEndpoint(kInvalidServerEndpoint); + request_url = GeneratePageBundleRequestURL(version_info::Channel::UNKNOWN); + EXPECT_EQ(default_server.host(), request_url.host()); + EXPECT_TRUE(request_url.SchemeIsCryptographic()); + + // Then a valid URL with a non-cryptographic scheme. + SetTestingServerEndpoint(kInvalidSchemeServerEndpoint); + request_url = GeneratePageBundleRequestURL(version_info::Channel::UNKNOWN); + EXPECT_EQ(default_server.host(), request_url.host()); + EXPECT_TRUE(request_url.SchemeIsCryptographic()); +} + +} // namespace offline_pages
diff --git a/components/omnibox/bug-triage.md b/components/omnibox/bug-triage.md index 385048e..5fc61ce 100644 --- a/components/omnibox/bug-triage.md +++ b/components/omnibox/bug-triage.md
@@ -31,7 +31,7 @@ ## Process * Every other day (weekend excluded), the triage engineer looks over [all - *Unconfirmed* and *Untriaged* omnibox bugs](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AUI%3EBrowser%3EOmnibox+status%3AUnconfirmed%2CUntriaged+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids) + *Unconfirmed* and *Untriaged* omnibox bugs (without *Needs=Feedback*)](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AUI%3EBrowser%3EOmnibox+status%3AUnconfirmed%2CUntriaged+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+-Needs%3DFeedback&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids) and triages them. * Every week on Tuesday, the triage engineer looks over [all *Unconfirmed* and *Untriaged* bugs filed that aren’t categorized as omnibox yet have relevant @@ -208,18 +208,18 @@ [General Chromium bug triage guidelines](http://www.chromium.org/getting-involved/bug-triage) -[Omnibox bugs that we intend/hope to tackle this year](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+NextAction%3C2018%2F1%2F1+OR+component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+-has%3ANextAction+&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids), +[Omnibox bugs that we intend/hope to tackle this year](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20NextAction%3C2018/1/1%20OR%20component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20-has:NextAction%20&sort=pri&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified), broken down: -* [User-facing](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+-Hotlist%3DCodeHealth+-Hotlist%3DRefactoring+-component%3ATest+NextAction%3C2018%2F1%2F1+OR+component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+-Hotlist%3DCodeHealth+-Hotlist%3DRefactoring+-component%3ATest+-has%3ANextAction&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids) +* [User-facing](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20-Hotlist=CodeHealth%20-Hotlist=Refactoring%20-component:Test%20NextAction%3C2018/1/1%20OR%20component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20-Hotlist=CodeHealth%20-Hotlist=Refactoring%20-component:Test%20-has:NextAction&sort=pri&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified (everything not tagged as one of the non-user-facing categories below). Some of these can be further categorized: Performance, Polish, Enterprise, Answers in Suggest, Tab To Search, Zero Suggest. * Non user-facing, divided into these categories: - * [Code health](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+NextAction%3C2018%2F1%2F1+OR+component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+-has%3ANextAction+&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids) + * [Code health](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20NextAction%3C2018/1/1%20OR%20component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20-has:NextAction%20&sort=pri&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified) - * [Refactoring](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+Hotlist%3DRefactoring+NextAction%3C2018%2F1%2F1+OR+component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+Hotlist%3DRefactoring+-has%3ANextAction&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids) + * [Refactoring](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20Hotlist=Refactoring%20NextAction%3C2018/1/1%20OR%20component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20Hotlist=Refactoring%20-has:NextAction&sort=pri&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified) - * [Testing](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+component%3ATests+NextAction%3C2018%2F1%2F1+OR+component%3AUI%3EBrowser%3EOmnibox+-component%3AUI%3EBrowser%3EOmnibox%3ESecurityIndicators+status%3AAvailable%2CAssigned%2CStarted+component%3ATests+-has%3ANextAction&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids) + * [Testing](https://bugs.chromium.org/p/chromium/issues/list?can=1&q=component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20component:Tests%20NextAction%3C2018/1/1%20OR%20component:UI%3EBrowser%3EOmnibox%20-component:UI%3EBrowser%3EOmnibox%3ESecurityIndicators%20status:Available,Assigned,Started%20component:Tests%20-has:NextAction&sort=pri&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified)
diff --git a/components/os_crypt/kwallet_dbus_unittest.cc b/components/os_crypt/kwallet_dbus_unittest.cc index bc494f1..53efb76 100644 --- a/components/os_crypt/kwallet_dbus_unittest.cc +++ b/components/os_crypt/kwallet_dbus_unittest.cc
@@ -21,6 +21,7 @@ using testing::_; using testing::AllOf; +using testing::ByMove; using testing::DoAll; using testing::ElementsAreArray; using testing::Invoke; @@ -30,43 +31,41 @@ const char kKWalletInterface[] = "org.kde.KWallet"; const char kKLauncherInterface[] = "org.kde.KLauncher"; -dbus::Response* RespondBool(bool value) { +std::unique_ptr<dbus::Response> RespondBool(bool value) { std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); writer.AppendBool(value); - return response.release(); + return response; } -dbus::Response* RespondString(const std::string& value) { +std::unique_ptr<dbus::Response> RespondString(const std::string& value) { std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); writer.AppendString(value); - return response.release(); + return response; } -dbus::Response* RespondBytes(const std::vector<uint8_t>& bytes) { +std::unique_ptr<dbus::Response> RespondBytes( + const std::vector<uint8_t>& bytes) { std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); writer.AppendArrayOfBytes(bytes.data(), bytes.size()); - return response.release(); + return response; } -dbus::Response* RespondArrayOfStrings(const std::vector<std::string>& strings) { +std::unique_ptr<dbus::Response> RespondArrayOfStrings( + const std::vector<std::string>& strings) { std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); writer.AppendArrayOfStrings(strings); - return response.release(); + return response; } -dbus::Response* RespondInt32(int value) { +std::unique_ptr<dbus::Response> RespondInt32(int value) { std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); writer.AppendInt32(value); - return response.release(); -} - -dbus::Response* RespondEmpty() { - return dbus::Response::CreateEmpty().release(); + return response; } class KWalletDBusTest @@ -328,28 +327,27 @@ } TEST_P(KWalletDBusTest, StartWalletd) { - // The receiver of the message takes ownership of the response object. - dbus::Response* response_success = RespondEmpty(); - dbus::MessageWriter writer(response_success); - writer.AppendInt32(0); // return code - writer.AppendString("dbus_name"); - writer.AppendString(std::string()); // error message - writer.AppendInt32(100); // pid - EXPECT_CALL( *mock_session_bus_.get(), GetObjectProxy("org.kde.klauncher", dbus::ObjectPath("/KLauncher"))) .WillOnce(Return(mock_klauncher_proxy_.get())); + auto response = dbus::Response::CreateEmpty(); + dbus::MessageWriter writer(response.get()); + writer.AppendInt32(0); // return code + writer.AppendString("dbus_name"); + writer.AppendString(std::string()); // error message + writer.AppendInt32(100); // pid + EXPECT_CALL( *mock_klauncher_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKLauncherInterface, "start_service_by_desktop_name"), ArgumentsAreStringStringsStringsStringBool( kwalletd_name_, std::vector<std::string>(), std::vector<std::string>(), std::string(), false)), _)) - .WillOnce(Return(response_success)); + .WillOnce(Return(ByMove(std::move(response)))); EXPECT_TRUE(kwallet_dbus_.StartKWalletd()); } @@ -362,9 +360,9 @@ EXPECT_CALL( *mock_klauncher_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( Calls(kKLauncherInterface, "start_service_by_desktop_name"), _)) - .WillOnce(Return(RespondEmpty())); + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); EXPECT_FALSE(kwallet_dbus_.StartKWalletd()); } @@ -377,17 +375,17 @@ EXPECT_CALL( *mock_klauncher_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( Calls(kKLauncherInterface, "start_service_by_desktop_name"), _)) - .WillOnce(Return(nullptr)); + .WillOnce(Return(ByMove(nullptr))); EXPECT_FALSE(kwallet_dbus_.StartKWalletd()); } TEST_P(KWalletDBusTest, IsEnabledTrue) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) - .WillOnce(Return(RespondBool(true))); + CallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) + .WillOnce(Return(ByMove(RespondBool(true)))); bool is_enabled = false; EXPECT_EQ(KWalletDBus::Error::SUCCESS, kwallet_dbus_.IsEnabled(&is_enabled)); @@ -396,8 +394,8 @@ TEST_P(KWalletDBusTest, IsEnabledFalse) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) - .WillOnce(Return(RespondBool(false))); + CallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) + .WillOnce(Return(ByMove(RespondBool(false)))); bool is_enabled = true; EXPECT_EQ(KWalletDBus::Error::SUCCESS, kwallet_dbus_.IsEnabled(&is_enabled)); @@ -406,8 +404,8 @@ TEST_P(KWalletDBusTest, IsEnabledErrorRead) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); bool is_enabled = true; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -416,8 +414,8 @@ TEST_P(KWalletDBusTest, IsEnabledErrorContact) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "isEnabled"), _)) + .WillOnce(Return(ByMove(nullptr))); bool is_enabled = true; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -427,8 +425,8 @@ TEST_P(KWalletDBusTest, NetworkWallet) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "networkWallet"), _)) - .WillOnce(Return(RespondString("mock_wallet"))); + CallMethodAndBlock(Calls(kKWalletInterface, "networkWallet"), _)) + .WillOnce(Return(ByMove(RespondString("mock_wallet")))); std::string wallet; EXPECT_EQ(KWalletDBus::Error::SUCCESS, kwallet_dbus_.NetworkWallet(&wallet)); @@ -438,8 +436,8 @@ TEST_P(KWalletDBusTest, NetworkWalletErrorRead) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "networkWallet"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "networkWallet"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); std::string wallet; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -449,8 +447,8 @@ TEST_P(KWalletDBusTest, NetworkWalletErrorContact) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "networkWallet"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "networkWallet"), _)) + .WillOnce(Return(ByMove(nullptr))); std::string wallet; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -459,11 +457,11 @@ TEST_P(KWalletDBusTest, Open) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "open"), ArgumentsAreStringInt64String("wallet", 0, "app")), _)) - .WillOnce(Return(RespondInt32(1234))); + .WillOnce(Return(ByMove(RespondInt32(1234)))); int ret; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -473,8 +471,8 @@ TEST_P(KWalletDBusTest, OpenErrorRead) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "open"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "open"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); int ret; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -483,8 +481,8 @@ TEST_P(KWalletDBusTest, OpenErrorContact) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "open"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "open"), _)) + .WillOnce(Return(ByMove(nullptr))); int ret; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -493,11 +491,11 @@ TEST_P(KWalletDBusTest, HasEntry) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(AllOf(Calls(kKWalletInterface, "hasEntry"), - ArgumentsAreIntStringStringString( - 123, "folder", "realm", "app")), - _)) - .WillOnce(Return(RespondBool(true))); + CallMethodAndBlock(AllOf(Calls(kKWalletInterface, "hasEntry"), + ArgumentsAreIntStringStringString( + 123, "folder", "realm", "app")), + _)) + .WillOnce(Return(ByMove(RespondBool(true)))); bool has_entry = false; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -507,8 +505,8 @@ TEST_P(KWalletDBusTest, HasEntryErrorRead) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "hasEntry"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "hasEntry"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); bool has_entry = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -517,8 +515,8 @@ TEST_P(KWalletDBusTest, HasEntryErrorContact) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "hasEntry"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "hasEntry"), _)) + .WillOnce(Return(ByMove(nullptr))); bool has_entry = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -529,11 +527,11 @@ const std::vector<uint8_t> bytes_expected = {1, 2, 1, 2}; EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(AllOf(Calls(kKWalletInterface, "readEntry"), - ArgumentsAreIntStringStringString( - 123, "folder", "realm", "app")), - _)) - .WillOnce(Return(RespondBytes(bytes_expected))); + CallMethodAndBlock(AllOf(Calls(kKWalletInterface, "readEntry"), + ArgumentsAreIntStringStringString( + 123, "folder", "realm", "app")), + _)) + .WillOnce(Return(ByMove(RespondBytes(bytes_expected)))); std::vector<uint8_t> bytes; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -542,10 +540,9 @@ } TEST_P(KWalletDBusTest, ReadEntryErrorRead) { - std::vector<uint8_t> bytes_expected = {1, 2, 1, 2}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "readEntry"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "readEntry"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); std::vector<uint8_t> bytes; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -553,10 +550,9 @@ } TEST_P(KWalletDBusTest, ReadEntryErrorContact) { - std::vector<uint8_t> bytes_expected = {1, 2, 1, 2}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "readEntry"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "readEntry"), _)) + .WillOnce(Return(ByMove(nullptr))); std::vector<uint8_t> bytes; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -566,11 +562,11 @@ TEST_P(KWalletDBusTest, EntryList) { std::vector<std::string> strings_expected = {"one", "two"}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "entryList"), ArgumentsAreIntStringString(123, "folder", "app")), _)) - .WillOnce(Return(RespondArrayOfStrings(strings_expected))); + .WillOnce(Return(ByMove(RespondArrayOfStrings(strings_expected)))); std::vector<std::string> strings; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -579,10 +575,9 @@ } TEST_P(KWalletDBusTest, EntryListErrorRead) { - std::vector<std::string> strings_expected = {"one", "two"}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "entryList"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "entryList"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); std::vector<std::string> strings; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -592,8 +587,8 @@ TEST_P(KWalletDBusTest, EntryListErrorContact) { std::vector<std::string> strings_expected = {"one", "two"}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "entryList"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "entryList"), _)) + .WillOnce(Return(ByMove(nullptr))); std::vector<std::string> strings; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -603,11 +598,11 @@ TEST_P(KWalletDBusTest, RemoveEntry) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(AllOf(Calls(kKWalletInterface, "removeEntry"), - ArgumentsAreIntStringStringString( - 123, "folder", "realm", "app")), - _)) - .WillOnce(Return(RespondInt32(0))); + CallMethodAndBlock(AllOf(Calls(kKWalletInterface, "removeEntry"), + ArgumentsAreIntStringStringString( + 123, "folder", "realm", "app")), + _)) + .WillOnce(Return(ByMove(RespondInt32(0)))); int ret; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -618,8 +613,8 @@ TEST_P(KWalletDBusTest, RemoveEntryErrorRead) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "removeEntry"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "removeEntry"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); int ret; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -629,8 +624,8 @@ TEST_P(KWalletDBusTest, RemoveEntryErrorContact) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "removeEntry"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "removeEntry"), _)) + .WillOnce(Return(ByMove(nullptr))); int ret; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -641,11 +636,11 @@ std::vector<uint8_t> bytes = {1, 2, 3, 1}; EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(AllOf(Calls(kKWalletInterface, "writeEntry"), - ArgumentsAreIntStringStringBytesString( - 123, "folder", "realm", bytes, "app")), - _)) - .WillOnce(Return(RespondInt32(0))); + CallMethodAndBlock(AllOf(Calls(kKWalletInterface, "writeEntry"), + ArgumentsAreIntStringStringBytesString( + 123, "folder", "realm", bytes, "app")), + _)) + .WillOnce(Return(ByMove(RespondInt32(0)))); int ret; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -657,8 +652,8 @@ TEST_P(KWalletDBusTest, WriteEntryErrorRead) { std::vector<uint8_t> bytes = {1, 2, 3, 1}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "writeEntry"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "writeEntry"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); int ret; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -669,8 +664,8 @@ TEST_P(KWalletDBusTest, WriteEntryErrorContact) { std::vector<uint8_t> bytes = {1, 2, 3, 1}; EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "writeEntry"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "writeEntry"), _)) + .WillOnce(Return(ByMove(nullptr))); int ret; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -680,11 +675,11 @@ TEST_P(KWalletDBusTest, HasFolder) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "hasFolder"), ArgumentsAreIntStringString(123, "wallet", "app")), _)) - .WillOnce(Return(RespondBool(true))); + .WillOnce(Return(ByMove(RespondBool(true)))); bool has_folder = false; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -694,8 +689,8 @@ TEST_P(KWalletDBusTest, HasFolderErrorRead) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "hasFolder"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "hasFolder"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); bool has_folder = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -704,8 +699,8 @@ TEST_P(KWalletDBusTest, HasFolderErrorContact) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "hasFolder"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "hasFolder"), _)) + .WillOnce(Return(ByMove(nullptr))); bool has_folder = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -714,11 +709,11 @@ TEST_P(KWalletDBusTest, CreateFolder) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "createFolder"), ArgumentsAreIntStringString(123, "folder", "app")), _)) - .WillOnce(Return(RespondBool(true))); + .WillOnce(Return(ByMove(RespondBool(true)))); bool created_folder = false; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -729,8 +724,8 @@ TEST_P(KWalletDBusTest, CreateFolderErrorRead) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "createFolder"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "createFolder"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); bool created_folder = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -740,8 +735,8 @@ TEST_P(KWalletDBusTest, CreateFolderErrorContact) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "createFolder"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "createFolder"), _)) + .WillOnce(Return(ByMove(nullptr))); bool created_folder = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -750,12 +745,12 @@ TEST_P(KWalletDBusTest, WritePassword) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "writePassword"), ArgumentsAreIntStringStringStringString( 123, "folder", "key", "password", "app")), _)) - .WillOnce(Return(RespondInt32(0))); + .WillOnce(Return(ByMove(RespondInt32(0)))); bool write_success = false; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -766,12 +761,12 @@ TEST_P(KWalletDBusTest, WritePasswordRejected) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "writePassword"), ArgumentsAreIntStringStringStringString( 123, "folder", "key", "password", "app")), _)) - .WillOnce(Return(RespondInt32(-1))); + .WillOnce(Return(ByMove(RespondInt32(-1)))); bool write_success = true; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -783,8 +778,8 @@ TEST_P(KWalletDBusTest, WritePasswordErrorRead) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "writePassword"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "writePassword"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); bool write_success = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -795,8 +790,8 @@ TEST_P(KWalletDBusTest, WritePasswordErrorContact) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "writePassword"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "writePassword"), _)) + .WillOnce(Return(ByMove(nullptr))); bool write_success = false; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -807,11 +802,11 @@ TEST_P(KWalletDBusTest, ReadPassword) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "readPassword"), ArgumentsAreIntStringStringString(123, "folder", "key", "app")), _)) - .WillOnce(Return(RespondString("password"))); + .WillOnce(Return(ByMove(RespondString("password")))); std::string password; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -822,8 +817,8 @@ TEST_P(KWalletDBusTest, ReadPasswordErrorRead) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "readPassword"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "readPassword"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); std::string password; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -833,8 +828,8 @@ TEST_P(KWalletDBusTest, ReadPasswordErrorContact) { EXPECT_CALL( *mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "readPassword"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "readPassword"), _)) + .WillOnce(Return(ByMove(nullptr))); std::string password; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT, @@ -843,11 +838,11 @@ TEST_P(KWalletDBusTest, CloseSuccess) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "close"), ArgumentsAreIntBoolString(123, false, "app")), _)) - .WillOnce(Return(RespondInt32(0))); + .WillOnce(Return(ByMove(RespondInt32(0)))); bool success = false; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -857,11 +852,11 @@ TEST_P(KWalletDBusTest, CloseUnsuccessful) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock( + CallMethodAndBlock( AllOf(Calls(kKWalletInterface, "close"), ArgumentsAreIntBoolString(123, false, "app")), _)) - .WillOnce(Return(RespondInt32(1))); + .WillOnce(Return(ByMove(RespondInt32(1)))); bool success = true; EXPECT_EQ(KWalletDBus::Error::SUCCESS, @@ -871,8 +866,8 @@ TEST_P(KWalletDBusTest, CloseErrorRead) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "close"), _)) - .WillOnce(Return(RespondEmpty())); + CallMethodAndBlock(Calls(kKWalletInterface, "close"), _)) + .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); bool success = true; EXPECT_EQ(KWalletDBus::Error::CANNOT_READ, @@ -881,8 +876,8 @@ TEST_P(KWalletDBusTest, CloseErrorContact) { EXPECT_CALL(*mock_kwallet_proxy_.get(), - MockCallMethodAndBlock(Calls(kKWalletInterface, "close"), _)) - .WillOnce(Return(nullptr)); + CallMethodAndBlock(Calls(kKWalletInterface, "close"), _)) + .WillOnce(Return(ByMove(nullptr))); bool success = true; EXPECT_EQ(KWalletDBus::Error::CANNOT_CONTACT,
diff --git a/components/payments/core/BUILD.gn b/components/payments/core/BUILD.gn index 5ceb667..c1a9b60 100644 --- a/components/payments/core/BUILD.gn +++ b/components/payments/core/BUILD.gn
@@ -28,6 +28,7 @@ "payment_options_provider.h", "payment_prefs.cc", "payment_prefs.h", + "payment_request_base_delegate.h", "payment_request_data_util.cc", "payment_request_data_util.h", "payment_request_delegate.h",
diff --git a/components/payments/core/address_normalization_manager.cc b/components/payments/core/address_normalization_manager.cc index 21475900..136146c8 100644 --- a/components/payments/core/address_normalization_manager.cc +++ b/components/payments/core/address_normalization_manager.cc
@@ -16,10 +16,10 @@ } // namespace AddressNormalizationManager::AddressNormalizationManager( - std::unique_ptr<AddressNormalizer> address_normalizer, + AddressNormalizer* address_normalizer, const std::string& default_country_code) : default_country_code_(default_country_code), - address_normalizer_(std::move(address_normalizer)) { + address_normalizer_(address_normalizer) { DCHECK(autofill::data_util::IsValidCountryCode(default_country_code)); DCHECK(address_normalizer_); @@ -45,8 +45,8 @@ DCHECK(accepting_requests_) << "FinalizeWithCompletionCallback has been " "called, cannot normalize more addresses"; - delegates_.push_back(base::MakeUnique<NormalizerDelegate>( - this, address_normalizer_.get(), profile)); + delegates_.push_back( + base::MakeUnique<NormalizerDelegate>(this, address_normalizer_, profile)); } void AddressNormalizationManager::MaybeRunCompletionCallback() {
diff --git a/components/payments/core/address_normalization_manager.h b/components/payments/core/address_normalization_manager.h index a838dbc..5205f30 100644 --- a/components/payments/core/address_normalization_manager.h +++ b/components/payments/core/address_normalization_manager.h
@@ -27,10 +27,9 @@ public: // Initializes an AddressNormalizationManager. |default_country_code| will be // used if the country code in an AutofillProfile to normalize is not valid. - // The AddressNormalizationManager takes ownership of |address_normalizer|. - AddressNormalizationManager( - std::unique_ptr<AddressNormalizer> address_normalizer, - const std::string& default_country_code); + // The AddressNormalizationManager does not own |address_normalizer|. + AddressNormalizationManager(AddressNormalizer* address_normalizer, + const std::string& default_country_code); ~AddressNormalizationManager(); @@ -95,8 +94,8 @@ // Storage for all the delegates that handle the normalization requests. std::vector<std::unique_ptr<NormalizerDelegate>> delegates_; - // The AddressNormalizer to use. Owned by this class. - std::unique_ptr<AddressNormalizer> address_normalizer_; + // An unowned raw pointer to the AddressNormalizer to use. + AddressNormalizer* address_normalizer_; THREAD_CHECKER(thread_checker_); DISALLOW_COPY_AND_ASSIGN(AddressNormalizationManager);
diff --git a/components/payments/core/address_normalization_manager_unittest.cc b/components/payments/core/address_normalization_manager_unittest.cc index c0a60fa..76b4656 100644 --- a/components/payments/core/address_normalization_manager_unittest.cc +++ b/components/payments/core/address_normalization_manager_unittest.cc
@@ -17,11 +17,9 @@ AddressNormalizationManagerTest() {} void Initialize(const std::string& country_code) { - std::unique_ptr<TestAddressNormalizer> address_normalizer = - base::MakeUnique<TestAddressNormalizer>(); - address_normalizer_ = address_normalizer.get(); + address_normalizer_ = base::MakeUnique<TestAddressNormalizer>(); manager_ = base::MakeUnique<AddressNormalizationManager>( - std::move(address_normalizer), country_code); + address_normalizer_.get(), country_code); } void Finalize() { @@ -32,8 +30,8 @@ void CompletionCallback() { completion_callback_called_ = true; } + std::unique_ptr<TestAddressNormalizer> address_normalizer_; std::unique_ptr<AddressNormalizationManager> manager_; - TestAddressNormalizer* address_normalizer_ = nullptr; // Weak. bool completion_callback_called_ = false; };
diff --git a/components/payments/core/autofill_payment_instrument.cc b/components/payments/core/autofill_payment_instrument.cc index 2d935ea..c18e195 100644 --- a/components/payments/core/autofill_payment_instrument.cc +++ b/components/payments/core/autofill_payment_instrument.cc
@@ -17,8 +17,8 @@ #include "components/autofill/core/browser/validation.h" #include "components/autofill/core/common/autofill_clock.h" #include "components/payments/core/basic_card_response.h" +#include "components/payments/core/payment_request_base_delegate.h" #include "components/payments/core/payment_request_data_util.h" -#include "components/payments/core/payment_request_delegate.h" namespace payments { @@ -28,7 +28,7 @@ bool matches_merchant_card_type_exactly, const std::vector<autofill::AutofillProfile*>& billing_profiles, const std::string& app_locale, - PaymentRequestDelegate* payment_request_delegate) + PaymentRequestBaseDelegate* payment_request_delegate) : PaymentInstrument( method_name, autofill::data_util::GetPaymentRequestData(card.network())
diff --git a/components/payments/core/autofill_payment_instrument.h b/components/payments/core/autofill_payment_instrument.h index fc4243e..c3b2944b 100644 --- a/components/payments/core/autofill_payment_instrument.h +++ b/components/payments/core/autofill_payment_instrument.h
@@ -19,7 +19,7 @@ namespace payments { -class PaymentRequestDelegate; +class PaymentRequestBaseDelegate; // Represents an Autofill/Payments credit card form of payment in Payment // Request. @@ -36,7 +36,7 @@ bool matches_merchant_card_type_exactly, const std::vector<autofill::AutofillProfile*>& billing_profiles, const std::string& app_locale, - PaymentRequestDelegate* payment_request_delegate); + PaymentRequestBaseDelegate* payment_request_delegate); ~AutofillPaymentInstrument() override; // PaymentInstrument: @@ -80,7 +80,7 @@ const std::string app_locale_; PaymentInstrument::Delegate* delegate_; - PaymentRequestDelegate* payment_request_delegate_; + PaymentRequestBaseDelegate* payment_request_delegate_; autofill::AutofillProfile billing_address_; base::string16 cvc_;
diff --git a/components/payments/core/payment_request_base_delegate.h b/components/payments/core/payment_request_base_delegate.h new file mode 100644 index 0000000..8b48dce8 --- /dev/null +++ b/components/payments/core/payment_request_base_delegate.h
@@ -0,0 +1,80 @@ +// 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_PAYMENTS_CORE_PAYMENT_REQUEST_BASE_DELEGATE_H_ +#define COMPONENTS_PAYMENTS_CORE_PAYMENT_REQUEST_BASE_DELEGATE_H_ + +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "components/autofill/core/browser/payments/full_card_request.h" + +class GURL; + +namespace autofill { +class CreditCard; +class PersonalDataManager; +class RegionDataLoader; +} // namespace autofill + +class PrefService; + +namespace ukm { +class UkmRecorder; +} // namespace ukm + +namespace payments { + +class AddressNormalizer; +class PaymentRequest; + +class PaymentRequestBaseDelegate { + public: + virtual ~PaymentRequestBaseDelegate() {} + + // Gets the PersonalDataManager associated with this PaymentRequest flow. + // Cannot be null. + virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0; + + virtual const std::string& GetApplicationLocale() const = 0; + + // Returns whether the user is in Incognito mode. + virtual bool IsIncognito() const = 0; + + // Returns true if the SSL certificate is valid. Should be called only for + // cryptographic schemes. + virtual bool IsSslCertificateValid() = 0; + + // Returns the URL of the page that is currently being displayed. + virtual const GURL& GetLastCommittedURL() const = 0; + + // Starts a FullCardRequest to unmask |credit_card|. + virtual void DoFullCardRequest( + const autofill::CreditCard& credit_card, + base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> + result_delegate) = 0; + + // Returns a pointer to the address normalizer to use for the duration of this + // Payment Request. + virtual AddressNormalizer* GetAddressNormalizer() = 0; + + // Creates a new region data loader that will self delete, or a test mock. + virtual autofill::RegionDataLoader* GetRegionDataLoader() = 0; + + // Returns a pointer to the UKM service. + virtual ukm::UkmRecorder* GetUkmRecorder() = 0; + + // Returns the user's signed-in email address, or empty string if not signed + // in. + virtual std::string GetAuthenticatedEmail() const = 0; + + // Gets the pref service for the browser context associated with this + // PaymentRequest. + virtual PrefService* GetPrefService() = 0; +}; + +} // namespace payments + +#endif // COMPONENTS_PAYMENTS_CORE_PAYMENT_REQUEST_BASE_DELEGATE_H_
diff --git a/components/payments/core/payment_request_delegate.h b/components/payments/core/payment_request_delegate.h index 53a44c70..dd50575 100644 --- a/components/payments/core/payment_request_delegate.h +++ b/components/payments/core/payment_request_delegate.h
@@ -5,35 +5,14 @@ #ifndef COMPONENTS_PAYMENTS_CORE_PAYMENT_REQUEST_DELEGATE_H_ #define COMPONENTS_PAYMENTS_CORE_PAYMENT_REQUEST_DELEGATE_H_ -#include <memory> -#include <string> - -#include "base/memory/weak_ptr.h" -#include "components/autofill/core/browser/payments/full_card_request.h" - -class GURL; - -namespace autofill { -class CreditCard; -class PersonalDataManager; -class RegionDataLoader; -} // namespace autofill - -class PrefService; - -namespace ukm { -class UkmRecorder; -} // namespace ukm +#include "components/payments/core/payment_request_base_delegate.h" namespace payments { -class AddressNormalizer; class PaymentRequest; -class PaymentRequestDelegate { +class PaymentRequestDelegate : public PaymentRequestBaseDelegate { public: - virtual ~PaymentRequestDelegate() {} - // Shows the Payment Request dialog for the given |request|. virtual void ShowDialog(PaymentRequest* request) = 0; @@ -44,46 +23,6 @@ // Disables the dialog and shows an error message that the transaction has // failed. virtual void ShowErrorMessage() = 0; - - // Gets the PersonalDataManager associated with this PaymentRequest flow. - // Cannot be null. - virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0; - - virtual const std::string& GetApplicationLocale() const = 0; - - // Returns whether the user is in Incognito mode. - virtual bool IsIncognito() const = 0; - - // Returns true if the SSL certificate is valid. Should be called only for - // cryptographic schemes. - virtual bool IsSslCertificateValid() = 0; - - // Returns the URL of the page that is currently being displayed. - virtual const GURL& GetLastCommittedURL() const = 0; - - // Starts a FullCardRequest to unmask |credit_card|. - virtual void DoFullCardRequest( - const autofill::CreditCard& credit_card, - base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> - result_delegate) = 0; - - // Returns a pointer to the address normalizer to use for the duration of this - // Payment Request. - virtual AddressNormalizer* GetAddressNormalizer() = 0; - - // Creates a new region data loader that will self delete, or a test mock. - virtual autofill::RegionDataLoader* GetRegionDataLoader() = 0; - - // Returns a pointer to the UKM service. - virtual ukm::UkmRecorder* GetUkmRecorder() = 0; - - // Returns the user's signed-in email address, or empty string if not signed - // in. - virtual std::string GetAuthenticatedEmail() const = 0; - - // Gets the pref service for the browser context associated with this - // PaymentRequest. - virtual PrefService* GetPrefService() = 0; }; } // namespace payments
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index f9d9434..6b580b1 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -334,9 +334,11 @@ } std::unique_ptr<blink::WebURLLoader> -WebViewPlugin::WebViewHelper::CreateURLLoader() { +WebViewPlugin::WebViewHelper::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return blink::Platform::Current()->CreateURLLoader(); + return blink::Platform::Current()->CreateURLLoader(request, task_runner); } void WebViewPlugin::WebViewHelper::DidClearWindowObject() {
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 458296b1..240dfe5 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -175,7 +175,9 @@ void DidInvalidateRect(const blink::WebRect&) override; void DidChangeCursor(const blink::WebCursorInfo& cursor) override; void ScheduleAnimation() override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; // WebFrameClient methods: void DidClearWindowObject() override;
diff --git a/components/policy/core/common/cloud/component_cloud_policy_store.cc b/components/policy/core/common/cloud/component_cloud_policy_store.cc index 762f557..0928108f 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_store.cc +++ b/components/policy/core/common/cloud/component_cloud_policy_store.cc
@@ -13,6 +13,7 @@ #include "base/json/json_reader.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" #include "base/strings/string_util.h" #include "base/values.h" @@ -148,31 +149,42 @@ const std::string& id(it->first); const PolicyNamespace ns(constants.domain, id); - // Validate each protobuf. - std::unique_ptr<em::PolicyFetchResponse> proto( - new em::PolicyFetchResponse); + // Validate the protobuf. + auto proto = base::MakeUnique<em::PolicyFetchResponse>(); + if (!proto->ParseFromString(it->second)) { + LOG(ERROR) << "Failed to parse the cached policy fetch response."; + Delete(ns); + continue; + } em::ExternalPolicyData payload; em::PolicyData policy_data; - if (!proto->ParseFromString(it->second) || - !ValidatePolicy(ns, std::move(proto), &policy_data, &payload)) { + if (!ValidatePolicy(ns, std::move(proto), &policy_data, &payload)) { + // The policy fetch response is corrupted. Note that the error details + // are logged by ValidatePolicy(). Delete(ns); continue; } // The protobuf looks good; load the policy data. std::string data; - PolicyMap policy; - if (cache_->Load(constants.data_cache_key, id, &data) && - ValidateData(data, payload.secure_hash(), &policy)) { - // The data is also good; expose the policies. - policy_bundle_.Get(ns).Swap(&policy); - cached_hashes_[ns] = payload.secure_hash(); - stored_policy_times_[ns] = - base::Time::FromJavaTime(policy_data.timestamp()); - } else { - // The data for this proto couldn't be loaded or is corrupted. + if (!cache_->Load(constants.data_cache_key, id, &data)) { + LOG(ERROR) << "Failed to load the cached policy data."; Delete(ns); + continue; } + PolicyMap policy; + if (!ValidateData(data, payload.secure_hash(), &policy)) { + // The data for this proto is corrupted. Note that the error details + // are logged by ValidateData(). + Delete(ns); + continue; + } + + // The data is also good; expose the policies. + policy_bundle_.Get(ns).Swap(&policy); + cached_hashes_[ns] = payload.secure_hash(); + stored_policy_times_[ns] = + base::Time::FromJavaTime(policy_data.timestamp()); } } } @@ -183,13 +195,23 @@ const std::string& secure_hash, const std::string& data) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + const DomainConstants* constants = GetDomainConstants(ns.domain); - PolicyMap policy; + if (!constants) { + // Ignore policies with domain that doesn't correspond to the known + // component policy domains. + return false; + } + // |serialized_policy| has already been validated; validate the data now. - if (!constants) + PolicyMap policy; + if (!ValidateData(data, secure_hash, &policy)) { + // TODO(emaxx): Incorporate the validation error message here and in other + // contextual log messages. + DLOG(ERROR) << "Discarding policy for component " << ns.component_id + << " due to validation failure."; return false; - if (!ValidateData(data, secure_hash, &policy)) - return false; + } // Flush the proto and the data to the cache. cache_->Store(constants->proto_cache_key, ns.component_id, serialized_policy); @@ -204,9 +226,13 @@ void ComponentCloudPolicyStore::Delete(const PolicyNamespace& ns) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + const DomainConstants* constants = GetDomainConstants(ns.domain); - if (!constants) + if (!constants) { + // Ignore policies with domain that doesn't correspond to the known + // component policy domains. return; + } cache_->Delete(constants->proto_cache_key, ns.component_id); cache_->Delete(constants->data_cache_key, ns.component_id); @@ -221,9 +247,13 @@ PolicyDomain domain, const ResourceCache::SubkeyFilter& filter) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + const DomainConstants* constants = GetDomainConstants(domain); - if (!constants) + if (!constants) { + // Ignore policies with domain that doesn't correspond to the known + // component policy domains. return; + } cache_->FilterSubkeys(constants->proto_cache_key, filter); cache_->FilterSubkeys(constants->data_cache_key, filter); @@ -281,17 +311,17 @@ em::ExternalPolicyData* payload) { std::string policy_type; if (!GetPolicyType(ns.domain, &policy_type)) { - LOG(ERROR) << "Bad policy type"; + LOG(ERROR) << "Bad policy type " << ns.domain << "."; return false; } if (ns.component_id.empty()) { - LOG(ERROR) << "Empty component id"; + LOG(ERROR) << "Empty component id."; return false; } if (username_.empty() || dm_token_.empty() || device_id_.empty() || public_key_.empty() || public_key_version_ == -1) { - LOG(WARNING) << "Credentials are not loaded yet"; + LOG(WARNING) << "Credentials are not loaded yet."; return false; } @@ -321,13 +351,13 @@ return false; if (!validator->policy_data()->has_public_key_version()) { - LOG(ERROR) << "Public key version missing"; + LOG(ERROR) << "Public key version missing."; return false; } if (validator->policy_data()->public_key_version() != public_key_version_) { LOG(ERROR) << "Wrong public key version " << validator->policy_data()->public_key_version() - << " - expected " << public_key_version_; + << " - expected " << public_key_version_ << "."; return false; } @@ -337,15 +367,15 @@ // policy, or that the policy has been removed. if (data->has_download_url() && !data->download_url().empty()) { if (!GURL(data->download_url()).is_valid()) { - LOG(ERROR) << "Invalid URL: " << data->download_url(); + LOG(ERROR) << "Invalid URL: " << data->download_url() << " ."; return false; } if (!data->has_secure_hash() || data->secure_hash().empty()) { - LOG(ERROR) << "Secure hash missing"; + LOG(ERROR) << "Secure hash missing."; return false; } } else if (data->has_secure_hash()) { - LOG(ERROR) << "URL missing"; + LOG(ERROR) << "URL missing."; return false; } @@ -360,17 +390,29 @@ const std::string& data, const std::string& secure_hash, PolicyMap* policy) { - return crypto::SHA256HashString(data) == secure_hash && - ParsePolicy(data, policy); + if (crypto::SHA256HashString(data) != secure_hash) { + LOG(ERROR) << "The received data doesn't match the expected hash."; + return false; + } + return ParsePolicy(data, policy); } bool ComponentCloudPolicyStore::ParsePolicy(const std::string& data, PolicyMap* policy) { - std::unique_ptr<base::Value> json = base::JSONReader::Read( - data, base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN); + std::string json_reader_error_message; + std::unique_ptr<base::Value> json = base::JSONReader::ReadAndReturnError( + data, base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN, + nullptr /* error_code_out */, &json_reader_error_message); base::DictionaryValue* dict = nullptr; - if (!json || !json->GetAsDictionary(&dict)) + if (!json) { + LOG(ERROR) << "Invalid JSON blob: " << json_reader_error_message; return false; + } + + if (!json->GetAsDictionary(&dict)) { + LOG(ERROR) << "The JSON blob is not a dictionary."; + return false; + } // Each top-level key maps a policy name to its description. // @@ -379,12 +421,18 @@ // "Recommended". for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { base::DictionaryValue* description = nullptr; - if (!dict->GetDictionaryWithoutPathExpansion(it.key(), &description)) + if (!dict->GetDictionaryWithoutPathExpansion(it.key(), &description)) { + LOG(ERROR) << "The JSON blob dictionary value is not a dictionary."; return false; + } std::unique_ptr<base::Value> value; - if (!description->RemoveWithoutPathExpansion(kValue, &value)) + if (!description->RemoveWithoutPathExpansion(kValue, &value)) { + LOG(ERROR) + << "The JSON blob dictionary value doesn't contain the required " + << kValue << " field."; return false; + } PolicyLevel level = POLICY_LEVEL_MANDATORY; std::string level_string;
diff --git a/components/policy/core/common/cloud/component_cloud_policy_store.h b/components/policy/core/common/cloud/component_cloud_policy_store.h index b2ce91ca..a150cbd 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_store.h +++ b/components/policy/core/common/cloud/component_cloud_policy_store.h
@@ -132,8 +132,8 @@ // parse was successful. bool ParsePolicy(const std::string& data, PolicyMap* policy); - Delegate* delegate_; - ResourceCache* cache_; + Delegate* const delegate_; + ResourceCache* const cache_; // The following fields contain credentials used for validating the policy. std::string username_;
diff --git a/components/policy/core/common/cloud/component_cloud_policy_updater.cc b/components/policy/core/common/cloud/component_cloud_policy_updater.cc index 4d5d6ac..15092a7 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_updater.cc +++ b/components/policy/core/common/cloud/component_cloud_policy_updater.cc
@@ -6,12 +6,15 @@ #include <stddef.h> #include <stdint.h> + #include <memory> +#include <string> #include <utility> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" #include "base/strings/string_number_conversions.h" #include "components/policy/core/common/cloud/component_cloud_policy_store.h" @@ -34,6 +37,12 @@ // Tha maximum number of policy data fetches to run in parallel. const int64_t kMaxParallelPolicyDataFetches = 2; +std::string NamespaceToKey(const PolicyNamespace& ns) { + const std::string domain = base::IntToString(ns.domain); + const std::string size = base::SizeTToString(domain.size()); + return size + ":" + domain + ":" + ns.component_id; +} + } // namespace ComponentCloudPolicyUpdater::ComponentCloudPolicyUpdater( @@ -54,13 +63,19 @@ // Keep a serialized copy of |response|, to cache it later. // The policy is also rejected if it exceeds the maximum size. std::string serialized_response; - if (!response->SerializeToString(&serialized_response) || - serialized_response.size() > kPolicyProtoMaxSize) { + if (!response->SerializeToString(&serialized_response)) { + LOG(ERROR) << "Failed to serialize policy fetch response."; + return; + } + if (serialized_response.size() > kPolicyProtoMaxSize) { + LOG(ERROR) << "Policy fetch response too large: " + << serialized_response.size() << " bytes (max " + << kPolicyProtoMaxSize << ")."; return; } // Validate the policy before doing anything else. - std::unique_ptr<em::PolicyData> policy_data(new em::PolicyData); + auto policy_data = base::MakeUnique<em::PolicyData>(); em::ExternalPolicyData data; if (!store_->ValidatePolicy(ns, std::move(response), policy_data.get(), &data)) { @@ -98,11 +113,4 @@ external_policy_data_updater_.CancelExternalDataFetch(NamespaceToKey(ns)); } -std::string ComponentCloudPolicyUpdater::NamespaceToKey( - const PolicyNamespace& ns) { - const std::string domain = base::IntToString(ns.domain); - const std::string size = base::SizeTToString(domain.size()); - return size + ":" + domain + ":" + ns.component_id; -} - } // namespace policy
diff --git a/components/policy/core/common/cloud/component_cloud_policy_updater.h b/components/policy/core/common/cloud/component_cloud_policy_updater.h index 694e95e..825930d5 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_updater.h +++ b/components/policy/core/common/cloud/component_cloud_policy_updater.h
@@ -6,7 +6,6 @@ #define COMPONENTS_POLICY_CORE_COMMON_CLOUD_COMPONENT_CLOUD_POLICY_UPDATER_H_ #include <memory> -#include <string> #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -56,9 +55,7 @@ void CancelUpdate(const PolicyNamespace& ns); private: - std::string NamespaceToKey(const PolicyNamespace& ns); - - ComponentCloudPolicyStore* store_; + ComponentCloudPolicyStore* const store_; ExternalPolicyDataUpdater external_policy_data_updater_; DISALLOW_COPY_AND_ASSIGN(ComponentCloudPolicyUpdater);
diff --git a/components/policy/core/common/cloud/external_policy_data_updater.cc b/components/policy/core/common/cloud/external_policy_data_updater.cc index 97324c54..b1c9621 100644 --- a/components/policy/core/common/cloud/external_policy_data_updater.cc +++ b/components/policy/core/common/cloud/external_policy_data_updater.cc
@@ -4,6 +4,8 @@ #include "components/policy/core/common/cloud/external_policy_data_updater.h" +#include <utility> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" @@ -132,28 +134,28 @@ void Reschedule(); // Always valid as long as |this| is alive. - ExternalPolicyDataUpdater* updater_; + ExternalPolicyDataUpdater* const updater_; const std::string key_; const ExternalPolicyDataUpdater::Request request_; - ExternalPolicyDataUpdater::FetchSuccessCallback callback_; + const ExternalPolicyDataUpdater::FetchSuccessCallback callback_; // If the job is currently running, a corresponding |fetch_job_| exists in the // |external_policy_data_fetcher_|. The job must eventually call back to the // |updater_|'s OnJobSucceeded() or OnJobFailed() method in this case. // If the job is currently not running, |fetch_job_| is NULL and no callbacks // should be invoked. - ExternalPolicyDataFetcher::Job* fetch_job_; // Not owned. + ExternalPolicyDataFetcher::Job* fetch_job_ = nullptr; // Not owned. // Some errors should trigger a limited number of retries, even with backoff. // This counts down the number of such retries to stop retrying once the limit // is reached. - int limited_retries_remaining_; + int limited_retries_remaining_ = kMaxLimitedRetries; // Various delays to retry a failed download, depending on the failure reason. - net::BackoffEntry retry_soon_entry_; - net::BackoffEntry retry_later_entry_; - net::BackoffEntry retry_much_later_entry_; + net::BackoffEntry retry_soon_entry_{&kRetrySoonPolicy}; + net::BackoffEntry retry_later_entry_{&kRetryLaterPolicy}; + net::BackoffEntry retry_much_later_entry_{&kRetryMuchLaterPolicy}; DISALLOW_COPY_AND_ASSIGN(FetchJob); }; @@ -176,16 +178,7 @@ const std::string& key, const ExternalPolicyDataUpdater::Request& request, const ExternalPolicyDataUpdater::FetchSuccessCallback& callback) - : updater_(updater), - key_(key), - request_(request), - callback_(callback), - fetch_job_(NULL), - limited_retries_remaining_(kMaxLimitedRetries), - retry_soon_entry_(&kRetrySoonPolicy), - retry_later_entry_(&kRetryLaterPolicy), - retry_much_later_entry_(&kRetryMuchLaterPolicy) { -} + : updater_(updater), key_(key), request_(request), callback_(callback) {} ExternalPolicyDataUpdater::FetchJob::~FetchJob() { if (fetch_job_) { @@ -207,8 +200,11 @@ void ExternalPolicyDataUpdater::FetchJob::Start() { DCHECK(!fetch_job_); + DVLOG(1) << "Fetching data for " << key_ << " from " << request_.url << " ."; // Start a fetch job in the |external_policy_data_fetcher_|. This will // eventually call back to OnFetchFinished() with the result. + // Passing |this| as base::Unretained() is safe here because the |FetchJob| + // destructor cancels the fetcher job if one is still running. fetch_job_ = updater_->external_policy_data_fetcher_->StartJob( GURL(request_.url), request_.max_size, base::Bind(&ExternalPolicyDataUpdater::FetchJob::OnFetchFinished, @@ -224,30 +220,37 @@ switch (result) { case ExternalPolicyDataFetcher::CONNECTION_INTERRUPTED: // The connection was interrupted. Try again soon. + DVLOG(1) << "Failed to fetch the data due to the interrupted connection."; OnFailed(&retry_soon_entry_); return; case ExternalPolicyDataFetcher::NETWORK_ERROR: // Another network error occurred. Try again later. + DVLOG(1) << "Failed to fetch the data due to a network error."; OnFailed(&retry_later_entry_); return; case ExternalPolicyDataFetcher::SERVER_ERROR: // Problem at the server. Try again soon. + LOG(WARNING) << "Failed to fetch the data due to a server HTTP error."; OnFailed(&retry_soon_entry_); return; case ExternalPolicyDataFetcher::CLIENT_ERROR: // Client error. This is unlikely to go away. Try again later, and give up // retrying after 3 attempts. + LOG(WARNING) << "Failed to fetch the data due to a client HTTP error."; OnFailed(limited_retries_remaining_ ? &retry_later_entry_ : NULL); if (limited_retries_remaining_) --limited_retries_remaining_; return; case ExternalPolicyDataFetcher::HTTP_ERROR: // Any other type of HTTP failure. Try again later. + LOG(WARNING) << "Failed to fetch the data due to an HTTP error."; OnFailed(&retry_later_entry_); return; case ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED: // Received |data| exceeds maximum allowed size. This may be because the // data being served is stale. Try again much later. + LOG(WARNING) << "Failed to fetch the data due to the excessive size (max " + << request_.max_size << " bytes)."; OnFailed(&retry_much_later_entry_); return; case ExternalPolicyDataFetcher::SUCCESS: @@ -257,6 +260,7 @@ if (crypto::SHA256HashString(*data) != request_.hash) { // Received |data| does not match expected hash. This may be because the // data being served is stale. Try again much later. + LOG(ERROR) << "The fetched data doesn't match the expected hash."; OnFailed(&retry_much_later_entry_); return; } @@ -274,14 +278,14 @@ void ExternalPolicyDataUpdater::FetchJob::OnFailed(net::BackoffEntry* entry) { if (entry) { entry->InformOfRequest(false); + const base::TimeDelta delay = entry->GetTimeUntilRelease(); + DVLOG(1) << "Rescheduling the fetch in " << delay << "."; // This function may have been invoked because the job was obsoleted and is // in the process of being deleted. If this is the case, the WeakPtr will // become invalid and the delayed task will never run. updater_->task_runner_->PostDelayedTask( - FROM_HERE, - base::Bind(&FetchJob::Reschedule, AsWeakPtr()), - entry->GetTimeUntilRelease()); + FROM_HERE, base::Bind(&FetchJob::Reschedule, AsWeakPtr()), delay); } updater_->OnJobFailed(this); @@ -296,20 +300,20 @@ std::unique_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher, size_t max_parallel_fetches) : task_runner_(task_runner), - external_policy_data_fetcher_(external_policy_data_fetcher.release()), - max_parallel_jobs_(max_parallel_fetches), - running_jobs_(0), - shutting_down_(false) { + external_policy_data_fetcher_(std::move(external_policy_data_fetcher)), + max_parallel_jobs_(max_parallel_fetches) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); } ExternalPolicyDataUpdater::~ExternalPolicyDataUpdater() { DCHECK(task_runner_->RunsTasksInCurrentSequence()); + // Raise the flag to prevent jobs from being started during the destruction of + // |job_map_|. shutting_down_ = true; } void ExternalPolicyDataUpdater::FetchExternalData( - const std::string key, + const std::string& key, const Request& request, const FetchSuccessCallback& callback) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); @@ -319,12 +323,16 @@ if (job) { // If the current |job| is handling the given |request| already, nothing // needs to be done. - if (job->request() == request) + if (job->request() == request) { + DVLOG(2) << "Fetching job already scheduled for " << key + << " with the same parameters."; return; + } // Otherwise, the current |job| is obsolete. If the |job| is on the queue, // its WeakPtr will be invalidated and skipped by StartNextJobs(). If |job| // is currently running, it will call OnJobFailed() immediately. + DVLOG(2) << "Removing the old job for " << key << "."; job_map_.erase(key); } @@ -342,8 +350,10 @@ // its WeakPtr will be invalidated and skipped by StartNextJobs(). If |job| is // currently running, it will call OnJobFailed() immediately. auto job = job_map_.find(key); - if (job != job_map_.end()) + if (job != job_map_.end()) { + DVLOG(1) << "Cancelling the job for " << key << "."; job_map_.erase(job); + } } void ExternalPolicyDataUpdater::StartNextJobs() { @@ -385,8 +395,8 @@ DCHECK(running_jobs_); --running_jobs_; - // Don't touch job_map_; deletion of FetchJobs cause a call to this method, so - // job_map_ is possibly in an inconsistent state. + // Don't touch |job_map_|; deletion of |FetchJob|s causes a call to this + // method, so |job_map_| is possibly in an inconsistent state. // The job is not deleted when it fails because a retry attempt may have been // scheduled.
diff --git a/components/policy/core/common/cloud/external_policy_data_updater.h b/components/policy/core/common/cloud/external_policy_data_updater.h index 9a8d693..9be6bf8 100644 --- a/components/policy/core/common/cloud/external_policy_data_updater.h +++ b/components/policy/core/common/cloud/external_policy_data_updater.h
@@ -76,7 +76,7 @@ // it will be canceled and replaced with the new |request|. The callback will // be invoked after a successful fetch. See the documentation of // |FetchSuccessCallback| for more details. - void FetchExternalData(const std::string key, + void FetchExternalData(const std::string& key, const Request& request, const FetchSuccessCallback& callback); @@ -101,14 +101,15 @@ // Callback for jobs that failed. void OnJobFailed(FetchJob* job); - scoped_refptr<base::SequencedTaskRunner> task_runner_; - std::unique_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + const std::unique_ptr<ExternalPolicyDataFetcher> + external_policy_data_fetcher_; // The maximum number of jobs to run in parallel. - size_t max_parallel_jobs_; + const size_t max_parallel_jobs_; // The number of jobs currently running. - size_t running_jobs_; + size_t running_jobs_ = 0; // Queue of jobs waiting to be run. Jobs are taken off the queue and started // by StartNextJobs(). @@ -118,9 +119,9 @@ // queued, running or waiting for a retry. std::map<std::string, std::unique_ptr<FetchJob>> job_map_; - // |True| once the destructor starts. Prevents jobs from being started during + // |true| once the destructor starts. Prevents jobs from being started during // shutdown. - bool shutting_down_; + bool shutting_down_ = false; DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataUpdater); };
diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc index 740f83e5..b92da73a 100644 --- a/components/printing/renderer/print_web_view_helper.cc +++ b/components/printing/renderer/print_web_view_helper.cc
@@ -689,7 +689,9 @@ const blink::WebFrameOwnerProperties& frame_owner_properties) override; void FrameDetached(blink::WebLocalFrame* frame, DetachType detach_type) override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; void CallOnReady(); void ResizeForPrinting(); @@ -863,9 +865,11 @@ } std::unique_ptr<blink::WebURLLoader> -PrepareFrameAndViewForPrint::CreateURLLoader() { +PrepareFrameAndViewForPrint::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return blink::Platform::Current()->CreateURLLoader(); + return blink::Platform::Current()->CreateURLLoader(request, task_runner); } void PrepareFrameAndViewForPrint::CallOnReady() {
diff --git a/components/proximity_auth/webui/resources/common.css b/components/proximity_auth/webui/resources/common.css index 728a573..441550d 100644 --- a/components/proximity_auth/webui/resources/common.css +++ b/components/proximity_auth/webui/resources/common.css
@@ -156,4 +156,5 @@ width: 100%; text-overflow: clip; overflow-x: auto; + white-space: pre-wrap; }
diff --git a/components/proximity_auth/webui/resources/proximity_auth.html b/components/proximity_auth/webui/resources/proximity_auth.html index b623904..4cca8be 100644 --- a/components/proximity_auth/webui/resources/proximity_auth.html +++ b/components/proximity_auth/webui/resources/proximity_auth.html
@@ -125,7 +125,7 @@ <div class="flex"></div> <div class='item-source'></div> </div> - <p class="item-text flex">This is an error.</p> + <pre class="item-text flex">This is an error.</pre> </div> </template> </body>
diff --git a/components/resources/components_resources.grd b/components/resources/components_resources.grd index cf622dc..ec0dffd 100644 --- a/components/resources/components_resources.grd +++ b/components/resources/components_resources.grd
@@ -19,6 +19,7 @@ <part file="physical_web_ui_resources.grdp" /> <part file="printing_resources.grdp" /> <part file="proximity_auth_resources.grdp" /> + <part file="safe_browsing_resources.grdp" /> <part file="security_interstitials_resources.grdp" /> <part file="signin_resources.grdp" /> <part file="supervised_user_error_page_resources.grdp" />
diff --git a/components/resources/safe_browsing_resources.grdp b/components/resources/safe_browsing_resources.grdp new file mode 100644 index 0000000..ae40ba6 --- /dev/null +++ b/components/resources/safe_browsing_resources.grdp
@@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <include name="IDR_SAFE_BROWSING_HTML" file="..\..\components\safe_browsing\web_ui\resources\safe_browsing.html" type="BINDATA" /> + <include name="IDR_SAFE_BROWSING_CSS" file="..\..\components\safe_browsing\web_ui\resources\safe_browsing.css" type="BINDATA" /> +</grit-part>
diff --git a/components/safe_browsing/csd.proto b/components/safe_browsing/csd.proto index 0e3a5aa..e33f34c7 100644 --- a/components/safe_browsing/csd.proto +++ b/components/safe_browsing/csd.proto
@@ -216,6 +216,19 @@ // Whether the reused password is used for Chrome signin. optional bool is_chrome_signin_password = 3; + + // Sync account type. Only set if |is_chrome_signin_password| is true. + enum SyncAccountType { + // Not a sign-in user. + NOT_SIGNED_IN = 0; + + // User signed in with @gmail.com, or @googlemail.com account. + GMAIL = 1; + + // User signed in with a G Suite account. + GSUITE = 2; + } + optional SyncAccountType sync_account_type = 4; } optional PasswordReuseEvent password_reuse_event = 4;
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index 552def6..99835fa7 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -148,6 +148,16 @@ request_proto_->mutable_password_reuse_event(); reuse_event->set_is_chrome_signin_password( saved_domain_ == std::string(password_manager::kSyncPasswordDomain)); + if (reuse_event->is_chrome_signin_password()) { + reuse_event->set_sync_account_type( + password_protection_service_->GetSyncAccountType()); + UMA_HISTOGRAM_ENUMERATION( + "PasswordProtection.PasswordReuseSyncAccountType", + reuse_event->sync_account_type(), + LoginReputationClientRequest::PasswordReuseEvent:: + SyncAccountType_MAX + + 1); + } break; } default:
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index 10036f4..46d086d2 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -50,6 +50,9 @@ class PasswordProtectionService : public history::HistoryServiceObserver { public: using TriggerType = LoginReputationClientRequest::TriggerType; + using SyncAccountType = + LoginReputationClientRequest::PasswordReuseEvent::SyncAccountType; + // The outcome of the request. These values are used for UMA. // DO NOT CHANGE THE ORDERING OF THESE VALUES. enum RequestOutcome { @@ -192,6 +195,10 @@ const std::string& token, content::WebContents* web_contents) = 0; + // Gets the type of sync account associated with current profile or + // |NOT_SIGNED_IN|. + virtual SyncAccountType GetSyncAccountType() = 0; + void CheckCsdWhitelistOnIOThread(const GURL& url, bool* check_result); HostContentSettingsMap* content_settings() const { return content_settings_; }
diff --git a/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/password_protection/password_protection_service_unittest.cc index 22fe4cf..110479f4 100644 --- a/components/safe_browsing/password_protection/password_protection_service_unittest.cc +++ b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -118,6 +118,11 @@ bool IsHistorySyncEnabled() override { return false; } + LoginReputationClientRequest::PasswordReuseEvent::SyncAccountType + GetSyncAccountType() override { + return LoginReputationClientRequest::PasswordReuseEvent::NOT_SIGNED_IN; + } + LoginReputationClientResponse* latest_response() { return latest_response_.get(); }
diff --git a/components/safe_browsing/web_ui/BUILD.gn b/components/safe_browsing/web_ui/BUILD.gn new file mode 100644 index 0000000..0c24b46 --- /dev/null +++ b/components/safe_browsing/web_ui/BUILD.gn
@@ -0,0 +1,28 @@ +# 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. + +static_library("web_ui") { + sources = [ + "safe_browsing_ui.cc", + "safe_browsing_ui.h", + ] + + deps = [ + ":constants", + "//base", + "//components/resources:components_resources_grit", + "//components/resources:components_scaled_resources_grit", + "//components/strings:components_strings_grit", + "//content/public/browser", + "//net", + "//url", + ] +} + +static_library("constants") { + sources = [ + "constants.cc", + "constants.h", + ] +}
diff --git a/components/safe_browsing/web_ui/DEPS b/components/safe_browsing/web_ui/DEPS new file mode 100644 index 0000000..101e622 --- /dev/null +++ b/components/safe_browsing/web_ui/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "+components/grit/components_resources.h", + "+components/strings/grit/components_strings.h", + "+components/grit/components_scaled_resources.h" +]
diff --git a/components/safe_browsing/web_ui/constants.cc b/components/safe_browsing/web_ui/constants.cc new file mode 100644 index 0000000..881c1cc --- /dev/null +++ b/components/safe_browsing/web_ui/constants.cc
@@ -0,0 +1,14 @@ +// 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 "components/safe_browsing/web_ui/constants.h" + +namespace safe_browsing { + +const char kChromeUISafeBrowsingURL[] = "chrome://safe-browsing/"; +const char kChromeUISafeBrowsingHost[] = "safe-browsing"; +const char kSbUnderConstruction[] = + "The safe browsing page is under construction."; + +} // namespace safe_browsing
diff --git a/components/safe_browsing/web_ui/constants.h b/components/safe_browsing/web_ui/constants.h new file mode 100644 index 0000000..6169e065 --- /dev/null +++ b/components/safe_browsing/web_ui/constants.h
@@ -0,0 +1,16 @@ +// 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_SAFE_BROWSING_WEB_UI_CONSTANTS_H_ +#define COMPONENTS_SAFE_BROWSING_WEB_UI_CONSTANTS_H_ + +namespace safe_browsing { + +extern const char kChromeUISafeBrowsingURL[]; +extern const char kChromeUISafeBrowsingHost[]; +extern const char kSbUnderConstruction[]; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_WEB_UI_CONSTANTS_H_
diff --git a/components/safe_browsing/web_ui/resources/safe_browsing.css b/components/safe_browsing/web_ui/resources/safe_browsing.css new file mode 100644 index 0000000..0bacdd7f --- /dev/null +++ b/components/safe_browsing/web_ui/resources/safe_browsing.css
@@ -0,0 +1,8 @@ + +/* 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. */ + + p { + white-space: pre-wrap; +}
diff --git a/components/safe_browsing/web_ui/resources/safe_browsing.html b/components/safe_browsing/web_ui/resources/safe_browsing.html new file mode 100644 index 0000000..31ae761 --- /dev/null +++ b/components/safe_browsing/web_ui/resources/safe_browsing.html
@@ -0,0 +1,17 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Safe Browsing</title> + <link rel="stylesheet" href="safe_browsing.css"> + <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> + <script src="chrome://resources/js/cr.js"></script> + <script src="chrome://resources/js/load_time_data.js"></script> + <script src="chrome://resources/js/util.js"></script> +</head> +<body> + <h1>Safe Browsing</h1> + <p>$i18n{sbUnderConstruction}</p> + <script src="chrome://resources/js/i18n_template.js"></script> +</body> +</html>
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc new file mode 100644 index 0000000..761b7cb --- /dev/null +++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -0,0 +1,33 @@ +// Copyright (c) 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/safe_browsing/web_ui/safe_browsing_ui.h" +#include "components/grit/components_resources.h" +#include "components/grit/components_scaled_resources.h" +#include "components/safe_browsing/web_ui/constants.h" +#include "components/strings/grit/components_strings.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" + +SafeBrowsingUI::SafeBrowsingUI(content::WebUI* web_ui) + : content::WebUIController(web_ui) { + // Set up the chrome://safe-browsing source. + content::WebUIDataSource* html_source = content::WebUIDataSource::Create( + safe_browsing::kChromeUISafeBrowsingHost); + + // Add localized string resources. + html_source->AddLocalizedString("sbUnderConstruction", + IDS_SB_UNDER_CONSTRUCTION); + + // Add required resources. + html_source->AddResourcePath("safe_browsing.css", IDR_SAFE_BROWSING_CSS); + html_source->SetDefaultResource(IDR_SAFE_BROWSING_HTML); + + content::BrowserContext* browser_context = + web_ui->GetWebContents()->GetBrowserContext(); + content::WebUIDataSource::Add(browser_context, html_source); +} + +SafeBrowsingUI::~SafeBrowsingUI() {}
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.h b/components/safe_browsing/web_ui/safe_browsing_ui.h new file mode 100644 index 0000000..440fae2 --- /dev/null +++ b/components/safe_browsing/web_ui/safe_browsing_ui.h
@@ -0,0 +1,22 @@ +// Copyright (c) 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_UI_WEBUI_SAFE_BROWSING_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_SAFE_BROWSING_UI_H_ + +#include "base/macros.h" +#include "content/public/browser/url_data_source.h" +#include "content/public/browser/web_ui_controller.h" + +// The WebUI for chrome://safe-browsing +class SafeBrowsingUI : public content::WebUIController { + public: + explicit SafeBrowsingUI(content::WebUI* web_ui); + ~SafeBrowsingUI() override; + + private: + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingUI); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_SAFE_BROWSING_UI_H_
diff --git a/components/safe_browsing_strings.grdp b/components/safe_browsing_strings.grdp new file mode 100644 index 0000000..92bb0ae --- /dev/null +++ b/components/safe_browsing_strings.grdp
@@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <message name="IDS_SB_UNDER_CONSTRUCTION" desc="A message that the Safe Browsing page is under construction."> + The Safe Browsing page is under construction. + </message> +</grit-part>
diff --git a/components/security_interstitials/content/security_interstitial_controller_client.cc b/components/security_interstitials/content/security_interstitial_controller_client.cc index 87d0789..49eba9c 100644 --- a/components/security_interstitials/content/security_interstitial_controller_client.cc +++ b/components/security_interstitials/content/security_interstitial_controller_client.cc
@@ -79,6 +79,14 @@ web_contents_->OpenURL(params); } +void SecurityInterstitialControllerClient::OpenUrlInNewForegroundTab( + const GURL& url) { + content::OpenURLParams params(url, Referrer(), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_LINK, false); + web_contents_->OpenURL(params); +} + const std::string& SecurityInterstitialControllerClient::GetApplicationLocale() const { return app_locale_;
diff --git a/components/security_interstitials/content/security_interstitial_controller_client.h b/components/security_interstitials/content/security_interstitial_controller_client.h index f10d26b..29aa10f 100644 --- a/components/security_interstitials/content/security_interstitial_controller_client.h +++ b/components/security_interstitials/content/security_interstitial_controller_client.h
@@ -45,6 +45,7 @@ void Proceed() override; void Reload() override; void OpenUrlInCurrentTab(const GURL& url) override; + void OpenUrlInNewForegroundTab(const GURL& url) override; PrefService* GetPrefService() override; const std::string& GetApplicationLocale() const override; bool CanLaunchDateAndTimeSettings() override;
diff --git a/components/security_interstitials/content/security_interstitial_page.cc b/components/security_interstitials/content/security_interstitial_page.cc index db371a66..eaa95eb 100644 --- a/components/security_interstitials/content/security_interstitial_page.cc +++ b/components/security_interstitials/content/security_interstitial_page.cc
@@ -88,7 +88,8 @@ AfterShow(); } -SecurityInterstitialControllerClient* SecurityInterstitialPage::controller() { +SecurityInterstitialControllerClient* SecurityInterstitialPage::controller() + const { return controller_.get(); }
diff --git a/components/security_interstitials/content/security_interstitial_page.h b/components/security_interstitials/content/security_interstitial_page.h index 710945ca..7cf5fc2 100644 --- a/components/security_interstitials/content/security_interstitial_page.h +++ b/components/security_interstitials/content/security_interstitial_page.h
@@ -65,7 +65,7 @@ content::WebContents* web_contents() const; GURL request_url() const; - SecurityInterstitialControllerClient* controller(); + SecurityInterstitialControllerClient* controller() const; // Update metrics when the interstitial is closed. void UpdateMetricsAfterSecurityInterstitial();
diff --git a/components/security_interstitials/core/browser/resources/list_of_interstitials.html b/components/security_interstitials/core/browser/resources/list_of_interstitials.html index 9f53597..d9a13f8b 100644 --- a/components/security_interstitials/core/browser/resources/list_of_interstitials.html +++ b/components/security_interstitials/core/browser/resources/list_of_interstitials.html
@@ -43,6 +43,9 @@ <li> <a href="ssl?type=hpkp_failure">Pinned certificate error</a> </li> + <li> + <a href="superfish-ssl">Superfish</a> + </li> </ul> <h3>SafeBrowsing</h3> <h4>Loud</h4>
diff --git a/components/security_interstitials/core/controller_client.cc b/components/security_interstitials/core/controller_client.cc index 1c61519..b1ab274 100644 --- a/components/security_interstitials/core/controller_client.cc +++ b/components/security_interstitials/core/controller_client.cc
@@ -12,7 +12,6 @@ #include "components/security_interstitials/core/urls.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" -#include "url/gurl.h" namespace security_interstitials { @@ -22,10 +21,12 @@ const char kPrivacyLinkHtml[] = "<a id=\"privacy-link\" href=\"#\" onclick=\"sendCommand(%d); " "return false;\" onmousedown=\"return false;\">%s</a>"; +const char kHelpCenterUrl[] = "https://support.google.com/chrome/"; ControllerClient::ControllerClient( std::unique_ptr<MetricsHelper> metrics_helper) - : metrics_helper_(std::move(metrics_helper)) {} + : metrics_helper_(std::move(metrics_helper)), + help_center_url_(kHelpCenterUrl) {} ControllerClient::~ControllerClient() {} @@ -45,7 +46,7 @@ GURL privacy_url(kSafeBrowsingPrivacyPolicyUrl); privacy_url = google_util::AppendGoogleLocaleParam(privacy_url, GetApplicationLocale()); - OpenUrlInCurrentTab(privacy_url); + OpenUrlInNewForegroundTab(privacy_url); } void ControllerClient::OpenExtendedReportingWhitepaper() { @@ -53,7 +54,15 @@ GURL whitepaper_url(kSafeBrowsingWhitePaperUrl); whitepaper_url = google_util::AppendGoogleLocaleParam(whitepaper_url, GetApplicationLocale()); - OpenUrlInCurrentTab(whitepaper_url); + OpenUrlInNewForegroundTab(whitepaper_url); +} + +GURL ControllerClient::GetBaseHelpCenterUrl() const { + return help_center_url_; +} + +void ControllerClient::SetBaseHelpCenterUrlForTesting(const GURL& test_url) { + help_center_url_ = test_url; } } // namespace security_interstitials
diff --git a/components/security_interstitials/core/controller_client.h b/components/security_interstitials/core/controller_client.h index 613c6bc9..ea3e214 100644 --- a/components/security_interstitials/core/controller_client.h +++ b/components/security_interstitials/core/controller_client.h
@@ -9,8 +9,8 @@ #include <string> #include "base/macros.h" +#include "url/gurl.h" -class GURL; class PrefService; namespace security_interstitials { @@ -89,15 +89,23 @@ virtual void OpenUrlInCurrentTab(const GURL& url) = 0; + virtual void OpenUrlInNewForegroundTab(const GURL& url) = 0; + virtual PrefService* GetPrefService() = 0; virtual const std::string& GetApplicationLocale() const = 0; + GURL GetBaseHelpCenterUrl() const; + + void SetBaseHelpCenterUrlForTesting(const GURL& test_url); + protected: virtual const std::string GetExtendedReportingPrefName() const = 0; private: std::unique_ptr<MetricsHelper> metrics_helper_; + // Link to the help center. + GURL help_center_url_; DISALLOW_COPY_AND_ASSIGN(ControllerClient); };
diff --git a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc index 12e67e3..85a5dfa 100644 --- a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc +++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
@@ -20,9 +20,6 @@ namespace security_interstitials { namespace { -// URL for the Help Center -const char kLearnMore[] = "https://support.google.com/chrome/"; - // For malware interstitial pages, we link the problematic URL to Google's // diagnostic page. #if defined(GOOGLE_CHROME_BUILD) @@ -70,9 +67,10 @@ controller->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW); controller->metrics_helper()->RecordUserInteraction( MetricsHelper::TOTAL_VISITS); - if (is_proceed_anyway_disabled()) + if (is_proceed_anyway_disabled()) { controller->metrics_helper()->RecordUserDecision( security_interstitials::MetricsHelper::PROCEEDING_DISABLED); + } } SafeBrowsingLoudErrorUI::~SafeBrowsingLoudErrorUI() { @@ -165,12 +163,13 @@ // User pressed "Learn more". controller()->metrics_helper()->RecordUserInteraction( security_interstitials::MetricsHelper::SHOW_LEARN_MORE); - GURL learn_more_url(kLearnMore); + + GURL learn_more_url = controller()->GetBaseHelpCenterUrl(); learn_more_url = net::AppendQueryParameter( learn_more_url, "p", get_help_center_article_link()); learn_more_url = google_util::AppendGoogleLocaleParam(learn_more_url, app_locale()); - controller()->OpenUrlInCurrentTab(learn_more_url); + OpenURL(learn_more_url); break; } case CMD_RELOAD: { @@ -197,7 +196,7 @@ GURL diagnostic_url(diagnostic); diagnostic_url = google_util::AppendGoogleLocaleParam(diagnostic_url, app_locale()); - controller()->OpenUrlInCurrentTab(diagnostic_url); + OpenURL(diagnostic_url); break; } case CMD_REPORT_PHISHING_ERROR: { @@ -206,7 +205,7 @@ GURL phishing_error_url(kReportPhishingErrorUrl); phishing_error_url = google_util::AppendGoogleLocaleParam( phishing_error_url, app_locale()); - controller()->OpenUrlInCurrentTab(phishing_error_url); + OpenURL(phishing_error_url); break; } case CMD_OPEN_DATE_SETTINGS: @@ -288,8 +287,9 @@ bool can_show_extended_reporting_option = CanShowExtendedReportingOption(); load_time_data->SetBoolean(security_interstitials::kDisplayCheckBox, can_show_extended_reporting_option); - if (!can_show_extended_reporting_option) + if (!can_show_extended_reporting_option) { return; + } const std::string privacy_link = base::StringPrintf( security_interstitials::kPrivacyLinkHtml, @@ -305,6 +305,14 @@ is_extended_reporting_enabled()); } +void SafeBrowsingLoudErrorUI::OpenURL(const GURL& url) { + if (should_open_links_in_new_tab()) { + controller()->OpenUrlInNewForegroundTab(url); + } else { + controller()->OpenUrlInCurrentTab(url); + } +} + int SafeBrowsingLoudErrorUI::GetHTMLTemplateId() const { return IDR_SECURITY_INTERSTITIAL_HTML; };
diff --git a/components/security_interstitials/core/safe_browsing_loud_error_ui.h b/components/security_interstitials/core/safe_browsing_loud_error_ui.h index d5a1e6a..4f1c1bd7 100644 --- a/components/security_interstitials/core/safe_browsing_loud_error_ui.h +++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.h
@@ -48,6 +48,10 @@ void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data); void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data); + // Helper method which either opens a URL in a new tab or a the current tab + // based on the display options setting. + void OpenURL(const GURL& url); + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingLoudErrorUI); };
diff --git a/components/security_interstitials/core/ssl_error_ui.cc b/components/security_interstitials/core/ssl_error_ui.cc index c982474..d4f74ae 100644 --- a/components/security_interstitials/core/ssl_error_ui.cc +++ b/components/security_interstitials/core/ssl_error_ui.cc
@@ -15,8 +15,8 @@ namespace security_interstitials { namespace { -// URL for help page. -const char kHelpURL[] = "https://support.google.com/chrome/answer/6098869"; +// Path to the relevant help center page. +const char kHelpPath[] = "answer/6098869"; bool IsMasked(int options, SSLErrorUI::SSLErrorOptionsMask mask) { return ((options & mask) != 0); @@ -190,7 +190,8 @@ case CMD_OPEN_HELP_CENTER: controller_->metrics_helper()->RecordUserInteraction( security_interstitials::MetricsHelper::SHOW_LEARN_MORE); - controller_->OpenUrlInCurrentTab(GURL(kHelpURL)); + controller_->OpenUrlInNewForegroundTab( + controller_->GetBaseHelpCenterUrl().Resolve(kHelpPath)); break; case CMD_RELOAD: controller_->metrics_helper()->RecordUserInteraction(
diff --git a/components/security_interstitials/core/superfish_error_ui.cc b/components/security_interstitials/core/superfish_error_ui.cc index c541249..2124319 100644 --- a/components/security_interstitials/core/superfish_error_ui.cc +++ b/components/security_interstitials/core/superfish_error_ui.cc
@@ -65,7 +65,7 @@ if (command == CMD_OPEN_HELP_CENTER) { controller()->metrics_helper()->RecordUserInteraction( security_interstitials::MetricsHelper::SHOW_LEARN_MORE); - controller()->OpenUrlInCurrentTab(GURL(kHelpURL)); + controller()->OpenUrlInNewForegroundTab(GURL(kHelpURL)); return; } SSLErrorUI::HandleCommand(command);
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc index 01c8cb7..a44ccfae 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc
@@ -52,7 +52,10 @@ weak_ptr_factory_(this) {} ActivationStateComputingNavigationThrottle:: - ~ActivationStateComputingNavigationThrottle() {} + ~ActivationStateComputingNavigationThrottle() { + if (!destruction_closure_.is_null()) + std::move(destruction_closure_).Run(); +} void ActivationStateComputingNavigationThrottle:: NotifyPageActivationWithRuleset(
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h index 2ca8b3ef..7850de3d 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
@@ -53,6 +53,10 @@ VerifiedRuleset::Handle* ruleset_handle, const ActivationState& page_activation_state); + void set_destruction_closure(base::OnceClosure closure) { + destruction_closure_ = std::move(closure); + } + // content::NavigationThrottle: content::NavigationThrottle::ThrottleCheckResult WillProcessResponse() override; @@ -92,6 +96,9 @@ base::TimeTicks defer_timestamp_; + // Callback to be run in the destructor. + base::OnceClosure destruction_closure_; + // Becomes true when the throttle manager reaches ReadyToCommitNavigation and // sends an activation IPC to the render process. Makes sure a caller cannot // take ownership of the subresource filter unless an activation IPC is sent
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc index 11e5fdf..d13a99c 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -211,11 +211,15 @@ MaybeCreateSubframeNavigationFilteringThrottle(navigation_handle)) { throttles->push_back(std::move(filtering_throttle)); } + + CHECK(!base::ContainsKey(ongoing_activation_throttles_, navigation_handle)); if (auto activation_throttle = MaybeCreateActivationStateComputingThrottle(navigation_handle)) { - CHECK(!base::ContainsKey(ongoing_activation_throttles_, navigation_handle)); ongoing_activation_throttles_[navigation_handle] = activation_throttle.get(); + activation_throttle->set_destruction_closure(base::BindOnce( + &ContentSubresourceFilterThrottleManager::OnActivationThrottleDestroyed, + weak_ptr_factory_.GetWeakPtr(), base::Unretained(navigation_handle))); throttles->push_back(std::move(activation_throttle)); } } @@ -318,4 +322,10 @@ statistics_->OnDocumentLoadStatistics(statistics); } +void ContentSubresourceFilterThrottleManager::OnActivationThrottleDestroyed( + content::NavigationHandle* navigation_handle) { + size_t num_erased = ongoing_activation_throttles_.erase(navigation_handle); + CHECK_EQ(0u, num_erased); +} + } // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h index 674877f..1ea51f3 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
@@ -129,6 +129,11 @@ void OnDocumentLoadStatistics(const DocumentLoadStatistics& statistics); + // The navigation handle ptr will be in an invalid state, do not access any + // members on it. This method is only for debugging crbug.com/736249. + void OnActivationThrottleDestroyed( + content::NavigationHandle* navigation_handle); + // For each RenderFrameHost where the last committed load has subresource // filtering activated, owns the corresponding AsyncDocumentSubresourceFilter. std::unordered_map<content::RenderFrameHost*,
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc index f415322..f714da0 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -125,8 +125,6 @@ NavigateAndCommit(GURL("https://example.first")); - Observe(RenderViewHostTestHarness::web_contents()); - // Initialize the ruleset dealer. std::vector<proto::UrlRule> rules; rules.push_back(testing::CreateWhitelistRuleForDocument( @@ -148,6 +146,7 @@ base::MakeUnique<ContentSubresourceFilterThrottleManager>( this, dealer_handle_.get(), RenderViewHostTestHarness::web_contents()); + Observe(RenderViewHostTestHarness::web_contents()); } void TearDown() override {
diff --git a/components/sync/android/javatests/src/org/chromium/components/sync/AndroidSyncSettingsTest.java b/components/sync/android/javatests/src/org/chromium/components/sync/AndroidSyncSettingsTest.java index dd73c86..a41e2f7 100644 --- a/components/sync/android/javatests/src/org/chromium/components/sync/AndroidSyncSettingsTest.java +++ b/components/sync/android/javatests/src/org/chromium/components/sync/AndroidSyncSettingsTest.java
@@ -284,6 +284,7 @@ @SmallTest @Feature({"Sync"}) + @DisabledTest(message = "crbug.com/737862") public void testSyncSettingsCaching() throws InterruptedException { // Turn on syncability. mSyncContentResolverDelegate.setMasterSyncAutomatically(true);
diff --git a/components/sync/protocol/printer_specifics.proto b/components/sync/protocol/printer_specifics.proto index 9713d632..b9ada32 100644 --- a/components/sync/protocol/printer_specifics.proto +++ b/components/sync/protocol/printer_specifics.proto
@@ -41,10 +41,12 @@ optional string description = 3; // Printer manufacturer. Should be a known manufacturuer. - optional string manufacturer = 4; + // Deprecated in favor of make_and_model. + optional string manufacturer = 4 [deprecated = true]; // Printer model. Should match a known model for the manufacturer. - optional string model = 5; + // Deprecated in favor of make_and_model. + optional string model = 5 [deprecated = true]; // Universal Resource Identifier for the printer on the network. usb:// will // be the scheme for USB printers. Example @@ -63,4 +65,9 @@ // Timestamp when printer was last updated. optional int64 updated_timestamp = 10; + + // The make and model of the printer in one string. The typical arrangement + // for this is '<make> <model>'. This aligns with the typical formatting of + // the IPP attribute printer-make-and-model. + optional string make_and_model = 11; }
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc index 4a73e953..0b47f20 100644 --- a/components/sync/protocol/proto_enum_conversions.cc +++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -294,19 +294,22 @@ return ""; } -const char* ProtoEnumToString(sync_pb::Translation::Interaction interaction) { - ASSERT_ENUM_BOUNDS(sync_pb::Translation, Interaction, UNKNOWN, - AUTO_TRANSLATION_BY_LINK); +const char* ProtoEnumToString( + sync_pb::UserEventSpecifics::Translation::Interaction interaction) { + ASSERT_ENUM_BOUNDS(sync_pb::UserEventSpecifics::Translation, Interaction, + UNKNOWN, AUTO_TRANSLATION_BY_LINK); switch (interaction) { - ENUM_CASE(sync_pb::Translation, UNKNOWN); - ENUM_CASE(sync_pb::Translation, ACCEPT); - ENUM_CASE(sync_pb::Translation, DECLINE); - ENUM_CASE(sync_pb::Translation, IGNORED); - ENUM_CASE(sync_pb::Translation, DISMISSED); - ENUM_CASE(sync_pb::Translation, MANUAL); - ENUM_CASE(sync_pb::Translation, TRANSLATION_REVERTED); - ENUM_CASE(sync_pb::Translation, AUTO_TRANSLATION_BY_PREF); - ENUM_CASE(sync_pb::Translation, AUTO_TRANSLATION_BY_LINK); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, UNKNOWN); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, ACCEPT); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, DECLINE); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, IGNORED); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, DISMISSED); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, MANUAL); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, TRANSLATION_REVERTED); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, + AUTO_TRANSLATION_BY_PREF); + ENUM_CASE(sync_pb::UserEventSpecifics::Translation, + AUTO_TRANSLATION_BY_LINK); } NOTREACHED(); return "";
diff --git a/components/sync/protocol/proto_enum_conversions.h b/components/sync/protocol/proto_enum_conversions.h index 3a2b50c..fbc82779 100644 --- a/components/sync/protocol/proto_enum_conversions.h +++ b/components/sync/protocol/proto_enum_conversions.h
@@ -65,7 +65,8 @@ const char* ProtoEnumToString(sync_pb::TabNavigation::PasswordState state); -const char* ProtoEnumToString(sync_pb::Translation::Interaction interaction); +const char* ProtoEnumToString( + sync_pb::UserEventSpecifics::Translation::Interaction interaction); const char* ProtoEnumToString( sync_pb::WalletMaskedCreditCard::WalletCardClass wallet_card_class);
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 38f162a2..3cd5a423 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -472,12 +472,13 @@ VISIT(is_bookmarked); } -VISIT_PROTO_FIELDS(const sync_pb::FieldTrial::FieldTrialPair& proto) { +VISIT_PROTO_FIELDS( + const sync_pb::UserEventSpecifics::FieldTrial::FieldTrialPair& proto) { VISIT(name_id); VISIT(group_id); } -VISIT_PROTO_FIELDS(const sync_pb::FieldTrial& proto) { +VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics::FieldTrial& proto) { VISIT_REP(field_trial_pairs); } @@ -540,12 +541,14 @@ VISIT(enabled); } -VISIT_PROTO_FIELDS(const sync_pb::LanguageDetection::Language& proto) { +VISIT_PROTO_FIELDS( + const sync_pb::UserEventSpecifics::LanguageDetection::Language& proto) { VISIT(language_code); VISIT(is_reliable); } -VISIT_PROTO_FIELDS(const sync_pb::LanguageDetection& proto) { +VISIT_PROTO_FIELDS( + const sync_pb::UserEventSpecifics::LanguageDetection& proto) { VISIT_REP(detected_languages); VISIT(adopted_language_code); } @@ -681,6 +684,7 @@ VISIT(uri); VISIT(uuid); VISIT(ppd_reference); + VISIT(make_and_model); } VISIT_PROTO_FIELDS(const sync_pb::PriorityPreferenceSpecifics& proto) { @@ -847,7 +851,7 @@ VISIT(end_time_usec); } -VISIT_PROTO_FIELDS(const sync_pb::Translation& proto) { +VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics::Translation& proto) { VISIT(from_language_code); VISIT(to_language_code); VISIT_ENUM(interaction);
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto index a2648f0b..d6a8066 100644 --- a/components/sync/protocol/user_event_specifics.proto +++ b/components/sync/protocol/user_event_specifics.proto
@@ -13,64 +13,6 @@ package sync_pb; -message FieldTrial { - message FieldTrialPair { - optional fixed32 name_id = 1; - optional fixed32 group_id = 2; - } - repeated FieldTrialPair field_trial_pairs = 1; -} - -// Language detection output. -message LanguageDetection { - message Language { - // ISO 639 language code will be used. - optional string language_code = 1; - // Whether the detected language is reliable, note this is determined by - // the CLD3. - optional bool is_reliable = 2; - } - // Top n languages. Typically we just log the top language, but for page that - // we're not confident about, we may log up to 3 top languages in descending - // order. - repeated Language detected_languages = 1; - // Adopted language code is the code of final determined language. - // It will be stored only if it's different from the first detected language. - optional string adopted_language_code = 2; -} - -// User translated a page or interacted with translate suggestion. -message Translation { - // Source language of the translation. - optional string from_language_code = 1; - // Target language of the translation. - optional string to_language_code = 2; - enum Interaction { - UNKNOWN = 0; - ACCEPT = 1; - DECLINE = 2; - // This happens when user scroll or click outside the UI without - // translation. - IGNORED = 3; - // This happens when user choose to close the translation window without - // translation. - DISMISSED = 4; - // User manually entered either language. - // In this case, from_language_code and to_language_code will be user chosen - // values. - MANUAL = 5; - // User choose to revert the translation, in this case, from_language_code - // and to_language_code will be previous chosen values. - TRANSLATION_REVERTED = 6; - // Automatically triggered translation. - // User sets always translate in user settings. - AUTO_TRANSLATION_BY_PREF = 7; - // User navigated through a click from a translated page. - AUTO_TRANSLATION_BY_LINK = 8; - } - optional Interaction interaction = 3; -} - message UserEventSpecifics { // Time of event, as measured by client in microseconds since Windows epoch. optional int64 event_time_usec = 1; @@ -87,6 +29,67 @@ // Used for testing and debugging EventLog system. message Test {} + // Reports field trial membership for the subset of trials that have been + // registered as important to other event types. + message FieldTrial { + message FieldTrialPair { + optional fixed32 name_id = 1; + optional fixed32 group_id = 2; + } + repeated FieldTrialPair field_trial_pairs = 1; + } + + // Language detection output. + message LanguageDetection { + message Language { + // ISO 639 language code will be used. + optional string language_code = 1; + // Whether the detected language is reliable, note this is determined by + // the CLD3. + optional bool is_reliable = 2; + } + // Top n languages. Typically we just log the top language, but for page + // that we're not confident about, we may log up to 3 top languages in + // descending order. + repeated Language detected_languages = 1; + // Adopted language code is the code of final determined language. + // It will be stored only if it's different from the first detected + // language. + optional string adopted_language_code = 2; + } + + // User translated a page or interacted with translate suggestion. + message Translation { + // Source language of the translation. + optional string from_language_code = 1; + // Target language of the translation. + optional string to_language_code = 2; + enum Interaction { + UNKNOWN = 0; + ACCEPT = 1; + DECLINE = 2; + // This happens when user scroll or click outside the UI without + // translation. + IGNORED = 3; + // This happens when user choose to close the translation window without + // translation. + DISMISSED = 4; + // User manually entered either language. + // In this case, from_language_code and to_language_code will be user + // chosen values. + MANUAL = 5; + // User choose to revert the translation, in this case, from_language_code + // and to_language_code will be previous chosen values. + TRANSLATION_REVERTED = 6; + // Automatically triggered translation. + // User sets always translate in user settings. + AUTO_TRANSLATION_BY_PREF = 7; + // User navigated through a click from a translated page. + AUTO_TRANSLATION_BY_LINK = 8; + } + optional Interaction interaction = 3; + } + oneof event { Test test_event = 8; FieldTrial field_trial_event = 9;
diff --git a/components/translate/core/common/language_detection_logging_helper.cc b/components/translate/core/common/language_detection_logging_helper.cc index 1f29dc3..cadb663 100644 --- a/components/translate/core/common/language_detection_logging_helper.cc +++ b/components/translate/core/common/language_detection_logging_helper.cc
@@ -23,7 +23,7 @@ // navigations is determined. specifics->set_navigation_id(navigation_id); - sync_pb::LanguageDetection lang_detection; + sync_pb::UserEventSpecifics::LanguageDetection lang_detection; auto* const lang = lang_detection.add_detected_languages(); lang->set_language_code(details.cld_language); lang->set_is_reliable(details.is_cld_reliable);
diff --git a/components/translate/core/common/language_detection_logging_helper_unittest.cc b/components/translate/core/common/language_detection_logging_helper_unittest.cc index fc9c7eba..948fa9d 100644 --- a/components/translate/core/common/language_detection_logging_helper_unittest.cc +++ b/components/translate/core/common/language_detection_logging_helper_unittest.cc
@@ -19,7 +19,7 @@ details.is_cld_reliable = false; details.adopted_language = "ja"; // Expected language detection. - sync_pb::LanguageDetection lang_detection; + sync_pb::UserEventSpecifics::LanguageDetection lang_detection; auto* const lang = lang_detection.add_detected_languages(); lang->set_language_code(details.cld_language); lang->set_is_reliable(details.is_cld_reliable); @@ -41,7 +41,7 @@ details.is_cld_reliable = true; details.adopted_language = "en"; // Expected language detection. - sync_pb::LanguageDetection lang_detection; + sync_pb::UserEventSpecifics::LanguageDetection lang_detection; auto* const lang = lang_detection.add_detected_languages(); lang->set_language_code(details.cld_language); lang->set_is_reliable(details.is_cld_reliable);
diff --git a/components/translate/core/common/translation_logging_helper.cc b/components/translate/core/common/translation_logging_helper.cc index f0d4c1c..d75f6948 100644 --- a/components/translate/core/common/translation_logging_helper.cc +++ b/components/translate/core/common/translation_logging_helper.cc
@@ -9,6 +9,8 @@ #include "components/metrics/proto/translate_event.pb.h" #include "components/sync/protocol/user_event_specifics.pb.h" +using Translation = sync_pb::UserEventSpecifics::Translation; + namespace translate { namespace { using metrics::TranslateEventProto; @@ -27,7 +29,7 @@ translation->set_to_language_code(translate_event.target_language()); switch (translate_event.event_type()) { case TranslateEventProto::UNKNOWN: - translation->set_interaction(sync_pb::Translation::UNKNOWN); + translation->set_interaction(Translation::UNKNOWN); break; case TranslateEventProto::USER_ACCEPT: if (translate_event.has_modified_source_language() || @@ -43,30 +45,28 @@ translation->set_to_language_code( translate_event.modified_target_language()); } - translation->set_interaction(sync_pb::Translation::MANUAL); + translation->set_interaction(Translation::MANUAL); } else { - translation->set_interaction(sync_pb::Translation::ACCEPT); + translation->set_interaction(Translation::ACCEPT); } break; case TranslateEventProto::USER_DECLINE: - translation->set_interaction(sync_pb::Translation::DECLINE); + translation->set_interaction(Translation::DECLINE); break; case TranslateEventProto::USER_IGNORE: - translation->set_interaction(sync_pb::Translation::IGNORED); + translation->set_interaction(Translation::IGNORED); break; case TranslateEventProto::USER_DISMISS: - translation->set_interaction(sync_pb::Translation::DISMISSED); + translation->set_interaction(Translation::DISMISSED); break; case TranslateEventProto::USER_REVERT: - translation->set_interaction(sync_pb::Translation::TRANSLATION_REVERTED); + translation->set_interaction(Translation::TRANSLATION_REVERTED); break; case TranslateEventProto::AUTO_TRANSLATION_BY_PREF: - translation->set_interaction( - sync_pb::Translation::AUTO_TRANSLATION_BY_PREF); + translation->set_interaction(Translation::AUTO_TRANSLATION_BY_PREF); break; case TranslateEventProto::AUTO_TRANSLATION_BY_LINK: - translation->set_interaction( - sync_pb::Translation::AUTO_TRANSLATION_BY_LINK); + translation->set_interaction(Translation::AUTO_TRANSLATION_BY_LINK); break; default: // We don't care about other events. return false;
diff --git a/components/translate/core/common/translation_logging_helper_unittest.cc b/components/translate/core/common/translation_logging_helper_unittest.cc index 62046de..2fbb624 100644 --- a/components/translate/core/common/translation_logging_helper_unittest.cc +++ b/components/translate/core/common/translation_logging_helper_unittest.cc
@@ -12,7 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" using metrics::TranslateEventProto; -using sync_pb::Translation; +using Translation = sync_pb::UserEventSpecifics::Translation; void EqualTranslationProto(const Translation& first, const Translation& second) {
diff --git a/components/ui_devtools/devtools_server.cc b/components/ui_devtools/devtools_server.cc index c8fd76c1..a901f93 100644 --- a/components/ui_devtools/devtools_server.cc +++ b/components/ui_devtools/devtools_server.cc
@@ -65,6 +65,10 @@ } UiDevToolsServer::~UiDevToolsServer() { + if (io_thread_task_runner_) + io_thread_task_runner_->DeleteSoon(FROM_HERE, server_.release()); + if (thread_ && thread_->IsRunning()) + thread_->Stop(); devtools_server_ = nullptr; }
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc index 298b1c18..154cbf7 100644 --- a/components/url_formatter/url_formatter.cc +++ b/components/url_formatter/url_formatter.cc
@@ -360,6 +360,7 @@ const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; +const FormatUrlType kFormatUrlExperimentalElideAfterHost = 1 << 3; base::string16 FormatUrl(const GURL& url, FormatUrlTypes format_types, @@ -506,29 +507,56 @@ } // Path & query. Both get the same general unescape & convert treatment. - if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || - !CanStripTrailingSlash(url)) { - AppendFormattedComponent(spec, parsed.path, - NonHostComponentTransform(unescape_rules), - &url_string, &new_parsed->path, adjustments); - } else { + if ((format_types & kFormatUrlOmitTrailingSlashOnBareHostname) && + CanStripTrailingSlash(url)) { + // Omit the path, which is a single trailing slash. There's no query or ref. if (parsed.path.len > 0) { adjustments->push_back(base::OffsetAdjuster::Adjustment( parsed.path.begin, parsed.path.len, 0)); } - } - if (parsed.query.is_valid()) - url_string.push_back('?'); - AppendFormattedComponent(spec, parsed.query, - NonHostComponentTransform(unescape_rules), - &url_string, &new_parsed->query, adjustments); + } else if ((format_types & kFormatUrlExperimentalElideAfterHost) && + url.IsStandard() && !url.SchemeIsFile() && + !url.SchemeIsFileSystem()) { + // Replace everything after the host with a forward slash and ellipsis. + url_string.push_back('/'); + constexpr base::char16 kEllipsisUTF16[] = {0x2026, 0}; + url_string.append(kEllipsisUTF16); - // Ref. This is valid, unescaped UTF-8, so we can just convert. - if (parsed.ref.is_valid()) - url_string.push_back('#'); - AppendFormattedComponent(spec, parsed.ref, - NonHostComponentTransform(net::UnescapeRule::NONE), - &url_string, &new_parsed->ref, adjustments); + // Compute the length of everything we're replacing. For the path, we are + // removing everything but the first slash. + size_t old_length = parsed.path.len - 1; + + // We're also removing any query, plus the delimiting '?'. + if (parsed.query.is_valid()) + old_length += parsed.query.len + 1; + + // We're also removing any ref, plus the delimiting '#'. + if (parsed.ref.is_valid()) + old_length += parsed.ref.len + 1; + + // We're replacing all of these with a single character (an ellipsis). The + // adjustment begins after the forward slash at the beginning of the path. + adjustments->push_back( + base::OffsetAdjuster::Adjustment(parsed.path.begin + 1, old_length, 1)); + } else { + // Append the formatted path, query, and ref. + AppendFormattedComponent(spec, parsed.path, + NonHostComponentTransform(unescape_rules), + &url_string, &new_parsed->path, adjustments); + + if (parsed.query.is_valid()) + url_string.push_back('?'); + AppendFormattedComponent(spec, parsed.query, + NonHostComponentTransform(unescape_rules), + &url_string, &new_parsed->query, adjustments); + + // Ref. This is valid, unescaped UTF-8, so we can just convert. + if (parsed.ref.is_valid()) + url_string.push_back('#'); + AppendFormattedComponent(spec, parsed.ref, + NonHostComponentTransform(net::UnescapeRule::NONE), + &url_string, &new_parsed->ref, adjustments); + } // If we need to strip out http do it after the fact. if (omit_http && base::StartsWith(url_string, base::ASCIIToUTF16(kHTTP),
diff --git a/components/url_formatter/url_formatter.h b/components/url_formatter/url_formatter.h index 90f2bbf9..3e01b2ef 100644 --- a/components/url_formatter/url_formatter.h +++ b/components/url_formatter/url_formatter.h
@@ -51,9 +51,14 @@ // meaningful for non-file "standard" URLs. extern const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname; -// Convenience for omitting all unecessary types. +// Convenience for omitting all unecessary types. Does not include experimental +// flags below. extern const FormatUrlType kFormatUrlOmitAll; +// Replaces the path, query, and ref with an ellipsis. Experimental and not in +// kFormatUrlOmitAll. +extern const FormatUrlType kFormatUrlExperimentalElideAfterHost; + // Creates a string representation of |url|. The IDN host name is turned to // Unicode if the Unicode representation is deemed safe. |format_type| is a // bitmask of FormatUrlTypes, see it for details. |unescape_rules| defines how
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc index 544f550..fc80118 100644 --- a/components/url_formatter/url_formatter_unittest.cc +++ b/components/url_formatter/url_formatter_unittest.cc
@@ -736,10 +736,9 @@ TEST(UrlFormatterTest, FormatUrl) { FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword; const UrlTestData tests[] = { - {"Empty URL", "", default_format_type, net::UnescapeRule::NORMAL, L"", - 0}, + {"Empty URL", "", default_format_type, net::UnescapeRule::NORMAL, L"", 0}, - {"Simple URL", "http://www.google.com/", default_format_type, + {"Simple URL", "http://www.google.com/", default_format_type, net::UnescapeRule::NORMAL, L"http://www.google.com/", 7}, {"With a port number and a reference", @@ -793,7 +792,8 @@ "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", default_format_type, net::UnescapeRule::NONE, // GURL parses %-encoded hostnames into Punycode. - L"http://\x30B0\x30FC\x30B0\x30EB.jp/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" + L"http://\x30B0\x30FC\x30B0\x30EB.jp/" + L"%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" L"?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", 7}, @@ -807,14 +807,14 @@ 7}, {"Unescape normally with BiDi control character", - "http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", - default_format_type, net::UnescapeRule::NORMAL, + "http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", default_format_type, + net::UnescapeRule::NORMAL, L"http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", 7}, {"Unescape normally including unescape spaces", - "http://www.google.com/search?q=Hello%20World", - default_format_type, net::UnescapeRule::SPACES, - L"http://www.google.com/search?q=Hello World", 7}, + "http://www.google.com/search?q=Hello%20World", default_format_type, + net::UnescapeRule::SPACES, L"http://www.google.com/search?q=Hello World", + 7}, /* {"unescape=true with some special characters", @@ -831,9 +831,8 @@ {"omit http", "http://www.google.com/", kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, L"www.google.com/", 0}, - {"omit http with https", "https://www.google.com/", - kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, - L"https://www.google.com/", 8}, + {"omit http with https", "https://www.google.com/", kFormatUrlOmitHTTP, + net::UnescapeRule::NORMAL, L"https://www.google.com/", 8}, {"omit http starts with ftp.", "http://ftp.google.com/", kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, L"http://ftp.google.com/", @@ -850,8 +849,8 @@ kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, L"http://www.google.com/?", 7}, {"omit slash when it's not the entire path", "http://www.google.com/foo", - kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::NORMAL, L"http://www.google.com/foo", 7}, + kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, + L"http://www.google.com/foo", 7}, {"omit slash for nonstandard URLs", "data:/", kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, L"data:/", 5}, @@ -865,20 +864,55 @@ L"view-source:http://\x30B0\x30FC\x30B0\x30EB.jp/", 19}, {"view-source of view-source", - "view-source:view-source:http://xn--qcka1pmc.jp/", - default_format_type, net::UnescapeRule::NORMAL, + "view-source:view-source:http://xn--qcka1pmc.jp/", default_format_type, + net::UnescapeRule::NORMAL, L"view-source:view-source:http://xn--qcka1pmc.jp/", 12}, // view-source should omit http and trailing slash where non-view-source // would. - {"view-source omit http", "view-source:http://a.b/c", - kFormatUrlOmitAll, net::UnescapeRule::NORMAL, L"view-source:a.b/c", 12}, + {"view-source omit http", "view-source:http://a.b/c", kFormatUrlOmitAll, + net::UnescapeRule::NORMAL, L"view-source:a.b/c", 12}, {"view-source omit http starts with ftp.", "view-source:http://ftp.b/c", kFormatUrlOmitAll, net::UnescapeRule::NORMAL, L"view-source:http://ftp.b/c", 19}, {"view-source omit slash when it's the entire path", - "view-source:http://a.b/", kFormatUrlOmitAll, - net::UnescapeRule::NORMAL, L"view-source:a.b", 12}, + "view-source:http://a.b/", kFormatUrlOmitAll, net::UnescapeRule::NORMAL, + L"view-source:a.b", 12}, + + // -------- elide after host -------- + {"elide after host but still strip trailing slashes", + "http://google.com/", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com", 0}, + {"elide after host in simple filename-only case", "http://google.com/foo", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host in directory and file case", "http://google.com/ab/cd", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with query only", "http://google.com/?foo=bar", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with ref only", "http://google.com/#foobar", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with path and query only", "http://google.com/foo?a=b", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with path and ref only", "http://google.com/foo#c", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with query and ref only", "http://google.com/?a=b#c", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with path, query and ref", + "http://google.com/foo?a=b#c", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, + {"elide after host with repeated delimiters (sanity check)", + "http://google.com////???####", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, }; for (size_t i = 0; i < arraysize(tests); ++i) { @@ -1221,6 +1255,28 @@ }; CheckAdjustedOffsets("http://user@foo.com/", kFormatUrlOmitAll, net::UnescapeRule::NORMAL, omit_all_offsets); + + const size_t elide_after_host_offsets[] = { + 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, + 5, 6, 7, 8, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 9}; + CheckAdjustedOffsets("http://foo.com/abcdefg", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, elide_after_host_offsets); + CheckAdjustedOffsets("http://foo.com/abc/def", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, elide_after_host_offsets); + CheckAdjustedOffsets("http://foo.com/abc?a=b", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, elide_after_host_offsets); + CheckAdjustedOffsets("http://foo.com/abc#def", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, elide_after_host_offsets); + CheckAdjustedOffsets("http://foo.com/a?a=b#f", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, elide_after_host_offsets); + CheckAdjustedOffsets("http://foo.com//??###", + kFormatUrlOmitAll | kFormatUrlExperimentalElideAfterHost, + net::UnescapeRule::NORMAL, elide_after_host_offsets); } } // namespace
diff --git a/components/viz/client/BUILD.gn b/components/viz/client/BUILD.gn index bde56a9..d96a543 100644 --- a/components/viz/client/BUILD.gn +++ b/components/viz/client/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "client_layer_tree_frame_sink.cc", "client_layer_tree_frame_sink.h", + "client_shared_bitmap_manager.cc", + "client_shared_bitmap_manager.h", "local_surface_id_provider.cc", "local_surface_id_provider.h", ]
diff --git a/services/ui/public/cpp/bitmap/child_shared_bitmap_manager.cc b/components/viz/client/client_shared_bitmap_manager.cc similarity index 66% rename from services/ui/public/cpp/bitmap/child_shared_bitmap_manager.cc rename to components/viz/client/client_shared_bitmap_manager.cc index 13eb4fc..0651549 100644 --- a/services/ui/public/cpp/bitmap/child_shared_bitmap_manager.cc +++ b/components/viz/client/client_shared_bitmap_manager.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 "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include <stddef.h> @@ -17,33 +17,36 @@ #include "mojo/public/cpp/system/platform_handle.h" #include "ui/gfx/geometry/size.h" -namespace ui { +namespace viz { namespace { -class ChildSharedBitmap : public cc::SharedBitmap { +class ClientSharedBitmap : public cc::SharedBitmap { public: - ChildSharedBitmap( - const scoped_refptr<cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr> - shared_bitmap_manager_ptr, + ClientSharedBitmap( + scoped_refptr< + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr> + shared_bitmap_allocation_notifier, base::SharedMemory* shared_memory, const cc::SharedBitmapId& id) : cc::SharedBitmap(static_cast<uint8_t*>(shared_memory->memory()), id), - shared_bitmap_manager_ptr_(shared_bitmap_manager_ptr) {} + shared_bitmap_allocation_notifier_( + std::move(shared_bitmap_allocation_notifier)) {} - ChildSharedBitmap( - const scoped_refptr<cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr> - shared_bitmap_manager_ptr, + ClientSharedBitmap( + scoped_refptr< + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr> + shared_bitmap_allocation_notifier, std::unique_ptr<base::SharedMemory> shared_memory_holder, const cc::SharedBitmapId& id) - : ChildSharedBitmap(shared_bitmap_manager_ptr, - shared_memory_holder.get(), - id) { + : ClientSharedBitmap(std::move(shared_bitmap_allocation_notifier), + shared_memory_holder.get(), + id) { shared_memory_holder_ = std::move(shared_memory_holder); } - ~ChildSharedBitmap() override { - (*shared_bitmap_manager_ptr_)->DidDeleteSharedBitmap(id()); + ~ClientSharedBitmap() override { + (*shared_bitmap_allocation_notifier_)->DidDeleteSharedBitmap(id()); } // cc::SharedBitmap: @@ -54,8 +57,9 @@ } private: - scoped_refptr<cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr> - shared_bitmap_manager_ptr_; + scoped_refptr< + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr> + shared_bitmap_allocation_notifier_; std::unique_ptr<base::SharedMemory> shared_memory_holder_; }; @@ -105,16 +109,18 @@ } // namespace -ChildSharedBitmapManager::ChildSharedBitmapManager( - const scoped_refptr<cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr>& - shared_bitmap_manager_ptr) - : shared_bitmap_manager_ptr_(shared_bitmap_manager_ptr) {} +ClientSharedBitmapManager::ClientSharedBitmapManager( + scoped_refptr< + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr> + shared_bitmap_allocation_notifier) + : shared_bitmap_allocation_notifier_( + std::move(shared_bitmap_allocation_notifier)) {} -ChildSharedBitmapManager::~ChildSharedBitmapManager() {} +ClientSharedBitmapManager::~ClientSharedBitmapManager() {} std::unique_ptr<cc::SharedBitmap> -ChildSharedBitmapManager::AllocateSharedBitmap(const gfx::Size& size) { - TRACE_EVENT2("renderer", "ChildSharedBitmapManager::AllocateSharedBitmap", +ClientSharedBitmapManager::AllocateSharedBitmap(const gfx::Size& size) { + TRACE_EVENT2("renderer", "ClientSharedBitmapManager::AllocateSharedBitmap", "width", size.width(), "height", size.height()); size_t memory_size; if (!cc::SharedBitmap::SizeInBytes(size, &memory_size)) @@ -131,28 +137,28 @@ // remains available. memory->Close(); - return base::MakeUnique<ChildSharedBitmap>(shared_bitmap_manager_ptr_, - std::move(memory), id); + return base::MakeUnique<ClientSharedBitmap>( + shared_bitmap_allocation_notifier_, std::move(memory), id); } std::unique_ptr<cc::SharedBitmap> -ChildSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size&, - const cc::SharedBitmapId&) { +ClientSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size&, + const cc::SharedBitmapId&) { NOTREACHED(); return nullptr; } std::unique_ptr<cc::SharedBitmap> -ChildSharedBitmapManager::GetBitmapForSharedMemory(base::SharedMemory* mem) { +ClientSharedBitmapManager::GetBitmapForSharedMemory(base::SharedMemory* mem) { cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); NotifyAllocatedSharedBitmap(mem, cc::SharedBitmap::GenerateId()); - return base::MakeUnique<ChildSharedBitmap>(shared_bitmap_manager_ptr_, mem, - id); + return base::MakeUnique<ClientSharedBitmap>( + shared_bitmap_allocation_notifier_, mem, id); } // Notifies the browser process that a shared bitmap with the given ID was // allocated. Caller keeps ownership of |memory|. -void ChildSharedBitmapManager::NotifyAllocatedSharedBitmap( +void ClientSharedBitmapManager::NotifyAllocatedSharedBitmap( base::SharedMemory* memory, const cc::SharedBitmapId& id) { base::SharedMemoryHandle handle_to_send = @@ -165,8 +171,8 @@ mojo::ScopedSharedBufferHandle buffer_handle = mojo::WrapSharedMemoryHandle( handle_to_send, memory->mapped_size(), true /* read_only */); - (*shared_bitmap_manager_ptr_) + (*shared_bitmap_allocation_notifier_) ->DidAllocateSharedBitmap(std::move(buffer_handle), id); } -} // namespace ui +} // namespace viz
diff --git a/components/viz/client/client_shared_bitmap_manager.h b/components/viz/client/client_shared_bitmap_manager.h new file mode 100644 index 0000000..5e4154cc --- /dev/null +++ b/components/viz/client/client_shared_bitmap_manager.h
@@ -0,0 +1,55 @@ +// 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 COMPONENTS_VIZ_CLIENT_CLIENT_SHARED_BITMAP_MANAGER_H_ +#define COMPONENTS_VIZ_CLIENT_CLIENT_SHARED_BITMAP_MANAGER_H_ + +#include <stdint.h> + +#include <memory> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/shared_memory.h" +#include "cc/ipc/shared_bitmap_allocation_notifier.mojom.h" +#include "cc/resources/shared_bitmap_manager.h" +#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" + +namespace viz { + +// A SharedBitmapManager implementation for use outside of the display +// compositor's process. This implementation supports SharedBitmaps that +// can be transported over process boundaries to the display compositor. +class ClientSharedBitmapManager : public cc::SharedBitmapManager { + public: + explicit ClientSharedBitmapManager( + scoped_refptr< + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr> + shared_bitmap_allocation_notifier); + ~ClientSharedBitmapManager() override; + + // cc::SharedBitmapManager implementation. + std::unique_ptr<cc::SharedBitmap> AllocateSharedBitmap( + const gfx::Size& size) override; + std::unique_ptr<cc::SharedBitmap> GetSharedBitmapFromId( + const gfx::Size&, + const cc::SharedBitmapId&) override; + + std::unique_ptr<cc::SharedBitmap> GetBitmapForSharedMemory( + base::SharedMemory* mem); + + private: + void NotifyAllocatedSharedBitmap(base::SharedMemory* memory, + const cc::SharedBitmapId& id); + + scoped_refptr< + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr> + shared_bitmap_allocation_notifier_; + + DISALLOW_COPY_AND_ASSIGN(ClientSharedBitmapManager); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_CLIENT_CLIENT_SHARED_BITMAP_MANAGER_H_
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index b5f8307..9b0aa5f 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -17,10 +17,12 @@ "display_compositor/display_provider.h", "display_compositor/gpu_display_provider.cc", "display_compositor/gpu_display_provider.h", - "display_compositor/host_shared_bitmap_manager.cc", - "display_compositor/host_shared_bitmap_manager.h", "display_compositor/in_process_gpu_memory_buffer_manager.cc", "display_compositor/in_process_gpu_memory_buffer_manager.h", + "display_compositor/server_shared_bitmap_manager.cc", + "display_compositor/server_shared_bitmap_manager.h", + "display_compositor/shared_bitmap_allocation_notifier_impl.cc", + "display_compositor/shared_bitmap_allocation_notifier_impl.h", "frame_sinks/frame_eviction_manager.cc", "frame_sinks/frame_eviction_manager.h", "frame_sinks/frame_evictor.cc", @@ -96,7 +98,7 @@ testonly = true sources = [ "display_compositor/buffer_queue_unittest.cc", - "display_compositor/host_shared_bitmap_manager_unittest.cc", + "display_compositor/server_shared_bitmap_manager_unittest.cc", ] if (!use_aura && !is_mac) {
diff --git a/components/viz/service/display_compositor/gpu_display_provider.cc b/components/viz/service/display_compositor/gpu_display_provider.cc index 49f1376..683daf0 100644 --- a/components/viz/service/display_compositor/gpu_display_provider.cc +++ b/components/viz/service/display_compositor/gpu_display_provider.cc
@@ -16,8 +16,8 @@ #include "cc/surfaces/display.h" #include "cc/surfaces/display_scheduler.h" #include "components/viz/service/display_compositor/display_output_surface.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" #include "components/viz/service/display_compositor/in_process_gpu_memory_buffer_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/service/image_factory.h" #include "gpu/ipc/service/gpu_channel_manager.h" @@ -100,7 +100,7 @@ *begin_frame_source = std::move(synthetic_begin_frame_source); return base::MakeUnique<cc::Display>( - HostSharedBitmapManager::current(), gpu_memory_buffer_manager_.get(), + ServerSharedBitmapManager::current(), gpu_memory_buffer_manager_.get(), settings, frame_sink_id, std::move(display_output_surface), std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>(task_runner_.get()));
diff --git a/components/viz/service/display_compositor/host_shared_bitmap_manager.cc b/components/viz/service/display_compositor/host_shared_bitmap_manager.cc deleted file mode 100644 index 1d30cbb..0000000 --- a/components/viz/service/display_compositor/host_shared_bitmap_manager.cc +++ /dev/null
@@ -1,236 +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 "components/viz/service/display_compositor/host_shared_bitmap_manager.h" - -#include <stdint.h> - -#include <utility> - -#include "base/lazy_instance.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/trace_event/process_memory_dump.h" -#include "build/build_config.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "ui/gfx/geometry/size.h" - -namespace viz { - -class BitmapData : public base::RefCountedThreadSafe<BitmapData> { - public: - explicit BitmapData(size_t buffer_size) : buffer_size(buffer_size) {} - std::unique_ptr<base::SharedMemory> memory; - std::unique_ptr<uint8_t[]> pixels; - size_t buffer_size; - - private: - friend class base::RefCountedThreadSafe<BitmapData>; - ~BitmapData() {} - DISALLOW_COPY_AND_ASSIGN(BitmapData); -}; - -namespace { - -class HostSharedBitmap : public cc::SharedBitmap { - public: - HostSharedBitmap(uint8_t* pixels, - scoped_refptr<BitmapData> bitmap_data, - const cc::SharedBitmapId& id, - HostSharedBitmapManager* manager) - : SharedBitmap(pixels, id), - bitmap_data_(bitmap_data), - manager_(manager) {} - - ~HostSharedBitmap() override { - if (manager_) - manager_->FreeSharedMemoryFromMap(id()); - } - - // cc::SharedBitmap: - base::SharedMemoryHandle GetSharedMemoryHandle() const override { - if (!bitmap_data_->memory) - return base::SharedMemoryHandle(); - return bitmap_data_->memory->handle(); - } - - private: - scoped_refptr<BitmapData> bitmap_data_; - HostSharedBitmapManager* manager_; -}; - -} // namespace - -base::LazyInstance<HostSharedBitmapManager>::DestructorAtExit - g_shared_memory_manager = LAZY_INSTANCE_INITIALIZER; - -HostSharedBitmapManagerClient::HostSharedBitmapManagerClient( - HostSharedBitmapManager* manager) - : manager_(manager), binding_(this) {} - -HostSharedBitmapManagerClient::~HostSharedBitmapManagerClient() { - for (const auto& id : owned_bitmaps_) - manager_->ChildDeletedSharedBitmap(id); -} - -void HostSharedBitmapManagerClient::Bind( - cc::mojom::SharedBitmapManagerAssociatedRequest request) { - binding_.Bind(std::move(request)); -} - -void HostSharedBitmapManagerClient::DidAllocateSharedBitmap( - mojo::ScopedSharedBufferHandle buffer, - const cc::SharedBitmapId& id) { - base::SharedMemoryHandle memory_handle; - size_t size; - MojoResult result = mojo::UnwrapSharedMemoryHandle( - std::move(buffer), &memory_handle, &size, NULL); - DCHECK_EQ(result, MOJO_RESULT_OK); - this->ChildAllocatedSharedBitmap(size, memory_handle, id); -} - -void HostSharedBitmapManagerClient::ChildAllocatedSharedBitmap( - size_t buffer_size, - const base::SharedMemoryHandle& handle, - const cc::SharedBitmapId& id) { - if (manager_->ChildAllocatedSharedBitmap(buffer_size, handle, id)) { - base::AutoLock lock(lock_); - owned_bitmaps_.insert(id); - } -} - -void HostSharedBitmapManagerClient::DidDeleteSharedBitmap( - const cc::SharedBitmapId& id) { - manager_->ChildDeletedSharedBitmap(id); - { - base::AutoLock lock(lock_); - owned_bitmaps_.erase(id); - } -} - -HostSharedBitmapManager::HostSharedBitmapManager() {} -HostSharedBitmapManager::~HostSharedBitmapManager() { - DCHECK(handle_map_.empty()); -} - -HostSharedBitmapManager* HostSharedBitmapManager::current() { - return g_shared_memory_manager.Pointer(); -} - -std::unique_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap( - const gfx::Size& size) { - base::AutoLock lock(lock_); - size_t bitmap_size; - if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size)) - return nullptr; - - scoped_refptr<BitmapData> data(new BitmapData(bitmap_size)); - // Bitmaps allocated in host don't need to be shared to other processes, so - // allocate them with new instead. - data->pixels = std::unique_ptr<uint8_t[]>(new uint8_t[bitmap_size]); - - cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); - handle_map_[id] = data; - return base::MakeUnique<HostSharedBitmap>(data->pixels.get(), data, id, this); -} - -std::unique_ptr<cc::SharedBitmap> -HostSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size& size, - const cc::SharedBitmapId& id) { - base::AutoLock lock(lock_); - BitmapMap::iterator it = handle_map_.find(id); - if (it == handle_map_.end()) - return nullptr; - - BitmapData* data = it->second.get(); - - size_t bitmap_size; - if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) || - bitmap_size > data->buffer_size) - return nullptr; - - if (data->pixels) { - return base::MakeUnique<HostSharedBitmap>(data->pixels.get(), data, id, - nullptr); - } - if (!data->memory->memory()) { - return nullptr; - } - - return base::MakeUnique<HostSharedBitmap>( - static_cast<uint8_t*>(data->memory->memory()), data, id, nullptr); -} - -bool HostSharedBitmapManager::OnMemoryDump( - const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) { - base::AutoLock lock(lock_); - - for (const auto& bitmap : handle_map_) { - base::trace_event::MemoryAllocatorDump* dump = - pmd->CreateAllocatorDump(base::StringPrintf( - "sharedbitmap/%s", - base::HexEncode(bitmap.first.name, sizeof(bitmap.first.name)) - .c_str())); - if (!dump) - return false; - - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - bitmap.second->buffer_size); - - // Generate a global GUID used to share this allocation with renderer - // processes. - auto guid = cc::GetSharedBitmapGUIDForTracing(bitmap.first); - base::UnguessableToken shared_memory_guid; - if (bitmap.second->memory) { - shared_memory_guid = bitmap.second->memory->handle().GetGUID(); - pmd->CreateSharedMemoryOwnershipEdge( - dump->guid(), guid, shared_memory_guid, 0 /* importance*/); - } else { - pmd->CreateSharedGlobalAllocatorDump(guid); - pmd->AddOwnershipEdge(dump->guid(), guid); - } - } - - return true; -} - -bool HostSharedBitmapManager::ChildAllocatedSharedBitmap( - size_t buffer_size, - const base::SharedMemoryHandle& handle, - const cc::SharedBitmapId& id) { - base::AutoLock lock(lock_); - if (handle_map_.find(id) != handle_map_.end()) - return false; - scoped_refptr<BitmapData> data(new BitmapData(buffer_size)); - - handle_map_[id] = data; - data->memory = base::MakeUnique<base::SharedMemory>(handle, false); - data->memory->Map(data->buffer_size); - data->memory->Close(); - return true; -} - -void HostSharedBitmapManager::ChildDeletedSharedBitmap( - const cc::SharedBitmapId& id) { - base::AutoLock lock(lock_); - handle_map_.erase(id); -} - -size_t HostSharedBitmapManager::AllocatedBitmapCount() const { - base::AutoLock lock(lock_); - return handle_map_.size(); -} - -void HostSharedBitmapManager::FreeSharedMemoryFromMap( - const cc::SharedBitmapId& id) { - base::AutoLock lock(lock_); - handle_map_.erase(id); -} - -} // namespace viz
diff --git a/components/viz/service/display_compositor/host_shared_bitmap_manager.h b/components/viz/service/display_compositor/host_shared_bitmap_manager.h deleted file mode 100644 index 3ac53791..0000000 --- a/components/viz/service/display_compositor/host_shared_bitmap_manager.h +++ /dev/null
@@ -1,111 +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 COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_ -#define COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_ - -#include <stddef.h> - -#include <map> -#include <memory> -#include <set> - -#include "base/containers/hash_tables.h" -#include "base/hash.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/shared_memory.h" -#include "base/synchronization/lock.h" -#include "base/trace_event/memory_dump_provider.h" -#include "cc/ipc/shared_bitmap_manager.mojom.h" -#include "cc/resources/shared_bitmap_manager.h" -#include "components/viz/service/viz_service_export.h" -#include "mojo/public/cpp/bindings/associated_binding.h" - -namespace BASE_HASH_NAMESPACE { -template <> -struct hash<cc::SharedBitmapId> { - size_t operator()(const cc::SharedBitmapId& id) const { - return base::Hash(reinterpret_cast<const char*>(id.name), sizeof(id.name)); - } -}; -} // namespace BASE_HASH_NAMESPACE - -namespace viz { -class BitmapData; -class HostSharedBitmapManager; - -class VIZ_SERVICE_EXPORT HostSharedBitmapManagerClient - : NON_EXPORTED_BASE(public cc::mojom::SharedBitmapManager) { - public: - explicit HostSharedBitmapManagerClient(HostSharedBitmapManager* manager); - - ~HostSharedBitmapManagerClient() override; - - void Bind(cc::mojom::SharedBitmapManagerAssociatedRequest request); - - // cc::mojom::SharedBitmapManager overrides: - void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer, - const cc::SharedBitmapId& id) override; - void DidDeleteSharedBitmap(const cc::SharedBitmapId& id) override; - - void ChildAllocatedSharedBitmap(size_t buffer_size, - const base::SharedMemoryHandle& handle, - const cc::SharedBitmapId& id); - - private: - HostSharedBitmapManager* manager_; - mojo::AssociatedBinding<cc::mojom::SharedBitmapManager> binding_; - - // Lock must be held around access to owned_bitmaps_. - base::Lock lock_; - base::hash_set<cc::SharedBitmapId> owned_bitmaps_; - - DISALLOW_COPY_AND_ASSIGN(HostSharedBitmapManagerClient); -}; - -class VIZ_SERVICE_EXPORT HostSharedBitmapManager - : public cc::SharedBitmapManager, - public base::trace_event::MemoryDumpProvider { - public: - HostSharedBitmapManager(); - ~HostSharedBitmapManager() override; - - static HostSharedBitmapManager* current(); - - // cc::SharedBitmapManager implementation. - std::unique_ptr<cc::SharedBitmap> AllocateSharedBitmap( - const gfx::Size& size) override; - std::unique_ptr<cc::SharedBitmap> GetSharedBitmapFromId( - const gfx::Size& size, - const cc::SharedBitmapId&) override; - - // base::trace_event::MemoryDumpProvider implementation. - bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) override; - - size_t AllocatedBitmapCount() const; - - void FreeSharedMemoryFromMap(const cc::SharedBitmapId& id); - - private: - friend class HostSharedBitmapManagerClient; - - bool ChildAllocatedSharedBitmap(size_t buffer_size, - const base::SharedMemoryHandle& handle, - const cc::SharedBitmapId& id); - void ChildDeletedSharedBitmap(const cc::SharedBitmapId& id); - - mutable base::Lock lock_; - - typedef base::hash_map<cc::SharedBitmapId, scoped_refptr<BitmapData>> - BitmapMap; - BitmapMap handle_map_; - - DISALLOW_COPY_AND_ASSIGN(HostSharedBitmapManager); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
diff --git a/components/viz/service/display_compositor/server_shared_bitmap_manager.cc b/components/viz/service/display_compositor/server_shared_bitmap_manager.cc new file mode 100644 index 0000000..ae9cd9a --- /dev/null +++ b/components/viz/service/display_compositor/server_shared_bitmap_manager.cc
@@ -0,0 +1,191 @@ +// 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 "components/viz/service/display_compositor/server_shared_bitmap_manager.h" + +#include <stdint.h> + +#include <utility> + +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "base/trace_event/process_memory_dump.h" +#include "ui/gfx/geometry/size.h" + +namespace viz { + +class BitmapData : public base::RefCountedThreadSafe<BitmapData> { + public: + explicit BitmapData(size_t buffer_size) : buffer_size(buffer_size) {} + std::unique_ptr<base::SharedMemory> memory; + std::unique_ptr<uint8_t[]> pixels; + size_t buffer_size; + + private: + friend class base::RefCountedThreadSafe<BitmapData>; + ~BitmapData() {} + DISALLOW_COPY_AND_ASSIGN(BitmapData); +}; + +namespace { + +class ServerSharedBitmap : public cc::SharedBitmap { + public: + ServerSharedBitmap(uint8_t* pixels, + scoped_refptr<BitmapData> bitmap_data, + const cc::SharedBitmapId& id, + ServerSharedBitmapManager* manager) + : SharedBitmap(pixels, id), + bitmap_data_(bitmap_data), + manager_(manager) {} + + ~ServerSharedBitmap() override { + if (manager_) + manager_->FreeSharedMemoryFromMap(id()); + } + + // cc::SharedBitmap: + base::SharedMemoryHandle GetSharedMemoryHandle() const override { + if (!bitmap_data_->memory) + return base::SharedMemoryHandle(); + return bitmap_data_->memory->handle(); + } + + private: + scoped_refptr<BitmapData> bitmap_data_; + ServerSharedBitmapManager* manager_; +}; + +} // namespace + +base::LazyInstance<ServerSharedBitmapManager>::DestructorAtExit + g_shared_memory_manager = LAZY_INSTANCE_INITIALIZER; + +ServerSharedBitmapManager::ServerSharedBitmapManager() = default; + +ServerSharedBitmapManager::~ServerSharedBitmapManager() { + DCHECK(handle_map_.empty()); +} + +ServerSharedBitmapManager* ServerSharedBitmapManager::current() { + return g_shared_memory_manager.Pointer(); +} + +std::unique_ptr<cc::SharedBitmap> +ServerSharedBitmapManager::AllocateSharedBitmap(const gfx::Size& size) { + base::AutoLock lock(lock_); + size_t bitmap_size; + if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size)) + return nullptr; + + scoped_refptr<BitmapData> data(new BitmapData(bitmap_size)); + // Bitmaps allocated in server don't need to be shared to other processes, so + // allocate them with new instead. + data->pixels = std::unique_ptr<uint8_t[]>(new uint8_t[bitmap_size]); + + cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); + handle_map_[id] = data; + return base::MakeUnique<ServerSharedBitmap>(data->pixels.get(), data, id, + this); +} + +std::unique_ptr<cc::SharedBitmap> +ServerSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size& size, + const cc::SharedBitmapId& id) { + base::AutoLock lock(lock_); + auto it = handle_map_.find(id); + if (it == handle_map_.end()) + return nullptr; + + BitmapData* data = it->second.get(); + + size_t bitmap_size; + if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) || + bitmap_size > data->buffer_size) + return nullptr; + + if (data->pixels) { + return base::MakeUnique<ServerSharedBitmap>(data->pixels.get(), data, id, + nullptr); + } + if (!data->memory->memory()) { + return nullptr; + } + + return base::MakeUnique<ServerSharedBitmap>( + static_cast<uint8_t*>(data->memory->memory()), data, id, nullptr); +} + +bool ServerSharedBitmapManager::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + base::AutoLock lock(lock_); + + for (const auto& bitmap : handle_map_) { + base::trace_event::MemoryAllocatorDump* dump = + pmd->CreateAllocatorDump(base::StringPrintf( + "sharedbitmap/%s", + base::HexEncode(bitmap.first.name, sizeof(bitmap.first.name)) + .c_str())); + if (!dump) + return false; + + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + bitmap.second->buffer_size); + + // Generate a global GUID used to share this allocation with renderer + // processes. + auto guid = cc::GetSharedBitmapGUIDForTracing(bitmap.first); + base::UnguessableToken shared_memory_guid; + if (bitmap.second->memory) { + shared_memory_guid = bitmap.second->memory->handle().GetGUID(); + pmd->CreateSharedMemoryOwnershipEdge( + dump->guid(), guid, shared_memory_guid, 0 /* importance*/); + } else { + pmd->CreateSharedGlobalAllocatorDump(guid); + pmd->AddOwnershipEdge(dump->guid(), guid); + } + } + + return true; +} + +bool ServerSharedBitmapManager::ChildAllocatedSharedBitmap( + size_t buffer_size, + const base::SharedMemoryHandle& handle, + const cc::SharedBitmapId& id) { + base::AutoLock lock(lock_); + if (handle_map_.find(id) != handle_map_.end()) + return false; + auto data = base::MakeRefCounted<BitmapData>(buffer_size); + data->memory = base::MakeUnique<base::SharedMemory>(handle, false); + data->memory->Map(data->buffer_size); + data->memory->Close(); + handle_map_[id] = std::move(data); + return true; +} + +void ServerSharedBitmapManager::ChildDeletedSharedBitmap( + const cc::SharedBitmapId& id) { + base::AutoLock lock(lock_); + handle_map_.erase(id); +} + +size_t ServerSharedBitmapManager::AllocatedBitmapCount() const { + base::AutoLock lock(lock_); + return handle_map_.size(); +} + +void ServerSharedBitmapManager::FreeSharedMemoryFromMap( + const cc::SharedBitmapId& id) { + base::AutoLock lock(lock_); + handle_map_.erase(id); +} + +} // namespace viz
diff --git a/components/viz/service/display_compositor/server_shared_bitmap_manager.h b/components/viz/service/display_compositor/server_shared_bitmap_manager.h new file mode 100644 index 0000000..3908634 --- /dev/null +++ b/components/viz/service/display_compositor/server_shared_bitmap_manager.h
@@ -0,0 +1,71 @@ +// 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 COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_SERVER_SHARED_BITMAP_MANAGER_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_SERVER_SHARED_BITMAP_MANAGER_H_ + +#include <memory> +#include <unordered_map> + +#include "base/memory/ref_counted.h" +#include "base/memory/shared_memory.h" +#include "base/synchronization/lock.h" +#include "base/trace_event/memory_dump_provider.h" +#include "cc/resources/shared_bitmap_manager.h" +#include "components/viz/service/viz_service_export.h" + +namespace viz { +class BitmapData; + +// A SharedBitmapManager implementation that lives in-process with the +// display compositor. It returns SharedBitmaps that can be transported +// over Mojo/IPC to the display compositor, but which are backed by +// non-shared memory. This is a cheaper implementation by using +// malloc/free, but can only be used in the same process as the display +// compositor. +class VIZ_SERVICE_EXPORT ServerSharedBitmapManager + : public cc::SharedBitmapManager, + public base::trace_event::MemoryDumpProvider { + public: + ServerSharedBitmapManager(); + ~ServerSharedBitmapManager() override; + + static ServerSharedBitmapManager* current(); + + // cc::SharedBitmapManager implementation. + std::unique_ptr<cc::SharedBitmap> AllocateSharedBitmap( + const gfx::Size& size) override; + std::unique_ptr<cc::SharedBitmap> GetSharedBitmapFromId( + const gfx::Size& size, + const cc::SharedBitmapId&) override; + + // base::trace_event::MemoryDumpProvider implementation. + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; + + size_t AllocatedBitmapCount() const; + + void FreeSharedMemoryFromMap(const cc::SharedBitmapId& id); + + private: + friend class SharedBitmapAllocationNotifierImpl; + + bool ChildAllocatedSharedBitmap(size_t buffer_size, + const base::SharedMemoryHandle& handle, + const cc::SharedBitmapId& id); + void ChildDeletedSharedBitmap(const cc::SharedBitmapId& id); + + mutable base::Lock lock_; + + std::unordered_map<cc::SharedBitmapId, + scoped_refptr<BitmapData>, + cc::SharedBitmapIdHash> + handle_map_; + + DISALLOW_COPY_AND_ASSIGN(ServerSharedBitmapManager); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_SERVER_SHARED_BITMAP_MANAGER_H_
diff --git a/components/viz/service/display_compositor/host_shared_bitmap_manager_unittest.cc b/components/viz/service/display_compositor/server_shared_bitmap_manager_unittest.cc similarity index 61% rename from components/viz/service/display_compositor/host_shared_bitmap_manager_unittest.cc rename to components/viz/service/display_compositor/server_shared_bitmap_manager_unittest.cc index 12d91b6..87da76e 100644 --- a/components/viz/service/display_compositor/host_shared_bitmap_manager_unittest.cc +++ b/components/viz/service/display_compositor/server_shared_bitmap_manager_unittest.cc
@@ -2,22 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stddef.h> -#include <string.h> +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "base/memory/ptr_util.h" +#include "components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h" #include "testing/gtest/include/gtest/gtest.h" namespace viz { namespace { -class HostSharedBitmapManagerTest : public testing::Test { +class ServerSharedBitmapManagerTest : public testing::Test { protected: - void SetUp() override { manager_.reset(new HostSharedBitmapManager()); } - std::unique_ptr<HostSharedBitmapManager> manager_; + void SetUp() override { + manager_ = base::MakeUnique<ServerSharedBitmapManager>(); + } + + void TearDown() override { manager_.reset(); } + + ServerSharedBitmapManager* manager() const { return manager_.get(); } + + private: + std::unique_ptr<ServerSharedBitmapManager> manager_; }; -TEST_F(HostSharedBitmapManagerTest, TestCreate) { +TEST_F(ServerSharedBitmapManagerTest, TestCreate) { gfx::Size bitmap_size(1, 1); size_t size_in_bytes; EXPECT_TRUE(cc::SharedBitmap::SizeInBytes(bitmap_size, &size_in_bytes)); @@ -26,46 +34,46 @@ memset(bitmap->memory(), 0xff, size_in_bytes); cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); - HostSharedBitmapManagerClient client(manager_.get()); + SharedBitmapAllocationNotifierImpl notifier(manager()); base::SharedMemoryHandle handle = bitmap->handle().Duplicate(); - client.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); + notifier.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); std::unique_ptr<cc::SharedBitmap> large_bitmap; - large_bitmap = manager_->GetSharedBitmapFromId(gfx::Size(1024, 1024), id); + large_bitmap = manager()->GetSharedBitmapFromId(gfx::Size(1024, 1024), id); EXPECT_TRUE(large_bitmap.get() == NULL); std::unique_ptr<cc::SharedBitmap> very_large_bitmap; very_large_bitmap = - manager_->GetSharedBitmapFromId(gfx::Size(1, (1 << 30) | 1), id); + manager()->GetSharedBitmapFromId(gfx::Size(1, (1 << 30) | 1), id); EXPECT_TRUE(very_large_bitmap.get() == NULL); std::unique_ptr<cc::SharedBitmap> negative_size_bitmap; negative_size_bitmap = - manager_->GetSharedBitmapFromId(gfx::Size(-1, 1024), id); + manager()->GetSharedBitmapFromId(gfx::Size(-1, 1024), id); EXPECT_TRUE(negative_size_bitmap.get() == NULL); cc::SharedBitmapId id2 = cc::SharedBitmap::GenerateId(); std::unique_ptr<cc::SharedBitmap> invalid_bitmap; - invalid_bitmap = manager_->GetSharedBitmapFromId(bitmap_size, id2); + invalid_bitmap = manager()->GetSharedBitmapFromId(bitmap_size, id2); EXPECT_TRUE(invalid_bitmap.get() == NULL); std::unique_ptr<cc::SharedBitmap> shared_bitmap; - shared_bitmap = manager_->GetSharedBitmapFromId(bitmap_size, id); + shared_bitmap = manager()->GetSharedBitmapFromId(bitmap_size, id); ASSERT_TRUE(shared_bitmap.get() != NULL); EXPECT_EQ(memcmp(shared_bitmap->pixels(), bitmap->memory(), 4), 0); std::unique_ptr<cc::SharedBitmap> large_bitmap2; - large_bitmap2 = manager_->GetSharedBitmapFromId(gfx::Size(1024, 1024), id); + large_bitmap2 = manager()->GetSharedBitmapFromId(gfx::Size(1024, 1024), id); EXPECT_TRUE(large_bitmap2.get() == NULL); std::unique_ptr<cc::SharedBitmap> shared_bitmap2; - shared_bitmap2 = manager_->GetSharedBitmapFromId(bitmap_size, id); + shared_bitmap2 = manager()->GetSharedBitmapFromId(bitmap_size, id); EXPECT_TRUE(shared_bitmap2->pixels() == shared_bitmap->pixels()); shared_bitmap2.reset(); EXPECT_EQ(memcmp(shared_bitmap->pixels(), bitmap->memory(), size_in_bytes), 0); - client.DidDeleteSharedBitmap(id); + notifier.DidDeleteSharedBitmap(id); memset(bitmap->memory(), 0, size_in_bytes); @@ -75,7 +83,7 @@ shared_bitmap.reset(); } -TEST_F(HostSharedBitmapManagerTest, RemoveProcess) { +TEST_F(ServerSharedBitmapManagerTest, ServiceDestroyed) { gfx::Size bitmap_size(1, 1); size_t size_in_bytes; EXPECT_TRUE(cc::SharedBitmap::SizeInBytes(bitmap_size, &size_in_bytes)); @@ -84,29 +92,29 @@ memset(bitmap->memory(), 0xff, size_in_bytes); cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); - std::unique_ptr<HostSharedBitmapManagerClient> client( - new HostSharedBitmapManagerClient(manager_.get())); - base::SharedMemoryHandle handle = bitmap->handle().Duplicate(); - client->ChildAllocatedSharedBitmap(size_in_bytes, handle, id); - + // This outlives the SharedBitmapAllocationNotifier. std::unique_ptr<cc::SharedBitmap> shared_bitmap; - shared_bitmap = manager_->GetSharedBitmapFromId(bitmap_size, id); - ASSERT_TRUE(shared_bitmap.get() != NULL); - EXPECT_EQ(1u, manager_->AllocatedBitmapCount()); - client.reset(); - EXPECT_EQ(0u, manager_->AllocatedBitmapCount()); + { + SharedBitmapAllocationNotifierImpl notifier(manager()); + base::SharedMemoryHandle handle = bitmap->handle().Duplicate(); + notifier.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); + + shared_bitmap = manager()->GetSharedBitmapFromId(bitmap_size, id); + ASSERT_TRUE(shared_bitmap.get() != NULL); + + EXPECT_EQ(1u, manager()->AllocatedBitmapCount()); + } + EXPECT_EQ(0u, manager()->AllocatedBitmapCount()); std::unique_ptr<cc::SharedBitmap> shared_bitmap2; - shared_bitmap2 = manager_->GetSharedBitmapFromId(bitmap_size, id); - EXPECT_TRUE(shared_bitmap2.get() == NULL); + shared_bitmap2 = manager()->GetSharedBitmapFromId(bitmap_size, id); + EXPECT_FALSE(!!shared_bitmap2); EXPECT_EQ(memcmp(shared_bitmap->pixels(), bitmap->memory(), size_in_bytes), 0); - - shared_bitmap.reset(); } -TEST_F(HostSharedBitmapManagerTest, AddDuplicate) { +TEST_F(ServerSharedBitmapManagerTest, AddDuplicate) { gfx::Size bitmap_size(1, 1); size_t size_in_bytes; EXPECT_TRUE(cc::SharedBitmap::SizeInBytes(bitmap_size, &size_in_bytes)); @@ -114,26 +122,27 @@ bitmap->CreateAndMapAnonymous(size_in_bytes); memset(bitmap->memory(), 0xff, size_in_bytes); cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); - HostSharedBitmapManagerClient client(manager_.get()); + + SharedBitmapAllocationNotifierImpl notifier(manager()); base::SharedMemoryHandle handle = bitmap->handle().Duplicate(); - client.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); + notifier.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); std::unique_ptr<base::SharedMemory> bitmap2(new base::SharedMemory()); bitmap2->CreateAndMapAnonymous(size_in_bytes); memset(bitmap2->memory(), 0x00, size_in_bytes); - client.ChildAllocatedSharedBitmap(size_in_bytes, bitmap2->handle(), id); + notifier.ChildAllocatedSharedBitmap(size_in_bytes, bitmap2->handle(), id); std::unique_ptr<cc::SharedBitmap> shared_bitmap; - shared_bitmap = manager_->GetSharedBitmapFromId(bitmap_size, id); + shared_bitmap = manager()->GetSharedBitmapFromId(bitmap_size, id); ASSERT_TRUE(shared_bitmap.get() != NULL); EXPECT_EQ(memcmp(shared_bitmap->pixels(), bitmap->memory(), size_in_bytes), 0); - client.DidDeleteSharedBitmap(id); + notifier.DidDeleteSharedBitmap(id); } -TEST_F(HostSharedBitmapManagerTest, SharedMemoryHandle) { +TEST_F(ServerSharedBitmapManagerTest, SharedMemoryHandle) { gfx::Size bitmap_size(1, 1); size_t size_in_bytes; EXPECT_TRUE(cc::SharedBitmap::SizeInBytes(bitmap_size, &size_in_bytes)); @@ -143,16 +152,17 @@ memset(bitmap->memory(), 0xff, size_in_bytes); cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); - HostSharedBitmapManagerClient client(manager_.get()); + SharedBitmapAllocationNotifierImpl notifier(manager()); + base::SharedMemoryHandle handle = bitmap->handle().Duplicate(); - client.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); + notifier.ChildAllocatedSharedBitmap(size_in_bytes, handle, id); std::unique_ptr<cc::SharedBitmap> shared_bitmap; - shared_bitmap = manager_->GetSharedBitmapFromId(gfx::Size(1, 1), id); + shared_bitmap = manager()->GetSharedBitmapFromId(gfx::Size(1, 1), id); EXPECT_EQ(shared_bitmap->GetSharedMemoryHandle().GetGUID(), shared_memory_guid); - client.DidDeleteSharedBitmap(id); + notifier.DidDeleteSharedBitmap(id); } } // namespace
diff --git a/components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.cc b/components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.cc new file mode 100644 index 0000000..5e102f04 --- /dev/null +++ b/components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.cc
@@ -0,0 +1,51 @@ +// 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/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h" + +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" +#include "mojo/public/cpp/system/platform_handle.h" + +namespace viz { + +SharedBitmapAllocationNotifierImpl::SharedBitmapAllocationNotifierImpl( + ServerSharedBitmapManager* manager) + : manager_(manager), binding_(this) {} + +SharedBitmapAllocationNotifierImpl::~SharedBitmapAllocationNotifierImpl() { + for (const auto& id : owned_bitmaps_) + manager_->ChildDeletedSharedBitmap(id); +} + +void SharedBitmapAllocationNotifierImpl::Bind( + cc::mojom::SharedBitmapAllocationNotifierAssociatedRequest request) { + binding_.Bind(std::move(request)); +} + +void SharedBitmapAllocationNotifierImpl::DidAllocateSharedBitmap( + mojo::ScopedSharedBufferHandle buffer, + const cc::SharedBitmapId& id) { + base::SharedMemoryHandle memory_handle; + size_t size; + MojoResult result = mojo::UnwrapSharedMemoryHandle( + std::move(buffer), &memory_handle, &size, NULL); + DCHECK_EQ(result, MOJO_RESULT_OK); + this->ChildAllocatedSharedBitmap(size, memory_handle, id); +} + +void SharedBitmapAllocationNotifierImpl::DidDeleteSharedBitmap( + const cc::SharedBitmapId& id) { + manager_->ChildDeletedSharedBitmap(id); + owned_bitmaps_.erase(id); +} + +void SharedBitmapAllocationNotifierImpl::ChildAllocatedSharedBitmap( + size_t buffer_size, + const base::SharedMemoryHandle& handle, + const cc::SharedBitmapId& id) { + if (manager_->ChildAllocatedSharedBitmap(buffer_size, handle, id)) + owned_bitmaps_.insert(id); +} + +} // namespace viz
diff --git a/components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h b/components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h new file mode 100644 index 0000000..35e63b2 --- /dev/null +++ b/components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h
@@ -0,0 +1,47 @@ +// 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_VIZ_SERVICE_DISPLAY_COMPOSITOR_SHARED_BITMAP_ALLOCATION_NOTIFIER_IMPL_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_SHARED_BITMAP_ALLOCATION_NOTIFIER_IMPL_H_ + +#include <unordered_set> + +#include "cc/ipc/shared_bitmap_allocation_notifier.mojom.h" +#include "cc/resources/shared_bitmap.h" +#include "components/viz/service/viz_service_export.h" +#include "mojo/public/cpp/bindings/associated_binding.h" + +namespace viz { +class ServerSharedBitmapManager; + +class VIZ_SERVICE_EXPORT SharedBitmapAllocationNotifierImpl + : NON_EXPORTED_BASE(public cc::mojom::SharedBitmapAllocationNotifier) { + public: + explicit SharedBitmapAllocationNotifierImpl( + ServerSharedBitmapManager* manager); + + ~SharedBitmapAllocationNotifierImpl() override; + + void Bind(cc::mojom::SharedBitmapAllocationNotifierAssociatedRequest request); + + // cc::mojom::SharedBitmapAllocationNotifier overrides: + void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer, + const cc::SharedBitmapId& id) override; + void DidDeleteSharedBitmap(const cc::SharedBitmapId& id) override; + + void ChildAllocatedSharedBitmap(size_t buffer_size, + const base::SharedMemoryHandle& handle, + const cc::SharedBitmapId& id); + + private: + ServerSharedBitmapManager* const manager_; + mojo::AssociatedBinding<cc::mojom::SharedBitmapAllocationNotifier> binding_; + std::unordered_set<cc::SharedBitmapId, cc::SharedBitmapIdHash> owned_bitmaps_; + + DISALLOW_COPY_AND_ASSIGN(SharedBitmapAllocationNotifierImpl); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_COMPOSITOR_SHARED_BITMAP_ALLOCATION_NOTIFIER_IMPL_H_
diff --git a/components/viz/service/frame_sinks/frame_eviction_manager.cc b/components/viz/service/frame_sinks/frame_eviction_manager.cc index bd6dc87..980ba52b 100644 --- a/components/viz/service/frame_sinks/frame_eviction_manager.cc +++ b/components/viz/service/frame_sinks/frame_eviction_manager.cc
@@ -15,7 +15,7 @@ #include "base/memory/shared_memory.h" #include "base/sys_info.h" #include "build/build_config.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" namespace viz { namespace { @@ -134,7 +134,7 @@ void FrameEvictionManager::CullUnlockedFrames(size_t saved_frame_limit) { if (unlocked_frames_.size() + locked_frames_.size() > 0) { float handles_per_frame = - HostSharedBitmapManager::current()->AllocatedBitmapCount() * 1.0f / + ServerSharedBitmapManager::current()->AllocatedBitmapCount() * 1.0f / (unlocked_frames_.size() + locked_frames_.size()); saved_frame_limit = std::max(
diff --git a/components/web_contents_delegate_android/DEPS b/components/web_contents_delegate_android/DEPS index 0cbb274..560840d 100644 --- a/components/web_contents_delegate_android/DEPS +++ b/components/web_contents_delegate_android/DEPS
@@ -2,7 +2,7 @@ "+content/public/browser", "+content/public/common", "+jni", - "+ui/android/window_android.h", + "+ui/android", "+ui/base", "+ui/gfx", ]
diff --git a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java index e6bef2a..c3c1a461 100644 --- a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java +++ b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java
@@ -8,7 +8,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.content.browser.ContentViewCore; import org.chromium.ui.base.WindowAndroid; /** @@ -44,13 +43,10 @@ } @CalledByNative - public static ColorChooserAndroid createColorChooserAndroid( - long nativeColorChooserAndroid, - ContentViewCore contentViewCore, - int initialColor, - ColorSuggestion[] suggestions) { - if (contentViewCore.getWindowAndroid() == null) return null; - Context windowContext = contentViewCore.getWindowAndroid().getContext().get(); + public static ColorChooserAndroid createColorChooserAndroid(long nativeColorChooserAndroid, + WindowAndroid windowAndroid, int initialColor, ColorSuggestion[] suggestions) { + if (windowAndroid == null) return null; + Context windowContext = windowAndroid.getContext().get(); if (WindowAndroid.activityFromContext(windowContext) == null) return null; ColorChooserAndroid chooser = new ColorChooserAndroid(nativeColorChooserAndroid, windowContext, initialColor, suggestions);
diff --git a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java index ec093851..13c0a0f 100644 --- a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java +++ b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java
@@ -16,58 +16,40 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.annotations.CalledByNative; -import org.chromium.content.browser.ContentViewCore; -import org.chromium.content.browser.RenderCoordinates; /** * This class is an implementation of validation message bubble UI. */ class ValidationMessageBubble { + private final View mView; private PopupWindow mPopup; /** - * Creates a popup window to show the specified messages, and show it on the specified anchor - * rectangle. + * Creates a popup window to show the specified messages. * - * If the anchor view is not in a state where a popup can be shown, this will return null. - * - * @param contentViewCore The ContentViewCore object to provide various information. - * @param anchorX Anchor position in the CSS unit. - * @param anchorY Anchor position in the CSS unit. - * @param anchorWidth Anchor size in the CSS unit. - * @param anchorHeight Anchor size in the CSS unit. + * @param containerView A parent view for the message bubble. * @param mainText The main message. It will shown at the top of the popup window, and its font * size is larger. * @param subText The sub message. It will shown below the main message, and its font size is * smaller. */ @CalledByNative - private static ValidationMessageBubble createAndShowIfApplicable( - ContentViewCore contentViewCore, int anchorX, int anchorY, int anchorWidth, - int anchorHeight, String mainText, String subText) { - if (!canShowBubble(contentViewCore)) return null; - - final RectF anchorPixInScreen = makePixRectInScreen( - contentViewCore, anchorX, anchorY, anchorWidth, anchorHeight); - return new ValidationMessageBubble(contentViewCore, anchorPixInScreen, mainText, subText); + private static ValidationMessageBubble createIfApplicable( + View containerView, String mainText, String subText) { + if (!canShowBubble(containerView)) return null; + return new ValidationMessageBubble(containerView, mainText, subText); } - private static boolean canShowBubble(ContentViewCore contentViewCore) { - return contentViewCore.getContainerView() != null - && contentViewCore.getContainerView().getWindowToken() != null; + private static boolean canShowBubble(View containerView) { + return containerView != null && containerView.getWindowToken() != null; } - private ValidationMessageBubble( - ContentViewCore contentViewCore, RectF anchor, String mainText, String subText) { - final ViewGroup root = (ViewGroup) View.inflate(contentViewCore.getContext(), - R.layout.validation_message_bubble, null); + private ValidationMessageBubble(View containerView, String mainText, String subText) { + mView = containerView; + ViewGroup root = (ViewGroup) View.inflate( + mView.getContext(), R.layout.validation_message_bubble, null); mPopup = new PopupWindow(root); updateTextViews(root, mainText, subText); - measure(contentViewCore.getRenderCoordinates()); - Point origin = adjustWindowPosition( - contentViewCore, (int) (anchor.centerX() - getAnchorOffset()), (int) anchor.bottom); - mPopup.showAtLocation( - contentViewCore.getContainerView(), Gravity.NO_GRAVITY, origin.x, origin.y); } @CalledByNative @@ -78,39 +60,44 @@ } /** - * Moves the popup window on the specified anchor rectangle. + * Moves the popup window on the specified anchor rectangle. All the values are in device + * pixel unit. * - * @param contentViewCore The ContentViewCore object to provide various information. - * @param anchorX Anchor position in the CSS unit. - * @param anchorY Anchor position in the CSS unit. - * @param anchorWidth Anchor size in the CSS unit. - * @param anchorHeight Anchor size in the CSS unit. + * @param viewportWidthPx Viewport width. + * @param viewportHeightPx Viewport height. + * @param contentOffsetYPx Content offset from the top. + * @param anchorXPx Anchor x position. + * @param anchorYPx Anchor y position. + * @param anchorWidthPx Anchor width. + * @param anchorHeightPx Anchor height. */ @CalledByNative - private void setPositionRelativeToAnchor(ContentViewCore contentViewCore, - int anchorX, int anchorY, int anchorWidth, int anchorHeight) { - RectF anchor = makePixRectInScreen( - contentViewCore, anchorX, anchorY, anchorWidth, anchorHeight); - Point origin = adjustWindowPosition( - contentViewCore, (int) (anchor.centerX() - getAnchorOffset()), (int) anchor.bottom); - mPopup.update(origin.x, origin.y, mPopup.getWidth(), mPopup.getHeight()); + private void showAtPositionRelativeToAnchor(int viewportWidthPx, int viewportHeightPx, + float contentOffsetYPx, int anchorXPx, int anchorYPx, int anchorWidthPx, + int anchorHeightPx) { + RectF anchor = makeRectInScreen( + mView, contentOffsetYPx, anchorXPx, anchorYPx, anchorWidthPx, anchorHeightPx); + Point origin = adjustWindowPosition(viewportWidthPx, viewportHeightPx, contentOffsetYPx, + (int) (anchor.centerX() - getAnchorOffset()), (int) anchor.bottom); + if (!mPopup.isShowing()) { + measure(viewportWidthPx, viewportHeightPx); + mPopup.showAtLocation(mView, Gravity.NO_GRAVITY, origin.x, origin.y); + } else { + mPopup.update(origin.x, origin.y, mPopup.getWidth(), mPopup.getHeight()); + } } - private static RectF makePixRectInScreen(ContentViewCore contentViewCore, - int anchorX, int anchorY, int anchorWidth, int anchorHeight) { - final RenderCoordinates coordinates = contentViewCore.getRenderCoordinates(); - final float yOffset = getWebViewOffsetYPixInScreen(contentViewCore); - return new RectF( - coordinates.fromLocalCssToPix(anchorX), - coordinates.fromLocalCssToPix(anchorY) + yOffset, - coordinates.fromLocalCssToPix(anchorX + anchorWidth), - coordinates.fromLocalCssToPix(anchorY + anchorHeight) + yOffset); + private static RectF makeRectInScreen(View containerView, float contentOffsetYPxPix, + int anchorXPx, int anchorYPx, int anchorWidthPx, int anchorHeightPx) { + final float yOffset = getWebViewOffsetYPixInScreen(containerView, contentOffsetYPxPix); + return new RectF(anchorXPx, anchorYPx + yOffset, anchorXPx + anchorWidthPx, + anchorYPx + anchorHeightPx + yOffset); } - private static float getWebViewOffsetYPixInScreen(ContentViewCore contentViewCore) { + private static float getWebViewOffsetYPixInScreen(View containerView, float contentOffsetYPx) { int[] location = new int[2]; - contentViewCore.getContainerView().getLocationOnScreen(location); - return location[1] + contentViewCore.getRenderCoordinates().getContentOffsetYPix(); + containerView.getLocationOnScreen(location); + return location[1] + contentOffsetYPx; } private static void updateTextViews(ViewGroup root, String mainText, String subText) { @@ -123,7 +110,7 @@ } } - private void measure(RenderCoordinates coordinates) { + private void measure(int viewportWidthPx, int viewportHeightPx) { mPopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); mPopup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); mPopup.getContentView().setLayoutParams( @@ -131,10 +118,8 @@ RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); mPopup.getContentView().measure( - View.MeasureSpec.makeMeasureSpec(coordinates.getLastFrameViewportWidthPixInt(), - View.MeasureSpec.AT_MOST), - View.MeasureSpec.makeMeasureSpec(coordinates.getLastFrameViewportHeightPixInt(), - View.MeasureSpec.AT_MOST)); + View.MeasureSpec.makeMeasureSpec(viewportWidthPx, View.MeasureSpec.AT_MOST), + View.MeasureSpec.makeMeasureSpec(viewportHeightPx, View.MeasureSpec.AT_MOST)); } private float getAnchorOffset() { @@ -148,21 +133,18 @@ /** * This adjusts the position if the popup protrudes the web view. */ - private Point adjustWindowPosition(ContentViewCore contentViewCore, int x, int y) { - final RenderCoordinates coordinates = contentViewCore.getRenderCoordinates(); - final int viewWidth = coordinates.getLastFrameViewportWidthPixInt(); - final int viewBottom = (int) getWebViewOffsetYPixInScreen(contentViewCore) - + coordinates.getLastFrameViewportHeightPixInt(); + private Point adjustWindowPosition( + int viewWidthPx, int viewHeightPx, float contentOffsetYPx, int x, int y) { + final int viewBottom = + (int) getWebViewOffsetYPixInScreen(mView, contentOffsetYPx) + viewHeightPx; final int width = mPopup.getContentView().getMeasuredWidth(); final int height = mPopup.getContentView().getMeasuredHeight(); if (x < 0) { x = 0; - } else if (x + width > viewWidth) { - x = viewWidth - width; + } else if (x + width > viewWidthPx) { + x = viewWidthPx - width; } - if (y + height > viewBottom) { - y = viewBottom - height; - } + if (y + height > viewBottom) y = viewBottom - height; return new Point(x, y); } }
diff --git a/components/web_contents_delegate_android/color_chooser_android.cc b/components/web_contents_delegate_android/color_chooser_android.cc index 5aeb8ee8..266d191a 100644 --- a/components/web_contents_delegate_android/color_chooser_android.cc +++ b/components/web_contents_delegate_android/color_chooser_android.cc
@@ -8,7 +8,6 @@ #include "base/android/jni_array.h" #include "base/android/jni_string.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/web_contents.h" #include "content/public/common/color_suggestion.h" #include "jni/ColorChooserAndroid_jni.h" @@ -16,7 +15,6 @@ using base::android::ConvertUTF16ToJavaString; using base::android::JavaRef; -using content::ContentViewCore; namespace web_contents_delegate_android { @@ -41,17 +39,14 @@ } } - ContentViewCore* content_view_core = - ContentViewCore::FromWebContents(web_contents); - if (content_view_core) { - base::android::ScopedJavaLocalRef<jobject> java_content_view_core = - content_view_core->GetJavaObject(); - if (!java_content_view_core.is_null()) { - j_color_chooser_.Reset(Java_ColorChooserAndroid_createColorChooserAndroid( - env, reinterpret_cast<intptr_t>(this), java_content_view_core, - initial_color, suggestions_array)); - } + auto* window_android = web_contents->GetNativeView()->GetWindowAndroid(); + if (window_android) { + j_color_chooser_.Reset(Java_ColorChooserAndroid_createColorChooserAndroid( + env, reinterpret_cast<intptr_t>(this), window_android->GetJavaObject(), + initial_color, suggestions_array)); } + + // Ends with the initial color if color chooser dialog failed. if (j_color_chooser_.is_null()) OnColorChosen(env, j_color_chooser_, initial_color); }
diff --git a/components/web_contents_delegate_android/validation_message_bubble_android.cc b/components/web_contents_delegate_android/validation_message_bubble_android.cc index e2ee3a1f..2f15a5e5 100644 --- a/components/web_contents_delegate_android/validation_message_bubble_android.cc +++ b/components/web_contents_delegate_android/validation_message_bubble_android.cc
@@ -5,47 +5,37 @@ #include "components/web_contents_delegate_android/validation_message_bubble_android.h" #include "base/android/jni_string.h" -#include "content/public/browser/android/content_view_core.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" #include "jni/ValidationMessageBubble_jni.h" -#include "ui/gfx/geometry/rect.h" +#include "ui/android/view_android.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/geometry/size_conversions.h" using base::android::ConvertUTF16ToJavaString; -using content::ContentViewCore; -using content::RenderWidgetHost; namespace { -base::android::ScopedJavaLocalRef<jobject> GetJavaContentViewCoreFrom( - RenderWidgetHost* widget_host) { - ContentViewCore* content_view_core = - ContentViewCore::FromWebContents(content::WebContents::FromRenderViewHost( - content::RenderViewHost::From(widget_host))); - if (!content_view_core) - return base::android::ScopedJavaLocalRef<jobject>(); - return content_view_core->GetJavaObject(); +gfx::Rect ScaleToRoundedRect(const gfx::Rect& rect, float scale) { + gfx::RectF scaledRect(rect); + scaledRect.Scale(scale); + return ToNearestRect(scaledRect); } + +gfx::Size ScaleToRoundedSize(const gfx::SizeF& size, float scale) { + return gfx::ToRoundedSize(gfx::ScaleSize(size, scale)); } +} // namespace namespace web_contents_delegate_android { ValidationMessageBubbleAndroid::ValidationMessageBubbleAndroid( - RenderWidgetHost* widget_host, - const gfx::Rect& anchor_in_root_view, + gfx::NativeView view, const base::string16& main_text, const base::string16& sub_text) { - base::android::ScopedJavaLocalRef<jobject> java_content_view_core = - GetJavaContentViewCoreFrom(widget_host); - if (java_content_view_core.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); java_validation_message_bubble_.Reset( - Java_ValidationMessageBubble_createAndShowIfApplicable( - env, java_content_view_core, anchor_in_root_view.x(), - anchor_in_root_view.y(), anchor_in_root_view.width(), - anchor_in_root_view.height(), + Java_ValidationMessageBubble_createIfApplicable( + env, view->GetContainerView(), ConvertUTF16ToJavaString(env, main_text), ConvertUTF16ToJavaString(env, sub_text))); } @@ -57,19 +47,22 @@ } } -void ValidationMessageBubbleAndroid::SetPositionRelativeToAnchor( - RenderWidgetHost* widget_host, const gfx::Rect& anchor_in_root_view) { - base::android::ScopedJavaLocalRef<jobject> java_content_view_core = - GetJavaContentViewCoreFrom(widget_host); - if (java_content_view_core.is_null() || - java_validation_message_bubble_.is_null()) { +void ValidationMessageBubbleAndroid::ShowAtPositionRelativeToAnchor( + gfx::NativeView view, + const gfx::Rect& anchor_in_screen) { + if (java_validation_message_bubble_.is_null()) return; - } - Java_ValidationMessageBubble_setPositionRelativeToAnchor( - base::android::AttachCurrentThread(), java_validation_message_bubble_, - java_content_view_core, anchor_in_root_view.x(), anchor_in_root_view.y(), - anchor_in_root_view.width(), anchor_in_root_view.height()); + // Convert to physical unit before passing to Java. + float scale = view->GetDipScale() * view->page_scale(); + gfx::Rect anchor = ScaleToRoundedRect(anchor_in_screen, scale); + gfx::Size viewport = ScaleToRoundedSize(view->viewport_size(), scale); + + JNIEnv* env = base::android::AttachCurrentThread(); + Java_ValidationMessageBubble_showAtPositionRelativeToAnchor( + env, java_validation_message_bubble_, viewport.width(), viewport.height(), + view->content_offset() * scale, anchor.x(), anchor.y(), anchor.width(), + anchor.height()); } } // namespace web_contents_delegate_android
diff --git a/components/web_contents_delegate_android/validation_message_bubble_android.h b/components/web_contents_delegate_android/validation_message_bubble_android.h index 1fe027b..08fa95de 100644 --- a/components/web_contents_delegate_android/validation_message_bubble_android.h +++ b/components/web_contents_delegate_android/validation_message_bubble_android.h
@@ -9,28 +9,24 @@ #include "base/android/scoped_java_ref.h" #include "base/strings/string16.h" +#include "ui/gfx/native_widget_types.h" namespace gfx { class Rect; } -namespace content { -class RenderWidgetHost; -} - namespace web_contents_delegate_android { // An implementation of ValidationMessageBubble for Android. This class is a // bridge to a Java implementation. class ValidationMessageBubbleAndroid { public: - ValidationMessageBubbleAndroid(content::RenderWidgetHost* widget_host, - const gfx::Rect& anchor_in_screen, + ValidationMessageBubbleAndroid(gfx::NativeView view, const base::string16& main_text, const base::string16& sub_text); virtual ~ValidationMessageBubbleAndroid(); - virtual void SetPositionRelativeToAnchor( - content::RenderWidgetHost* widget_host, + virtual void ShowAtPositionRelativeToAnchor( + gfx::NativeView view, const gfx::Rect& anchor_in_screen); private:
diff --git a/components/web_contents_delegate_android/web_contents_delegate_android.cc b/components/web_contents_delegate_android/web_contents_delegate_android.cc index 12e077c5..19edd77 100644 --- a/components/web_contents_delegate_android/web_contents_delegate_android.cc +++ b/components/web_contents_delegate_android/web_contents_delegate_android.cc
@@ -11,7 +11,6 @@ #include "base/android/jni_string.h" #include "components/web_contents_delegate_android/color_chooser_android.h" #include "components/web_contents_delegate_android/validation_message_bubble_android.h" -#include "content/public/browser/android/content_view_core.h" #include "content/public/browser/color_chooser.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/invalidate_type.h" @@ -383,14 +382,9 @@ const gfx::Rect& anchor_in_root_view, const base::string16& main_text, const base::string16& sub_text) { - RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView(); - if (rwhv) { - validation_message_bubble_.reset( - new ValidationMessageBubbleAndroid(rwhv->GetRenderWidgetHost(), - anchor_in_root_view, - main_text, - sub_text)); - } + validation_message_bubble_.reset(new ValidationMessageBubbleAndroid( + web_contents->GetNativeView(), main_text, sub_text)); + MoveValidationMessage(web_contents, anchor_in_root_view); } void WebContentsDelegateAndroid::HideValidationMessage( @@ -403,11 +397,8 @@ const gfx::Rect& anchor_in_root_view) { if (!validation_message_bubble_) return; - RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView(); - if (rwhv) { - validation_message_bubble_->SetPositionRelativeToAnchor( - rwhv->GetRenderWidgetHost(), anchor_in_root_view); - } + validation_message_bubble_->ShowAtPositionRelativeToAnchor( + web_contents->GetNativeView(), anchor_in_root_view); } void WebContentsDelegateAndroid::RequestAppBannerFromDevTools(
diff --git a/content/app/android/content_main.cc b/content/app/android/content_main.cc index f974e71..dda83c2 100644 --- a/content/app/android/content_main.cc +++ b/content/app/android/content_main.cc
@@ -33,15 +33,10 @@ static jint Start(JNIEnv* env, const JavaParamRef<jclass>& clazz) { TRACE_EVENT0("startup", "content::Start"); - // On Android we can have multiple requests to start the browser in process - // simultaneously. If we get an asynchonous request followed by a synchronous - // request then we have to call this a second time to finish starting the - // browser synchronously. - if (!g_service_manager_main_delegate.Get()) { - g_service_manager_main_delegate.Get() = - base::MakeUnique<ContentServiceManagerMainDelegate>( - ContentMainParams(g_content_main_delegate.Get().get())); - } + DCHECK(!g_service_manager_main_delegate.Get()); + g_service_manager_main_delegate.Get() = + base::MakeUnique<ContentServiceManagerMainDelegate>( + ContentMainParams(g_content_main_delegate.Get().get())); service_manager::MainParams main_params( g_service_manager_main_delegate.Get().get());
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 3a21b3d..1b664a14 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1194,7 +1194,6 @@ "renderer_host/input/touch_selection_controller_client_aura.h", "renderer_host/input/touch_selection_controller_client_child_frame.cc", "renderer_host/input/touch_selection_controller_client_child_frame.h", - "renderer_host/input/touch_selection_controller_client_manager.h", "renderer_host/input/touch_timeout_handler.cc", "renderer_host/input/touch_timeout_handler.h", "renderer_host/input/touchpad_tap_suppression_controller.cc",
diff --git a/content/browser/android/browser_startup_controller.cc b/content/browser/android/browser_startup_controller.cc index 4280c6b..87f0462 100644 --- a/content/browser/android/browser_startup_controller.cc +++ b/content/browser/android/browser_startup_controller.cc
@@ -7,6 +7,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "content/browser/android/content_startup_flags.h" +#include "content/browser/browser_main_loop.h" #include "ppapi/features/features.h" #include "jni/BrowserStartupController_jni.h" @@ -15,11 +16,6 @@ namespace content { -bool BrowserMayStartAsynchronously() { - JNIEnv* env = base::android::AttachCurrentThread(); - return Java_BrowserStartupController_browserMayStartAsynchonously(env); -} - void BrowserStartupComplete(int result) { JNIEnv* env = base::android::AttachCurrentThread(); Java_BrowserStartupController_browserStartupComplete(env, result); @@ -65,4 +61,8 @@ #endif } +static void FlushStartupTasks(JNIEnv* env, const JavaParamRef<jclass>& clazz) { + BrowserMainLoop::GetInstance()->SynchronouslyFlushStartupTasks(); +} + } // namespace content
diff --git a/content/browser/android/browser_startup_controller.h b/content/browser/android/browser_startup_controller.h index 6a98bfa..d4f2556f 100644 --- a/content/browser/android/browser_startup_controller.h +++ b/content/browser/android/browser_startup_controller.h
@@ -9,7 +9,6 @@ namespace content { -bool BrowserMayStartAsynchronously(); void BrowserStartupComplete(int result); bool ShouldStartGpuProcessOnBrowserStartup();
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index 528f094a..7b5e1d2e 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -51,9 +51,9 @@ RDH_INVALID_PRIORITY = 27, RDH_REQUEST_NOT_TRANSFERRING = 28, RDH_BAD_DOWNLOAD = 29, - NMF_NO_PERMISSION_SHOW = 30, - NMF_NO_PERMISSION_CLOSE = 31, - NMF_NO_PERMISSION_VERIFY = 32, + NMF_NO_PERMISSION_SHOW = 30, // obsolete; no longer used + NMF_NO_PERMISSION_CLOSE = 31, // obsolete; no longer used + NMF_NO_PERMISSION_VERIFY = 32, // obsolete; no longer used MH_INVALID_MIDI_PORT = 33, MH_SYS_EX_PERMISSION = 34, ACDH_REGISTER = 35,
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc index 104283f..6dfe51c 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.cc +++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -15,6 +15,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" +#include "base/supports_user_data.h" #include "base/task_runner.h" #include "base/task_scheduler/post_task.h" #include "content/browser/resource_context_impl.h" @@ -24,7 +25,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/common/content_features.h" #include "storage/browser/blob/blob_data_builder.h" -#include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_memory_controller.h" #include "storage/browser/blob/blob_registry_impl.h" #include "storage/browser/blob/blob_storage_context.h" @@ -210,8 +210,11 @@ return blob_storage_context->context(); } -bool AttachRequestBodyBlobDataHandles(ResourceRequestBodyImpl* body, - ResourceContext* resource_context) { +bool GetBodyBlobDataHandles(ResourceRequestBodyImpl* body, + ResourceContext* resource_context, + BlobHandles* blob_handles) { + blob_handles->clear(); + storage::BlobStorageContext* blob_context = GetBlobStorageContext( GetChromeBlobStorageContextForResourceContext(resource_context)); @@ -224,10 +227,7 @@ blob_context->GetBlobDataFromUUID(element.blob_uuid()); if (!handle) return false; - // Ensure the blob and any attached shareable files survive until - // upload completion. The |body| takes ownership of |handle|. - const void* key = handle.get(); - body->SetUserData(key, std::move(handle)); + blob_handles->push_back(std::move(handle)); } return true; }
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.h b/content/browser/blob_storage/chrome_blob_storage_context.h index 9111e08..9c0312f 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.h +++ b/content/browser/blob_storage/chrome_blob_storage_context.h
@@ -9,12 +9,14 @@ #include <stdint.h> #include <memory> +#include <vector> #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/sequenced_task_runner_helpers.h" #include "content/common/content_export.h" #include "services/service_manager/public/cpp/bind_source_info.h" +#include "storage/browser/blob/blob_data_handle.h" #include "storage/public/interfaces/blobs.mojom.h" namespace base { @@ -96,10 +98,14 @@ storage::BlobStorageContext* GetBlobStorageContext( ChromeBlobStorageContext* blob_storage_context); -// Attaches blob data handles to the ResourceRequestBodyImpl body passed in. -// This is used for POST and PUT requests. -bool AttachRequestBodyBlobDataHandles(ResourceRequestBodyImpl* body, - ResourceContext* resource_context); +using BlobHandles = std::vector<std::unique_ptr<storage::BlobDataHandle>>; + +// Attempts to create a vector of BlobDataHandles that ensure any blob data +// associated with |body| isn't cleaned up until the handles are destroyed. +// Returns false on failure. This is used for POST and PUT requests. +bool GetBodyBlobDataHandles(ResourceRequestBodyImpl* body, + ResourceContext* resource_context, + BlobHandles* blob_handles); } // namespace content
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 5efa919..9486c42 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -54,7 +54,7 @@ #include "components/tracing/common/trace_to_console.h" #include "components/tracing/common/tracing_switches.h" #include "components/viz/host/host_frame_sink_manager.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/child_process_security_policy_impl.h" @@ -579,7 +579,7 @@ if (parts_) parts_->PreEarlyInitialization(); -#if defined(OS_MACOSX) || defined(OS_LINUX) +#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) // We use quite a few file descriptors for our IPC as well as disk the disk // cache,and the default limit on the Mac is low (256), so bump it up. @@ -588,7 +588,7 @@ // users can easily hit this limit with many open tabs. Bump up the limit to // an arbitrarily high number. See https://crbug.com/539567 base::SetFdLimit(8192); -#endif // defined(OS_MACOSX) || defined(OS_LINUX) +#endif // defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) #if defined(OS_WIN) net::EnsureWinsockInit(); @@ -781,8 +781,8 @@ tracing::ProcessMetricsMemoryDumpProvider::RegisterForProcess( base::kNullProcessId); base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( - viz::HostSharedBitmapManager::current(), "viz::HostSharedBitmapManager", - nullptr); + viz::ServerSharedBitmapManager::current(), + "viz::ServerSharedBitmapManager", nullptr); base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr); base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( @@ -890,52 +890,48 @@ void BrowserMainLoop::CreateStartupTasks() { TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks"); - // First time through, we really want to create all the tasks - if (!startup_task_runner_.get()) { + DCHECK(!startup_task_runner_); #if defined(OS_ANDROID) - startup_task_runner_ = base::MakeUnique<StartupTaskRunner>( - base::Bind(&BrowserStartupComplete), - base::ThreadTaskRunnerHandle::Get()); + startup_task_runner_ = base::MakeUnique<StartupTaskRunner>( + base::Bind(&BrowserStartupComplete), base::ThreadTaskRunnerHandle::Get()); #else - startup_task_runner_ = base::MakeUnique<StartupTaskRunner>( - base::Callback<void(int)>(), base::ThreadTaskRunnerHandle::Get()); + startup_task_runner_ = base::MakeUnique<StartupTaskRunner>( + base::Callback<void(int)>(), base::ThreadTaskRunnerHandle::Get()); #endif - StartupTask pre_create_threads = - base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this)); - startup_task_runner_->AddTask(pre_create_threads); + StartupTask pre_create_threads = + base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this)); + startup_task_runner_->AddTask(pre_create_threads); - StartupTask create_threads = - base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this)); - startup_task_runner_->AddTask(create_threads); + StartupTask create_threads = + base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this)); + startup_task_runner_->AddTask(create_threads); - StartupTask browser_thread_started = base::Bind( - &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this)); - startup_task_runner_->AddTask(browser_thread_started); + StartupTask browser_thread_started = base::Bind( + &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this)); + startup_task_runner_->AddTask(browser_thread_started); - StartupTask pre_main_message_loop_run = base::Bind( - &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this)); - startup_task_runner_->AddTask(pre_main_message_loop_run); + StartupTask pre_main_message_loop_run = base::Bind( + &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this)); + startup_task_runner_->AddTask(pre_main_message_loop_run); #if defined(OS_ANDROID) - if (BrowserMayStartAsynchronously()) { - startup_task_runner_->StartRunningTasksAsync(); - } -#endif - } -#if defined(OS_ANDROID) - if (!BrowserMayStartAsynchronously()) { - // A second request for asynchronous startup can be ignored, so - // StartupRunningTasksAsync is only called first time through. If, however, - // this is a request for synchronous startup then it must override any - // previous call for async startup, so we call RunAllTasksNow() - // unconditionally. + if (parameters_.ui_task) { + // Running inside browser tests, which relies on synchronous start. startup_task_runner_->RunAllTasksNow(); + } else { + startup_task_runner_->StartRunningTasksAsync(); } #else startup_task_runner_->RunAllTasksNow(); #endif } +#if defined(OS_ANDROID) +void BrowserMainLoop::SynchronouslyFlushStartupTasks() { + startup_task_runner_->RunAllTasksNow(); +} +#endif // OS_ANDROID + int BrowserMainLoop::CreateThreads() { TRACE_EVENT0("startup,rail", "BrowserMainLoop::CreateThreads");
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 7bd02b5c..f771cf9 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -170,6 +170,10 @@ return startup_trace_file_; } +#if defined(OS_ANDROID) + void SynchronouslyFlushStartupTasks(); +#endif // OS_ANDROID + #if !defined(OS_ANDROID) // TODO(fsamuel): We should find an object to own HostFrameSinkManager on all // platforms including Android. See http://crbug.com/732507.
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 478a4781..b05459ac 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -33,7 +33,7 @@ #include "components/viz/common/gl_helper.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/display_compositor/compositor_overlay_candidate_validator.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" #include "content/browser/browser_main_loop.h" #include "content/browser/compositor/browser_compositor_output_surface.h" #include "content/browser/compositor/gpu_browser_compositor_output_surface.h" @@ -603,7 +603,7 @@ // The Display owns and uses the |display_output_surface| created above. data->display = base::MakeUnique<cc::Display>( - viz::HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(), + viz::ServerSharedBitmapManager::current(), GetGpuMemoryBufferManager(), renderer_settings_, compositor->frame_sink_id(), std::move(display_output_surface), std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>( @@ -629,7 +629,7 @@ compositor->frame_sink_id(), GetSurfaceManager(), data->display.get(), context_provider, shared_worker_context_provider_, GetGpuMemoryBufferManager(), - viz::HostSharedBitmapManager::current()); + viz::ServerSharedBitmapManager::current()); data->display->Resize(compositor->size()); data->display->SetOutputIsSecure(data->output_is_secure); compositor->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
diff --git a/content/browser/frame_host/debug_urls.h b/content/browser/frame_host/debug_urls.h index 413cd0f..bab8a6d1 100644 --- a/content/browser/frame_host/debug_urls.h +++ b/content/browser/frame_host/debug_urls.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_FRAME_HOST_DEBUG_URLS_H_ #define CONTENT_BROWSER_FRAME_HOST_DEBUG_URLS_H_ +#include "content/common/content_export.h" #include "ui/base/page_transition_types.h" class GURL; @@ -19,7 +20,7 @@ // renderer process, such as one that crashes or hangs the renderer, or a // javascript: URL that operates on the current page in the renderer. Such URLs // do not represent actual navigations and can be loaded in any SiteInstance. -bool IsRendererDebugURL(const GURL& url); +CONTENT_EXPORT bool IsRendererDebugURL(const GURL& url); } // namespace content
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 2ad3b58d..cb8deac 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -592,7 +592,8 @@ return; } - RegisterNavigationThrottles(); + if (!IsRendererDebugURL(url_)) + RegisterNavigationThrottles(); if (IsBrowserSideNavigationEnabled()) navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this);
diff --git a/content/browser/frame_host/navigation_handle_impl_unittest.cc b/content/browser/frame_host/navigation_handle_impl_unittest.cc index 60669a1..64535f9 100644 --- a/content/browser/frame_host/navigation_handle_impl_unittest.cc +++ b/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -2,16 +2,37 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/macros.h" #include "content/browser/frame_host/navigation_handle_impl.h" +#include "base/macros.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/ssl_status.h" #include "content/public/common/request_context_type.h" +#include "content/public/common/url_constants.h" +#include "content/test/test_content_browser_client.h" #include "content/test/test_render_frame_host.h" #include "content/test/test_web_contents.h" namespace content { +using ThrottleInsertionCallback = + base::RepeatingCallback<std::vector<std::unique_ptr<NavigationThrottle>>( + NavigationHandle*)>; + +class ThrottleInserterContentBrowserClient : public TestContentBrowserClient { + public: + ThrottleInserterContentBrowserClient( + const ThrottleInsertionCallback& callback) + : throttle_insertion_callback_(callback) {} + + std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation( + NavigationHandle* navigation_handle) override { + return throttle_insertion_callback_.Run(navigation_handle); + } + + private: + ThrottleInsertionCallback throttle_insertion_callback_; +}; + // Test version of a NavigationThrottle. It will always return the current // NavigationThrottle::ThrottleCheckResult |result_|, It also monitors the // number of times WillStartRequest, WillRedirectRequest, and @@ -197,6 +218,61 @@ NavigationThrottle::ThrottleCheckResult callback_result_; }; +// Test harness that automatically inserts a navigation throttle via the content +// browser client. +class NavigationHandleImplThrottleInsertionTest + : public RenderViewHostImplTestHarness { + public: + NavigationHandleImplThrottleInsertionTest() : old_browser_client_(nullptr) {} + + void SetUp() override { + RenderViewHostImplTestHarness::SetUp(); + contents()->GetMainFrame()->InitializeRenderFrameIfNeeded(); + test_browser_client_ = + base::MakeUnique<ThrottleInserterContentBrowserClient>( + base::Bind(&NavigationHandleImplThrottleInsertionTest::GetThrottles, + base::Unretained(this))); + old_browser_client_ = + SetBrowserClientForTesting(test_browser_client_.get()); + } + + void TearDown() override { + SetBrowserClientForTesting(old_browser_client_); + RenderViewHostImplTestHarness::TearDown(); + } + + size_t throttles_inserted() const { return throttles_inserted_; } + + private: + std::vector<std::unique_ptr<NavigationThrottle>> GetThrottles( + NavigationHandle* handle) { + auto throttle = base::MakeUnique<TestNavigationThrottle>( + handle, NavigationThrottle::ThrottleCheckResult::PROCEED); + std::vector<std::unique_ptr<NavigationThrottle>> vec; + throttles_inserted_++; + vec.push_back(std::move(throttle)); + return vec; + } + + std::unique_ptr<ThrottleInserterContentBrowserClient> test_browser_client_; + ContentBrowserClient* old_browser_client_ = nullptr; + + size_t throttles_inserted_ = 0u; + + DISALLOW_COPY_AND_ASSIGN(NavigationHandleImplThrottleInsertionTest); +}; + +// Do not insert throttles that correspond to RendererDebugURLs. This aligns +// throttle insertion with WebContentsObserver callbacks. +TEST_F(NavigationHandleImplThrottleInsertionTest, + RendererDebugURL_DoNotInsert) { + NavigateAndCommit(GURL("https://example.test/")); + EXPECT_EQ(1u, throttles_inserted()); + + NavigateAndCommit(GURL(kChromeUICrashURL)); + EXPECT_EQ(1u, throttles_inserted()); +} + // Checks that the request_context_type is properly set. // Note: can be extended to cover more internal members. TEST_F(NavigationHandleImplTest, SimpleDataChecks) {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 47514f72..bb9ac746 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -454,6 +454,7 @@ pending_web_ui_type_(WebUI::kNoWebUI), should_reuse_web_ui_(false), has_selection_(false), + is_audible_(false), last_navigation_previews_state_(PREVIEWS_UNSPECIFIED), frame_host_interface_broker_binding_(this), frame_host_associated_binding_(this), @@ -1012,6 +1013,9 @@ // Any future UpdateState or UpdateTitle messages from this or a recreated // process should be ignored until the next commit. set_nav_entry_id(0); + + if (is_audible_) + GetProcess()->OnAudioStreamRemoved(); } void RenderFrameHostImpl::ReportContentSecurityPolicyViolation( @@ -1199,6 +1203,16 @@ } } +void RenderFrameHostImpl::OnAudibleStateChanged(bool is_audible) { + if (is_audible_ == is_audible) + return; + if (is_audible) + GetProcess()->OnAudioStreamAdded(); + else + GetProcess()->OnAudioStreamRemoved(); + is_audible_ = is_audible; +} + void RenderFrameHostImpl::OnDidAddMessageToConsole( int32_t level, const base::string16& message,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index dc24b89..58b1813b 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -248,6 +248,10 @@ // after they are blocked in RenderWidgetHelper::CreateNewWindow. void Init(); + // Returns true if the frame recently plays an audio. + bool is_audible() const { return is_audible_; } + void OnAudibleStateChanged(bool is_audible); + int routing_id() const { return routing_id_; } // Called when this frame has added a child. This is a continuation of an IPC @@ -1188,6 +1192,11 @@ // If true, then the RenderFrame has selected text. bool has_selection_; + // If true, then this RenderFrame has one or more audio streams with audible + // signal. If false, all audio streams are currently silent (or there are no + // audio streams). + bool is_audible_; + // PlzNavigate: The Previews state of the last navigation. This is used during // history navigation of subframes to ensure that subframes navigate with the // same Previews status as the top-level frame.
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 2e14e9fa..0e0e30a2 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -91,7 +91,7 @@ auto* root_view = frame_connector_->GetRootRenderWidgetHostView(); if (root_view) { - auto* manager = root_view->touch_selection_controller_client_manager(); + auto* manager = root_view->GetTouchSelectionControllerClientManager(); if (manager) manager->RemoveObserver(this); } @@ -138,7 +138,7 @@ if (current_device_scale_factor_ == 0.f) current_device_scale_factor_ = 1.f; - auto* manager = root_view->touch_selection_controller_client_manager(); + auto* manager = root_view->GetTouchSelectionControllerClientManager(); if (manager) { // We will only have a manager on Aura (and eventually Android). // TODO(wjmaclean): update this comment when TSE OOPIF support becomes
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index a1959a6..30be4ba6 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -23,11 +23,11 @@ #include "cc/surfaces/surface_sequence.h" #include "content/browser/compositor/image_transport_factory.h" #include "content/browser/renderer_host/event_with_latency_info.h" -#include "content/browser/renderer_host/input/touch_selection_controller_client_manager.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/common/content_export.h" #include "content/common/input/input_event_ack_state.h" #include "content/public/browser/readback_types.h" +#include "content/public/browser/touch_selection_controller_client_manager.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h"
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 1298d75..011454b 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -285,6 +285,10 @@ bool IsCheckerImagingEnabled() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( + cc::switches::kDisableCheckerImaging)) + return false; + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( cc::switches::kEnableCheckerImaging)) return true;
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 1b862ad..6005e0d 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -491,7 +491,7 @@ swiftshader_rendering_(false), kind_(kind), process_launched_(false), - initialized_(false), + status_(UNKNOWN), gpu_host_binding_(this), weak_ptr_factory_(this) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -516,6 +516,12 @@ SendOutstandingReplies(); + if (status_ == UNKNOWN) { + RunRequestGPUInfoCallbacks(gpu::GPUInfo()); + } else { + DCHECK(request_gpu_info_callbacks_.empty()); + } + // In case we never started, clean up. while (!queued_messages_.empty()) { delete queued_messages_.front(); @@ -753,6 +759,15 @@ gpu_service_ptr_->DestroyGpuMemoryBuffer(id, client_id, sync_token); } +void GpuProcessHost::RequestGPUInfo(RequestGPUInfoCallback request_cb) { + if (status_ == SUCCESS || status_ == FAILURE) { + std::move(request_cb).Run(GpuDataManagerImpl::GetInstance()->GetGPUInfo()); + return; + } + + request_gpu_info_callbacks_.push_back(std::move(request_cb)); +} + #if defined(OS_ANDROID) void GpuProcessHost::SendDestroyingVideoSurface(int surface_id, const base::Closure& done_cb) { @@ -845,18 +860,21 @@ const gpu::GPUInfo& gpu_info, const gpu::GpuFeatureInfo& gpu_feature_info) { UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true); - initialized_ = true; + status_ = SUCCESS; GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); if (!gpu_data_manager->ShouldUseSwiftShader()) { gpu_data_manager->UpdateGpuInfo(gpu_info); gpu_data_manager->UpdateGpuFeatureInfo(gpu_feature_info); } + RunRequestGPUInfoCallbacks(gpu_data_manager->GetGPUInfo()); } void GpuProcessHost::DidFailInitialize() { UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false); - initialized_ = false; - GpuDataManagerImpl::GetInstance()->OnGpuProcessInitFailure(); + status_ = FAILURE; + GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); + gpu_data_manager->OnGpuProcessInitFailure(); + RunRequestGPUInfoCallbacks(gpu_data_manager->GetGPUInfo()); } void GpuProcessHost::DidCreateOffscreenContext(const GURL& url) { @@ -1089,6 +1107,13 @@ base::ResetAndReturn(&send_destroying_video_surface_done_cb_).Run(); } +void GpuProcessHost::RunRequestGPUInfoCallbacks(const gpu::GPUInfo& gpu_info) { + for (auto& callback : request_gpu_info_callbacks_) + std::move(callback).Run(gpu_info); + + request_gpu_info_callbacks_.clear(); +} + void GpuProcessHost::BlockLiveOffscreenContexts() { for (std::multiset<GURL>::iterator iter = urls_with_live_offscreen_contexts_.begin(); @@ -1145,7 +1170,8 @@ crashed_before_ = true; last_gpu_crash_time = current_time; - if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount || !initialized_) && + if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount || + status_ == FAILURE) && !disable_crash_limit) { #if !defined(OS_CHROMEOS) // The GPU process is too unstable to use. Disable it for current
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 8cef249..857b4c2 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h
@@ -86,6 +86,8 @@ base::Callback<void(const gfx::GpuMemoryBufferHandle& handle, BufferCreationStatus status)>; + using RequestGPUInfoCallback = base::Callback<void(const gpu::GPUInfo&)>; + static bool gpu_enabled() { return gpu_enabled_; } static int gpu_crash_count() { return gpu_crash_count_; } @@ -146,6 +148,8 @@ int client_id, const gpu::SyncToken& sync_token); + void RequestGPUInfo(RequestGPUInfoCallback request_cb); + #if defined(OS_ANDROID) // Tells the GPU process that the given surface is being destroyed so that it // can stop using it. @@ -165,6 +169,8 @@ private: class ConnectionFilterImpl; + enum GpuInitializationStatus { UNKNOWN, SUCCESS, FAILURE }; + static bool ValidateHost(GpuProcessHost* host); GpuProcessHost(int host_id, GpuProcessKind kind); @@ -215,6 +221,8 @@ void SendOutstandingReplies(); + void RunRequestGPUInfoCallbacks(const gpu::GPUInfo& gpu_info); + void BlockLiveOffscreenContexts(); // Update GPU crash counters. Disable GPU if crash limit is reached. @@ -235,6 +243,8 @@ // A callback to signal the completion of a SendDestroyingVideoSurface call. base::Closure send_destroying_video_surface_done_cb_; + std::vector<RequestGPUInfoCallback> request_gpu_info_callbacks_; + // Qeueud messages to send when the process launches. std::queue<IPC::Message*> queued_messages_; @@ -253,8 +263,7 @@ // Whether we actually launched a GPU process. bool process_launched_; - // Whether the GPU process successfully initialized. - bool initialized_; + GpuInitializationStatus status_; // Time Init started. Used to log total GPU process startup time to UMA. base::TimeTicks init_start_time_;
diff --git a/content/browser/image_capture/image_capture_impl.cc b/content/browser/image_capture/image_capture_impl.cc index d2f8235..3471fca 100644 --- a/content/browser/image_capture/image_capture_impl.cc +++ b/content/browser/image_capture/image_capture_impl.cc
@@ -80,6 +80,9 @@ callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); +// TODO(mcasas): Enable PhotoState collection in Windows when understood why it +// prevents normal capture https://crbug.com/722038. +#if !defined(OS_WIN) const int session_id = media_stream_manager->VideoDeviceIdToSessionId(source_id); @@ -87,6 +90,7 @@ return; media_stream_manager->video_capture_manager()->GetPhotoState( session_id, std::move(callback)); +#endif } void SetOptionsOnIOThread(
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 5cbd63e..642ed4d 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -1266,7 +1266,8 @@ leveldb::Status IndexedDBDatabase::PutOperation( std::unique_ptr<PutOperationParams> params, IndexedDBTransaction* transaction) { - IDB_TRACE1("IndexedDBDatabase::PutOperation", "txn.id", transaction->id()); + IDB_TRACE2("IndexedDBDatabase::PutOperation", "txn.id", transaction->id(), + "size", params->value.SizeEstimate()); DCHECK_NE(transaction->mode(), blink::kWebIDBTransactionModeReadOnly); bool key_was_generated = false; leveldb::Status s = leveldb::Status::OK();
diff --git a/content/browser/indexed_db/indexed_db_tracing.h b/content/browser/indexed_db/indexed_db_tracing.h index ee94737..7e00c1f 100644 --- a/content/browser/indexed_db/indexed_db_tracing.h +++ b/content/browser/indexed_db/indexed_db_tracing.h
@@ -10,6 +10,9 @@ #define IDB_TRACE1(a, arg1_name, arg1_val) \ TRACE_EVENT1("IndexedDB", (a), (arg1_name), (arg1_val)); +#define IDB_TRACE2(a, b, b_val, c, c_val) \ + TRACE_EVENT2("IndexedDB", (a), (b), (b_val), (c), (c_val)); + #define IDB_ASYNC_TRACE_BEGIN(a, id) \ TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", (a), (id)); #define IDB_ASYNC_TRACE_END(a, id) \
diff --git a/content/browser/loader/DEPS b/content/browser/loader/DEPS index c6e43ce..6a53b48c 100644 --- a/content/browser/loader/DEPS +++ b/content/browser/loader/DEPS
@@ -223,6 +223,7 @@ ], "resource_request_info_impl\.(cc|h)": [ "-content", + "+content/browser/blob_storage/chrome_blob_storage_context.h", "+content/browser/loader/global_routing_id.h", "+content/browser/loader/resource_handler.h", "+content/browser/loader/resource_message_filter.h",
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index 5c54eb9..f6628597 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -125,8 +125,8 @@ : RESOURCE_TYPE_SUB_FRAME; if (resource_request_->request_body) { - AttachRequestBodyBlobDataHandles(resource_request_->request_body.get(), - resource_context_); + GetBodyBlobDataHandles(resource_request_->request_body.get(), + resource_context_, &blob_handles_); } // Requests to WebUI scheme won't get redirected to/from other schemes @@ -297,13 +297,15 @@ std::unique_ptr<ThrottlingURLLoader> url_loader_; - // This is referenced only on the UI thread. - base::WeakPtr<NavigationURLLoaderNetworkService> owner_; + BlobHandles blob_handles_; // Currently used by the AppCache loader to pass its factory to the // renderer which enables it to handle subresources. mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_; + // This is referenced only on the UI thread. + base::WeakPtr<NavigationURLLoaderNetworkService> owner_; + DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); };
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index b5a1c61..0bfe5f2 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -39,7 +39,6 @@ #include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/appcache/chrome_appcache_service.h" #include "content/browser/bad_message.h" -#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/browsing_data/clear_site_data_throttle.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/frame_host/navigation_request_info.h" @@ -1159,6 +1158,7 @@ return; } + BlobHandles blob_handles; if (!is_navigation_stream_request) { storage::BlobStorageContext* blob_context = GetBlobStorageContext(requester_info->blob_storage_context()); @@ -1168,12 +1168,11 @@ // because ResourceMessageFilters created in PluginProcessHost don't have // the blob context. if (blob_context) { - // Attaches the BlobDataHandles to request_body not to free the blobs - // and any attached shareable files until upload completion. These data + // Get BlobHandles to request_body to prevent blobs and any attached + // shareable files from being freed until upload completion. These data // will be used in UploadDataStream and ServiceWorkerURLRequestJob. - bool blobs_alive = AttachRequestBodyBlobDataHandles( - request_data.request_body.get(), resource_context); - if (!blobs_alive) { + if (!GetBodyBlobDataHandles(request_data.request_body.get(), + resource_context, &blob_handles)) { AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler, request_id, std::move(url_loader_client)); @@ -1206,7 +1205,8 @@ base::Unretained(this), make_scoped_refptr(requester_info), request_id, request_data, sync_result_handler, route_id, headers, base::Passed(std::move(mojo_request)), - base::Passed(std::move(url_loader_client)))); + base::Passed(std::move(url_loader_client)), + base::Passed(std::move(blob_handles)))); return; } } @@ -1215,7 +1215,7 @@ ContinuePendingBeginRequest( requester_info, request_id, request_data, sync_result_handler, route_id, headers, std::move(mojo_request), std::move(url_loader_client), - HeaderInterceptorResult::CONTINUE); + std::move(blob_handles), HeaderInterceptorResult::CONTINUE); } void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( @@ -1227,6 +1227,7 @@ const net::HttpRequestHeaders& headers, mojom::URLLoaderAssociatedRequest mojo_request, mojom::URLLoaderClientPtr url_loader_client, + BlobHandles blob_handles, HeaderInterceptorResult interceptor_result) { DCHECK(requester_info->IsRenderer() || requester_info->IsNavigationPreload()); if (interceptor_result != HeaderInterceptorResult::CONTINUE) { @@ -1407,6 +1408,7 @@ resource_context, request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME), request_data.request_body, request_data.initiated_in_secure_context); + extra_info->SetBlobHandles(std::move(blob_handles)); // Request takes ownership. extra_info->AssociateWithRequest(new_request.get()); @@ -2115,9 +2117,9 @@ // Resolve elements from request_body and prepare upload data. ResourceRequestBodyImpl* body = info.common_params.post_data.get(); + BlobHandles blob_handles; if (body) { - bool blobs_alive = AttachRequestBodyBlobDataHandles(body, resource_context); - if (!blobs_alive) { + if (!GetBodyBlobDataHandles(body, resource_context, &blob_handles)) { new_request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); loader->NotifyRequestFailed(false, net::ERR_ABORTED); return; @@ -2163,6 +2165,7 @@ // If in the future this changes this should be updated to somehow get a // meaningful value. false); // initiated_in_secure_context + extra_info->SetBlobHandles(std::move(blob_handles)); extra_info->set_navigation_ui_data(std::move(navigation_ui_data)); // Request takes ownership.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index 70f377e..49673ff9 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -26,6 +26,7 @@ #include "base/observer_list.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/global_routing_id.h" #include "content/browser/loader/resource_loader_delegate.h" #include "content/common/content_export.h" @@ -593,6 +594,7 @@ const net::HttpRequestHeaders& headers, mojom::URLLoaderAssociatedRequest mojo_request, mojom::URLLoaderClientPtr url_loader_client, + BlobHandles blob_handles, HeaderInterceptorResult interceptor_result); // Creates a ResourceHandler to be used by BeginRequest() for normal resource
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc index 2d9e6e90..439278d 100644 --- a/content/browser/loader/resource_request_info_impl.cc +++ b/content/browser/loader/resource_request_info_impl.cc
@@ -365,4 +365,8 @@ body_ = nullptr; } +void ResourceRequestInfoImpl::SetBlobHandles(BlobHandles blob_handles) { + blob_handles_ = std::move(blob_handles); +} + } // namespace content
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h index d9dac75..5aabe8bc 100644 --- a/content/browser/loader/resource_request_info_impl.h +++ b/content/browser/loader/resource_request_info_impl.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/supports_user_data.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/resource_requester_info.h" #include "content/common/resource_request_body_impl.h" #include "content/common/url_loader.mojom.h" @@ -200,6 +201,8 @@ on_transfer_ = on_transfer; } + void SetBlobHandles(BlobHandles blob_handles); + private: FRIEND_TEST_ALL_PREFIXES(ResourceDispatcherHostTest, DeletedFilterDetached); @@ -239,6 +242,9 @@ bool initiated_in_secure_context_; std::unique_ptr<NavigationUIData> navigation_ui_data_; + // Keeps upload body blobs alive for the duration of the request. + BlobHandles blob_handles_; + // This callback is set by MojoAsyncResourceHandler to update its mojo binding // and remote endpoint. This callback will be removed once PlzNavigate is // shipped.
diff --git a/content/browser/manifest/OWNERS b/content/browser/manifest/OWNERS index a37fa32..edb36297 100644 --- a/content/browser/manifest/OWNERS +++ b/content/browser/manifest/OWNERS
@@ -1,5 +1,3 @@ mlamouri@chromium.org -per-file manifest_icon_*=dfalcantara@chromium.org - # COMPONENT: Manifest
diff --git a/content/browser/media/audio_stream_monitor.cc b/content/browser/media/audio_stream_monitor.cc index bab83477..de5a2d9 100644 --- a/content/browser/media/audio_stream_monitor.cc +++ b/content/browser/media/audio_stream_monitor.cc
@@ -6,10 +6,10 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/invalidate_type.h" -#include "content/public/browser/render_frame_host.h" namespace content { @@ -29,13 +29,6 @@ if (!render_process_host) return nullptr; - // TODO(dalecurtis, maxmorin): We should really only be sending these when the - // streams are audible or we don't have power level monitoring. - if (action_type == ActionType::STARTING) - render_process_host->OnAudioStreamAdded(); - else - render_process_host->OnAudioStreamRemoved(); - WebContentsImpl* const web_contents = static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost( RenderFrameHost::FromID(render_process_id, render_frame_id))); @@ -44,6 +37,18 @@ } // namespace +bool AudioStreamMonitor::StreamID::operator<(const StreamID& other) const { + return std::tie(render_process_id, render_frame_id, stream_id) < + std::tie(other.render_process_id, other.render_frame_id, + other.stream_id); +} + +bool AudioStreamMonitor::StreamID::operator==(const StreamID& other) const { + return std::tie(render_process_id, render_frame_id, stream_id) == + std::tie(other.render_process_id, other.render_frame_id, + other.stream_id); +} + AudioStreamMonitor::AudioStreamMonitor(WebContents* contents) : web_contents_(contents), clock_(&default_tick_clock_), @@ -72,9 +77,8 @@ // reused. During this period StartStopMonitoringHelper() will be unable to // lookup the WebContents using the now-dead |render_frame_id|. We must thus // have this secondary mechanism for clearing stale callbacks. - for (auto it = poll_callbacks_.begin(); it != poll_callbacks_.end();) { - if (it->first.first == render_process_id) { + if (it->first.render_process_id == render_process_id) { it = poll_callbacks_.erase(it); OnStreamRemoved(); } else { @@ -122,8 +126,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (AudioStreamMonitor* monitor = StartStopMonitoringHelper( ActionType::STARTING, render_process_id, render_frame_id)) { - monitor->StartMonitoringStreamOnUIThread(render_process_id, stream_id, - read_power_callback); + monitor->StartMonitoringStreamOnUIThread(render_process_id, render_frame_id, + stream_id, read_power_callback); } } @@ -134,34 +138,58 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (AudioStreamMonitor* monitor = StartStopMonitoringHelper( ActionType::STOPPING, render_process_id, render_frame_id)) { - monitor->StopMonitoringStreamOnUIThread(render_process_id, stream_id); + monitor->StopMonitoringStreamOnUIThread(render_process_id, render_frame_id, + stream_id); } } void AudioStreamMonitor::StartMonitoringStreamOnUIThread( int render_process_id, + int render_frame_id, int stream_id, const ReadPowerAndClipCallback& read_power_callback) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!read_power_callback.is_null()); - const StreamID qualified_id(render_process_id, stream_id); + const StreamID qualified_id = {render_process_id, render_frame_id, stream_id}; DCHECK(poll_callbacks_.find(qualified_id) == poll_callbacks_.end()); poll_callbacks_[qualified_id] = read_power_callback; + + // Sends audible signal to RenderFrameHost when there is no power level + // monitoring, otherwise sends the signal when the stream becomes audible. + if (!power_level_monitoring_available()) { + if (auto* render_frame_host = static_cast<RenderFrameHostImpl*>( + RenderFrameHost::FromID(render_process_id, render_frame_id))) { + render_frame_host->OnAudibleStateChanged(true); + } + } + OnStreamAdded(); } void AudioStreamMonitor::StopMonitoringStreamOnUIThread(int render_process_id, + int render_frame_id, int stream_id) { DCHECK(thread_checker_.CalledOnValidThread()); // In the event of render process death, these may have already been cleared. - auto it = poll_callbacks_.find(StreamID(render_process_id, stream_id)); + auto it = poll_callbacks_.find( + StreamID{render_process_id, render_frame_id, stream_id}); if (it == poll_callbacks_.end()) return; poll_callbacks_.erase(it); + + // Sends non-audible signal to RenderFrameHost when there is no power level + // monitoring, otherwise sends the signal when the stream becomes non-audible. + if (!power_level_monitoring_available()) { + if (auto* render_frame_host = static_cast<RenderFrameHostImpl*>( + RenderFrameHost::FromID(render_process_id, render_frame_id))) { + render_frame_host->OnAudibleStateChanged(false); + } + } + OnStreamRemoved(); } @@ -169,21 +197,40 @@ bool was_audible = is_audible_; is_audible_ = false; - for (StreamPollCallbackMap::const_iterator it = poll_callbacks_.begin(); - it != poll_callbacks_.end(); - ++it) { + // Record whether or not a RenderFrameHost is audible. + base::flat_map<RenderFrameHostImpl*, bool> audible_frame_map; + audible_frame_map.reserve(poll_callbacks_.size()); + for (auto& kv : poll_callbacks_) { // TODO(miu): A new UI for delivering specific power level and clipping // information is still in the works. For now, we throw away all // information except for "is it audible?" - const float power_dbfs = it->second.Run().first; + const float power_dbfs = kv.second.Run().first; const float kSilenceThresholdDBFS = -72.24719896f; - if (power_dbfs >= kSilenceThresholdDBFS) { + const bool is_stream_audible = power_dbfs >= kSilenceThresholdDBFS; + if (!is_audible_ && is_stream_audible) { last_blurt_time_ = clock_->NowTicks(); is_audible_ = true; MaybeToggle(); - break; // No need to poll remaining streams. } + + // Record whether or not the RenderFrame is audible. A RenderFrame is + // audible when it has at least one audio stream that is audible. + auto* render_frame_host_impl = + static_cast<RenderFrameHostImpl*>(RenderFrameHost::FromID( + kv.first.render_process_id, kv.first.render_frame_id)); + // This may be nullptr in tests. + if (!render_frame_host_impl) + continue; + audible_frame_map[render_frame_host_impl] |= is_stream_audible; + } + + // Update RenderFrameHost audible state only when state changed. + for (auto& kv : audible_frame_map) { + auto* render_frame_host_impl = kv.first; + bool is_frame_audible = kv.second; + if (is_frame_audible != render_frame_host_impl->is_audible()) + render_frame_host_impl->OnAudibleStateChanged(is_frame_audible); } if (is_audible_ != was_audible)
diff --git a/content/browser/media/audio_stream_monitor.h b/content/browser/media/audio_stream_monitor.h index f925c91..7433ced 100644 --- a/content/browser/media/audio_stream_monitor.h +++ b/content/browser/media/audio_stream_monitor.h
@@ -9,6 +9,7 @@ #include <utility> #include "base/callback_forward.h" +#include "base/containers/flat_map.h" #include "base/macros.h" #include "base/threading/thread_checker.h" #include "base/time/default_tick_clock.h" @@ -111,12 +112,15 @@ // Starts polling the stream for audio stream power levels using |callback|. void StartMonitoringStreamOnUIThread( int render_process_id, + int render_frame_id, int stream_id, const ReadPowerAndClipCallback& callback); // Stops polling the stream, discarding the internal copy of the |callback| // provided in the call to StartMonitoringStream(). - void StopMonitoringStreamOnUIThread(int render_process_id, int stream_id); + void StopMonitoringStreamOnUIThread(int render_process_id, + int render_frame_id, + int stream_id); // Called by |poll_timer_| to sample the power levels from each of the streams // playing in the tab. @@ -146,8 +150,15 @@ // The callbacks to read power levels for each stream. Only playing (i.e., // not paused) streams will have an entry in this map. - using StreamID = std::pair<int, int>; - using StreamPollCallbackMap = std::map<StreamID, ReadPowerAndClipCallback>; + struct CONTENT_EXPORT StreamID { + int render_process_id; + int render_frame_id; + int stream_id; + bool operator<(const StreamID& other) const; + bool operator==(const StreamID& other) const; + }; + using StreamPollCallbackMap = + base::flat_map<StreamID, ReadPowerAndClipCallback>; StreamPollCallbackMap poll_callbacks_; // Records the last time at which sound was audible from any stream.
diff --git a/content/browser/media/audio_stream_monitor_unittest.cc b/content/browser/media/audio_stream_monitor_unittest.cc index 95f28b9..cb6931d576 100644 --- a/content/browser/media/audio_stream_monitor_unittest.cc +++ b/content/browser/media/audio_stream_monitor_unittest.cc
@@ -30,6 +30,8 @@ const int kAnotherRenderProcessId = 2; const int kStreamId = 3; const int kAnotherStreamId = 6; +const int kRenderFrameId = 4; +const int kAnotherRenderFrameId = 8; // Used to confirm audio indicator state changes occur at the correct times. class MockWebContentsDelegate : public WebContentsDelegate { @@ -76,8 +78,12 @@ void SimulateOffTimerFired() { monitor_->MaybeToggle(); } - void ExpectIsPolling(int render_process_id, int stream_id, bool is_polling) { - const AudioStreamMonitor::StreamID key(render_process_id, stream_id); + void ExpectIsPolling(int render_process_id, + int render_frame_id, + int stream_id, + bool is_polling) { + const AudioStreamMonitor::StreamID key = {render_process_id, + render_frame_id, stream_id}; EXPECT_EQ(is_polling, monitor_->poll_callbacks_.find(key) != monitor_->poll_callbacks_.end()); EXPECT_EQ(!monitor_->poll_callbacks_.empty(), @@ -140,22 +146,26 @@ void StartMonitoring( int render_process_id, + int render_frame_id, int stream_id, const AudioStreamMonitor::ReadPowerAndClipCallback& callback) { if (!power_level_monitoring_available() && monitor_->poll_callbacks_.empty()) { ExpectCurrentlyAudibleChangeNotification(true); } - monitor_->StartMonitoringStreamOnUIThread(render_process_id, stream_id, - callback); + monitor_->StartMonitoringStreamOnUIThread( + render_process_id, render_frame_id, stream_id, callback); } - void StopMonitoring(int render_process_id, int stream_id) { + void StopMonitoring(int render_process_id, + int render_frame_id, + int stream_id) { if (!power_level_monitoring_available() && monitor_->poll_callbacks_.size() == 1u) { ExpectCurrentlyAudibleChangeNotification(false); } - monitor_->StopMonitoringStreamOnUIThread(render_process_id, stream_id); + monitor_->StopMonitoringStreamOnUIThread(render_process_id, render_frame_id, + stream_id); } bool power_level_monitoring_available() { @@ -193,17 +203,18 @@ EXPECT_FALSE(monitor_->WasRecentlyAudible()); ExpectNotCurrentlyAudible(); - ExpectIsPolling(kRenderProcessId, kStreamId, false); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, false); - StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); + StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); EXPECT_FALSE(monitor_->WasRecentlyAudible()); ExpectNotCurrentlyAudible(); - ExpectIsPolling(kRenderProcessId, kStreamId, true); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); - StopMonitoring(kRenderProcessId, kStreamId); + StopMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); EXPECT_FALSE(monitor_->WasRecentlyAudible()); ExpectNotCurrentlyAudible(); - ExpectIsPolling(kRenderProcessId, kStreamId, false); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, false); } // Tests that AudioStreamMonitor debounces the power level readings it's taking, @@ -214,7 +225,8 @@ if (!power_level_monitoring_available()) return; - StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); + StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); // Expect WebContents will get one call form AudioStreamMonitor to toggle the // indicator on upon the very first poll. @@ -269,9 +281,10 @@ if (!power_level_monitoring_available()) return; - StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); - StartMonitoring( - kRenderProcessId, kAnotherStreamId, CreatePollCallback(kAnotherStreamId)); + StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); + StartMonitoring(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, + CreatePollCallback(kAnotherStreamId)); base::TimeTicks last_blurt_time; ExpectTabWasRecentlyAudible(false, last_blurt_time); @@ -355,28 +368,30 @@ } TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) { - StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); - StartMonitoring( - kAnotherRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); - ExpectIsPolling(kRenderProcessId, kStreamId, true); - ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); - StopMonitoring(kAnotherRenderProcessId, kStreamId); - ExpectIsPolling(kRenderProcessId, kStreamId, true); - ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false); + StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); + StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); + ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); + StopMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); + ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false); } TEST_F(AudioStreamMonitorTest, RenderProcessGone) { - StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); - StartMonitoring(kAnotherRenderProcessId, kStreamId, + StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, CreatePollCallback(kStreamId)); - ExpectIsPolling(kRenderProcessId, kStreamId, true); - ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); + StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); + ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); monitor_->RenderProcessGone(kRenderProcessId); - ExpectIsPolling(kRenderProcessId, kStreamId, false); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, false); if (!power_level_monitoring_available()) ExpectCurrentlyAudibleChangeNotification(false); monitor_->RenderProcessGone(kAnotherRenderProcessId); - ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false); + ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false); } TEST_F(AudioStreamMonitorTest, NoPowerLevelMonitoring) { @@ -384,18 +399,19 @@ return; ExpectNotCurrentlyAudible(); - StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); - ExpectIsCurrentlyAudible(); - ExpectIsPolling(kRenderProcessId, kStreamId, true); - - StartMonitoring(kAnotherRenderProcessId, kStreamId, + StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, CreatePollCallback(kStreamId)); ExpectIsCurrentlyAudible(); - ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); + ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); - StopMonitoring(kRenderProcessId, kStreamId); + StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, + CreatePollCallback(kStreamId)); ExpectIsCurrentlyAudible(); - StopMonitoring(kAnotherRenderProcessId, kStreamId); + ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); + + StopMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); + ExpectIsCurrentlyAudible(); + StopMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); ExpectNotCurrentlyAudible(); }
diff --git a/content/browser/notifications/notification_message_filter.cc b/content/browser/notifications/notification_message_filter.cc index c4182128..ae0e378 100644 --- a/content/browser/notifications/notification_message_filter.cc +++ b/content/browser/notifications/notification_message_filter.cc
@@ -190,7 +190,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); if (GetPermissionForOriginOnIO(origin) != blink::mojom::PermissionStatus::GRANTED) { - bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_SHOW); + // We can't assume that the renderer is compromised at this point because + // it's possible for the user to revoke an origin's permission between the + // time where a website requests the notification to be shown and the call + // arriving in the message filter. return; } @@ -338,7 +341,6 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); if (GetPermissionForOriginOnIO(origin) != blink::mojom::PermissionStatus::GRANTED) { - bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_CLOSE); return; } @@ -390,11 +392,12 @@ blink::mojom::PermissionStatus permission_status = service->CheckPermissionOnUIThread(browser_context_, origin, process_id_); - if (permission_status == blink::mojom::PermissionStatus::GRANTED) - return true; + // We can't assume that the renderer is compromised at this point because + // it's possible for the user to revoke an origin's permission between the + // time where a website requests the notification to be shown and the call + // arriving in the message filter. - bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_VERIFY); - return false; + return permission_status == blink::mojom::PermissionStatus::GRANTED; } NotificationIdGenerator* NotificationMessageFilter::GetNotificationIdGenerator()
diff --git a/content/browser/notifications/notification_message_filter.h b/content/browser/notifications/notification_message_filter.h index 958af62..e3d67c5b 100644 --- a/content/browser/notifications/notification_message_filter.h +++ b/content/browser/notifications/notification_message_filter.h
@@ -126,9 +126,7 @@ const GURL& origin) const; // Verifies that Web Notification permission has been granted for |origin| in - // cases where the renderer shouldn't send messages if it weren't the case. If - // no permission has been granted, a bad message has been received and the - // renderer should be killed accordingly. + // cases where the renderer shouldn't send messages if it weren't the case. bool VerifyNotificationPermissionGranted(PlatformNotificationService* service, const GURL& origin);
diff --git a/content/browser/presentation/presentation_service_impl_unittest.cc b/content/browser/presentation/presentation_service_impl_unittest.cc index f53b562..d582207 100644 --- a/content/browser/presentation/presentation_service_impl_unittest.cc +++ b/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -52,6 +52,12 @@ expected.presentation_id == arg.presentation_id; } +ACTION_TEMPLATE(SaveArgByMove, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_1_VALUE_PARAMS(pointer)) { + *pointer = std::move(::testing::get<k>(args)); +} + const char kPresentationId[] = "presentationId"; const char kPresentationUrl1[] = "http://foo.com/index.html"; const char kPresentationUrl2[] = "http://example.com/index.html"; @@ -95,20 +101,41 @@ void(int render_process_id, int routing_id, const std::vector<GURL>& default_presentation_urls, - const PresentationConnectionCallback& callback)); - MOCK_METHOD5(StartPresentation, + DefaultPresentationConnectionCallback callback)); + + // TODO(crbug.com/729950): Use MOCK_METHOD directly once GMock gets the + // move-only type support. + void StartPresentation(int render_process_id, + int render_frame_id, + const std::vector<GURL>& presentation_urls, + PresentationConnectionCallback success_cb, + PresentationConnectionErrorCallback error_cb) { + StartPresentationInternal(render_process_id, render_frame_id, + presentation_urls, success_cb, error_cb); + } + MOCK_METHOD5(StartPresentationInternal, void(int render_process_id, int render_frame_id, const std::vector<GURL>& presentation_urls, - const PresentationConnectionCallback& success_cb, - const PresentationConnectionErrorCallback& error_cb)); - MOCK_METHOD6(ReconnectPresentation, + PresentationConnectionCallback& success_cb, + PresentationConnectionErrorCallback& error_cb)); + void ReconnectPresentation(int render_process_id, + int render_frame_id, + const std::vector<GURL>& presentation_urls, + const std::string& presentation_id, + PresentationConnectionCallback success_cb, + PresentationConnectionErrorCallback error_cb) { + ReconnectPresentationInternal(render_process_id, render_frame_id, + presentation_urls, presentation_id, + success_cb, error_cb); + } + MOCK_METHOD6(ReconnectPresentationInternal, void(int render_process_id, int render_frame_id, const std::vector<GURL>& presentation_urls, const std::string& presentation_id, - const PresentationConnectionCallback& success_cb, - const PresentationConnectionErrorCallback& error_cb)); + PresentationConnectionCallback& success_cb, + PresentationConnectionErrorCallback& error_cb)); MOCK_METHOD3(CloseConnection, void(int render_process_id, int render_frame_id, @@ -117,11 +144,6 @@ void(int render_process_id, int render_frame_id, const std::string& presentation_id)); - MOCK_METHOD4(ListenForConnectionMessages, - void(int render_process_id, - int render_frame_id, - const PresentationInfo& presentation_info, - const PresentationConnectionMessageCallback& message_cb)); // PresentationConnectionMessage is move-only. // TODO(crbug.com/729950): Use MOCK_METHOD directly once GMock gets the @@ -424,7 +446,7 @@ PresentationConnectionCallback callback; EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _, more_urls, _)) - .WillOnce(SaveArg<3>(&callback)); + .WillOnce(SaveArgByMove<3>(&callback)); service_impl_->SetDefaultPresentationUrls(more_urls); PresentationInfo presentation_info(presentation_url2_, kPresentationId); @@ -432,7 +454,8 @@ EXPECT_CALL(mock_client_, OnDefaultPresentationStarted(InfoEquals(presentation_info))); EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)); - callback.Run(PresentationInfo(presentation_url2_, kPresentationId)); + std::move(callback).Run( + PresentationInfo(presentation_url2_, kPresentationId)); base::RunLoop().RunUntilIdle(); } @@ -491,32 +514,37 @@ TEST_F(PresentationServiceImplTest, StartPresentationSuccess) { base::MockCallback<NewPresentationCallback> mock_presentation_cb; - base::Callback<void(const PresentationInfo&)> success_cb; - EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) - .WillOnce(SaveArg<3>(&success_cb)); + base::OnceCallback<void(const PresentationInfo&)> success_cb; + EXPECT_CALL(mock_delegate_, + StartPresentationInternal(_, _, presentation_urls_, _, _)) + .WillOnce(SaveArgByMove<3>(&success_cb)); service_impl_->StartPresentation(presentation_urls_, mock_presentation_cb.Get()); EXPECT_FALSE(success_cb.is_null()); EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) .Times(1); EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNotNull(), OptionalIsNull())); - success_cb.Run(PresentationInfo(presentation_url1_, kPresentationId)); + std::move(success_cb) + .Run(PresentationInfo(presentation_url1_, kPresentationId)); } TEST_F(PresentationServiceImplTest, StartPresentationError) { base::MockCallback<NewPresentationCallback> mock_presentation_cb; - base::Callback<void(const PresentationError&)> error_cb; - EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) - .WillOnce(SaveArg<4>(&error_cb)); + base::OnceCallback<void(const PresentationError&)> error_cb; + EXPECT_CALL(mock_delegate_, + StartPresentationInternal(_, _, presentation_urls_, _, _)) + .WillOnce(SaveArgByMove<4>(&error_cb)); service_impl_->StartPresentation(presentation_urls_, mock_presentation_cb.Get()); EXPECT_FALSE(error_cb.is_null()); EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNull(), OptionalIsNotNull())); - error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); + std::move(error_cb).Run( + PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); } TEST_F(PresentationServiceImplTest, StartPresentationInProgress) { - EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) + EXPECT_CALL(mock_delegate_, + StartPresentationInternal(_, _, presentation_urls_, _, _)) .Times(1); // Uninvoked callbacks must outlive |service_impl_| since they get invoked // at |service_impl_|'s destruction. @@ -532,10 +560,11 @@ TEST_F(PresentationServiceImplTest, ReconnectPresentationSuccess) { base::MockCallback<NewPresentationCallback> mock_presentation_cb; - base::Callback<void(const PresentationInfo&)> success_cb; - EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, presentation_urls_, - kPresentationId, _, _)) - .WillOnce(SaveArg<4>(&success_cb)); + base::OnceCallback<void(const PresentationInfo&)> success_cb; + EXPECT_CALL(mock_delegate_, + ReconnectPresentationInternal(_, _, presentation_urls_, + kPresentationId, _, _)) + .WillOnce(SaveArgByMove<4>(&success_cb)); service_impl_->ReconnectPresentation( presentation_urls_, base::Optional<std::string>(kPresentationId), mock_presentation_cb.Get()); @@ -543,21 +572,24 @@ EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) .Times(1); EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNotNull(), OptionalIsNull())); - success_cb.Run(PresentationInfo(presentation_url1_, kPresentationId)); + std::move(success_cb) + .Run(PresentationInfo(presentation_url1_, kPresentationId)); } TEST_F(PresentationServiceImplTest, ReconnectPresentationError) { base::MockCallback<NewPresentationCallback> mock_presentation_cb; - base::Callback<void(const PresentationError&)> error_cb; - EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, presentation_urls_, - kPresentationId, _, _)) - .WillOnce(SaveArg<5>(&error_cb)); + base::OnceCallback<void(const PresentationError&)> error_cb; + EXPECT_CALL(mock_delegate_, + ReconnectPresentationInternal(_, _, presentation_urls_, + kPresentationId, _, _)) + .WillOnce(SaveArgByMove<5>(&error_cb)); service_impl_->ReconnectPresentation( presentation_urls_, base::Optional<std::string>(kPresentationId), mock_presentation_cb.Get()); EXPECT_FALSE(error_cb.is_null()); EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNull(), OptionalIsNotNull())); - error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); + std::move(error_cb).Run( + PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); } TEST_F(PresentationServiceImplTest, MaxPendingReconnectPresentationRequests) { @@ -565,7 +597,7 @@ const char* presentation_id = "presentationId%d"; int num_requests = PresentationServiceImpl::kMaxQueuedRequests; int i = 0; - EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, _, _, _, _)) + EXPECT_CALL(mock_delegate_, ReconnectPresentationInternal(_, _, _, _, _, _)) .Times(num_requests); for (; i < num_requests; ++i) { std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))};
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 8b9cc1b6..ce101b0 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -46,9 +46,10 @@ #include "cc/surfaces/frame_sink_id_allocator.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" +#include "components/viz/common/gl_helper.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/display_compositor/compositor_overlay_candidate_validator_android.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "content/browser/compositor/surface_utils.h" #include "content/browser/gpu/browser_gpu_channel_host_factory.h" @@ -797,7 +798,7 @@ renderer_settings.enable_color_correct_rendering = base::FeatureList::IsEnabled(features::kColorCorrectRendering); display_.reset(new cc::Display( - viz::HostSharedBitmapManager::current(), + viz::ServerSharedBitmapManager::current(), BrowserGpuMemoryBufferManager::current(), renderer_settings, frame_sink_id_, std::move(display_output_surface), std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>(task_runner))); @@ -810,7 +811,7 @@ : base::MakeUnique<cc::DirectLayerTreeFrameSink>( frame_sink_id_, manager, display_.get(), context_provider, nullptr, BrowserGpuMemoryBufferManager::current(), - viz::HostSharedBitmapManager::current()); + viz::ServerSharedBitmapManager::current()); display_->SetVisible(true); display_->Resize(size_);
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc index b6823be..c7306154 100644 --- a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc +++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
@@ -75,6 +75,67 @@ } } +void RecordEQTAccuracy(base::TimeDelta queueing_time, + base::TimeDelta expected_queueing_time) { + float expected_queueing_time_ms = expected_queueing_time.InMillisecondsF(); + + if (expected_queueing_time_ms < 10) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.10ms", + queueing_time); + } + + if (expected_queueing_time_ms < 150) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.150ms", + queueing_time); + } + + if (expected_queueing_time_ms < 300) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.300ms", + queueing_time); + } + + if (expected_queueing_time_ms < 450) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.450ms", + queueing_time); + } + + if (expected_queueing_time_ms > 10) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.10ms", + queueing_time); + } + + if (expected_queueing_time_ms > 150) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.150ms", + queueing_time); + } + + if (expected_queueing_time_ms > 300) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.300ms", + queueing_time); + } + + if (expected_queueing_time_ms > 450) { + UMA_HISTOGRAM_TIMES( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.450ms", + queueing_time); + } +} + } // namespace RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker() @@ -167,6 +228,10 @@ UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( "Event.Latency.QueueingTime." + event_name + default_action_status, rwh_component, main_component); + + RecordEQTAccuracy( + main_component.last_event_time - rwh_component.first_event_time, + latency.expected_queueing_time_on_dispatch()); } }
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc b/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc index e9f279f..492319d 100644 --- a/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc +++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
@@ -1297,4 +1297,100 @@ ElementsAre(Bucket(14, 1))); } +TEST_F(RenderWidgetHostLatencyTrackerTest, ExpectedQueueingTimeAccuracy) { + // These numbers are sensitive to where the histogram buckets are. + int event_timestamps_ms[] = {11, 25, 35}; + + for (float expected_queueing_time_ms : {2, 15, 200, 400}) { + base::TimeDelta expected_queueing_time = + base::TimeDelta::FromMilliseconds(expected_queueing_time_ms); + SyntheticWebTouchEvent event; + // Touch start. + event.PressPoint(1, 1); + + ui::LatencyInfo latency; + latency.set_source_event_type(ui::SourceEventType::TOUCH); + tracker()->OnInputEvent(event, &latency); + + ui::LatencyInfo fake_latency; + fake_latency.set_trace_id(kTraceEventId); + fake_latency.set_expected_queueing_time_on_dispatch(expected_queueing_time); + fake_latency.set_source_event_type(ui::SourceEventType::TOUCH); + fake_latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, + tracker()->latency_component_id(), 0, + base::TimeTicks() + + base::TimeDelta::FromMilliseconds(event_timestamps_ms[0]), + 1); + + fake_latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0, 0, + base::TimeTicks() + + base::TimeDelta::FromMilliseconds(event_timestamps_ms[1]), + 1); + + fake_latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0, + base::TimeTicks() + + base::TimeDelta::FromMilliseconds(event_timestamps_ms[2]), + 1); + + // Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck + // overwriting components. + tracker()->ComputeInputLatencyHistograms( + event.GetType(), tracker()->latency_component_id(), fake_latency, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + + tracker()->OnInputEventAck(event, &latency, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + } + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.10ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 1))); + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.150ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 2))); + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.300ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 3))); + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_LessThan.450ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 4))); + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.10ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 3))); + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.150ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 2))); + + EXPECT_THAT( + histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.300ms"), + ElementsAre(Bucket(event_timestamps_ms[1] - event_timestamps_ms[0], 1))); + + EXPECT_THAT(histogram_tester().GetAllSamples( + "RendererScheduler." + "QueueingDurationWhenExpectedQueueingTime_GreaterThan.450ms"), + ElementsAre()); +} + } // namespace content
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura.h b/content/browser/renderer_host/input/touch_selection_controller_client_aura.h index 1aecd58..69b1111 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_aura.h +++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
@@ -10,8 +10,8 @@ #include "base/macros.h" #include "base/observer_list.h" #include "base/timer/timer.h" -#include "content/browser/renderer_host/input/touch_selection_controller_client_manager.h" #include "content/common/content_export.h" +#include "content/public/browser/touch_selection_controller_client_manager.h" #include "ui/touch_selection/touch_selection_controller.h" #include "ui/touch_selection/touch_selection_menu_runner.h"
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc index 5a40845a..8dcb229 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
@@ -5,11 +5,11 @@ #include "content/browser/renderer_host/input/touch_selection_controller_client_child_frame.h" #include "content/browser/frame_host/render_widget_host_view_child_frame.h" -#include "content/browser/renderer_host/input/touch_selection_controller_client_manager.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/common/content_switches_internal.h" #include "content/common/view_messages.h" +#include "content/public/browser/touch_selection_controller_client_manager.h" #include "ui/base/clipboard/clipboard.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/strings/grit/ui_strings.h"
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 0bf2749f..c94fe4c 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
@@ -16,6 +16,7 @@ #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "content/browser/gpu/browser_gpu_channel_host_factory.h" +#include "content/browser/gpu/gpu_process_host.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "media/base/media_switches.h" @@ -217,6 +218,34 @@ } // static +void VideoCaptureGpuJpegDecoder::RequestGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + GpuProcessHost* host = + GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false); + if (host) { + host->RequestGPUInfo( + base::Bind(&VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread, + task_runner, weak_this)); + } else { + DidReceiveGPUInfoOnIOThread(std::move(task_runner), std::move(weak_this), + gpu::GPUInfo()); + } +} + +// static +void VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this, + const gpu::GPUInfo& gpu_info) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // TODO(c.padhi): Implement this, see http://crbug.com/699255. + NOTIMPLEMENTED(); +} + +// static void VideoCaptureGpuJpegDecoder::EstablishGpuChannelOnUIThread( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this) {
diff --git a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h index 04ef6ca..3d0201d 100644 --- a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h +++ b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
@@ -19,6 +19,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" #include "content/common/content_export.h" +#include "gpu/config/gpu_info.h" #include "media/capture/video/video_capture_jpeg_decoder.h" #include "media/video/jpeg_decode_accelerator.h" @@ -66,6 +67,15 @@ media::JpegDecodeAccelerator::Error error) override; private: + static void RequestGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this); + + static void DidReceiveGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this, + const gpu::GPUInfo& gpu_info); + // Initialization helper, to establish GPU channel. static void EstablishGpuChannelOnUIThread( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 1cda159..52fe2b6 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc
@@ -20,6 +20,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread.h" #include "build/build_config.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/browser_main_loop.h" #include "content/browser/cache_storage/cache_storage_cache.h" @@ -130,7 +131,8 @@ arraysize(kFilteredMessageClasses)), BrowserAssociatedInterface<mojom::RenderMessageFilter>(this, this), resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()), - bitmap_manager_client_(viz::HostSharedBitmapManager::current()), + shared_bitmap_allocation_notifier_impl_( + viz::ServerSharedBitmapManager::current()), request_context_(request_context), resource_context_(browser_context->GetResourceContext()), render_widget_helper_(render_widget_helper), @@ -213,9 +215,9 @@ std::move(callback).Run(route_id); } -void RenderMessageFilter::GetSharedBitmapManager( - cc::mojom::SharedBitmapManagerAssociatedRequest request) { - bitmap_manager_client_.Bind(std::move(request)); +void RenderMessageFilter::GetSharedBitmapAllocationNotifier( + cc::mojom::SharedBitmapAllocationNotifierAssociatedRequest request) { + shared_bitmap_allocation_notifier_impl_.Bind(std::move(request)); } #if defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index c99f6b84..94b9e16 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h
@@ -20,7 +20,7 @@ #include "base/strings/string16.h" #include "build/build_config.h" #include "cc/resources/shared_bitmap_manager.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h" #include "content/common/cache_storage/cache_storage_types.h" #include "content/common/render_message_filter.mojom.h" #include "content/public/browser/browser_associated_interface.h" @@ -116,8 +116,9 @@ CreateNewWidgetCallback callback) override; void CreateFullscreenWidget(int opener_id, CreateFullscreenWidgetCallback callback) override; - void GetSharedBitmapManager( - cc::mojom::SharedBitmapManagerAssociatedRequest request) override; + void GetSharedBitmapAllocationNotifier( + cc::mojom::SharedBitmapAllocationNotifierAssociatedRequest request) + override; // Message handlers called on the browser IO thread: void OnHasGpuProcess(IPC::Message* reply); @@ -159,7 +160,8 @@ // than we do. ResourceDispatcherHostImpl* resource_dispatcher_host_; - viz::HostSharedBitmapManagerClient bitmap_manager_client_; + viz::SharedBitmapAllocationNotifierImpl + shared_bitmap_allocation_notifier_impl_; // Contextual information to be used for requests created here. scoped_refptr<net::URLRequestContextGetter> request_context_;
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 9ae1ad4..d177e31 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -31,7 +31,7 @@ #include "build/build_config.h" #include "cc/base/switches.h" #include "cc/output/compositor_frame.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/bad_message.h" #include "content/browser/browser_plugin/browser_plugin_guest.h" @@ -2146,7 +2146,8 @@ DCHECK(!size.IsEmpty()); std::unique_ptr<cc::SharedBitmap> bitmap = - viz::HostSharedBitmapManager::current()->GetSharedBitmapFromId(size, id); + viz::ServerSharedBitmapManager::current()->GetSharedBitmapFromId(size, + id); if (!bitmap) { bad_message::ReceivedBadMessage(GetProcess(), bad_message::RWH_SHARED_BITMAP);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 18910b8..4e63e2f0 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1017,7 +1017,8 @@ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); blink::WebTouchEvent web_event = ui::CreateWebTouchEventFromMotionEvent(*cancel_event, causes_scrolling); - if (host_->delegate()->GetInputEventRouter()) { + if (SiteIsolationPolicy::AreCrossProcessFramesPossible() && + host_->delegate()->GetInputEventRouter()) { host_->delegate()->GetInputEventRouter()->RouteTouchEvent( this, &web_event, latency_info); } else {
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 c9a55fe..364819d1 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2044,7 +2044,7 @@ } TouchSelectionControllerClientManager* -RenderWidgetHostViewAura::touch_selection_controller_client_manager() { +RenderWidgetHostViewAura::GetTouchSelectionControllerClientManager() { return selection_controller_client_.get(); }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index e5f15fe9..3db5e41 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -117,6 +117,8 @@ void FocusedNodeTouched(const gfx::Point& location_dips_screen, bool editable) override; void SetNeedsBeginFrames(bool needs_begin_frames) override; + TouchSelectionControllerClientManager* + GetTouchSelectionControllerClientManager() override; // Overridden from RenderWidgetHostViewBase: void InitAsPopup(RenderWidgetHostView* parent_host_view, @@ -330,9 +332,6 @@ return event_handler_.get(); } - TouchSelectionControllerClientManager* - touch_selection_controller_client_manager() override; - protected: ~RenderWidgetHostViewAura() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 2dab601b..43b4eaf0 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -34,7 +34,8 @@ #include "cc/test/fake_external_begin_frame_source.h" #include "cc/test/fake_surface_observer.h" #include "components/viz/common/gl_helper.h" -#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/server_shared_bitmap_manager.h" +#include "components/viz/service/display_compositor/shared_bitmap_allocation_notifier_impl.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/compositor/test/no_transport_image_transport_factory.h" #include "content/browser/frame_host/render_widget_host_view_guest.h" @@ -3046,7 +3047,7 @@ gfx::Rect view_rect(100, 100); gfx::Size frame_size = view_rect.size(); DCHECK_EQ(0u, - viz::HostSharedBitmapManager::current()->AllocatedBitmapCount()); + viz::ServerSharedBitmapManager::current()->AllocatedBitmapCount()); std::unique_ptr<RenderWidgetHostImpl* []> hosts( new RenderWidgetHostImpl*[renderer_count]); @@ -3185,12 +3186,12 @@ int handles_per_frame = 5; FrameEvictionManager::GetInstance()->set_max_handles(handles_per_frame * 2); - viz::HostSharedBitmapManagerClient bitmap_client( - viz::HostSharedBitmapManager::current()); + viz::SharedBitmapAllocationNotifierImpl notifier( + viz::ServerSharedBitmapManager::current()); for (size_t i = 0; i < (renderer_count - 1) * handles_per_frame; i++) { - bitmap_client.ChildAllocatedSharedBitmap(1, base::SharedMemoryHandle(), - cc::SharedBitmap::GenerateId()); + notifier.ChildAllocatedSharedBitmap(1, base::SharedMemoryHandle(), + cc::SharedBitmap::GenerateId()); } // Hiding this last bitmap should evict all but two frames. @@ -3220,7 +3221,7 @@ gfx::Rect view_rect(100, 100); gfx::Size frame_size = view_rect.size(); DCHECK_EQ(0u, - viz::HostSharedBitmapManager::current()->AllocatedBitmapCount()); + viz::ServerSharedBitmapManager::current()->AllocatedBitmapCount()); std::unique_ptr<RenderWidgetHostImpl* []> hosts( new RenderWidgetHostImpl*[renderer_count]); @@ -3293,7 +3294,7 @@ gfx::Rect view_rect(100, 100); gfx::Size frame_size = view_rect.size(); DCHECK_EQ(0u, - viz::HostSharedBitmapManager::current()->AllocatedBitmapCount()); + viz::ServerSharedBitmapManager::current()->AllocatedBitmapCount()); std::unique_ptr<RenderWidgetHostImpl* []> hosts( new RenderWidgetHostImpl*[renderer_count]);
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index e9ed770..c2cdfa4d 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -482,7 +482,7 @@ } TouchSelectionControllerClientManager* -RenderWidgetHostViewBase::touch_selection_controller_client_manager() { +RenderWidgetHostViewBase::GetTouchSelectionControllerClientManager() { return nullptr; }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 0e159d7..4f35147 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -119,6 +119,8 @@ void EndFrameSubscription() override; void FocusedNodeTouched(const gfx::Point& location_dips_screen, bool editable) override; + TouchSelectionControllerClientManager* + GetTouchSelectionControllerClientManager() override; // This only needs to be overridden by RenderWidgetHostViewBase subclasses // that handle content embedded within other RenderWidgetHostViews. @@ -433,13 +435,6 @@ web_contents_accessibility_ = wcax; } - // This only returns non-null on platforms that implement touch - // selection editing (TSE), currently Aura and (soon) Android. - // TODO(wjmaclean): update this comment when OOPIF TSE is implemented on - // Android. - virtual TouchSelectionControllerClientManager* - touch_selection_controller_client_manager(); - // Exposed for testing. virtual bool IsChildFrameForTesting() const; virtual cc::SurfaceId SurfaceIdForTesting() const;
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 7ac9818..fdbad66 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -280,6 +280,13 @@ // TODO(nhiroki): Reconsider this bizarre layering. } + void set_start_worker_sent_time(base::TimeTicks time) { + start_worker_sent_time_ = time; + } + base::TimeTicks start_worker_sent_time() const { + return start_worker_sent_time_; + } + void Start(std::unique_ptr<EmbeddedWorkerStartParams> params, const StatusCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -417,6 +424,7 @@ // Used for UMA. bool is_installed_; bool started_during_browser_startup_; + base::TimeTicks start_worker_sent_time_; base::WeakPtrFactory<StartTask> weak_factory_; @@ -452,6 +460,7 @@ DCHECK(!params->pause_after_download || !params->is_installed); DCHECK_NE(kInvalidServiceWorkerVersionId, params->service_worker_version_id); + step_time_ = base::TimeTicks::Now(); status_ = EmbeddedWorkerStatus::STARTING; starting_phase_ = ALLOCATING_PROCESS; @@ -594,15 +603,12 @@ mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info; instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info)); - DCHECK(pending_dispatcher_request_.is_pending()); + inflight_start_task_->set_start_worker_sent_time(base::TimeTicks::Now()); client_->StartWorker(*params, std::move(pending_dispatcher_request_), std::move(host_ptr_info)); registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); OnStartWorkerMessageSent(); - // Once the start worker message is received, renderer side will prepare a - // shadow page for getting worker script. - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "PREPARING_SCRIPT_LOAD", - this); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "SENT_START_WORKER", this); return SERVICE_WORKER_OK; } @@ -676,10 +682,7 @@ } void EmbeddedWorkerInstance::OnURLJobCreatedForMainScript() { - // Indicates that the shadow page has been created in renderer side and starts - // to get the worker script. - TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "PREPARING_SCRIPT_LOAD", - this); + TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "SENT_START_WORKER", this); TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "SCRIPT_LOADING", this); if (!inflight_start_task_) return; @@ -778,13 +781,20 @@ // |this| may be destroyed by the callback. } -void EmbeddedWorkerInstance::OnStarted() { +void EmbeddedWorkerInstance::OnStarted( + mojom::EmbeddedWorkerStartTimingPtr start_timing) { if (!registry_->OnWorkerStarted(process_id(), embedded_worker_id_)) return; // Stop is requested before OnStarted is sent back from the worker. if (status_ == EmbeddedWorkerStatus::STOPPING) return; + if (inflight_start_task_->is_installed()) { + ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming( + std::move(start_timing), inflight_start_task_->start_worker_sent_time(), + start_situation_); + } + TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "WAITING_FOR_START_COMPLETE", this); DCHECK(status_ == EmbeddedWorkerStatus::STARTING);
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h index 737417c8..2e2e6a2 100644 --- a/content/browser/service_worker/embedded_worker_instance.h +++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -233,7 +233,7 @@ // Fires the callback passed to Start(). void OnScriptEvaluated(bool success) override; // Changes the internal worker status from STARTING to RUNNING. - void OnStarted() override; + void OnStarted(mojom::EmbeddedWorkerStartTimingPtr start_timing) override; // Resets the embedded worker instance to the initial state. This will change // the internal status from STARTING or RUNNING to STOPPED. void OnStopped() override;
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index 3485ac19..77b4cd77 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -610,7 +610,8 @@ EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id); ASSERT_TRUE(worker); ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]); - embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]->OnStarted(); + embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]->OnStarted( + mojom::EmbeddedWorkerStartTiming::New()); base::RunLoop().RunUntilIdle(); }
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index e0ed0c76..fabe2de 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -790,6 +790,52 @@ duration); } +void ServiceWorkerMetrics::RecordStartMessageLatencyType( + CrossProcessTimeDelta type) { + UMA_HISTOGRAM_ENUMERATION( + "EmbeddedWorkerInstance.Start.StartMessageLatency.Type", type, + CrossProcessTimeDelta::NUM_TYPES); +} + +void ServiceWorkerMetrics::RecordWaitedForRendererSetup(bool waited) { + UMA_HISTOGRAM_BOOLEAN("EmbeddedWorkerInstance.Start.WaitedForRendererSetup", + waited); +} + +void ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming( + mojom::EmbeddedWorkerStartTimingPtr start_timing, + base::TimeTicks start_worker_sent_time, + StartSituation situation) { + if (!base::TimeTicks::IsHighResolution() || + !base::TimeTicks::IsConsistentAcrossProcesses()) { + RecordStartMessageLatencyType(CrossProcessTimeDelta::INACCURATE_CLOCK); + return; + } + if (start_timing->start_worker_received_time < start_worker_sent_time) { + RecordStartMessageLatencyType(CrossProcessTimeDelta::NEGATIVE); + return; + } + + RecordStartMessageLatencyType(CrossProcessTimeDelta::NORMAL); + + const base::TimeDelta start_worker_message_latency = + start_timing->start_worker_received_time - start_worker_sent_time; + UMA_HISTOGRAM_MEDIUM_TIMES("EmbeddedWorkerInstance.Start.StartMessageLatency", + start_worker_message_latency); + RecordSuffixedMediumTimeHistogram( + "EmbeddedWorkerInstance.Start.StartMessageLatency", + StartSituationToSuffix(situation), start_worker_message_latency); + + if (start_worker_sent_time < start_timing->blink_initialized_time) { + RecordWaitedForRendererSetup(true); + UMA_HISTOGRAM_MEDIUM_TIMES( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", + (start_timing->blink_initialized_time - start_worker_sent_time)); + } else { + RecordWaitedForRendererSetup(false); + } +} + const char* ServiceWorkerMetrics::LoadSourceToString(LoadSource source) { switch (source) { case LoadSource::NETWORK:
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index 2fdd8794..9d7b582a 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_database.h" +#include "content/common/service_worker/embedded_worker.mojom.h" #include "content/common/service_worker/service_worker_types.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponseError.h" #include "ui/base/page_transition_types.h" @@ -173,6 +174,16 @@ NUM_TYPES }; + // Used for UMA. Append only. + // Describes the outcome of a time measurement taken between processes. + enum class CrossProcessTimeDelta { + NORMAL, + NEGATIVE, + INACCURATE_CLOCK, + // Add new types here. + NUM_TYPES + }; + // Not used for UMA. enum class LoadSource { NETWORK, HTTP_CACHE, SERVICE_WORKER_STORAGE }; @@ -317,6 +328,12 @@ StartSituation start_situation); static void RecordTimeToEvaluateScript(base::TimeDelta duration, StartSituation start_situation); + static void RecordStartMessageLatencyType(CrossProcessTimeDelta type); + static void RecordWaitedForRendererSetup(bool waited); + CONTENT_EXPORT static void RecordEmbeddedWorkerStartTiming( + mojom::EmbeddedWorkerStartTimingPtr start_timing, + base::TimeTicks start_worker_sent_time, + StartSituation start_situation); static const char* LoadSourceToString(LoadSource source); static StartSituation GetStartSituation(bool is_browser_startup_complete,
diff --git a/content/browser/service_worker/service_worker_metrics_unittest.cc b/content/browser/service_worker/service_worker_metrics_unittest.cc index 75b2697..fa63add 100644 --- a/content/browser/service_worker/service_worker_metrics_unittest.cc +++ b/content/browser/service_worker/service_worker_metrics_unittest.cc
@@ -64,6 +64,7 @@ } // namespace +using CrossProcessTimeDelta = ServiceWorkerMetrics::CrossProcessTimeDelta; using StartSituation = ServiceWorkerMetrics::StartSituation; using WorkerPreparationType = ServiceWorkerMetrics::WorkerPreparationType; @@ -335,4 +336,106 @@ static_cast<int>(WorkerPreparationType::START_DURING_STARTUP), 1); } +TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming) { + base::TimeTicks start_worker_sent_time = base::TimeTicks::Now(); + const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(33); + auto start_timing = mojom::EmbeddedWorkerStartTiming::New(); + start_timing->blink_initialized_time = start_worker_sent_time; + start_timing->start_worker_received_time = start_worker_sent_time + latency; + StartSituation start_situation = StartSituation::EXISTING_PROCESS; + base::HistogramTester histogram_tester; + + ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming( + std::move(start_timing), start_worker_sent_time, start_situation); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.StartMessageLatency.Type", + static_cast<int>(CrossProcessTimeDelta::NORMAL), 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency", latency, 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency_ExistingProcess", + latency, 1); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", false, 1); + histogram_tester.ExpectTotalCount( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", 0); +} + +TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming_BrowserStartup) { + base::TimeTicks start_worker_sent_time = base::TimeTicks::Now(); + const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(66); + auto start_timing = mojom::EmbeddedWorkerStartTiming::New(); + start_timing->blink_initialized_time = start_worker_sent_time; + start_timing->start_worker_received_time = start_worker_sent_time + latency; + StartSituation start_situation = StartSituation::DURING_STARTUP; + base::HistogramTester histogram_tester; + + ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming( + std::move(start_timing), start_worker_sent_time, start_situation); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.StartMessageLatency.Type", + static_cast<int>(CrossProcessTimeDelta::NORMAL), 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency", latency, 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency_DuringStartup", latency, + 1); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", false, 1); + histogram_tester.ExpectTotalCount( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", 0); +} + +TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming_WaitForRenderer) { + base::TimeTicks start_worker_sent_time = base::TimeTicks::Now(); + const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(777); + const base::TimeDelta renderer_setup = base::TimeDelta::FromMilliseconds(333); + auto start_timing = mojom::EmbeddedWorkerStartTiming::New(); + start_timing->blink_initialized_time = + start_worker_sent_time + renderer_setup; + start_timing->start_worker_received_time = start_worker_sent_time + latency; + StartSituation start_situation = StartSituation::NEW_PROCESS; + base::HistogramTester histogram_tester; + + ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming( + std::move(start_timing), start_worker_sent_time, start_situation); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.StartMessageLatency.Type", + static_cast<int>(CrossProcessTimeDelta::NORMAL), 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency", latency, 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency_NewProcess", latency, + 1); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", true, 1); + histogram_tester.ExpectTimeBucketCount( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", + renderer_setup, 1); +} + +TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming_NegativeLatency) { + base::TimeTicks start_worker_sent_time = base::TimeTicks::Now(); + const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(777); + auto start_timing = mojom::EmbeddedWorkerStartTiming::New(); + start_timing->blink_initialized_time = start_worker_sent_time; + start_timing->start_worker_received_time = start_worker_sent_time - latency; + StartSituation start_situation = StartSituation::EXISTING_PROCESS; + base::HistogramTester histogram_tester; + + ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming( + std::move(start_timing), start_worker_sent_time, start_situation); + histogram_tester.ExpectUniqueSample( + "EmbeddedWorkerInstance.Start.StartMessageLatency.Type", + static_cast<int>(CrossProcessTimeDelta::NEGATIVE), 1); + histogram_tester.ExpectTotalCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency", 0); + histogram_tester.ExpectTotalCount( + "EmbeddedWorkerInstance.Start.StartMessageLatency_ExistingProcess", 0); + histogram_tester.ExpectTotalCount( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", 0); + histogram_tester.ExpectTotalCount( + "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", 0); +} + } // namespace content
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 1b7c0e6..c0e2943 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -366,6 +366,7 @@ Context(WebURLLoaderImpl* loader, ResourceDispatcher* resource_dispatcher, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, mojom::URLLoaderFactory* factory); WebURLLoaderClient* client() const { return client_; } @@ -377,8 +378,6 @@ int intra_priority_value); void Start(const WebURLRequest& request, SyncLoadResponse* sync_load_response); - void SetTaskRunner( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); void OnUploadProgress(uint64_t position, uint64_t size); bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, @@ -453,13 +452,15 @@ // WebURLLoaderImpl::Context -------------------------------------------------- -WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader, - ResourceDispatcher* resource_dispatcher, - mojom::URLLoaderFactory* url_loader_factory) +WebURLLoaderImpl::Context::Context( + WebURLLoaderImpl* loader, + ResourceDispatcher* resource_dispatcher, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + mojom::URLLoaderFactory* url_loader_factory) : loader_(loader), client_(NULL), resource_dispatcher_(resource_dispatcher), - task_runner_(base::ThreadTaskRunnerHandle::Get()), + task_runner_(std::move(task_runner)), defers_loading_(NOT_DEFERRING), request_id_(-1), url_loader_factory_(url_loader_factory) {} @@ -655,11 +656,6 @@ resource_dispatcher_->SetDefersLoading(request_id_, true); } -void WebURLLoaderImpl::Context::SetTaskRunner( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { - task_runner_ = task_runner; -} - void WebURLLoaderImpl::Context::OnUploadProgress(uint64_t position, uint64_t size) { if (client_) @@ -1061,9 +1057,14 @@ // WebURLLoaderImpl ----------------------------------------------------------- -WebURLLoaderImpl::WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher, - mojom::URLLoaderFactory* url_loader_factory) - : context_(new Context(this, resource_dispatcher, url_loader_factory)) {} +WebURLLoaderImpl::WebURLLoaderImpl( + ResourceDispatcher* resource_dispatcher, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + mojom::URLLoaderFactory* url_loader_factory) + : context_(new Context(this, + resource_dispatcher, + std::move(task_runner), + url_loader_factory)) {} WebURLLoaderImpl::~WebURLLoaderImpl() { Cancel(); @@ -1286,9 +1287,4 @@ context_->DidChangePriority(new_priority, intra_priority_value); } -void WebURLLoaderImpl::SetLoadingTaskRunner( - base::SingleThreadTaskRunner* loading_task_runner) { - context_->SetTaskRunner(loading_task_runner); -} - } // namespace content
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h index 6bb506d1..4fc8700 100644 --- a/content/child/web_url_loader_impl.h +++ b/content/child/web_url_loader_impl.h
@@ -16,6 +16,10 @@ #include "third_party/WebKit/public/platform/WebURLLoader.h" #include "url/gurl.h" +namespace base { +class SingleThreadTaskRunner; +} + namespace content { class ResourceDispatcher; @@ -48,9 +52,8 @@ class CONTENT_EXPORT WebURLLoaderImpl : public NON_EXPORTED_BASE(blink::WebURLLoader) { public: - - // Takes ownership of |web_task_runner|. WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, mojom::URLLoaderFactory* url_loader_factory); ~WebURLLoaderImpl() override; @@ -76,9 +79,6 @@ void SetDefersLoading(bool value) override; void DidChangePriority(blink::WebURLRequest::Priority new_priority, int intra_priority_value) override; - void SetLoadingTaskRunner( - base::SingleThreadTaskRunner* loading_task_runner) override; - private: class Context; class RequestPeerImpl;
diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc index 1c4c9cb7..6d60c973 100644 --- a/content/child/web_url_loader_impl_unittest.cc +++ b/content/child/web_url_loader_impl_unittest.cc
@@ -129,7 +129,9 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient { public: TestWebURLLoaderClient(ResourceDispatcher* dispatcher) - : loader_(new WebURLLoaderImpl(dispatcher, nullptr)), + : loader_(new WebURLLoaderImpl(dispatcher, + base::ThreadTaskRunnerHandle::Get(), + nullptr)), delete_on_receive_redirect_(false), delete_on_receive_response_(false), delete_on_receive_data_(false),
diff --git a/content/common/render_message_filter.mojom b/content/common/render_message_filter.mojom index 9998a0b..5a7da2f4e 100644 --- a/content/common/render_message_filter.mojom +++ b/content/common/render_message_filter.mojom
@@ -4,7 +4,7 @@ module content.mojom; -import "cc/ipc/shared_bitmap_manager.mojom"; +import "cc/ipc/shared_bitmap_allocation_notifier.mojom"; import "content/common/native_types.mojom"; interface RenderMessageFilter { @@ -20,5 +20,6 @@ [Sync] CreateFullscreenWidget(int32 opener_id) => (int32 route_id); - GetSharedBitmapManager(associated cc.mojom.SharedBitmapManager& bitmap_manager); + GetSharedBitmapAllocationNotifier( + associated cc.mojom.SharedBitmapAllocationNotifier& notifier); };
diff --git a/content/common/resource_request_body_impl.h b/content/common/resource_request_body_impl.h index bb74d6a8f..969f74d 100644 --- a/content/common/resource_request_body_impl.h +++ b/content/common/resource_request_body_impl.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/supports_user_data.h" #include "content/common/content_export.h" #include "content/public/common/resource_request_body.h" #include "storage/common/data_element.h" @@ -25,8 +24,7 @@ // A struct used to represent upload data. The data field is populated by // WebURLLoader from the data given as WebHTTPBody. -class CONTENT_EXPORT ResourceRequestBodyImpl : public ResourceRequestBody, - public base::SupportsUserData { +class CONTENT_EXPORT ResourceRequestBodyImpl : public ResourceRequestBody { public: typedef storage::DataElement Element;
diff --git a/content/common/service_worker/embedded_worker.mojom b/content/common/service_worker/embedded_worker.mojom index 48ec1576..33508fe 100644 --- a/content/common/service_worker/embedded_worker.mojom +++ b/content/common/service_worker/embedded_worker.mojom
@@ -6,6 +6,7 @@ import "content/common/service_worker/service_worker_event_dispatcher.mojom"; import "mojo/common/string16.mojom"; +import "mojo/common/time.mojom"; import "services/service_manager/public/interfaces/interface_provider.mojom"; import "third_party/WebKit/public/web/console_message.mojom"; import "url/mojo/url.mojom"; @@ -13,22 +14,35 @@ [Native] struct EmbeddedWorkerStartParams; -// Interface to control a renderer-side embedded worker. The browser uses this -// interface to start, stop, and issue commands to the worker. +// Holds timing information about the start worker sequence for UMA. +struct EmbeddedWorkerStartTiming { + // When this Blink instance finished initializing. + mojo.common.mojom.TimeTicks blink_initialized_time; + // When the start worker message was received by the renderer. + mojo.common.mojom.TimeTicks start_worker_received_time; +}; + +// EmbeddedWorkerInstanceClient is the renderer-side ("Client") of +// EmbeddedWorkerInstanceHost. It allows control of a renderer-side +// embedded worker. The browser uses this interface to start, stop, and +// issue commands to the worker. interface EmbeddedWorkerInstanceClient { + // Called back as various functions in EmbeddedWorkerInstanceHost, such + // as OnThreadStarted(), OnStarted(). StartWorker(EmbeddedWorkerStartParams params, ServiceWorkerEventDispatcher& dispatcher_request, associated EmbeddedWorkerInstanceHost instance_host); // The response is sent back via EmbeddedWorkerInstanceHost.OnStopped(). StopWorker(); ResumeAfterDownload(); - AddMessageToConsole(blink.mojom.ConsoleMessageLevel level, - string message); + AddMessageToConsole(blink.mojom.ConsoleMessageLevel level, string message); }; -// Interface to control a browser-side embedded worker instance. The renderer -// uses this interface to report embedded worker state back to the browser. -// This interface is associated with the EmbeddedWorkerInstanceClient interface. +// EmbeddedWorkerInstanceHost is the browser-side ("Host") of +// EmbeddedWorkerInstanceClient. It allows control of a browser-side +// embedded worker instance. The renderer uses this interface to report +// embedded worker state back to the browser. This interface is associated +// with the EmbeddedWorkerInstanceClient interface. interface EmbeddedWorkerInstanceHost { // Indicates that the worker is ready for inspection. OnReadyForInspection(); @@ -49,7 +63,7 @@ OnScriptEvaluated(bool success); // Indicates that the worker has started. // This is called after OnScriptEvaluated. - OnStarted(); + OnStarted(EmbeddedWorkerStartTiming start_timing); // Reports that an uncaught exception occurred in the worker. OnReportException(mojo.common.mojom.String16 error_message, int32 line_number, int32 column_number, url.mojom.Url source_url);
diff --git a/content/common/site_isolation_policy.cc b/content/common/site_isolation_policy.cc index 3fc8ba5f..7fa66c2 100644 --- a/content/common/site_isolation_policy.cc +++ b/content/common/site_isolation_policy.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/feature_list.h" +#include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -13,7 +14,17 @@ // static bool SiteIsolationPolicy::AreCrossProcessFramesPossible() { +// Before turning this on for Android, input event routing needs to be +// completed there, and perf regressions in https://crbug.com/690229 need to be +// investigated. +#if defined(OS_ANDROID) + return UseDedicatedProcessesForAllSites() || + IsTopDocumentIsolationEnabled() || AreIsolatedOriginsEnabled() || + GetContentClient()->IsSupplementarySiteIsolationModeEnabled() || + base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames); +#else return true; +#endif } // static
diff --git a/content/network/network_context.cc b/content/network/network_context.cc index 5862ea6..ea81b5c 100644 --- a/content/network/network_context.cc +++ b/content/network/network_context.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_number_conversions.h" #include "components/network_session_configurator/common/network_switches.h" #include "content/network/cache_url_loader.h" +#include "content/network/network_service.h" #include "content/network/network_service_url_loader_factory_impl.h" #include "content/network/url_loader_impl.h" #include "content/public/common/content_client.h" @@ -86,11 +87,17 @@ } // namespace -NetworkContext::NetworkContext(mojom::NetworkContextRequest request, +NetworkContext::NetworkContext(NetworkService* network_service, + mojom::NetworkContextRequest request, mojom::NetworkContextParamsPtr params) - : url_request_context_(MakeURLRequestContext()), + : network_service_(network_service), + url_request_context_(MakeURLRequestContext()), params_(std::move(params)), - binding_(this, std::move(request)) {} + binding_(this, std::move(request)) { + network_service_->RegisterNetworkContext(this); + binding_.set_connection_error_handler( + base::Bind(&NetworkContext::OnConnectionError, base::Unretained(this))); +} NetworkContext::~NetworkContext() { // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the @@ -99,6 +106,10 @@ // so have to be careful. while (!url_loaders_.empty()) (*url_loaders_.begin())->Cleanup(); + + // May be nullptr in tests. + if (network_service_) + network_service_->DeregisterNetworkContext(this); } std::unique_ptr<NetworkContext> NetworkContext::CreateForTesting() { @@ -128,8 +139,22 @@ StartCacheURLLoader(url, url_request_context_.get(), std::move(client)); } +void NetworkContext::Cleanup() { + // The NetworkService is going away, so have to destroy the + // net::URLRequestContext held by this NetworkContext. + delete this; +} + NetworkContext::NetworkContext() - : url_request_context_(MakeURLRequestContext()), + : network_service_(nullptr), + url_request_context_(MakeURLRequestContext()), binding_(this) {} +void NetworkContext::OnConnectionError() { + // Don't delete |this| in response to connection errors when it was created by + // CreateForTesting. + if (network_service_) + delete this; +} + } // namespace content
diff --git a/content/network/network_context.h b/content/network/network_context.h index a4dd42c..b6b5332f 100644 --- a/content/network/network_context.h +++ b/content/network/network_context.h
@@ -22,11 +22,13 @@ } namespace content { +class NetworkService; class URLLoaderImpl; class NetworkContext : public mojom::NetworkContext { public: - NetworkContext(mojom::NetworkContextRequest request, + NetworkContext(NetworkService* network_service, + mojom::NetworkContextRequest request, mojom::NetworkContextParamsPtr params); ~NetworkContext() override; @@ -47,9 +49,18 @@ void HandleViewCacheRequest(const GURL& url, mojom::URLLoaderClientPtr client) override; + // Called when the associated NetworkService is going away. Guaranteed to + // destroy NetworkContext's URLRequestContext. + void Cleanup(); + private: NetworkContext(); + // On connection errors the NetworkContext destroys itself. + void OnConnectionError(); + + NetworkService* const network_service_; + std::unique_ptr<net::URLRequestContext> url_request_context_; // Put it below |url_request_context_| so that it outlives all the
diff --git a/content/network/network_service.cc b/content/network/network_service.cc index 28d947b..a133884 100644 --- a/content/network/network_service.cc +++ b/content/network/network_service.cc
@@ -55,11 +55,44 @@ NetworkService::NetworkService( std::unique_ptr<service_manager::BinderRegistry> registry) : net_log_(new MojoNetLog), registry_(std::move(registry)), binding_(this) { - registry_->AddInterface<mojom::NetworkService>( - base::Bind(&NetworkService::Create, base::Unretained(this))); + // |registry_| may be nullptr in tests. + if (registry_) { + registry_->AddInterface<mojom::NetworkService>( + base::Bind(&NetworkService::Create, base::Unretained(this))); + } } -NetworkService::~NetworkService() = default; +NetworkService::~NetworkService() { + // Call each Network and ask it to release its net::URLRequestContext, as they + // may have references to shared objects owned by the NetworkService. The + // NetworkContexts deregister themselves in Cleanup(), so have to be careful. + while (!network_contexts_.empty()) + (*network_contexts_.begin())->Cleanup(); +} + +std::unique_ptr<NetworkService> NetworkService::CreateForTesting() { + return base::WrapUnique(new NetworkService()); +} + +void NetworkService::RegisterNetworkContext(NetworkContext* network_context) { + DCHECK_EQ(0u, network_contexts_.count(network_context)); + network_contexts_.insert(network_context); +} + +void NetworkService::DeregisterNetworkContext(NetworkContext* network_context) { + DCHECK_EQ(1u, network_contexts_.count(network_context)); + network_contexts_.erase(network_context); +} + +void NetworkService::CreateNetworkContext( + mojom::NetworkContextRequest request, + mojom::NetworkContextParamsPtr params) { + // The NetworkContext will destroy itself on connection error, or when the + // service is destroyed. + new NetworkContext(this, std::move(request), std::move(params)); +} + +NetworkService::NetworkService() : NetworkService(nullptr) {} void NetworkService::OnBindInterface( const service_manager::BindSourceInfo& source_info, @@ -75,12 +108,4 @@ binding_.Bind(std::move(request)); } -void NetworkService::CreateNetworkContext( - mojom::NetworkContextRequest request, - mojom::NetworkContextParamsPtr params) { - mojo::MakeStrongBinding( - base::MakeUnique<NetworkContext>(std::move(request), std::move(params)), - std::move(request)); -} - } // namespace content
diff --git a/content/network/network_service.h b/content/network/network_service.h index e139546d..c945b9ad 100644 --- a/content/network/network_service.h +++ b/content/network/network_service.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/macros.h" +#include "content/common/content_export.h" #include "content/common/network_service.mojom.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -15,6 +16,8 @@ namespace content { +class NetworkContext; + class NetworkService : public service_manager::Service, public mojom::NetworkService { public: @@ -22,9 +25,23 @@ std::unique_ptr<service_manager::BinderRegistry> registry); ~NetworkService() override; + CONTENT_EXPORT static std::unique_ptr<NetworkService> CreateForTesting(); + + // These are called by NetworkContexts as they are being created and + // destroyed. + void RegisterNetworkContext(NetworkContext* network_context); + void DeregisterNetworkContext(NetworkContext* network_context); + + // mojom::NetworkService implementation: + void CreateNetworkContext(mojom::NetworkContextRequest request, + mojom::NetworkContextParamsPtr params) override; + private: class MojoNetLog; + // Used for tests. + NetworkService(); + // service_manager::Service implementation. void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, @@ -33,16 +50,18 @@ void Create(const service_manager::BindSourceInfo& source_info, mojom::NetworkServiceRequest request); - // mojom::NetworkService implementation: - void CreateNetworkContext(mojom::NetworkContextRequest request, - mojom::NetworkContextParamsPtr params) override; - std::unique_ptr<MojoNetLog> net_log_; std::unique_ptr<service_manager::BinderRegistry> registry_; mojo::Binding<mojom::NetworkService> binding_; + // NetworkContexts register themselves with the NetworkService so that they + // can be cleaned up when the NetworkService goes away. This is needed as + // NetworkContexts share global state with the NetworkService, so must be + // destroyed first. + std::set<NetworkContext*> network_contexts_; + DISALLOW_COPY_AND_ASSIGN(NetworkService); };
diff --git a/content/network/network_service_unittest.cc b/content/network/network_service_unittest.cc new file mode 100644 index 0000000..398808c6 --- /dev/null +++ b/content/network/network_service_unittest.cc
@@ -0,0 +1,71 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> + +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "content/common/network_service.mojom.h" +#include "content/network/network_context.h" +#include "content/network/network_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +class NetworkServiceTest : public testing::Test { + public: + NetworkServiceTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO), + service_(NetworkService::CreateForTesting()) {} + ~NetworkServiceTest() override {} + + NetworkService* service() const { return service_.get(); } + + void DestroyService() { service_.reset(); } + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + std::unique_ptr<NetworkService> service_; +}; + +// Test shutdown in the case a NetworkContext is destroyed before the +// NetworkService. +TEST_F(NetworkServiceTest, CreateAndDestroyContext) { + mojom::NetworkContextPtr network_context; + mojom::NetworkContextParamsPtr context_params = + mojom::NetworkContextParams::New(); + + service()->CreateNetworkContext(mojo::MakeRequest(&network_context), + std::move(context_params)); + network_context.reset(); + // Make sure the NetworkContext is destroyed. + base::RunLoop().RunUntilIdle(); +} + +// Test shutdown in the case there is still a live NetworkContext when the +// NetworkService is destroyed. The service should destroy the NetworkContext +// itself. +TEST_F(NetworkServiceTest, DestroyingServiceDestroysContext) { + mojom::NetworkContextPtr network_context; + mojom::NetworkContextParamsPtr context_params = + mojom::NetworkContextParams::New(); + + service()->CreateNetworkContext(mojo::MakeRequest(&network_context), + std::move(context_params)); + base::RunLoop run_loop; + network_context.set_connection_error_handler(run_loop.QuitClosure()); + DestroyService(); + + // Destroying the service should destroy the context, causing a connection + // error. + run_loop.Run(); +} + +} // namespace + +} // namespace content
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc index 6ade0ca..6190e33 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -206,7 +206,9 @@ return NULL; } -std::unique_ptr<blink::WebURLLoader> PpapiBlinkPlatformImpl::CreateURLLoader() { +std::unique_ptr<blink::WebURLLoader> PpapiBlinkPlatformImpl::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { NOTREACHED(); return NULL; }
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.h b/content/ppapi_plugin/ppapi_blink_platform_impl.h index 1db3cf4..fc83aea6 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.h +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -43,7 +43,9 @@ const blink::WebURL& first_party_for_cookies); blink::WebString DefaultLocale() override; blink::WebThemeEngine* ThemeEngine() override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; void GetPluginList(bool refresh, const blink::WebSecurityOrigin& mainFrameOrigin, blink::WebPluginListBuilder*) override;
diff --git a/content/public/android/java/res/OWNERS b/content/public/android/java/res/OWNERS index 6575857e..fb94e03 100644 --- a/content/public/android/java/res/OWNERS +++ b/content/public/android/java/res/OWNERS
@@ -2,6 +2,5 @@ tedchoc@chromium.org dtrainor@chromium.org yusufo@chromium.org -dfalcantara@chromium.org # COMPONENT: Content>Core
diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java index f6c01ad0..fb1ef17 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java +++ b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
@@ -61,25 +61,14 @@ private static BrowserStartupController sInstance; - private static boolean sBrowserMayStartAsynchronously; private static boolean sShouldStartGpuProcessOnBrowserStartup; - private static void setAsynchronousStartup(boolean enable) { - sBrowserMayStartAsynchronously = enable; - } - private static void setShouldStartGpuProcessOnBrowserStartup(boolean enable) { sShouldStartGpuProcessOnBrowserStartup = enable; } @VisibleForTesting @CalledByNative - static boolean browserMayStartAsynchonously() { - return sBrowserMayStartAsynchronously; - } - - @VisibleForTesting - @CalledByNative static void browserStartupComplete(int result) { if (sInstance != null) { sInstance.executeEnqueuedCallbacks(result, NOT_ALREADY_STARTED); @@ -101,6 +90,8 @@ // Whether tasks that occur after resource extraction have been completed. private boolean mPostResourceExtractionTasksCompleted; + private boolean mHasCalledContentStart; + // Whether the async startup of the browser process is complete. private boolean mStartupDone; @@ -170,15 +161,12 @@ // flag that indicates that we have kicked off starting the browser process. mHasStartedInitializingBrowserProcess = true; - setAsynchronousStartup(true); setShouldStartGpuProcessOnBrowserStartup(startGpuProcess); prepareToStartBrowserProcess(false, new Runnable() { @Override public void run() { ThreadUtils.assertOnUiThread(); - // Make sure to not call ContentMain.start twice, if startBrowserProcessesSync - // is called before this runs. - if (!sBrowserMayStartAsynchronously) return; + if (mHasCalledContentStart) return; if (contentStart() > 0) { // Failed. The callbacks may not have run, so run them. enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); @@ -206,10 +194,16 @@ prepareToStartBrowserProcess(singleProcess, null); } - setAsynchronousStartup(false); - if (contentStart() > 0) { - // Failed. The callbacks may not have run, so run them. - enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); + boolean startedSuccessfully = true; + if (!mHasCalledContentStart) { + if (contentStart() > 0) { + // Failed. The callbacks may not have run, so run them. + enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); + startedSuccessfully = false; + } + } + if (startedSuccessfully) { + flushStartupTasks(); } } @@ -225,9 +219,16 @@ */ @VisibleForTesting int contentStart() { + assert !mHasCalledContentStart; + mHasCalledContentStart = true; return ContentMain.start(); } + @VisibleForTesting + void flushStartupTasks() { + nativeFlushStartupTasks(); + } + /** * @return Whether the browser process completed successfully. */ @@ -358,4 +359,6 @@ private static native boolean nativeIsOfficialBuild(); private static native boolean nativeIsPluginEnabled(); + + private static native void nativeFlushStartupTasks(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/crypto/OWNERS b/content/public/android/java/src/org/chromium/content/browser/crypto/OWNERS index 10a1369..d223560 100644 --- a/content/public/android/java/src/org/chromium/content/browser/crypto/OWNERS +++ b/content/public/android/java/src/org/chromium/content/browser/crypto/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org palmer@chromium.org # COMPONENT: Internals>Core
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java index 43ef2d6..dbb7011 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java
@@ -30,6 +30,7 @@ private int mStartupResult; private boolean mLibraryLoadSucceeds; private int mInitializedCounter = 0; + private boolean mStartupCompleteCalled; @Override void prepareToStartBrowserProcess(boolean singleProcess, Runnable completionCallback) @@ -49,20 +50,24 @@ @Override int contentStart() { mInitializedCounter++; - if (BrowserStartupController.browserMayStartAsynchonously()) { - // Post to the UI thread to emulate what would happen in a real scenario. - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - BrowserStartupController.browserStartupComplete(mStartupResult); - } - }); - } else { - BrowserStartupController.browserStartupComplete(mStartupResult); - } + // Post to the UI thread to emulate what would happen in a real scenario. + ThreadUtils.postOnUiThread(new Runnable() { + @Override + public void run() { + if (mStartupCompleteCalled) return; + BrowserStartupController.browserStartupComplete(mStartupResult); + } + }); return mStartupResult; } + @Override + void flushStartupTasks() { + assert mInitializedCounter > 0; + if (mStartupCompleteCalled) return; + BrowserStartupController.browserStartupComplete(mStartupResult); + } + private int initializedCounter() { return mInitializedCounter; } @@ -118,8 +123,6 @@ } }); - Assert.assertTrue("Asynchronous mode should have been set.", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); @@ -170,8 +173,6 @@ } }); - Assert.assertTrue("Asynchronous mode should have been set.", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); @@ -217,8 +218,6 @@ } }); - Assert.assertTrue("Asynchronous mode should have been set.", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); @@ -283,8 +282,6 @@ } }); - Assert.assertTrue("Asynchronous mode should have been set.", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); @@ -321,8 +318,6 @@ } }); - Assert.assertTrue("Asynchronous mode should have been set.", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); @@ -380,8 +375,6 @@ } } }); - Assert.assertFalse("Synchronous mode should have been set", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); @@ -413,8 +406,6 @@ } } }); - Assert.assertFalse("Synchronous mode should have been set", - BrowserStartupController.browserMayStartAsynchonously()); Assert.assertEquals("The browser process should have been initialized twice.", 2, mController.initializedCounter()); @@ -448,9 +439,6 @@ Assert.assertEquals("The browser process should have been initialized once.", 1, mController.initializedCounter()); - Assert.assertFalse("Synchronous mode should have been set", - BrowserStartupController.browserMayStartAsynchonously()); - // Kick off the asynchronous startup request. This should just queue the callback. ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/crypto/OWNERS b/content/public/android/javatests/src/org/chromium/content/browser/crypto/OWNERS index 10a1369..d223560 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/crypto/OWNERS +++ b/content/public/android/javatests/src/org/chromium/content/browser/crypto/OWNERS
@@ -1,4 +1,3 @@ -dfalcantara@chromium.org palmer@chromium.org # COMPONENT: Internals>Core
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 473549a..54bc620 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -253,6 +253,7 @@ "stream_handle.h", "stream_info.cc", "stream_info.h", + "touch_selection_controller_client_manager.h", "trace_uploader.h", "tracing_controller.h", "tracing_delegate.cc",
diff --git a/content/public/browser/presentation_service_delegate.h b/content/public/browser/presentation_service_delegate.h index fce64074..3c26278 100644 --- a/content/public/browser/presentation_service_delegate.h +++ b/content/public/browser/presentation_service_delegate.h
@@ -23,13 +23,11 @@ class PresentationScreenAvailabilityListener; using PresentationConnectionCallback = - base::RepeatingCallback<void(const PresentationInfo&)>; + base::OnceCallback<void(const PresentationInfo&)>; using PresentationConnectionErrorCallback = - base::RepeatingCallback<void(const PresentationError&)>; - -// Param: a vector of messages that are received. -using PresentationConnectionMessageCallback = base::RepeatingCallback<void( - std::vector<content::PresentationConnectionMessage>)>; + base::OnceCallback<void(const PresentationError&)>; +using DefaultPresentationConnectionCallback = + base::RepeatingCallback<void(const PresentationInfo&)>; struct PresentationConnectionStateChangeInfo { explicit PresentationConnectionStateChangeInfo( @@ -131,7 +129,7 @@ int render_process_id, int render_frame_id, const std::vector<GURL>& default_presentation_urls, - const PresentationConnectionCallback& callback) = 0; + DefaultPresentationConnectionCallback callback) = 0; // Starts a new presentation. The presentation id of the presentation will // be the default presentation ID if any or a generated one otherwise. @@ -147,8 +145,8 @@ int render_process_id, int render_frame_id, const std::vector<GURL>& presentation_urls, - const PresentationConnectionCallback& success_cb, - const PresentationConnectionErrorCallback& error_cb) = 0; + PresentationConnectionCallback success_cb, + PresentationConnectionErrorCallback error_cb) = 0; // Reconnects to an existing presentation. Unlike StartPresentation(), this // does not bring a screen list UI. @@ -163,8 +161,8 @@ int render_frame_id, const std::vector<GURL>& presentation_urls, const std::string& presentation_id, - const PresentationConnectionCallback& success_cb, - const PresentationConnectionErrorCallback& error_cb) = 0; + PresentationConnectionCallback success_cb, + PresentationConnectionErrorCallback error_cb) = 0; // Closes an existing presentation connection. // |render_process_id|, |render_frame_id|: ID for originating frame.
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h index 55281d3..725d7b06 100644 --- a/content/public/browser/render_widget_host_view.h +++ b/content/public/browser/render_widget_host_view.h
@@ -35,6 +35,7 @@ class RenderWidgetHost; class RenderWidgetHostViewFrameSubscriber; +class TouchSelectionControllerClientManager; // RenderWidgetHostView is an interface implemented by an object that acts as // the "View" portion of a RenderWidgetHost. The RenderWidgetHost and its @@ -125,6 +126,13 @@ // Returns the currently selected text. virtual base::string16 GetSelectedText() = 0; + // This only returns non-null on platforms that implement touch + // selection editing (TSE), currently Aura and (soon) Android. + // TODO(wjmaclean): update this comment when OOPIF TSE is implemented on + // Android. https://crbug.com/470662. + virtual TouchSelectionControllerClientManager* + GetTouchSelectionControllerClientManager() = 0; + // Subclasses should override this method to set the background color. |color| // has to be either SK_ColorTRANSPARENT or opaque. If set to // SK_ColorTRANSPARENT, the renderer's background color will be overridden to
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_manager.h b/content/public/browser/touch_selection_controller_client_manager.h similarity index 88% rename from content/browser/renderer_host/input/touch_selection_controller_client_manager.h rename to content/public/browser/touch_selection_controller_client_manager.h index a28c11c3..7b62d91 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_manager.h +++ b/content/public/browser/touch_selection_controller_client_manager.h
@@ -15,7 +15,7 @@ class TouchSelectionController; class TouchSelectionControllerClient; class TouchSelectionMenuClient; -} +} // namespace ui namespace content { @@ -46,12 +46,18 @@ const gfx::SelectionBound& end, ui::TouchSelectionControllerClient* client, ui::TouchSelectionMenuClient* menu_client) = 0; + // Used by clients to inform the manager that the client no longer wants to // participate in touch selection editing, usually because the client's view // is being destroyed or detached. virtual void InvalidateClient(ui::TouchSelectionControllerClient* client) = 0; + + // Provides direct access to the TouchSelectionController that will be used + // with all clients accessing this manager. Always returns non-null value. virtual ui::TouchSelectionController* GetTouchSelectionController() = 0; + // The following two functions allow clients (or their owners, etc.) to + // monitor the manager's lifetime. virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; };
diff --git a/content/public/test/android/OWNERS b/content/public/test/android/OWNERS index 97a8717f..58517af3 100644 --- a/content/public/test/android/OWNERS +++ b/content/public/test/android/OWNERS
@@ -1,6 +1,5 @@ aelias@chromium.org boliu@chromium.org -dfalcantara@chromium.org dtrainor@chromium.org nyquist@chromium.org skyostil@chromium.org
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc index 99ff137b..432d781c 100644 --- a/content/public/test/mock_render_thread.cc +++ b/content/public/test/mock_render_thread.cc
@@ -58,8 +58,9 @@ NOTREACHED(); } - void GetSharedBitmapManager( - cc::mojom::SharedBitmapManagerAssociatedRequest request) override { + void GetSharedBitmapAllocationNotifier( + cc::mojom::SharedBitmapAllocationNotifierAssociatedRequest request) + override { NOTREACHED(); }
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 3ad0810..adcf1fcb 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -486,7 +486,6 @@ "//services/device/public/interfaces:constants", "//services/service_manager/public/cpp", "//services/service_manager/public/interfaces", - "//services/ui/public/cpp/bitmap", "//services/ui/public/cpp/gpu", "//skia", "//storage/common",
diff --git a/content/renderer/fetchers/resource_fetcher_impl.cc b/content/renderer/fetchers/resource_fetcher_impl.cc index c83f04c..46b770f 100644 --- a/content/renderer/fetchers/resource_fetcher_impl.cc +++ b/content/renderer/fetchers/resource_fetcher_impl.cc
@@ -188,7 +188,7 @@ client_.reset(new ClientImpl(this, callback)); - loader_ = frame->CreateURLLoader(); + loader_ = frame->CreateURLLoader(request_, frame->LoadingTaskRunner()); loader_->LoadAsynchronously(request_, client_.get()); // No need to hold on to the request; reset it now.
diff --git a/content/renderer/input/render_widget_input_handler.cc b/content/renderer/input/render_widget_input_handler.cc index 4a9261b..36e63db 100644 --- a/content/renderer/input/render_widget_input_handler.cc +++ b/content/renderer/input/render_widget_input_handler.cc
@@ -247,6 +247,14 @@ std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor; ui::LatencyInfo swap_latency_info(latency_info); + + if (RenderThreadImpl::current()) { + swap_latency_info.set_expected_queueing_time_on_dispatch( + RenderThreadImpl::current() + ->GetRendererScheduler() + ->MostRecentExpectedQueueingTime()); + } + swap_latency_info.AddLatencyNumber( ui::LatencyComponentType::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0, 0);
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index 8173b4f..839ea34 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -20,6 +20,7 @@ #include "content/renderer/render_frame_impl.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" +#include "media/base/cdm_factory.h" #include "media/base/decoder_factory.h" #include "media/base/media_switches.h" #include "media/base/renderer_factory_selector.h"
diff --git a/content/renderer/mojo/blink_interface_provider_impl.cc b/content/renderer/mojo/blink_interface_provider_impl.cc index 02e4167..251de34 100644 --- a/content/renderer/mojo/blink_interface_provider_impl.cc +++ b/content/renderer/mojo/blink_interface_provider_impl.cc
@@ -36,9 +36,15 @@ void BlinkInterfaceProviderImpl::GetInterface( const char* name, mojo::ScopedMessagePipeHandle handle) { + GetInterfaceInternal(name, std::move(handle)); +} + +void BlinkInterfaceProviderImpl::GetInterfaceInternal( + const std::string& name, + mojo::ScopedMessagePipeHandle handle) { if (!main_thread_task_runner_->BelongsToCurrentThread()) { main_thread_task_runner_->PostTask( - FROM_HERE, base::Bind(&BlinkInterfaceProviderImpl::GetInterface, + FROM_HERE, base::Bind(&BlinkInterfaceProviderImpl::GetInterfaceInternal, weak_ptr_, name, base::Passed(&handle))); return; }
diff --git a/content/renderer/mojo/blink_interface_provider_impl.h b/content/renderer/mojo/blink_interface_provider_impl.h index 3b36af2..c14509504 100644 --- a/content/renderer/mojo/blink_interface_provider_impl.h +++ b/content/renderer/mojo/blink_interface_provider_impl.h
@@ -37,6 +37,9 @@ mojo::ScopedMessagePipeHandle handle) override; private: + void GetInterfaceInternal(const std::string& name, + mojo::ScopedMessagePipeHandle handle); + const base::WeakPtr<service_manager::Connector> connector_; const base::WeakPtr<service_manager::InterfaceProvider> remote_interfaces_;
diff --git a/content/renderer/pepper/pepper_compositor_host.cc b/content/renderer/pepper/pepper_compositor_host.cc index 5c08126..d8e505b 100644 --- a/content/renderer/pepper/pepper_compositor_host.cc +++ b/content/renderer/pepper/pepper_compositor_host.cc
@@ -16,6 +16,7 @@ #include "cc/layers/texture_layer.h" #include "cc/resources/texture_mailbox.h" #include "cc/trees/layer_tree_host.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/gfx_conversion.h" #include "content/renderer/pepper/host_globals.h" @@ -28,7 +29,6 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_image_data_api.h" -#include "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" #include "third_party/khronos/GLES2/gl2.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/transform.h"
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc index 6b6959e..a411e2f 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -17,6 +17,7 @@ #include "cc/paint/paint_flags.h" #include "cc/resources/shared_bitmap.h" #include "cc/resources/texture_mailbox.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/gfx_conversion.h" @@ -34,7 +35,6 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/ppb_view_shared.h" #include "ppapi/thunk/enter.h" -#include "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkSwizzle.h"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 766dd522..0081a29c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -6711,9 +6711,11 @@ return current_state; } -std::unique_ptr<blink::WebURLLoader> RenderFrameImpl::CreateURLLoader() { +std::unique_ptr<blink::WebURLLoader> RenderFrameImpl::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return blink::Platform::Current()->CreateURLLoader(); + return blink::Platform::Current()->CreateURLLoader(request, task_runner); } void RenderFrameImpl::DraggableRegionsChanged() {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 1453dce..f756ebb9 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -669,7 +669,9 @@ const blink::WebSecurityOrigin& security_origin, blink::WebSetSinkIdCallbacks* web_callbacks) override; blink::WebPageVisibilityState VisibilityState() const override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; void DraggableRegionsChanged() override; // WebFrameSerializerClient implementation:
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 1058781..8cf0aef8 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -56,6 +56,7 @@ #include "components/metrics/public/interfaces/single_sample_metrics.mojom.h" #include "components/metrics/single_sample_metrics.h" #include "components/viz/client/client_layer_tree_frame_sink.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include "components/viz/client/local_surface_id_provider.h" #include "content/child/appcache/appcache_dispatcher.h" #include "content/child/appcache/appcache_frontend_impl.h" @@ -152,7 +153,6 @@ #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" #include "services/ui/public/interfaces/constants.mojom.h" #include "skia/ext/event_tracer_impl.h" @@ -670,13 +670,14 @@ IsRunningInMash() ? ui::mojom::kServiceName : mojom::kBrowserServiceName, GetIOTaskRunner()); - cc::mojom::SharedBitmapManagerAssociatedPtr shared_bitmap_manager_ptr; - render_message_filter()->GetSharedBitmapManager( - mojo::MakeRequest(&shared_bitmap_manager_ptr)); - shared_bitmap_manager_.reset(new ui::ChildSharedBitmapManager( - cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr::Create( - shared_bitmap_manager_ptr.PassInterface(), - GetChannel()->ipc_task_runner_refptr()))); + cc::mojom::SharedBitmapAllocationNotifierAssociatedPtr + shared_bitmap_allocation_notifier_ptr; + render_message_filter()->GetSharedBitmapAllocationNotifier( + mojo::MakeRequest(&shared_bitmap_allocation_notifier_ptr)); + shared_bitmap_manager_ = base::MakeUnique<viz::ClientSharedBitmapManager>( + cc::mojom::ThreadSafeSharedBitmapAllocationNotifierAssociatedPtr::Create( + shared_bitmap_allocation_notifier_ptr.PassInterface(), + GetChannel()->ipc_task_runner_refptr())); InitializeWebKit(resource_task_queue); @@ -761,7 +762,8 @@ auto registry = base::MakeUnique<service_manager::BinderRegistry>(); registry->AddInterface(base::Bind(&CreateFrameFactory), base::ThreadTaskRunnerHandle::Get()); - registry->AddInterface(base::Bind(&EmbeddedWorkerInstanceClientImpl::Create), + registry->AddInterface(base::Bind(&EmbeddedWorkerInstanceClientImpl::Create, + base::TimeTicks::Now()), base::ThreadTaskRunnerHandle::Get()); GetServiceManagerConnection()->AddConnectionFilter( base::MakeUnique<SimpleConnectionFilter>(std::move(registry)));
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 8520704..a05e2740 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -107,7 +107,6 @@ } namespace ui { -class ChildSharedBitmapManager; class ContextProviderCommandBuffer; class Gpu; } @@ -116,6 +115,10 @@ class Extension; } +namespace viz { +class ClientSharedBitmapManager; +} + namespace content { class AppCacheDispatcher; @@ -365,7 +368,7 @@ return vc_manager_.get(); } - ui::ChildSharedBitmapManager* shared_bitmap_manager() const { + viz::ClientSharedBitmapManager* shared_bitmap_manager() const { DCHECK(shared_bitmap_manager_); return shared_bitmap_manager_.get(); } @@ -655,7 +658,7 @@ // Used on the render thread. std::unique_ptr<VideoCaptureImplManager> vc_manager_; - std::unique_ptr<ui::ChildSharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<viz::ClientSharedBitmapManager> shared_bitmap_manager_; // The count of RenderWidgets running through this thread. int widget_count_;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 0be19c3..0ef0f67 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -40,6 +40,7 @@ #include "build/build_config.h" #include "cc/base/switches.h" #include "cc/paint/skia_paint_canvas.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include "content/child/appcache/appcache_dispatcher.h" #include "content/child/appcache/web_application_cache_host_impl.h" #include "content/child/request_extra_data.h" @@ -109,7 +110,6 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/http/http_util.h" #include "ppapi/features/features.h" -#include "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/public/platform/FilePathConversion.h" #include "third_party/WebKit/public/platform/URLConversion.h"
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 0686251..f5613ba 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -305,8 +305,9 @@ //------------------------------------------------------------------------------ -std::unique_ptr<blink::WebURLLoader> -RendererBlinkPlatformImpl::CreateURLLoader() { +std::unique_ptr<blink::WebURLLoader> RendererBlinkPlatformImpl::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { ChildThreadImpl* child_thread = ChildThreadImpl::current(); if (!url_loader_factory_ && child_thread) { @@ -327,7 +328,7 @@ // There may be no child thread in RenderViewTests. These tests can still use // data URLs to bypass the ResourceDispatcher. return base::MakeUnique<WebURLLoaderImpl>( - child_thread ? child_thread->resource_dispatcher() : nullptr, + child_thread ? child_thread->resource_dispatcher() : nullptr, task_runner, url_loader_factory_.get()); }
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index cc4166c..3ea9374 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -16,6 +16,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "cc/blink/web_compositor_support_impl.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include "content/child/blink_platform_impl.h" #include "content/common/content_export.h" #include "content/common/possibly_associated_interface_ptr.h" @@ -23,7 +24,6 @@ #include "content/renderer/origin_trials/web_trial_token_validator_impl.h" #include "content/renderer/top_level_blame_context.h" #include "content/renderer/webpublicsuffixlist_impl.h" -#include "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBFactory.h" #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h" @@ -242,7 +242,9 @@ return web_database_observer_impl_.get(); } - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; void RequestPurgeMemory() override; @@ -292,7 +294,7 @@ scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_; scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<QuotaMessageFilter> quota_message_filter_; - ui::ChildSharedBitmapManager* shared_bitmap_manager_; + viz::ClientSharedBitmapManager* shared_bitmap_manager_; std::unique_ptr<WebDatabaseObserverImpl> web_database_observer_impl_;
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc index cf4ab1b..f41f8f1 100644 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc +++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -30,10 +30,13 @@ // static void EmbeddedWorkerInstanceClientImpl::Create( + base::TimeTicks blink_initialized_time, const service_manager::BindSourceInfo& source_info, mojom::EmbeddedWorkerInstanceClientRequest request) { // This won't be leaked because the lifetime will be managed internally. - new EmbeddedWorkerInstanceClientImpl(std::move(request)); + EmbeddedWorkerInstanceClientImpl* client = + new EmbeddedWorkerInstanceClientImpl(std::move(request)); + client->blink_initialized_time_ = blink_initialized_time; } void EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed() { @@ -53,12 +56,13 @@ TRACE_EVENT0("ServiceWorker", "EmbeddedWorkerInstanceClientImpl::StartWorker"); - wrapper_ = StartWorkerContext( - params, - base::MakeUnique<ServiceWorkerContextClient>( - params.embedded_worker_id, params.service_worker_version_id, - params.scope, params.script_url, std::move(dispatcher_request), - std::move(instance_host), std::move(temporal_self_))); + auto client = base::MakeUnique<ServiceWorkerContextClient>( + params.embedded_worker_id, params.service_worker_version_id, params.scope, + params.script_url, std::move(dispatcher_request), + std::move(instance_host), std::move(temporal_self_)); + client->set_blink_initialized_time(blink_initialized_time_); + client->set_start_worker_received_time(base::TimeTicks::Now()); + wrapper_ = StartWorkerContext(params, std::move(client)); } void EmbeddedWorkerInstanceClientImpl::StopWorker() {
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.h b/content/renderer/service_worker/embedded_worker_instance_client_impl.h index fbef235..2bef6ee8 100644 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.h +++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.h
@@ -33,7 +33,8 @@ class EmbeddedWorkerInstanceClientImpl : public mojom::EmbeddedWorkerInstanceClient { public: - static void Create(const service_manager::BindSourceInfo& source_info, + static void Create(base::TimeTicks blink_initialized_time, + const service_manager::BindSourceInfo& source_info, mojom::EmbeddedWorkerInstanceClientRequest request); ~EmbeddedWorkerInstanceClientImpl() override; @@ -94,6 +95,9 @@ // nullptr means the worker is not running. std::unique_ptr<WorkerWrapper> wrapper_; + // For UMA. + base::TimeTicks blink_initialized_time_; + DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceClientImpl); };
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 7332acf3..f9ea547 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -1239,7 +1239,11 @@ TRACE_EVENT_ASYNC_END0("ServiceWorker", "ServiceWorkerContextClient::StartingWorkerContext", this); - (*instance_host_)->OnStarted(); + mojom::EmbeddedWorkerStartTimingPtr timing = + mojom::EmbeddedWorkerStartTiming::New(); + timing->start_worker_received_time = start_worker_received_time_; + timing->blink_initialized_time = blink_initialized_time_; + (*instance_host_)->OnStarted(std::move(timing)); } void ServiceWorkerContextClient::SetRegistrationInServiceWorkerGlobalScope(
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 2d39dcba..b3af6f50 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -63,8 +63,10 @@ class EmbeddedWorkerInstanceClientImpl; class WebWorkerFetchContext; -// This class provides access to/from an ServiceWorker's WorkerGlobalScope. -// Unless otherwise noted, all methods are called on the worker thread. +// ServiceWorkerContextClient is a "client" of a service worker execution +// context. This class enables communication between the embedder and Blink's +// ServiceWorker's WorkerGlobalScope. Unless otherwise noted, all methods are +// called on the worker thread. class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient, public mojom::ServiceWorkerEventDispatcher { public: @@ -90,6 +92,15 @@ std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client); ~ServiceWorkerContextClient() override; + // Called on the main thread. + void set_blink_initialized_time(base::TimeTicks blink_initialized_time) { + blink_initialized_time_ = blink_initialized_time; + } + void set_start_worker_received_time( + base::TimeTicks start_worker_received_time) { + start_worker_received_time_ = start_worker_received_time; + } + void OnMessageReceived(int thread_id, int embedded_worker_id, const IPC::Message& message); @@ -367,6 +378,9 @@ // destructed on the worker thread in willDestroyWorkerContext. std::unique_ptr<WorkerContextData> context_; + base::TimeTicks blink_initialized_time_; + base::TimeTicks start_worker_received_time_; + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextClient); };
diff --git a/content/renderer/service_worker/service_worker_fetch_context_impl.cc b/content/renderer/service_worker/service_worker_fetch_context_impl.cc index 9be60e51..6fc427c8 100644 --- a/content/renderer/service_worker/service_worker_fetch_context_impl.cc +++ b/content/renderer/service_worker/service_worker_fetch_context_impl.cc
@@ -30,9 +30,11 @@ } std::unique_ptr<blink::WebURLLoader> -ServiceWorkerFetchContextImpl::CreateURLLoader() { - return base::MakeUnique<content::WebURLLoaderImpl>(resource_dispatcher_.get(), - url_loader_factory_.get()); +ServiceWorkerFetchContextImpl::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { + return base::MakeUnique<content::WebURLLoaderImpl>( + resource_dispatcher_.get(), task_runner, url_loader_factory_.get()); } void ServiceWorkerFetchContextImpl::WillSendRequest(
diff --git a/content/renderer/service_worker/service_worker_fetch_context_impl.h b/content/renderer/service_worker/service_worker_fetch_context_impl.h index 451d980..d15c1fe0 100644 --- a/content/renderer/service_worker/service_worker_fetch_context_impl.h +++ b/content/renderer/service_worker/service_worker_fetch_context_impl.h
@@ -26,7 +26,9 @@ // blink::WebWorkerFetchContext implementation: void InitializeOnWorkerThread(base::SingleThreadTaskRunner*) override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; void WillSendRequest(blink::WebURLRequest&) override; bool IsControlledByServiceWorker() const override; void SetDataSaverEnabled(bool enabled) override;
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.cc b/content/renderer/service_worker/worker_fetch_context_impl.cc index a98fd88c3..240c247 100644 --- a/content/renderer/service_worker/worker_fetch_context_impl.cc +++ b/content/renderer/service_worker/worker_fetch_context_impl.cc
@@ -39,9 +39,11 @@ service_worker_provider_id_); } -std::unique_ptr<blink::WebURLLoader> WorkerFetchContextImpl::CreateURLLoader() { - return base::MakeUnique<content::WebURLLoaderImpl>(resource_dispatcher_.get(), - url_loader_factory_.get()); +std::unique_ptr<blink::WebURLLoader> WorkerFetchContextImpl::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { + return base::MakeUnique<content::WebURLLoaderImpl>( + resource_dispatcher_.get(), task_runner, url_loader_factory_.get()); } void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.h b/content/renderer/service_worker/worker_fetch_context_impl.h index 217ad86..82ec3c73 100644 --- a/content/renderer/service_worker/worker_fetch_context_impl.h +++ b/content/renderer/service_worker/worker_fetch_context_impl.h
@@ -39,7 +39,9 @@ // blink::WebWorkerFetchContext implementation: void InitializeOnWorkerThread(base::SingleThreadTaskRunner*) override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; void WillSendRequest(blink::WebURLRequest&) override; bool IsControlledByServiceWorker() const override; void SetDataSaverEnabled(bool) override;
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index 2a0443ee..eceffc1d 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -15,10 +15,22 @@ ] } +generate_jni_registration("content_shell_jni_registration") { + testonly = true + target = ":content_shell_apk" + output = "$root_gen_dir/content/shell/android/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] +} + shared_library("libcontent_shell_content_view") { testonly = true deps = [ ":content_shell_jni_headers", + ":content_shell_jni_registration", "//build/config:exe_and_shlib_deps", "//components/crash/content/browser", "//content/shell:content_shell_lib", @@ -26,6 +38,17 @@ "//media", "//skia", ] + + # Explicit dependency required for JNI registration to be able to + # find the native side functions. + if (is_component_build) { + deps += [ + "//device/gamepad", + "//device/generic_sensor", + "//device/sensors", + "//media/midi", + ] + } sources = [ "shell_library_loader.cc", ] @@ -242,6 +265,7 @@ deps = [ ":linker_test_jni_headers", + ":linker_test_jni_registration", "//build/config:exe_and_shlib_deps", "//content/shell:content_shell_lib", @@ -250,6 +274,17 @@ "//skia", "//third_party/re2", ] + + # Explicit dependency required for JNI registration to be able to + # find the native side functions. + if (is_component_build) { + deps += [ + "//device/gamepad", + "//device/generic_sensor", + "//device/sensors", + "//media/midi", + ] + } } generate_jni("linker_test_jni_headers") { @@ -259,6 +294,18 @@ "linker_test_apk/src/org/chromium/chromium_linker_test_apk/LinkerTests.java", ] } + + generate_jni_registration("linker_test_jni_registration") { + testonly = true + target = ":chromium_linker_test_apk__apk" + output = + "$root_gen_dir/content/shell/android/linker_test_apk/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] + } } android_library("content_shell_browsertests_java") {
diff --git a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc index 19f9c47..310bb2a 100644 --- a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc +++ b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
@@ -9,6 +9,7 @@ #include "content/public/app/content_main.h" #include "content/public/browser/android/compositor.h" #include "content/shell/android/linker_test_apk/chromium_linker_test_linker_tests.h" +#include "content/shell/android/linker_test_apk/linker_test_jni_registration.h" #include "content/shell/android/shell_jni_registrar.h" #include "content/shell/app/shell_main_delegate.h" @@ -40,6 +41,11 @@ JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); + if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) { + return -1; + } + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) || !NativeInit()) { return -1;
diff --git a/content/shell/android/shell_library_loader.cc b/content/shell/android/shell_library_loader.cc index dc88bd67..8cd2e99 100644 --- a/content/shell/android/shell_library_loader.cc +++ b/content/shell/android/shell_library_loader.cc
@@ -8,6 +8,7 @@ #include "content/public/app/content_jni_onload.h" #include "content/public/app/content_main.h" #include "content/public/browser/android/compositor.h" +#include "content/shell/android/content_shell_jni_registration.h" #include "content/shell/android/shell_jni_registrar.h" #include "content/shell/app/shell_main_delegate.h" @@ -33,6 +34,12 @@ JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); + if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) { + return -1; + } + + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) || !NativeInit()) { return -1;
diff --git a/content/shell/renderer/layout_test/blink_test_helpers.cc b/content/shell/renderer/layout_test/blink_test_helpers.cc index 9a58bc248..c5d98a80 100644 --- a/content/shell/renderer/layout_test/blink_test_helpers.cc +++ b/content/shell/renderer/layout_test/blink_test_helpers.cc
@@ -98,7 +98,7 @@ #if defined(OS_ANDROID) prefs->text_autosizing_enabled = false; #endif - prefs->viewport_enabled = false; + prefs->viewport_enabled = command_line.HasSwitch(switches::kEnableViewport); prefs->default_minimum_page_scale_factor = 1.f; prefs->default_maximum_page_scale_factor = 4.f; }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 0a8482f..d1855cb 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1421,6 +1421,7 @@ "../common/service_worker/service_worker_utils_unittest.cc", "../common/throttling_url_loader_unittest.cc", "../common/webplugininfo_unittest.cc", + "../network/network_service_unittest.cc", "../network/url_loader_unittest.cc", "../public/test/referrer_unittest.cc", "../public/test/test_browser_thread_bundle_unittest.cc",
diff --git a/content/test/gpu/gpu_tests/depth_capture_expectations.py b/content/test/gpu/gpu_tests/depth_capture_expectations.py index 4f6f920..2c4d80f 100644 --- a/content/test/gpu/gpu_tests/depth_capture_expectations.py +++ b/content/test/gpu/gpu_tests/depth_capture_expectations.py
@@ -11,4 +11,9 @@ # Sample Usage: # self.Fail('DepthCapture_depthStreamToRGBAFloatTexture', # ['mac', 'amd', ('nvidia', 0x1234)], bug=123) - return + self.Flaky('DepthCapture_depthStreamToR32FloatTexture', + ['linux', 'nvidia'], bug=737410) + self.Flaky('DepthCapture_depthStreamToRGBAFloatTexture', + ['linux', 'nvidia'], bug=737410) + self.Flaky('DepthCapture_depthStreamToRGBAUint8Texture', + ['linux', 'nvidia'], bug=737410)
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc index c8e4a28..c3daaa47 100644 --- a/content/test/test_blink_web_unit_test_support.cc +++ b/content/test/test_blink_web_unit_test_support.cc
@@ -189,10 +189,13 @@ } std::unique_ptr<blink::WebURLLoader> -TestBlinkWebUnitTestSupport::CreateURLLoader() { +TestBlinkWebUnitTestSupport::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { // This loader should be used only for process-local resources such as // data URLs. - auto default_loader = base::MakeUnique<WebURLLoaderImpl>(nullptr, nullptr); + auto default_loader = + base::MakeUnique<WebURLLoaderImpl>(nullptr, task_runner, nullptr); return url_loader_factory_->CreateURLLoader(std::move(default_loader)); }
diff --git a/content/test/test_blink_web_unit_test_support.h b/content/test/test_blink_web_unit_test_support.h index 78b7d2c..7ebb831b 100644 --- a/content/test/test_blink_web_unit_test_support.h +++ b/content/test/test_blink_web_unit_test_support.h
@@ -41,7 +41,9 @@ blink::WebFileUtilities* GetFileUtilities() override; blink::WebIDBFactory* IdbFactory() override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) override; blink::WebString UserAgent() override; blink::WebString QueryLocalizedString( blink::WebLocalizedString::Name name) override;
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index 3fa54de..ac14a0b8 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc
@@ -8,6 +8,7 @@ #include "content/browser/browser_url_handler_impl.h" #include "content/browser/frame_host/cross_process_frame_connector.h" +#include "content/browser/frame_host/debug_urls.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/frame_host/navigator.h" @@ -294,7 +295,8 @@ if (!rfh) rfh = old_rfh; const bool browser_side_navigation = IsBrowserSideNavigationEnabled(); - CHECK(!browser_side_navigation || rfh->is_loading()); + CHECK(!browser_side_navigation || rfh->is_loading() || + IsRendererDebugURL(entry->GetURL())); CHECK(!browser_side_navigation || !rfh->frame_tree_node()->navigation_request());
diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn index 6299b59..54539e9 100644 --- a/crypto/BUILD.gn +++ b/crypto/BUILD.gn
@@ -16,8 +16,6 @@ "capi_util.cc", "capi_util.h", "crypto_export.h", - "cssm_init.cc", - "cssm_init.h", "ec_private_key.cc", "ec_private_key.h", "ec_signature_creator.cc", @@ -100,8 +98,6 @@ if (!is_mac) { sources -= [ - "cssm_init.cc", - "cssm_init.h", "mac_security_services_lock.cc", "mac_security_services_lock.h", ]
diff --git a/crypto/cssm_init.cc b/crypto/cssm_init.cc deleted file mode 100644 index e9bef7c..0000000 --- a/crypto/cssm_init.cc +++ /dev/null
@@ -1,212 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "crypto/cssm_init.h" - -#include <Security/SecBase.h> -#include <stdint.h> - -#include "base/logging.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/memory/singleton.h" -#include "base/strings/sys_string_conversions.h" - -// When writing crypto code for Mac OS X, you may find the following -// documentation useful: -// - Common Security: CDSA and CSSM, Version 2 (with corrigenda) -// http://www.opengroup.org/security/cdsa.htm -// - Apple Cryptographic Service Provider Functional Specification -// - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/ - -// CSSM functions are deprecated as of OSX 10.7, but have no replacement. -// https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -namespace { - -void* CSSMMalloc(CSSM_SIZE size, void* alloc_ref) { - return malloc(size); -} - -void CSSMFree(void* mem_ptr, void* alloc_ref) { - free(mem_ptr); -} - -void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) { - return realloc(ptr, size); -} - -void* CSSMCalloc(uint32_t num, CSSM_SIZE size, void* alloc_ref) { - return calloc(num, size); -} - -class CSSMInitSingleton { - public: - static CSSMInitSingleton* GetInstance() { - return base::Singleton<CSSMInitSingleton, base::LeakySingletonTraits< - CSSMInitSingleton>>::get(); - } - - CSSM_CSP_HANDLE csp_handle() const { return csp_handle_; } - CSSM_CL_HANDLE cl_handle() const { return cl_handle_; } - CSSM_TP_HANDLE tp_handle() const { return tp_handle_; } - - private: - CSSMInitSingleton() - : inited_(false), csp_loaded_(false), cl_loaded_(false), - tp_loaded_(false), csp_handle_(CSSM_INVALID_HANDLE), - cl_handle_(CSSM_INVALID_HANDLE), tp_handle_(CSSM_INVALID_HANDLE) { - static CSSM_VERSION version = {2, 0}; - // TODO(wtc): what should our caller GUID be? - static const CSSM_GUID test_guid = { - 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } - }; - CSSM_RETURN crtn; - CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE; - crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid, - CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL); - if (crtn) { - NOTREACHED(); - return; - } - inited_ = true; - - crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (crtn) { - NOTREACHED(); - return; - } - csp_loaded_ = true; - crtn = CSSM_ModuleLoad( - &gGuidAppleX509CL, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (crtn) { - NOTREACHED(); - return; - } - cl_loaded_ = true; - crtn = CSSM_ModuleLoad( - &gGuidAppleX509TP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (crtn) { - NOTREACHED(); - return; - } - tp_loaded_ = true; - - const CSSM_API_MEMORY_FUNCS cssmMemoryFunctions = { - CSSMMalloc, - CSSMFree, - CSSMRealloc, - CSSMCalloc, - NULL - }; - - crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &cssmMemoryFunctions, 0, - CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, - NULL, 0, NULL, &csp_handle_); - DCHECK_EQ(CSSM_OK, crtn); - crtn = CSSM_ModuleAttach(&gGuidAppleX509CL, &version, &cssmMemoryFunctions, - 0, CSSM_SERVICE_CL, 0, CSSM_KEY_HIERARCHY_NONE, - NULL, 0, NULL, &cl_handle_); - DCHECK_EQ(CSSM_OK, crtn); - crtn = CSSM_ModuleAttach(&gGuidAppleX509TP, &version, &cssmMemoryFunctions, - 0, CSSM_SERVICE_TP, 0, CSSM_KEY_HIERARCHY_NONE, - NULL, 0, NULL, &tp_handle_); - DCHECK_EQ(CSSM_OK, crtn); - } - - ~CSSMInitSingleton() { - CSSM_RETURN crtn; - if (csp_handle_) { - CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); - DCHECK_EQ(CSSM_OK, crtn); - } - if (cl_handle_) { - CSSM_RETURN crtn = CSSM_ModuleDetach(cl_handle_); - DCHECK_EQ(CSSM_OK, crtn); - } - if (tp_handle_) { - CSSM_RETURN crtn = CSSM_ModuleDetach(tp_handle_); - DCHECK_EQ(CSSM_OK, crtn); - } - if (csp_loaded_) { - crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); - DCHECK_EQ(CSSM_OK, crtn); - } - if (cl_loaded_) { - crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL); - DCHECK_EQ(CSSM_OK, crtn); - } - if (tp_loaded_) { - crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL); - DCHECK_EQ(CSSM_OK, crtn); - } - if (inited_) { - crtn = CSSM_Terminate(); - DCHECK_EQ(CSSM_OK, crtn); - } - } - - bool inited_; // True if CSSM_Init has been called successfully. - bool csp_loaded_; // True if gGuidAppleCSP has been loaded - bool cl_loaded_; // True if gGuidAppleX509CL has been loaded. - bool tp_loaded_; // True if gGuidAppleX509TP has been loaded. - CSSM_CSP_HANDLE csp_handle_; - CSSM_CL_HANDLE cl_handle_; - CSSM_TP_HANDLE tp_handle_; - - friend struct base::DefaultSingletonTraits<CSSMInitSingleton>; -}; - -} // namespace - -namespace crypto { - -void EnsureCSSMInit() { - CSSMInitSingleton::GetInstance(); -} - -CSSM_CSP_HANDLE GetSharedCSPHandle() { - return CSSMInitSingleton::GetInstance()->csp_handle(); -} - -CSSM_CL_HANDLE GetSharedCLHandle() { - return CSSMInitSingleton::GetInstance()->cl_handle(); -} - -CSSM_TP_HANDLE GetSharedTPHandle() { - return CSSMInitSingleton::GetInstance()->tp_handle(); -} - -void* CSSMMalloc(CSSM_SIZE size) { - return ::CSSMMalloc(size, NULL); -} - -void CSSMFree(void* ptr) { - ::CSSMFree(ptr, NULL); -} - -void LogCSSMError(const char* fn_name, CSSM_RETURN err) { - if (!err) - return; - base::ScopedCFTypeRef<CFStringRef> cfstr( - SecCopyErrorMessageString(err, NULL)); - LOG(ERROR) << fn_name << " returned " << err - << " (" << base::SysCFStringRefToUTF8(cfstr) << ")"; -} - -ScopedCSSMData::ScopedCSSMData() { - memset(&data_, 0, sizeof(data_)); -} - -ScopedCSSMData::~ScopedCSSMData() { - if (data_.Data) { - CSSMFree(data_.Data); - data_.Data = NULL; - } -} - -} // namespace crypto - -#pragma clang diagnostic pop // "-Wdeprecated-declarations"
diff --git a/crypto/cssm_init.h b/crypto/cssm_init.h deleted file mode 100644 index a4da34aa..0000000 --- a/crypto/cssm_init.h +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CRYPTO_CSSM_INIT_H_ -#define CRYPTO_CSSM_INIT_H_ - -#include <Security/cssm.h> - -#include "base/macros.h" -#include "crypto/crypto_export.h" - -namespace crypto { - -// CSSM functions are deprecated as of OSX 10.7, but have no replacement. -// https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -// Initialize CSSM if it isn't already initialized. This must be called before -// any other CSSM functions. This function is thread-safe, and CSSM will only -// ever be initialized once. CSSM will be properly shut down on program exit. -CRYPTO_EXPORT void EnsureCSSMInit(); - -// Returns the shared CSP handle used by CSSM functions. -CRYPTO_EXPORT CSSM_CSP_HANDLE GetSharedCSPHandle(); - -// Returns the shared CL handle used by CSSM functions. -CRYPTO_EXPORT CSSM_CL_HANDLE GetSharedCLHandle(); - -// Returns the shared TP handle used by CSSM functions. -CRYPTO_EXPORT CSSM_TP_HANDLE GetSharedTPHandle(); - -// Set of pointers to memory function wrappers that are required for CSSM -extern const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions; - -// Utility function to log an error message including the error name. -CRYPTO_EXPORT void LogCSSMError(const char *function_name, CSSM_RETURN err); - -// Utility functions to allocate and release CSSM memory. -void* CSSMMalloc(CSSM_SIZE size); -CRYPTO_EXPORT void CSSMFree(void* ptr); - -// Wrapper class for CSSM_DATA type. This should only be used when using the -// CL/TP/CSP handles from above, since that's the only time we're guaranteed (or -// supposed to be guaranteed) that our memory management functions will be used. -// Apple's Sec* APIs manage their own memory so it shouldn't be used for those. -// The constructor initializes data_ to zero and the destructor releases the -// data properly. -class ScopedCSSMData { - public: - ScopedCSSMData(); - ~ScopedCSSMData(); - operator CSSM_DATA*() { return &data_; } - CSSM_DATA* operator ->() { return &data_; } - - private: - CSSM_DATA data_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCSSMData); -}; - -#pragma clang diagnostic pop // "-Wdeprecated-declarations" - -} // namespace crypto - -#endif // CRYPTO_CSSM_INIT_H_
diff --git a/crypto/mac_security_services_lock.cc b/crypto/mac_security_services_lock.cc index 902a871..a9a70cdf 100644 --- a/crypto/mac_security_services_lock.cc +++ b/crypto/mac_security_services_lock.cc
@@ -10,8 +10,6 @@ namespace { -// This singleton pertains to Apple's wrappers over their own CSSM handles, -// as opposed to our own CSSM_CSP_HANDLE in cssm_init.cc. class SecurityServicesSingleton { public: static SecurityServicesSingleton* GetInstance() {
diff --git a/dbus/mock_object_proxy.h b/dbus/mock_object_proxy.h index 17d2a9f..6b0258b 100644 --- a/dbus/mock_object_proxy.h +++ b/dbus/mock_object_proxy.h
@@ -5,6 +5,7 @@ #ifndef DBUS_MOCK_OBJECT_PROXY_H_ #define DBUS_MOCK_OBJECT_PROXY_H_ +#include <memory> #include <string> #include "dbus/message.h" @@ -21,29 +22,13 @@ const std::string& service_name, const ObjectPath& object_path); - // GMock doesn't support the return type of std::unique_ptr<> because - // std::unique_ptr is uncopyable. This is a workaround which defines - // |MockCallMethodAndBlock| as a mock method and makes - // |CallMethodAndBlock| call the mocked method. Use |MockCallMethodAndBlock| - // for setting/testing expectations. - MOCK_METHOD3(MockCallMethodAndBlockWithErrorDetails, - Response*(MethodCall* method_call, - int timeout_ms, - ScopedDBusError* error)); - std::unique_ptr<Response> CallMethodAndBlockWithErrorDetails( - MethodCall* method_call, - int timeout_ms, - ScopedDBusError* error) override { - return std::unique_ptr<Response>( - MockCallMethodAndBlockWithErrorDetails(method_call, timeout_ms, error)); - } - MOCK_METHOD2(MockCallMethodAndBlock, Response*(MethodCall* method_call, - int timeout_ms)); - std::unique_ptr<Response> CallMethodAndBlock(MethodCall* method_call, - int timeout_ms) override { - return std::unique_ptr<Response>( - MockCallMethodAndBlock(method_call, timeout_ms)); - } + MOCK_METHOD3(CallMethodAndBlockWithErrorDetails, + std::unique_ptr<Response>(MethodCall* method_call, + int timeout_ms, + ScopedDBusError* error)); + MOCK_METHOD2(CallMethodAndBlock, + std::unique_ptr<Response>(MethodCall* method_call, + int timeout_ms)); MOCK_METHOD3(CallMethod, void(MethodCall* method_call, int timeout_ms, ResponseCallback callback));
diff --git a/dbus/mock_unittest.cc b/dbus/mock_unittest.cc index 15bdf27..7f3d759e 100644 --- a/dbus/mock_unittest.cc +++ b/dbus/mock_unittest.cc
@@ -45,10 +45,10 @@ // Set an expectation so mock_proxy's CallMethodAndBlock() will use // CreateMockProxyResponse() to return responses. - EXPECT_CALL(*mock_proxy_.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_proxy_.get(), CallMethodAndBlock(_, _)) .WillRepeatedly(Invoke(this, &MockTest::CreateMockProxyResponse)); EXPECT_CALL(*mock_proxy_.get(), - MockCallMethodAndBlockWithErrorDetails(_, _, _)) + CallMethodAndBlockWithErrorDetails(_, _, _)) .WillRepeatedly( Invoke(this, &MockTest::CreateMockProxyResponseWithErrorDetails)); @@ -91,8 +91,8 @@ private: // Returns a response for the given method call. Used to implement // CallMethodAndBlock() for |mock_proxy_|. - Response* CreateMockProxyResponse(MethodCall* method_call, - int timeout_ms) { + std::unique_ptr<Response> CreateMockProxyResponse(MethodCall* method_call, + int timeout_ms) { if (method_call->GetInterface() == "org.chromium.TestInterface" && method_call->GetMember() == "Echo") { MessageReader reader(method_call); @@ -101,18 +101,18 @@ std::unique_ptr<Response> response = Response::CreateEmpty(); MessageWriter writer(response.get()); writer.AppendString(text_message); - return response.release(); + return response; } } LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); - return NULL; + return nullptr; } - Response* CreateMockProxyResponseWithErrorDetails( + std::unique_ptr<Response> CreateMockProxyResponseWithErrorDetails( MethodCall* method_call, int timeout_ms, ScopedDBusError* error) { dbus_set_error(error->get(), DBUS_ERROR_NOT_SUPPORTED, "Not implemented"); - return NULL; + return nullptr; } // Creates a response and runs the given response callback in the @@ -121,19 +121,19 @@ MethodCall* method_call, int timeout_ms, ObjectProxy::ResponseCallback response_callback) { - Response* response = CreateMockProxyResponse(method_call, timeout_ms); + std::unique_ptr<Response> response = + CreateMockProxyResponse(method_call, timeout_ms); message_loop_.task_runner()->PostTask( FROM_HERE, base::Bind(&MockTest::RunResponseCallback, base::Unretained(this), - response_callback, response)); + response_callback, base::Passed(&response))); } // Runs the given response callback with the given response. void RunResponseCallback( ObjectProxy::ResponseCallback response_callback, - Response* response) { - response_callback.Run(response); - delete response; + std::unique_ptr<Response> response) { + response_callback.Run(response.get()); } };
diff --git a/device/base/synchronization/one_writer_seqlock_unittest.cc b/device/base/synchronization/one_writer_seqlock_unittest.cc index 57cfa0c4..28cd2b0 100644 --- a/device/base/synchronization/one_writer_seqlock_unittest.cc +++ b/device/base/synchronization/one_writer_seqlock_unittest.cc
@@ -68,7 +68,7 @@ TEST(OneWriterSeqLockTest, MAYBE_ManyThreads) { OneWriterSeqLock seqlock; TestData data = {0, 0, 0}; - base::AtomicRefCount ready = 0; + base::AtomicRefCount ready(0); ANNOTATE_BENIGN_RACE_SIZED(&data, sizeof(data), "Racey reads are discarded");
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h index 291adef..bdefc09b 100644 --- a/device/bluetooth/bluetooth_adapter.h +++ b/device/bluetooth/bluetooth_adapter.h
@@ -456,6 +456,12 @@ const base::TimeDelta& max, const base::Closure& callback, const AdvertisementErrorCallback& error_callback) = 0; + + // Resets advertising on this adapter. This will unregister all existing + // advertisements and will stop advertising them. + virtual void ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) = 0; #endif // Returns the local GATT services associated with this adapter with the
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc index 264cc4c..02c503a 100644 --- a/device/bluetooth/bluetooth_adapter_unittest.cc +++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -106,6 +106,9 @@ const base::TimeDelta& max, const base::Closure& callback, const AdvertisementErrorCallback& error_callback) override {} + void ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) override {} #endif BluetoothLocalGattService* GetGattService(
diff --git a/device/bluetooth/bluetooth_advertisement.h b/device/bluetooth/bluetooth_advertisement.h index 412baa72..70659f3 100644 --- a/device/bluetooth/bluetooth_advertisement.h +++ b/device/bluetooth/bluetooth_advertisement.h
@@ -40,6 +40,7 @@ #if defined(OS_CHROMEOS) || defined(OS_LINUX) ERROR_INVALID_ADVERTISEMENT_INTERVAL, // Advertisement interval specified // is out of valid range. + ERROR_RESET_ADVERTISING, // Error while resetting advertising. #endif INVALID_ADVERTISEMENT_ERROR_CODE };
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc index eb330ee6..552f4f03 100644 --- a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc +++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
@@ -150,6 +150,17 @@ error_callback.Run(code); } +void ResetAdvertisingErrorCallbackConnector( + const device::BluetoothAdapter::AdvertisementErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message) { + BLUETOOTH_LOG(ERROR) << "Error while resetting advertising. error_name = " + << error_name << ", error_message = " << error_message; + + error_callback.Run( + device::BluetoothAdvertisement::ErrorCode::ERROR_RESET_ADVERTISING); +} + } // namespace // static @@ -522,6 +533,17 @@ base::Bind(&SetIntervalErrorCallbackConnector, error_callback)); } +void BluetoothAdapterBlueZ::ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) { + DCHECK(bluez::BluezDBusManager::Get()); + bluez::BluezDBusManager::Get() + ->GetBluetoothLEAdvertisingManagerClient() + ->ResetAdvertising( + object_path_, callback, + base::Bind(&ResetAdvertisingErrorCallbackConnector, error_callback)); +} + device::BluetoothLocalGattService* BluetoothAdapterBlueZ::GetGattService( const std::string& identifier) const { const auto& service = owned_gatt_services_.find(dbus::ObjectPath(identifier));
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.h b/device/bluetooth/bluez/bluetooth_adapter_bluez.h index 04e8b2b..8e0c2ae 100644 --- a/device/bluetooth/bluez/bluetooth_adapter_bluez.h +++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.h
@@ -132,6 +132,10 @@ const base::Closure& callback, const AdvertisementErrorCallback& error_callback) override; + void ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) override; + device::BluetoothLocalGattService* GetGattService( const std::string& identifier) const override;
diff --git a/device/bluetooth/bluez/bluetooth_advertisement_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_advertisement_bluez_unittest.cc index 3c7addf..170c8063 100644 --- a/device/bluetooth/bluez/bluetooth_advertisement_bluez_unittest.cc +++ b/device/bluetooth/bluez/bluetooth_advertisement_bluez_unittest.cc
@@ -279,4 +279,31 @@ ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); } +TEST_F(BluetoothAdvertisementBlueZTest, ResetAdvertising) { + bluez::FakeBluetoothLEAdvertisingManagerClient* adv_client = + static_cast<bluez::FakeBluetoothLEAdvertisingManagerClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothLEAdvertisingManagerClient()); + + // Creates and registers multiple advertisements. + scoped_refptr<BluetoothAdvertisement> advertisement1 = CreateAdvertisement(); + ExpectSuccess(); + EXPECT_TRUE(advertisement1); + scoped_refptr<BluetoothAdvertisement> advertisement2 = CreateAdvertisement(); + ExpectSuccess(); + EXPECT_TRUE(advertisement2); + // There should be 2 currently registered advertisements. + EXPECT_EQ(2, adv_client->currently_registered()); + + adapter_->ResetAdvertising( + base::Bind(&BluetoothAdvertisementBlueZTest::Callback, + base::Unretained(this)), + base::Bind(&BluetoothAdvertisementBlueZTest::AdvertisementErrorCallback, + base::Unretained(this))); + ExpectSuccess(); + + // Checks that the advertisements have been cleared after ResetAdvertising. + EXPECT_EQ(0, adv_client->currently_registered()); +} + } // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc index 3488cc19..277f81c 100644 --- a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc +++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
@@ -133,6 +133,24 @@ weak_ptr_factory_.GetWeakPtr(), error_callback)); } + void ResetAdvertising(const dbus::ObjectPath& manager_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface, + bluetooth_advertising_manager::kResetAdvertising); + + DCHECK(object_manager_); + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(manager_object_path); + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdvertisementManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdvertisementManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + protected: void Init(dbus::Bus* bus) override { DCHECK(bus);
diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h index 4a338ad..7bd0956 100644 --- a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h +++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
@@ -76,6 +76,11 @@ const base::Closure& callback, const ErrorCallback& error_callback) = 0; + // Resets advertising. + virtual void ResetAdvertising(const dbus::ObjectPath& manager_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + // Creates the instance. static BluetoothLEAdvertisingManagerClient* Create();
diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc index 6236ca7..5586a6c 100644 --- a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc
@@ -108,6 +108,15 @@ callback.Run(); } +void FakeBluetoothLEAdvertisingManagerClient::ResetAdvertising( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + currently_registered_.clear(); + service_provider_map_.clear(); + callback.Run(); +} + void FakeBluetoothLEAdvertisingManagerClient:: RegisterAdvertisementServiceProvider( FakeBluetoothLEAdvertisementServiceProvider* service_provider) {
diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h index ee54311..eeb1f0f7 100644 --- a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h +++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
@@ -53,6 +53,10 @@ const base::Closure& callback, const ErrorCallback& error_callback) override; + void ResetAdvertising(const dbus::ObjectPath& manager_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + // Register, unregister and retrieve pointers to profile server providers. void RegisterAdvertisementServiceProvider( FakeBluetoothLEAdvertisementServiceProvider* service_provider);
diff --git a/device/bluetooth/test/fake_central.cc b/device/bluetooth/test/fake_central.cc index fa8b1242..a373a45 100644 --- a/device/bluetooth/test/fake_central.cc +++ b/device/bluetooth/test/fake_central.cc
@@ -304,6 +304,11 @@ const AdvertisementErrorCallback& error_callback) { NOTREACHED(); } +void FakeCentral::ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) { + NOTREACHED(); +} #endif device::BluetoothLocalGattService* FakeCentral::GetGattService(
diff --git a/device/bluetooth/test/fake_central.h b/device/bluetooth/test/fake_central.h index f1ecba5..f0364c7f 100644 --- a/device/bluetooth/test/fake_central.h +++ b/device/bluetooth/test/fake_central.h
@@ -118,6 +118,9 @@ const base::TimeDelta& max, const base::Closure& callback, const AdvertisementErrorCallback& error_callback) override; + void ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) override; #endif device::BluetoothLocalGattService* GetGattService( const std::string& identifier) const override;
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.cc b/device/bluetooth/test/mock_bluetooth_adapter.cc index d8eed43a..030c69d 100644 --- a/device/bluetooth/test/mock_bluetooth_adapter.cc +++ b/device/bluetooth/test/mock_bluetooth_adapter.cc
@@ -108,6 +108,9 @@ const base::TimeDelta& max, const base::Closure& callback, const AdvertisementErrorCallback& error_callback) {} +void MockBluetoothAdapter::ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) {} #endif } // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h index 6fa8644e..fe58faf 100644 --- a/device/bluetooth/test/mock_bluetooth_adapter.h +++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -141,6 +141,9 @@ const base::TimeDelta& max, const base::Closure& callback, const AdvertisementErrorCallback& error_callback) override; + void ResetAdvertising( + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) override; #endif virtual ~MockBluetoothAdapter();
diff --git a/device/gamepad/BUILD.gn b/device/gamepad/BUILD.gn index 2cbc2e5c..5bf30b3f 100644 --- a/device/gamepad/BUILD.gn +++ b/device/gamepad/BUILD.gn
@@ -72,10 +72,12 @@ cflags = [ "/wd4267" ] # conversion from 'size_t' (64 bit) to 'type'(32 bit). } - if (is_linux && use_udev) { - deps += [ "//device/udev_linux" ] - } else if (!is_win && !is_mac && !is_android) { - sources -= [ "gamepad_platform_data_fetcher_linux.cc" ] + if (is_linux) { + if (use_udev) { + deps += [ "//device/udev_linux" ] + } else { + sources -= [ "gamepad_platform_data_fetcher_linux.cc" ] + } } if (is_android) {
diff --git a/device/geolocation/wifi_data_provider_linux_unittest.cc b/device/geolocation/wifi_data_provider_linux_unittest.cc index 1153a396..004b38c 100644 --- a/device/geolocation/wifi_data_provider_linux_unittest.cc +++ b/device/geolocation/wifi_data_provider_linux_unittest.cc
@@ -42,7 +42,7 @@ // CallMethodAndBlock() will use CreateNetworkManagerProxyResponse() // to return responses. EXPECT_CALL(*mock_network_manager_proxy_.get(), - MockCallMethodAndBlock(_, _)) + CallMethodAndBlock(_, _)) .WillRepeatedly(Invoke(this, &GeolocationWifiDataProviderLinuxTest:: CreateNetworkManagerProxyResponse)); @@ -50,7 +50,7 @@ mock_device_proxy_ = new dbus::MockObjectProxy( mock_bus_.get(), "org.freedesktop.NetworkManager", dbus::ObjectPath("/org/freedesktop/NetworkManager/Devices/0")); - EXPECT_CALL(*mock_device_proxy_.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_device_proxy_.get(), CallMethodAndBlock(_, _)) .WillRepeatedly(Invoke( this, &GeolocationWifiDataProviderLinuxTest::CreateDeviceProxyResponse)); @@ -59,7 +59,7 @@ mock_access_point_proxy_ = new dbus::MockObjectProxy( mock_bus_.get(), "org.freedesktop.NetworkManager", dbus::ObjectPath("/org/freedesktop/NetworkManager/AccessPoint/0")); - EXPECT_CALL(*mock_access_point_proxy_.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_access_point_proxy_.get(), CallMethodAndBlock(_, _)) .WillRepeatedly(Invoke(this, &GeolocationWifiDataProviderLinuxTest:: CreateAccessPointProxyResponse)); @@ -113,7 +113,7 @@ private: // Creates a response for |mock_network_manager_proxy_|. - dbus::Response* CreateNetworkManagerProxyResponse( + std::unique_ptr<dbus::Response> CreateNetworkManagerProxyResponse( dbus::MethodCall* method_call, Unused) { if (method_call->GetInterface() == "org.freedesktop.NetworkManager" && @@ -126,16 +126,17 @@ std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); writer.AppendArrayOfObjectPaths(object_paths); - return response.release(); + return response; } LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); - return NULL; + return nullptr; } // Creates a response for |mock_device_proxy_|. - dbus::Response* CreateDeviceProxyResponse(dbus::MethodCall* method_call, - Unused) { + std::unique_ptr<dbus::Response> CreateDeviceProxyResponse( + dbus::MethodCall* method_call, + Unused) { if (method_call->GetInterface() == DBUS_INTERFACE_PROPERTIES && method_call->GetMember() == "Get") { dbus::MessageReader reader(method_call); @@ -150,7 +151,7 @@ // This matches NM_DEVICE_TYPE_WIFI in wifi_data_provider_linux.cc. const int kDeviceTypeWifi = 2; writer.AppendVariantOfUint32(kDeviceTypeWifi); - return response.release(); + return response; } } else if (method_call->GetInterface() == "org.freedesktop.NetworkManager.Device.Wireless" && @@ -162,16 +163,17 @@ object_paths.push_back( dbus::ObjectPath("/org/freedesktop/NetworkManager/AccessPoint/0")); writer.AppendArrayOfObjectPaths(object_paths); - return response.release(); + return response; } LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); - return NULL; + return nullptr; } // Creates a response for |mock_access_point_proxy_|. - dbus::Response* CreateAccessPointProxyResponse(dbus::MethodCall* method_call, - Unused) { + std::unique_ptr<dbus::Response> CreateAccessPointProxyResponse( + dbus::MethodCall* method_call, + Unused) { if (method_call->GetInterface() == DBUS_INTERFACE_PROPERTIES && method_call->GetMember() == "Get") { dbus::MessageReader reader(method_call); @@ -203,12 +205,12 @@ const uint32_t kFrequency = 2427; writer.AppendVariantOfUint32(kFrequency); } - return response.release(); + return response; } } LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); - return NULL; + return nullptr; } };
diff --git a/docs/mac_build_instructions.md b/docs/mac_build_instructions.md index 1a9824a6..c3a9234 100644 --- a/docs/mac_build_instructions.md +++ b/docs/mac_build_instructions.md
@@ -152,7 +152,7 @@ Once it is built, you can simply run the browser: ```shell -$ out/Default/chrome +$ out/Default/Chromium.app/Contents/MacOS/Chromium ``` ## Running test targets
diff --git a/docs/updating_clang.md b/docs/updating_clang.md index d337089..a08566dd 100644 --- a/docs/updating_clang.md +++ b/docs/updating_clang.md
@@ -19,8 +19,6 @@ gsutil cp -n -a public-read gs://chromium-browser-clang-staging/$x/translation_unit-$rev.tgz \ gs://chromium-browser-clang/$x/translation_unit-$rev.tgz ; \ done -$ gsutil cp -n -a public-read gs://chromium-browser-clang-staging/Linux_x64/llvmgold-$rev.tgz \ - gs://chromium-browser-clang/Linux_x64/llvmgold-$rev.tgz ``` 1. Run the goma package update script to push these packages to goma. If you do
diff --git a/extensions/browser/api/api_resource_manager.h b/extensions/browser/api/api_resource_manager.h index 8626e21..d8ca7c33 100644 --- a/extensions/browser/api/api_resource_manager.h +++ b/extensions/browser/api/api_resource_manager.h
@@ -36,7 +36,7 @@ class TCPServerSocketEventDispatcher; class TCPSocketEventDispatcher; class UDPSocketEventDispatcher; -} +} // namespace api template <typename T> struct NamedThreadTraits { @@ -126,12 +126,12 @@ } // BrowserContextKeyedAPI implementation. - static BrowserContextKeyedAPIFactory<ApiResourceManager<T> >* - GetFactoryInstance(); + static BrowserContextKeyedAPIFactory<ApiResourceManager<T>>* + GetFactoryInstance(); // Convenience method to get the ApiResourceManager for a profile. static ApiResourceManager<T>* Get(content::BrowserContext* context) { - return BrowserContextKeyedAPIFactory<ApiResourceManager<T> >::Get(context); + return BrowserContextKeyedAPIFactory<ApiResourceManager<T>>::Get(context); } // BrowserContextKeyedAPI implementation. @@ -171,7 +171,7 @@ friend class api::TCPServerSocketEventDispatcher; friend class api::TCPSocketEventDispatcher; friend class api::UDPSocketEventDispatcher; - friend class BrowserContextKeyedAPIFactory<ApiResourceManager<T> >; + friend class BrowserContextKeyedAPIFactory<ApiResourceManager<T>>; static const bool kServiceHasOwnInstanceInIncognito = true; static const bool kServiceIsNULLWhileTesting = true; @@ -182,7 +182,7 @@ public: typedef std::map<int, std::unique_ptr<T>> ApiResourceMap; // Lookup map from extension id's to allocated resource id's. - typedef std::map<std::string, base::hash_set<int> > ExtensionToResourceMap; + typedef std::map<std::string, base::hash_set<int>> ExtensionToResourceMap; ApiResourceData() : next_id_(1) { sequence_checker_.DetachFromSequence(); } @@ -197,8 +197,9 @@ ExtensionToResourceMap::iterator it = extension_resource_map_.find(extension_id); if (it == extension_resource_map_.end()) { - it = extension_resource_map_.insert( - std::make_pair(extension_id, base::hash_set<int>())).first; + it = extension_resource_map_ + .insert(std::make_pair(extension_id, base::hash_set<int>())) + .first; } it->second.insert(id); return id; @@ -243,24 +244,22 @@ } void InitiateExtensionUnloadedCleanup(const std::string& extension_id) { - ThreadingTraits::GetSequencedTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension, - this, - extension_id)); + ThreadingTraits::GetSequencedTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension, + this, extension_id)); } void InitiateExtensionSuspendedCleanup(const std::string& extension_id) { - ThreadingTraits::GetSequencedTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension, - this, - extension_id)); + ThreadingTraits::GetSequencedTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension, + this, extension_id)); } void InititateCleanup() { - ThreadingTraits::GetSequencedTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ApiResourceData::Cleanup, this)); + ThreadingTraits::GetSequencedTaskRunner()->PostTask( + FROM_HERE, base::Bind(&ApiResourceData::Cleanup, this)); } private: @@ -378,65 +377,6 @@ } }; -// With WorkerPoolThreadTraits, ApiResourceManager can be used to manage the -// lifetime of a set of resources that live on sequenced task runner threads -// which ApiFunctions use. Examples of such resources are temporary file -// resources produced by certain API calls. -// -// Instead of kThreadId. classes used for tracking such resources should define -// kSequenceToken and kShutdownBehavior to identify sequence task runner for -// ApiResourceManager to work on and how pending tasks should behave on -// shutdown. -// The user must also define a static const char* service_name() that returns -// the name of the service, and in order for ApiWorkerPoolResourceManager to use -// service_name() friend this class. -// -// In the cc file the user must define a GetFactoryInstance() and manage their -// own instances (typically using LazyInstance or Singleton). -// -// E.g.: -// -// class PoolResource { -// public: -// static const char kSequenceToken[] = "temp_files"; -// static const base::SequencedWorkerPool::WorkerShutdown kShutdownBehavior = -// base::SequencedWorkerPool::BLOCK_SHUTDOWN; -// private: -// friend class ApiResourceManager<WorkerPoolResource, -// WorkerPoolThreadTraits>; -// static const char* service_name() { -// return "TempFilesResourceManager"; -// } -// }; -// -// In the cc file: -// -// static base::LazyInstance<BrowserContextKeyedAPIFactory< -// ApiResourceManager<Resource, WorkerPoolThreadTraits> > > -// g_factory = LAZY_INSTANCE_INITIALIZER; -// -// -// template <> -// BrowserContextKeyedAPIFactory<ApiResourceManager<WorkerPoolResource> >* -// ApiResourceManager<WorkerPoolPoolResource, -// WorkerPoolThreadTraits>::GetFactoryInstance() { -// return g_factory.Pointer(); -// } -template <typename T> -struct WorkerPoolThreadTraits { - static bool IsMessageLoopValid() { - return content::BrowserThread::GetBlockingPool() != NULL; - } - - static scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() { - return content::BrowserThread::GetBlockingPool() - ->GetSequencedTaskRunnerWithShutdownBehavior( - content::BrowserThread::GetBlockingPool()->GetNamedSequenceToken( - T::kSequenceToken), - T::kShutdownBehavior); - } -}; - } // namespace extensions #endif // EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_
diff --git a/extensions/browser/api/async_api_function.cc b/extensions/browser/api/async_api_function.cc index a4e40f6f..b17063f 100644 --- a/extensions/browser/api/async_api_function.cc +++ b/extensions/browser/api/async_api_function.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/async_api_function.h" #include "base/bind.h" +#include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" using content::BrowserThread; @@ -12,7 +13,9 @@ namespace extensions { // AsyncApiFunction -AsyncApiFunction::AsyncApiFunction() : work_thread_id_(BrowserThread::IO) {} +AsyncApiFunction::AsyncApiFunction() + : work_task_runner_( + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) {} AsyncApiFunction::~AsyncApiFunction() {} @@ -22,15 +25,15 @@ if (!PrePrepare() || !Prepare()) { return false; } - bool rv = BrowserThread::PostTask( - work_thread_id_, - FROM_HERE, - base::Bind(&AsyncApiFunction::WorkOnWorkThread, this)); + bool rv = work_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&AsyncApiFunction::WorkOnWorkThread, this)); DCHECK(rv); return true; } -bool AsyncApiFunction::PrePrepare() { return true; } +bool AsyncApiFunction::PrePrepare() { + return true; +} void AsyncApiFunction::Work() {} @@ -42,8 +45,7 @@ void AsyncApiFunction::AsyncWorkCompleted() { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { bool rv = BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, + BrowserThread::UI, FROM_HERE, base::Bind(&AsyncApiFunction::RespondOnUIThread, this)); DCHECK(rv); } else { @@ -52,11 +54,7 @@ } void AsyncApiFunction::WorkOnWorkThread() { - DCHECK_CURRENTLY_ON(work_thread_id_); - DLOG_IF(ERROR, (work_thread_id_ == BrowserThread::UI)) - << "You have specified that AsyncApiFunction::Work() should happen on " - "the UI thread. This nullifies the point of this class. Either " - "specify a different thread or derive from a different class."; + DCHECK(work_task_runner_->RunsTasksInCurrentSequence()); AsyncWorkStart(); }
diff --git a/extensions/browser/api/async_api_function.h b/extensions/browser/api/async_api_function.h index e260806..ab47953 100644 --- a/extensions/browser/api/async_api_function.h +++ b/extensions/browser/api/async_api_function.h
@@ -5,7 +5,8 @@ #ifndef EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_ #define EXTENSIONS_BROWSER_API_ASYNC_API_FUNCTION_H_ -#include "content/public/browser/browser_thread.h" +#include "base/memory/ref_counted.h" +#include "base/sequenced_task_runner.h" #include "extensions/browser/extension_function.h" namespace extensions { @@ -25,11 +26,11 @@ // thread. virtual bool Prepare() = 0; - // Do actual work. Guaranteed to happen on the thread specified in - // work_thread_id_. + // Do actual work. Guaranteed to happen on the task runner specified in + // |work_task_runner_| if non-null; or on the IO thread otherwise. virtual void Work(); - // Start the asynchronous work. Guraranteed to happen on requested thread. + // Start the asynchronous work. Guraranteed to happen on work thread. virtual void AsyncWorkStart(); // Notify AsyncIOApiFunction that the work is completed @@ -42,9 +43,12 @@ bool RunAsync() override; protected: - content::BrowserThread::ID work_thread_id() const { return work_thread_id_; } - void set_work_thread_id(content::BrowserThread::ID work_thread_id) { - work_thread_id_ = work_thread_id; + scoped_refptr<base::SequencedTaskRunner> work_task_runner() const { + return work_task_runner_; + } + void set_work_task_runner( + scoped_refptr<base::SequencedTaskRunner> work_task_runner) { + work_task_runner_ = work_task_runner; } private: @@ -52,8 +56,8 @@ void RespondOnUIThread(); // If you don't want your Work() method to happen on the IO thread, then set - // this to the thread that you do want, preferably in Prepare(). - content::BrowserThread::ID work_thread_id_; + // this to the SequenceTaskRunner you do want to use, preferably in Prepare(). + scoped_refptr<base::SequencedTaskRunner> work_task_runner_; }; } // namespace extensions
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc index 515838f..45933bc4 100644 --- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc +++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
@@ -1089,8 +1089,29 @@ advertisements_manager_->Remove(extension_id(), advertisement_id); } +const base::hash_set<int>* +BluetoothLowEnergyAdvertisementFunction::GetAdvertisementIds() { + return advertisements_manager_->GetResourceIds(extension_id()); +} + bool BluetoothLowEnergyAdvertisementFunction::RunAsync() { Initialize(); + + // Check permission in the manifest. + if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { + SetError(kErrorPermissionDenied); + return false; + } + + // For advertisement API to be available the app has to be either auto + // launched in Kiosk Mode or the enable-ble-advertisement-in-apps + // should be set. + if (!(IsAutoLaunchedKioskApp(extension()->id()) || + IsPeripheralFlagEnabled())) { + SetError(kErrorPermissionDenied); + return false; + } + return BluetoothLowEnergyExtensionFunctionDeprecated::RunAsync(); } @@ -1104,23 +1125,6 @@ bool BluetoothLowEnergyRegisterAdvertisementFunction::DoWork() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Check permissions in manifest. - if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { - error_ = kErrorPermissionDenied; - SendResponse(false); - return false; - } - - // For this API to be available the app has to be either auto - // launched in Kiosk Mode or the enable-ble-advertisement-in-apps - // should be set. - if (!(IsAutoLaunchedKioskApp(extension()->id()) || - IsPeripheralFlagEnabled())) { - error_ = kErrorPermissionDenied; - SendResponse(false); - return false; - } - BluetoothLowEnergyEventRouter* event_router = GetEventRouter(browser_context()); @@ -1199,23 +1203,6 @@ bool BluetoothLowEnergyUnregisterAdvertisementFunction::DoWork() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Check permission in the manifest. - if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { - error_ = kErrorPermissionDenied; - SendResponse(false); - return false; - } - - // For this API to be available the app has to be either auto - // launched in Kiosk Mode or the enable-ble-advertisement-in-apps - // should be set. - if (!(IsAutoLaunchedKioskApp(extension()->id()) || - IsPeripheralFlagEnabled())) { - error_ = kErrorPermissionDenied; - SendResponse(false); - return false; - } - BluetoothLowEnergyEventRouter* event_router = GetEventRouter(browser_context()); @@ -1267,6 +1254,54 @@ SendResponse(false); } +// ResetAdvertising: + +bool BluetoothLowEnergyResetAdvertisingFunction::DoWork() { +#if defined(OS_CHROMEOS) || defined(OS_LINUX) + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + BluetoothLowEnergyEventRouter* event_router = + GetEventRouter(browser_context()); + + // If the adapter is not initialized, there is nothing to reset. + if (!event_router->HasAdapter()) { + SendResponse(true); + return true; + } + + const base::hash_set<int>* advertisement_ids = GetAdvertisementIds(); + if (!advertisement_ids || advertisement_ids->empty()) { + SendResponse(true); + return true; + } + + // Copy the hash set, as RemoveAdvertisement can change advertisement_ids + // while we are iterating over it. + base::hash_set<int> advertisement_ids_tmp = *advertisement_ids; + for (int advertisement_id : advertisement_ids_tmp) { + RemoveAdvertisement(advertisement_id); + } + + event_router->adapter()->ResetAdvertising( + base::Bind(&BluetoothLowEnergyResetAdvertisingFunction::SuccessCallback, + this), + base::Bind(&BluetoothLowEnergyResetAdvertisingFunction::ErrorCallback, + this)); +#endif + + return true; +} + +void BluetoothLowEnergyResetAdvertisingFunction::SuccessCallback() { + SendResponse(true); +} + +void BluetoothLowEnergyResetAdvertisingFunction::ErrorCallback( + device::BluetoothAdvertisement::ErrorCode status) { + error_ = kErrorOperationFailed; + SendResponse(false); +} + // SetAdvertisingInterval: template class BLEPeripheralExtensionFunction<
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h index b56d3bfd..26c3303d 100644 --- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h +++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h
@@ -438,6 +438,7 @@ int AddAdvertisement(BluetoothApiAdvertisement* advertisement); BluetoothApiAdvertisement* GetAdvertisement(int advertisement_id); void RemoveAdvertisement(int advertisement_id); + const base::hash_set<int>* GetAdvertisementIds(); // ExtensionFunction override. bool RunAsync() override; @@ -485,6 +486,23 @@ device::BluetoothAdvertisement::ErrorCode status); }; +class BluetoothLowEnergyResetAdvertisingFunction + : public BluetoothLowEnergyAdvertisementFunction { + public: + DECLARE_EXTENSION_FUNCTION("bluetoothLowEnergy.resetAdvertising", + BLUETOOTHLOWENERGY_RESETADVERTISING); + + protected: + ~BluetoothLowEnergyResetAdvertisingFunction() override {} + + // BluetoothLowEnergyExtensionFunctionDeprecated override. + bool DoWork() override; + + private: + void SuccessCallback(); + void ErrorCallback(device::BluetoothAdvertisement::ErrorCode status); +}; + class BluetoothLowEnergySetAdvertisingIntervalFunction : public BLEPeripheralExtensionFunction< extensions::api::bluetooth_low_energy::SetAdvertisingInterval::
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc index 44844998..811b681d 100644 --- a/extensions/browser/api/cast_channel/cast_channel_api.cc +++ b/extensions/browser/api/cast_channel/cast_channel_api.cc
@@ -119,7 +119,7 @@ } // namespace CastChannelAPI::CastChannelAPI(content::BrowserContext* context) - : browser_context_(context), logger_(new Logger()) { + : browser_context_(context) { DCHECK(browser_context_); } @@ -128,10 +128,6 @@ return BrowserContextKeyedAPIFactory<CastChannelAPI>::Get(context); } -scoped_refptr<Logger> CastChannelAPI::GetLogger() { - return logger_; -} - void CastChannelAPI::SendEvent(const std::string& extension_id, std::unique_ptr<Event> event) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -216,9 +212,7 @@ SetResult(channel_info.ToValue()); } -CastChannelOpenFunction::CastChannelOpenFunction() - : new_channel_id_(0) { -} +CastChannelOpenFunction::CastChannelOpenFunction() {} CastChannelOpenFunction::~CastChannelOpenFunction() { } @@ -278,21 +272,10 @@ DCHECK(api_); DCHECK(ip_endpoint_.get()); const ConnectInfo& connect_info = params_->connect_info; - CastSocket* socket; + std::unique_ptr<CastSocket> test_socket = api_->GetSocketForTest(); - if (test_socket.get()) { - socket = test_socket.release(); - } else { - socket = new CastSocketImpl( - *ip_endpoint_, ExtensionsBrowserClient::Get()->GetNetLog(), - base::TimeDelta::FromMilliseconds(connect_info.timeout.get() - ? *connect_info.timeout - : kDefaultConnectTimeoutMillis), - liveness_timeout_, ping_interval_, api_->GetLogger(), - connect_info.capabilities.get() ? *connect_info.capabilities - : CastDeviceCapability::NONE); - } - new_channel_id_ = cast_socket_service_->AddSocket(base::WrapUnique(socket)); + if (test_socket.get()) + cast_socket_service_->SetSocketForTest(std::move(test_socket)); auto* observer = cast_socket_service_->GetObserver(extension_->id()); if (!observer) { @@ -300,28 +283,33 @@ extension_->id(), base::MakeUnique<CastMessageHandler>( base::Bind(&CastChannelAPI::SendEvent, api_->AsWeakPtr(), extension_->id()), - api_->GetLogger())); + cast_socket_service_->GetLogger())); } - socket->AddObserver(observer); - // Construct read delegates. - socket->Connect(base::Bind(&CastChannelOpenFunction::OnOpen, this)); + cast_socket_service_->OpenSocket( + *ip_endpoint_, ExtensionsBrowserClient::Get()->GetNetLog(), + base::TimeDelta::FromMilliseconds(connect_info.timeout.get() + ? *connect_info.timeout + : kDefaultConnectTimeoutMillis), + liveness_timeout_, ping_interval_, + connect_info.capabilities.get() ? *connect_info.capabilities + : CastDeviceCapability::NONE, + base::Bind(&CastChannelOpenFunction::OnOpen, this), observer); } -void CastChannelOpenFunction::OnOpen(ChannelError result) { +void CastChannelOpenFunction::OnOpen(int channel_id, ChannelError result) { DCHECK_CURRENTLY_ON(BrowserThread::IO); VLOG(1) << "Connect finished, OnOpen invoked."; // TODO: If we failed to open the CastSocket, we may want to clean up here, // rather than relying on the extension to call close(). This can be done by // calling RemoveSocket() and api_->GetLogger()->ClearLastError(channel_id). if (result != ChannelError::UNKNOWN) { - CastSocket* socket = cast_socket_service_->GetSocket(new_channel_id_); + CastSocket* socket = cast_socket_service_->GetSocket(channel_id); CHECK(socket); SetResultFromSocket(*socket); } else { // The socket is being destroyed. - SetResultFromError(new_channel_id_, - api::cast_channel::CHANNEL_ERROR_UNKNOWN); + SetResultFromError(channel_id, api::cast_channel::CHANNEL_ERROR_UNKNOWN); } AsyncWorkCompleted(); @@ -429,7 +417,7 @@ SetResultFromSocket(*socket); // This will delete |socket|. cast_socket_service_->RemoveSocket(channel_id); - api_->GetLogger()->ClearLastError(channel_id); + cast_socket_service_->GetLogger()->ClearLastError(channel_id); } AsyncWorkCompleted(); }
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.h b/extensions/browser/api/cast_channel/cast_channel_api.h index 4453a79..c65af793 100644 --- a/extensions/browser/api/cast_channel/cast_channel_api.h +++ b/extensions/browser/api/cast_channel/cast_channel_api.h
@@ -46,14 +46,6 @@ // BrowserContextKeyedAPI implementation. static BrowserContextKeyedAPIFactory<CastChannelAPI>* GetFactoryInstance(); - // Returns a pointer to the Logger member variable. - // TODO(imcheng): Consider whether it is possible for this class to own the - // CastSockets and make this class the sole owner of Logger. - // Alternatively, - // consider making Logger not ref-counted by passing a weak - // reference of Logger to the CastSockets instead. - scoped_refptr<cast_channel::Logger> GetLogger(); - // Sets the CastSocket instance to be used for testing. void SetSocketForTest( std::unique_ptr<cast_channel::CastSocket> socket_for_test); @@ -79,7 +71,6 @@ static const char* service_name() { return "CastChannelAPI"; } content::BrowserContext* const browser_context_; - scoped_refptr<cast_channel::Logger> logger_; std::unique_ptr<cast_channel::CastSocket> socket_for_test_; DISALLOW_COPY_AND_ASSIGN(CastChannelAPI); @@ -163,11 +154,9 @@ static net::IPEndPoint* ParseConnectInfo( const api::cast_channel::ConnectInfo& connect_info); - void OnOpen(cast_channel::ChannelError result); + void OnOpen(int channel_id, cast_channel::ChannelError result); std::unique_ptr<api::cast_channel::Open::Params> params_; - // The id of the newly opened socket. - int new_channel_id_; CastChannelAPI* api_; std::unique_ptr<net::IPEndPoint> ip_endpoint_; base::TimeDelta liveness_timeout_;
diff --git a/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/extensions/browser/api/cast_channel/cast_channel_apitest.cc index 13293a28..1639bf6 100644 --- a/extensions/browser/api/cast_channel/cast_channel_apitest.cc +++ b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
@@ -13,6 +13,8 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/ui/browser.h" #include "components/cast_channel/cast_socket.h" +#include "components/cast_channel/cast_socket_service.h" +#include "components/cast_channel/cast_socket_service_factory.h" #include "components/cast_channel/cast_test_util.h" #include "components/cast_channel/logger.h" #include "components/cast_channel/proto/cast_channel.pb.h" @@ -56,6 +58,7 @@ using ::testing::ReturnRef; using ::testing::ReturnPointee; using ::testing::SaveArg; +using ::testing::WithArgs; namespace { @@ -92,27 +95,25 @@ extensions::CastChannelAPI* api = GetApi(); net::IPEndPoint ip_endpoint(net::IPAddress(192, 168, 1, 1), 8009); - mock_cast_socket_ = new MockCastSocket; + mock_cast_socket_ = new MockCastSocket(); + mock_cast_socket_->SetIPEndpoint(ip_endpoint_); + mock_cast_socket_->SetKeepAlive(false); // Transfers ownership of the socket. api->SetSocketForTest(base::WrapUnique<CastSocket>(mock_cast_socket_)); - ON_CALL(*mock_cast_socket_, set_id(_)) - .WillByDefault(SaveArg<0>(&channel_id_)); - ON_CALL(*mock_cast_socket_, id()) - .WillByDefault(ReturnPointee(&channel_id_)); - ON_CALL(*mock_cast_socket_, ip_endpoint()) - .WillByDefault(ReturnRef(ip_endpoint_)); - ON_CALL(*mock_cast_socket_, keep_alive()).WillByDefault(Return(false)); } void SetUpOpenSendClose() { SetUpMockCastSocket(); - EXPECT_CALL(*mock_cast_socket_, error_state()) - .WillRepeatedly(Return(ChannelError::NONE)); + mock_cast_socket_->SetErrorState(ChannelError::NONE); { InSequence sequence; + EXPECT_CALL(*mock_cast_socket_, AddObserver(_)); EXPECT_CALL(*mock_cast_socket_, Connect(_)) - .WillOnce(InvokeCompletionCallback<0>(ChannelError::NONE)); + .WillOnce(WithArgs<0>( + Invoke([&](const CastSocket::OnOpenCallback& callback) { + callback.Run(mock_cast_socket_->id(), ChannelError::NONE); + }))); EXPECT_CALL(*mock_cast_socket_, ready_state()) .WillOnce(Return(ReadyState::OPEN)); EXPECT_CALL(*mock_cast_socket_->mock_transport(), @@ -129,15 +130,17 @@ void SetUpOpenPingTimeout() { SetUpMockCastSocket(); - EXPECT_CALL(*mock_cast_socket_, error_state()) - .WillRepeatedly(Return(ChannelError::NONE)); - EXPECT_CALL(*mock_cast_socket_, keep_alive()).WillRepeatedly(Return(true)); + mock_cast_socket_->SetErrorState(ChannelError::NONE); + mock_cast_socket_->SetKeepAlive(true); { InSequence sequence; EXPECT_CALL(*mock_cast_socket_, AddObserver(_)) .WillOnce(SaveArg<0>(&message_observer_)); EXPECT_CALL(*mock_cast_socket_, Connect(_)) - .WillOnce(InvokeCompletionCallback<0>(ChannelError::NONE)); + .WillOnce(WithArgs<0>( + Invoke([&](const CastSocket::OnOpenCallback& callback) { + callback.Run(mock_cast_socket_->id(), ChannelError::NONE); + }))); EXPECT_CALL(*mock_cast_socket_, ready_state()) .WillOnce(Return(ReadyState::OPEN)) .RetiresOnSaturation(); @@ -150,10 +153,16 @@ return extensions::CastChannelAPI::Get(profile()); } + cast_channel::CastSocketService* GetCastSocketService() { + return cast_channel::CastSocketServiceFactory::GetForBrowserContext( + profile()) + .get(); + } + // Logs some bogus error details and calls the OnError handler. - void DoCallOnError(extensions::CastChannelAPI* api) { - api->GetLogger()->LogSocketEventWithRv( - mock_cast_socket_->id(), ::cast_channel::ChannelEvent::SOCKET_WRITE, + void DoCallOnError(cast_channel::CastSocketService* cast_socket_service) { + cast_socket_service->GetLogger()->LogSocketEventWithRv( + mock_cast_socket_->id(), cast_channel::ChannelEvent::SOCKET_WRITE, net::ERR_FAILED); message_observer_->OnError(*mock_cast_socket_, ChannelError::CONNECT_ERROR); } @@ -211,11 +220,11 @@ int channel_id_; }; -ACTION_P2(InvokeObserverOnError, api_test, api) { +ACTION_P2(InvokeObserverOnError, api_test, cast_socket_service) { content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::Bind(&CastChannelAPITest::DoCallOnError, base::Unretained(api_test), - base::Unretained(api))); + cast_socket_service)); } // TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionSubtest @@ -288,15 +297,17 @@ // writing, reading, and closing. IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenReceiveClose) { SetUpMockCastSocket(); - EXPECT_CALL(*mock_cast_socket_, error_state()) - .WillRepeatedly(Return(ChannelError::NONE)); + mock_cast_socket_->SetErrorState(ChannelError::NONE); { InSequence sequence; EXPECT_CALL(*mock_cast_socket_, AddObserver(_)) .WillOnce(SaveArg<0>(&message_observer_)); EXPECT_CALL(*mock_cast_socket_, Connect(_)) - .WillOnce(InvokeCompletionCallback<0>(ChannelError::NONE)); + .WillOnce( + WithArgs<0>(Invoke([&](const CastSocket::OnOpenCallback& callback) { + callback.Run(mock_cast_socket_->id(), ChannelError::NONE); + }))); EXPECT_CALL(*mock_cast_socket_, ready_state()) .Times(3) .WillRepeatedly(Return(ReadyState::OPEN)); @@ -328,11 +339,13 @@ EXPECT_CALL(*mock_cast_socket_, AddObserver(_)) .WillOnce(DoAll(SaveArg<0>(&message_observer_), - InvokeObserverOnError(this, GetApi()))); + InvokeObserverOnError(this, GetCastSocketService()))); EXPECT_CALL(*mock_cast_socket_, Connect(_)) - .WillOnce(InvokeCompletionCallback<0>(ChannelError::CONNECT_ERROR)); - EXPECT_CALL(*mock_cast_socket_, error_state()) - .WillRepeatedly(Return(ChannelError::CONNECT_ERROR)); + .WillOnce( + WithArgs<0>(Invoke([&](const CastSocket::OnOpenCallback& callback) { + callback.Run(mock_cast_socket_->id(), ChannelError::CONNECT_ERROR); + }))); + mock_cast_socket_->SetErrorState(ChannelError::CONNECT_ERROR); EXPECT_CALL(*mock_cast_socket_, ready_state()) .WillRepeatedly(Return(ReadyState::CLOSED)); EXPECT_CALL(*mock_cast_socket_, Close(_))
diff --git a/extensions/browser/api/document_scan/document_scan_api.cc b/extensions/browser/api/document_scan/document_scan_api.cc index 317199f..54e9b95f 100644 --- a/extensions/browser/api/document_scan/document_scan_api.cc +++ b/extensions/browser/api/document_scan/document_scan_api.cc
@@ -5,6 +5,7 @@ #include "extensions/browser/api/document_scan/document_scan_api.h" #include "base/stl_util.h" +#include "base/task_scheduler/post_task.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" @@ -23,14 +24,13 @@ namespace api { DocumentScanScanFunction::DocumentScanScanFunction() - : document_scan_interface_(DocumentScanInterface::CreateInstance()) { -} + : document_scan_interface_(DocumentScanInterface::CreateInstance()) {} -DocumentScanScanFunction::~DocumentScanScanFunction() { -} +DocumentScanScanFunction::~DocumentScanScanFunction() {} bool DocumentScanScanFunction::Prepare() { - set_work_thread_id(BrowserThread::FILE); + set_work_task_runner(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); params_ = document_scan::Scan::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); return true;
diff --git a/extensions/browser/api/serial/serial_api.cc b/extensions/browser/api/serial/serial_api.cc index d7326aa..734b6b3f 100644 --- a/extensions/browser/api/serial/serial_api.cc +++ b/extensions/browser/api/serial/serial_api.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <vector> +#include "base/task_scheduler/post_task.h" #include "base/values.h" #include "build/build_config.h" #include "content/public/browser/browser_thread.h" @@ -50,11 +51,9 @@ } // namespace -SerialAsyncApiFunction::SerialAsyncApiFunction() : manager_(NULL) { -} +SerialAsyncApiFunction::SerialAsyncApiFunction() : manager_(NULL) {} -SerialAsyncApiFunction::~SerialAsyncApiFunction() { -} +SerialAsyncApiFunction::~SerialAsyncApiFunction() {} bool SerialAsyncApiFunction::PrePrepare() { manager_ = ApiResourceManager<SerialConnection>::Get(browser_context()); @@ -75,16 +74,16 @@ manager_->Remove(extension_->id(), api_resource_id); } -SerialGetDevicesFunction::SerialGetDevicesFunction() { -} +SerialGetDevicesFunction::SerialGetDevicesFunction() {} bool SerialGetDevicesFunction::Prepare() { - set_work_thread_id(BrowserThread::FILE); + set_work_task_runner(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); return true; } void SerialGetDevicesFunction::Work() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + DCHECK(work_task_runner()->RunsTasksInCurrentSequence()); std::unique_ptr<device::SerialDeviceEnumerator> enumerator = device::SerialDeviceEnumerator::Create(); @@ -93,11 +92,9 @@ mojo::ConvertTo<std::vector<serial::DeviceInfo>>(devices)); } -SerialConnectFunction::SerialConnectFunction() { -} +SerialConnectFunction::SerialConnectFunction() {} -SerialConnectFunction::~SerialConnectFunction() { -} +SerialConnectFunction::~SerialConnectFunction() {} bool SerialConnectFunction::Prepare() { params_ = serial::Connect::Params::Create(*args_); @@ -144,8 +141,7 @@ } BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, + BrowserThread::IO, FROM_HERE, base::Bind(&SerialConnectFunction::FinishConnect, this)); } @@ -174,11 +170,9 @@ return new SerialConnection(port, extension_id); } -SerialUpdateFunction::SerialUpdateFunction() { -} +SerialUpdateFunction::SerialUpdateFunction() {} -SerialUpdateFunction::~SerialUpdateFunction() { -} +SerialUpdateFunction::~SerialUpdateFunction() {} bool SerialUpdateFunction::Prepare() { params_ = serial::Update::Params::Create(*args_); @@ -197,11 +191,9 @@ results_ = serial::Update::Results::Create(success); } -SerialDisconnectFunction::SerialDisconnectFunction() { -} +SerialDisconnectFunction::SerialDisconnectFunction() {} -SerialDisconnectFunction::~SerialDisconnectFunction() { -} +SerialDisconnectFunction::~SerialDisconnectFunction() {} bool SerialDisconnectFunction::Prepare() { params_ = serial::Disconnect::Params::Create(*args_); @@ -220,11 +212,9 @@ results_ = serial::Disconnect::Results::Create(true); } -SerialSendFunction::SerialSendFunction() { -} +SerialSendFunction::SerialSendFunction() {} -SerialSendFunction::~SerialSendFunction() { -} +SerialSendFunction::~SerialSendFunction() {} bool SerialSendFunction::Prepare() { params_ = serial::Send::Params::Create(*args_); @@ -257,11 +247,9 @@ AsyncWorkCompleted(); } -SerialFlushFunction::SerialFlushFunction() { -} +SerialFlushFunction::SerialFlushFunction() {} -SerialFlushFunction::~SerialFlushFunction() { -} +SerialFlushFunction::~SerialFlushFunction() {} bool SerialFlushFunction::Prepare() { params_ = serial::Flush::Params::Create(*args_); @@ -280,11 +268,9 @@ results_ = serial::Flush::Results::Create(success); } -SerialSetPausedFunction::SerialSetPausedFunction() { -} +SerialSetPausedFunction::SerialSetPausedFunction() {} -SerialSetPausedFunction::~SerialSetPausedFunction() { -} +SerialSetPausedFunction::~SerialSetPausedFunction() {} bool SerialSetPausedFunction::Prepare() { params_ = serial::SetPaused::Params::Create(*args_); @@ -313,11 +299,9 @@ results_ = serial::SetPaused::Results::Create(); } -SerialGetInfoFunction::SerialGetInfoFunction() { -} +SerialGetInfoFunction::SerialGetInfoFunction() {} -SerialGetInfoFunction::~SerialGetInfoFunction() { -} +SerialGetInfoFunction::~SerialGetInfoFunction() {} bool SerialGetInfoFunction::Prepare() { params_ = serial::GetInfo::Params::Create(*args_); @@ -339,11 +323,9 @@ results_ = serial::GetInfo::Results::Create(info); } -SerialGetConnectionsFunction::SerialGetConnectionsFunction() { -} +SerialGetConnectionsFunction::SerialGetConnectionsFunction() {} -SerialGetConnectionsFunction::~SerialGetConnectionsFunction() { -} +SerialGetConnectionsFunction::~SerialGetConnectionsFunction() {} bool SerialGetConnectionsFunction::Prepare() { return true; @@ -355,8 +337,7 @@ manager_->GetResourceIds(extension_->id()); if (connection_ids) { for (base::hash_set<int>::const_iterator it = connection_ids->begin(); - it != connection_ids->end(); - ++it) { + it != connection_ids->end(); ++it) { int connection_id = *it; SerialConnection* connection = GetSerialConnection(connection_id); if (connection) { @@ -370,11 +351,9 @@ results_ = serial::GetConnections::Results::Create(infos); } -SerialGetControlSignalsFunction::SerialGetControlSignalsFunction() { -} +SerialGetControlSignalsFunction::SerialGetControlSignalsFunction() {} -SerialGetControlSignalsFunction::~SerialGetControlSignalsFunction() { -} +SerialGetControlSignalsFunction::~SerialGetControlSignalsFunction() {} bool SerialGetControlSignalsFunction::Prepare() { params_ = serial::GetControlSignals::Params::Create(*args_); @@ -399,11 +378,9 @@ results_ = serial::GetControlSignals::Results::Create(signals); } -SerialSetControlSignalsFunction::SerialSetControlSignalsFunction() { -} +SerialSetControlSignalsFunction::SerialSetControlSignalsFunction() {} -SerialSetControlSignalsFunction::~SerialSetControlSignalsFunction() { -} +SerialSetControlSignalsFunction::~SerialSetControlSignalsFunction() {} bool SerialSetControlSignalsFunction::Prepare() { params_ = serial::SetControlSignals::Params::Create(*args_); @@ -423,11 +400,9 @@ results_ = serial::SetControlSignals::Results::Create(success); } -SerialSetBreakFunction::SerialSetBreakFunction() { -} +SerialSetBreakFunction::SerialSetBreakFunction() {} -SerialSetBreakFunction::~SerialSetBreakFunction() { -} +SerialSetBreakFunction::~SerialSetBreakFunction() {} bool SerialSetBreakFunction::Prepare() { params_ = serial::SetBreak::Params::Create(*args_); @@ -446,11 +421,9 @@ results_ = serial::SetBreak::Results::Create(success); } -SerialClearBreakFunction::SerialClearBreakFunction() { -} +SerialClearBreakFunction::SerialClearBreakFunction() {} -SerialClearBreakFunction::~SerialClearBreakFunction() { -} +SerialClearBreakFunction::~SerialClearBreakFunction() {} bool SerialClearBreakFunction::Prepare() { params_ = serial::ClearBreak::Params::Create(*args_);
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc index 73930c1e..100d76d 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api_unittest.cc
@@ -36,13 +36,9 @@ }; TEST_F(SocketsTcpUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketsTcpCreateFunction* function = new SocketsTcpCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc b/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc index 4d3cf42..2b651825 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api_unittest.cc
@@ -35,13 +35,9 @@ }; TEST_F(SocketsUdpUnitTest, Create) { - // Get BrowserThread - content::BrowserThread::ID id; - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&id)); - // Create SocketCreateFunction and put it on BrowserThread SocketsUdpCreateFunction* function = new SocketsUdpCreateFunction(); - function->set_work_thread_id(id); + function->set_work_task_runner(base::SequencedTaskRunnerHandle::Get()); // Run tests std::unique_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index d898c33..75be042 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -629,9 +629,7 @@ NotifyPageLoad(); request_time_tracker_->LogRequestStartTime(request->identifier(), - base::Time::Now(), - request->url(), - browser_context); + base::Time::Now()); // Whether to initialized |blocked_requests_|. bool initialize_blocked_requests = false; @@ -1766,13 +1764,6 @@ linked_ptr<helpers::EventResponseDelta>(delta)); } - if (!extension_id.empty()) { - base::TimeDelta block_time = - base::Time::Now() - blocked_request.blocking_time; - request_time_tracker_->IncrementExtensionBlockTime( - extension_id, request_id, block_time); - } - if (num_handlers_blocking == 0) { blocked_request.request->LogUnblocked(); ExecuteDeltas(browser_context, request_id, nullptr, true);
diff --git a/extensions/browser/api/web_request/web_request_time_tracker.cc b/extensions/browser/api/web_request/web_request_time_tracker.cc index 4b790ab..3785f3ff8 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker.cc +++ b/extensions/browser/api/web_request/web_request_time_tracker.cc
@@ -4,239 +4,74 @@ #include "extensions/browser/api/web_request/web_request_time_tracker.h" -#include "base/bind.h" -#include "base/compiler_specific.h" #include "base/metrics/histogram_macros.h" -#include "extensions/browser/warning_set.h" - -// TODO(mpcomplete): tweak all these constants. namespace { -// The number of requests we keep track of at a time. -const size_t kMaxRequestsLogged = 100u; - // If a request completes faster than this amount (in ms), then we ignore it. // Any delays on such a request was negligible. const int kMinRequestTimeToCareMs = 10; - -// Thresholds above which we consider a delay caused by an extension to be "too -// much". This is given in percentage of total request time that was spent -// waiting on the extension. -const double kThresholdModerateDelay = 0.20; -const double kThresholdExcessiveDelay = 0.50; - -// If this many requests (of the past kMaxRequestsLogged) have had "too much" -// delay, then we will warn the user. -const size_t kNumModerateDelaysBeforeWarning = 50u; -const size_t kNumExcessiveDelaysBeforeWarning = 10u; - -// Default implementation for ExtensionWebRequestTimeTrackerDelegate -// that sets a warning in the extension service of |profile|. -class DefaultDelegate : public ExtensionWebRequestTimeTrackerDelegate { - public: - ~DefaultDelegate() override {} - - // Implementation of ExtensionWebRequestTimeTrackerDelegate. - void NotifyExcessiveDelays( - void* profile, - size_t num_delayed_messages, - size_t total_num_messages, - const std::set<std::string>& extension_ids) override; - void NotifyModerateDelays( - void* profile, - size_t num_delayed_messages, - size_t total_num_messages, - const std::set<std::string>& extension_ids) override; -}; - -void DefaultDelegate::NotifyExcessiveDelays( - void* profile, - size_t num_delayed_messages, - size_t total_num_messages, - const std::set<std::string>& extension_ids) { - // TODO(battre) Enable warning the user if extensions misbehave as soon as we - // have data that allows us to decide on reasonable limits for triggering the - // warnings. - // BrowserThread::PostTask( - // BrowserThread::UI, - // FROM_HERE, - // base::Bind(&ExtensionWarningSet::NotifyWarningsOnUI, - // profile, - // extension_ids, - // ExtensionWarningSet::kNetworkDelay)); -} - -void DefaultDelegate::NotifyModerateDelays( - void* profile, - size_t num_delayed_messages, - size_t total_num_messages, - const std::set<std::string>& extension_ids) { - // TODO(battre) Enable warning the user if extensions misbehave as soon as we - // have data that allows us to decide on reasonable limits for triggering the - // warnings. - // BrowserThread::PostTask( - // BrowserThread::UI, - // FROM_HERE, - // base::Bind(&ExtensionWarningSet::NotifyWarningsOnUI, - // profile, - // extension_ids, - // ExtensionWarningSet::kNetworkDelay)); -} - } // namespace -ExtensionWebRequestTimeTracker::RequestTimeLog::RequestTimeLog() - : profile(NULL), completed(false) { -} +ExtensionWebRequestTimeTracker::RequestTimeLog::RequestTimeLog() = default; +ExtensionWebRequestTimeTracker::RequestTimeLog::~RequestTimeLog() = default; -ExtensionWebRequestTimeTracker::RequestTimeLog::RequestTimeLog( - const RequestTimeLog& other) = default; - -ExtensionWebRequestTimeTracker::RequestTimeLog::~RequestTimeLog() { -} - -ExtensionWebRequestTimeTracker::ExtensionWebRequestTimeTracker() - : delegate_(new DefaultDelegate) { -} - -ExtensionWebRequestTimeTracker::~ExtensionWebRequestTimeTracker() { -} +ExtensionWebRequestTimeTracker::ExtensionWebRequestTimeTracker() = default; +ExtensionWebRequestTimeTracker::~ExtensionWebRequestTimeTracker() = default; void ExtensionWebRequestTimeTracker::LogRequestStartTime( int64_t request_id, - const base::Time& start_time, - const GURL& url, - void* profile) { - // Trim old completed request logs. - while (request_ids_.size() > kMaxRequestsLogged) { - int64_t to_remove = request_ids_.front(); - request_ids_.pop(); - std::map<int64_t, RequestTimeLog>::iterator iter = - request_time_logs_.find(to_remove); - if (iter != request_time_logs_.end() && iter->second.completed) { - request_time_logs_.erase(iter); - moderate_delays_.erase(to_remove); - excessive_delays_.erase(to_remove); - } - } - request_ids_.push(request_id); - - if (request_time_logs_.find(request_id) != request_time_logs_.end()) { - RequestTimeLog& log = request_time_logs_[request_id]; - DCHECK(!log.completed); + const base::Time& start_time) { + auto iter = request_time_logs_.find(request_id); + if (iter != request_time_logs_.end()) return; - } - RequestTimeLog& log = request_time_logs_[request_id]; - log.request_start_time = start_time; - log.url = url; - log.profile = profile; + + request_time_logs_[request_id].request_start_time = start_time; } void ExtensionWebRequestTimeTracker::LogRequestEndTime( int64_t request_id, const base::Time& end_time) { - if (request_time_logs_.find(request_id) == request_time_logs_.end()) + auto iter = request_time_logs_.find(request_id); + if (iter == request_time_logs_.end()) return; - RequestTimeLog& log = request_time_logs_[request_id]; - if (log.completed) - return; + AnalyzeLogRequest(iter->second, end_time); - log.request_duration = end_time - log.request_start_time; - log.completed = true; + request_time_logs_.erase(iter); +} - if (log.extension_block_durations.empty()) +void ExtensionWebRequestTimeTracker::AnalyzeLogRequest( + const RequestTimeLog& log, + const base::Time& end_time) { + base::TimeDelta request_duration = end_time - log.request_start_time; + + if (log.block_duration.is_zero()) return; UMA_HISTOGRAM_TIMES("Extensions.NetworkDelay", log.block_duration); - Analyze(request_id); -} - -std::set<std::string> ExtensionWebRequestTimeTracker::GetExtensionIds( - const RequestTimeLog& log) const { - std::set<std::string> result; - for (std::map<std::string, base::TimeDelta>::const_iterator i = - log.extension_block_durations.begin(); - i != log.extension_block_durations.end(); - ++i) { - result.insert(i->first); - } - return result; -} - -void ExtensionWebRequestTimeTracker::Analyze(int64_t request_id) { - RequestTimeLog& log = request_time_logs_[request_id]; - // Ignore really short requests. Time spent on these is negligible, and any // extra delay the extension adds is likely to be noise. - if (log.request_duration.InMilliseconds() < kMinRequestTimeToCareMs) - return; - - double percentage = - log.block_duration.InMillisecondsF() / - log.request_duration.InMillisecondsF(); - UMA_HISTOGRAM_PERCENTAGE("Extensions.NetworkDelayPercentage", - static_cast<int>(100*percentage)); - VLOG(1) << "WR percent " << request_id << ": " << log.url << ": " << - log.block_duration.InMilliseconds() << "/" << - log.request_duration.InMilliseconds() << " = " << percentage; - - // TODO(mpcomplete): blame a specific extension. Maybe go through the list - // of recent requests and find the extension that has caused the most delays. - if (percentage > kThresholdExcessiveDelay) { - excessive_delays_.insert(request_id); - if (excessive_delays_.size() > kNumExcessiveDelaysBeforeWarning) { - VLOG(1) << "WR excessive delays:" << excessive_delays_.size(); - if (delegate_.get()) { - delegate_->NotifyExcessiveDelays(log.profile, - excessive_delays_.size(), - request_ids_.size(), - GetExtensionIds(log)); - } - } - } else if (percentage > kThresholdModerateDelay) { - moderate_delays_.insert(request_id); - if (moderate_delays_.size() + excessive_delays_.size() > - kNumModerateDelaysBeforeWarning) { - VLOG(1) << "WR moderate delays:" << moderate_delays_.size(); - if (delegate_.get()) { - delegate_->NotifyModerateDelays( - log.profile, - moderate_delays_.size() + excessive_delays_.size(), - request_ids_.size(), - GetExtensionIds(log)); - } - } + if (request_duration.InMilliseconds() >= kMinRequestTimeToCareMs) { + double percentage = log.block_duration.InMillisecondsF() / + request_duration.InMillisecondsF(); + UMA_HISTOGRAM_PERCENTAGE("Extensions.NetworkDelayPercentage", + static_cast<int>(100 * percentage)); } } -void ExtensionWebRequestTimeTracker::IncrementExtensionBlockTime( - const std::string& extension_id, - int64_t request_id, - const base::TimeDelta& block_time) { - if (request_time_logs_.find(request_id) == request_time_logs_.end()) - return; - RequestTimeLog& log = request_time_logs_[request_id]; - log.extension_block_durations[extension_id] += block_time; -} - void ExtensionWebRequestTimeTracker::IncrementTotalBlockTime( int64_t request_id, const base::TimeDelta& block_time) { - if (request_time_logs_.find(request_id) == request_time_logs_.end()) - return; - RequestTimeLog& log = request_time_logs_[request_id]; - log.block_duration += block_time; + auto iter = request_time_logs_.find(request_id); + if (iter != request_time_logs_.end()) + iter->second.block_duration += block_time; } void ExtensionWebRequestTimeTracker::SetRequestCanceled(int64_t request_id) { // Canceled requests won't actually hit the network, so we can't compare // their request time to the time spent waiting on the extension. Just ignore // them. - // TODO(mpcomplete): may want to count cancels as "bonuses" for an extension. - // i.e. if it slows down 50% of requests but cancels 25% of the rest, that - // might average out to only being "25% slow". request_time_logs_.erase(request_id); } @@ -246,8 +81,3 @@ // down this request. Just ignore it. request_time_logs_.erase(request_id); } - -void ExtensionWebRequestTimeTracker::SetDelegate( - ExtensionWebRequestTimeTrackerDelegate* delegate) { - delegate_.reset(delegate); -}
diff --git a/extensions/browser/api/web_request/web_request_time_tracker.h b/extensions/browser/api/web_request/web_request_time_tracker.h index 1314f351a..1e6f41e 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker.h +++ b/extensions/browser/api/web_request/web_request_time_tracker.h
@@ -9,63 +9,24 @@ #include <stdint.h> #include <map> -#include <memory> -#include <queue> -#include <set> -#include <string> #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/time/time.h" -#include "url/gurl.h" -namespace base { -class Time; -} - -class ExtensionWebRequestTimeTrackerDelegate { - public: - virtual ~ExtensionWebRequestTimeTrackerDelegate() {} - - // Notifies the delegate that |num_delayed_messages| of the last - // |total_num_messages| inspected messages were excessively/moderately - // delayed. Every excessively delayed message is also counted as a moderately - // delayed message. - virtual void NotifyExcessiveDelays( - void* profile, - size_t num_delayed_messages, - size_t total_num_messages, - const std::set<std::string>& extension_ids) = 0; - virtual void NotifyModerateDelays( - void* profile, - size_t num_delayed_messages, - size_t total_num_messages, - const std::set<std::string>& extension_ids) = 0; -}; - -// This class keeps monitors how much delay extensions add to network requests -// by using the webRequest API. If the delay is sufficient, we will warn the -// user that extensions are slowing down the browser. +// This class monitors how much delay extensions add to network requests +// by using the webRequest API. class ExtensionWebRequestTimeTracker { public: ExtensionWebRequestTimeTracker(); ~ExtensionWebRequestTimeTracker(); // Records the time that a request was created. - void LogRequestStartTime(int64_t request_id, - const base::Time& start_time, - const GURL& url, - void* profile); + void LogRequestStartTime(int64_t request_id, const base::Time& start_time); // Records the time that a request either completed or encountered an error. void LogRequestEndTime(int64_t request_id, const base::Time& end_time); - // Records an additional delay for the given request caused by the given - // extension. - void IncrementExtensionBlockTime(const std::string& extension_id, - int64_t request_id, - const base::TimeDelta& block_time); - // Records an additional delay for the given request caused by all extensions // combined. void IncrementTotalBlockTime(int64_t request_id, @@ -77,53 +38,27 @@ // Called when an extension has redirected the given request to another URL. void SetRequestRedirected(int64_t request_id); - // Takes ownership of |delegate|. - void SetDelegate(ExtensionWebRequestTimeTrackerDelegate* delegate); - private: + FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTimeTrackerTest, Histograms); + // Timing information for a single request. struct RequestTimeLog { - GURL url; // used for debug purposes only - void* profile; // profile that created the request - bool completed; base::Time request_start_time; - base::TimeDelta request_duration; base::TimeDelta block_duration; - std::map<std::string, base::TimeDelta> extension_block_durations; + RequestTimeLog(); - RequestTimeLog(const RequestTimeLog& other); ~RequestTimeLog(); + + private: + DISALLOW_COPY_AND_ASSIGN(RequestTimeLog); }; - // Called after a request finishes, to analyze the delays and warn the user - // if necessary. - void Analyze(int64_t request_id); + // Records UMA metrics for the given request and its end time. + void AnalyzeLogRequest(const RequestTimeLog& log, const base::Time& end_time); - // Returns a list of all extension IDs that contributed to delay for |log|. - std::set<std::string> GetExtensionIds(const RequestTimeLog& log) const; - - // A map of recent request IDs to timing info for each request. + // A map of current request IDs to timing info for each request. std::map<int64_t, RequestTimeLog> request_time_logs_; - // A list of recent request IDs that we know about. Used to limit the size of - // the logs. - std::queue<int64_t> request_ids_; - - // The set of recent requests that have been delayed either a large or - // moderate amount by extensions. - std::set<int64_t> excessive_delays_; - std::set<int64_t> moderate_delays_; - - // Defaults to a delegate that sets warnings in the extension service. - std::unique_ptr<ExtensionWebRequestTimeTrackerDelegate> delegate_; - - FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTimeTrackerTest, Basic); - FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTimeTrackerTest, - IgnoreFastRequests); - FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTimeTrackerTest, - CancelOrRedirect); - FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTimeTrackerTest, Delays); - DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestTimeTracker); };
diff --git a/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc b/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc index c3959a7..2055c47 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc +++ b/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc
@@ -7,7 +7,7 @@ #include <stddef.h> #include <stdint.h> -#include "testing/gmock/include/gmock/gmock.h" +#include "base/test/histogram_tester.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -15,136 +15,40 @@ const base::TimeDelta kTinyDelay = base::TimeDelta::FromMilliseconds(1); const base::TimeDelta kModerateDelay = base::TimeDelta::FromMilliseconds(25); const base::TimeDelta kExcessiveDelay = base::TimeDelta::FromMilliseconds(75); - -class ExtensionWebRequestTimeTrackerDelegateMock - : public ExtensionWebRequestTimeTrackerDelegate { - public: - MOCK_METHOD4(NotifyExcessiveDelays, - void (void*, size_t, size_t, const std::set<std::string>&)); - MOCK_METHOD4(NotifyModerateDelays, - void (void*, size_t, size_t, const std::set<std::string>&)); -}; - } // namespace -//class ExtensionWebRequestTimeTrackerTest : public testing::Test {}; +// Test the basis recording of histograms. +TEST(ExtensionWebRequestTimeTrackerTest, Histograms) { + base::HistogramTester histogram_tester; -TEST(ExtensionWebRequestTimeTrackerTest, Basic) { ExtensionWebRequestTimeTracker tracker; base::Time start; - void* profile = NULL; - tracker.LogRequestStartTime(42, start, GURL(), profile); - EXPECT_EQ(1u, tracker.request_time_logs_.size()); - ASSERT_EQ(1u, tracker.request_ids_.size()); - EXPECT_EQ(42, tracker.request_ids_.front()); - tracker.LogRequestEndTime(42, start + kRequestDelta); - EXPECT_EQ(1u, tracker.request_time_logs_.size()); - EXPECT_EQ(0u, tracker.moderate_delays_.size()); - EXPECT_EQ(0u, tracker.excessive_delays_.size()); -} - -TEST(ExtensionWebRequestTimeTrackerTest, CancelOrRedirect) { - ExtensionWebRequestTimeTracker tracker; - base::Time start; - void* profile = NULL; - - tracker.LogRequestStartTime(1, start, GURL(), profile); - EXPECT_EQ(1u, tracker.request_time_logs_.size()); - tracker.SetRequestCanceled(1); - tracker.LogRequestEndTime(1, start + kRequestDelta); - EXPECT_EQ(0u, tracker.request_time_logs_.size()); - - tracker.LogRequestStartTime(2, start, GURL(), profile); - EXPECT_EQ(1u, tracker.request_time_logs_.size()); - tracker.SetRequestRedirected(2); - tracker.LogRequestEndTime(2, start + kRequestDelta); - EXPECT_EQ(0u, tracker.request_time_logs_.size()); -} - -TEST(ExtensionWebRequestTimeTrackerTest, Delays) { - ExtensionWebRequestTimeTracker tracker; - base::Time start; - std::string extension1_id("1"); - std::string extension2_id("2"); - void* profile = NULL; - - // Start 3 requests with different amounts of delay from 2 extensions. - tracker.LogRequestStartTime(1, start, GURL(), profile); - tracker.LogRequestStartTime(2, start, GURL(), profile); - tracker.LogRequestStartTime(3, start, GURL(), profile); - tracker.IncrementExtensionBlockTime(extension1_id, 1, kTinyDelay); - tracker.IncrementExtensionBlockTime(extension1_id, 2, kTinyDelay); - tracker.IncrementExtensionBlockTime(extension1_id, 3, kTinyDelay); - tracker.IncrementExtensionBlockTime(extension2_id, 2, kModerateDelay); - tracker.IncrementExtensionBlockTime(extension2_id, 3, kExcessiveDelay); + tracker.LogRequestStartTime(1, start); + tracker.LogRequestStartTime(2, start); + tracker.LogRequestStartTime(3, start); tracker.IncrementTotalBlockTime(1, kTinyDelay); tracker.IncrementTotalBlockTime(2, kModerateDelay); + tracker.IncrementTotalBlockTime(2, kModerateDelay); tracker.IncrementTotalBlockTime(3, kExcessiveDelay); tracker.LogRequestEndTime(1, start + kRequestDelta); tracker.LogRequestEndTime(2, start + kRequestDelta); tracker.LogRequestEndTime(3, start + kRequestDelta); - EXPECT_EQ(3u, tracker.request_time_logs_.size()); - EXPECT_EQ(1u, tracker.moderate_delays_.size()); - EXPECT_EQ(1u, tracker.moderate_delays_.count(2)); - EXPECT_EQ(1u, tracker.excessive_delays_.size()); - EXPECT_EQ(1u, tracker.excessive_delays_.count(3)); - // Now issue a bunch more requests and ensure that the old delays are - // forgotten. - for (int64_t i = 4; i < 500; ++i) { - tracker.LogRequestStartTime(i, start, GURL(), profile); - tracker.LogRequestEndTime(i, start + kRequestDelta); - } - EXPECT_EQ(0u, tracker.moderate_delays_.size()); - EXPECT_EQ(0u, tracker.excessive_delays_.size()); -} + histogram_tester.ExpectTimeBucketCount("Extensions.NetworkDelay", kTinyDelay, + 1); + histogram_tester.ExpectTimeBucketCount("Extensions.NetworkDelay", + 2 * kModerateDelay, 1); + histogram_tester.ExpectTimeBucketCount("Extensions.NetworkDelay", + kExcessiveDelay, 1); + histogram_tester.ExpectTotalCount("Extensions.NetworkDelay", 3); -TEST(ExtensionWebRequestTimeTrackerTest, Delegate) { - using testing::Mock; + histogram_tester.ExpectBucketCount("Extensions.NetworkDelayPercentage", 1, 1); + histogram_tester.ExpectBucketCount("Extensions.NetworkDelayPercentage", + 2 * 25, 1); + histogram_tester.ExpectBucketCount("Extensions.NetworkDelayPercentage", 75, + 1); + histogram_tester.ExpectTotalCount("Extensions.NetworkDelayPercentage", 3); - ExtensionWebRequestTimeTrackerDelegateMock* delegate( - new ExtensionWebRequestTimeTrackerDelegateMock); - ExtensionWebRequestTimeTracker tracker; - tracker.SetDelegate(delegate); - base::Time start; - std::string extension1_id("1"); - void* profile = NULL; - // Set of all extensions that blocked network requests. - std::set<std::string> extensions; - extensions.insert(extension1_id); - - const int num_moderate_delays = 51; - const int num_excessive_delays = 11; - int request_nr = 0; - - // Check that (only) the last moderate delay triggers the delegate callback. - for (int64_t i = 0; i < num_moderate_delays; ++i) { - request_nr++; - if (i == num_moderate_delays-1) { - EXPECT_CALL(*delegate, - NotifyModerateDelays(profile , i+1, request_nr, extensions)); - } - tracker.LogRequestStartTime(request_nr, start, GURL(), profile); - tracker.IncrementExtensionBlockTime(extension1_id, request_nr, - kModerateDelay); - tracker.IncrementTotalBlockTime(request_nr, kModerateDelay); - tracker.LogRequestEndTime(request_nr, start + kRequestDelta); - Mock::VerifyAndClearExpectations(delegate); - } - - // Check that (only) the last excessive delay triggers the delegate callback. - for (int64_t i = 0; i < num_excessive_delays; ++i) { - request_nr++; - if (i == num_excessive_delays-1) { - EXPECT_CALL(*delegate, - NotifyExcessiveDelays(profile, i+1, request_nr, extensions)); - } - tracker.LogRequestStartTime(request_nr, start, GURL(), profile); - tracker.IncrementExtensionBlockTime(extension1_id, request_nr, - kExcessiveDelay); - tracker.IncrementTotalBlockTime(request_nr, kExcessiveDelay); - tracker.LogRequestEndTime(request_nr, start + kRequestDelta); - Mock::VerifyAndClearExpectations(delegate); - } + EXPECT_TRUE(tracker.request_time_logs_.empty()); }
diff --git a/extensions/browser/content_hash_fetcher_unittest.cc b/extensions/browser/content_hash_fetcher_unittest.cc index 46be54e5..01d6bdc 100644 --- a/extensions/browser/content_hash_fetcher_unittest.cc +++ b/extensions/browser/content_hash_fetcher_unittest.cc
@@ -14,6 +14,7 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/sequenced_worker_pool.h" #include "base/version.h" #include "content/public/browser/browser_thread.h" @@ -172,7 +173,8 @@ url.scheme(), url.host(), content::BrowserThread::GetTaskRunnerForThread( content::BrowserThread::IO), - content::BrowserThread::GetBlockingPool()); + base::CreateTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})); interceptor_->SetResponse(url, response_path); }
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 2487b81..1109f52 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1245,6 +1245,7 @@ LOCKSCREENDATA_GETCONTENT, LOCKSCREENDATA_SETCONTENT, LOCKSCREENDATA_DELETE, + BLUETOOTHLOWENERGY_RESETADVERTISING, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/process_map_factory.cc b/extensions/browser/process_map_factory.cc index 26c4487..8e93e3f 100644 --- a/extensions/browser/process_map_factory.cc +++ b/extensions/browser/process_map_factory.cc
@@ -34,7 +34,10 @@ KeyedService* ProcessMapFactory::BuildServiceInstanceFor( BrowserContext* context) const { - return new ProcessMap; + ProcessMap* process_map = new ProcessMap(); + process_map->set_is_lock_screen_context( + ExtensionsBrowserClient::Get()->IsLockScreenContext(context)); + return process_map; } BrowserContext* ProcessMapFactory::GetBrowserContextToUse(
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index 5677d9c..a88157396 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -31,6 +31,8 @@ #include "extensions/common/extension_unpacker.mojom.h" #include "extensions/common/extension_utility_types.h" #include "extensions/common/extensions_client.h" +#include "extensions/common/features/feature_channel.h" +#include "extensions/common/features/feature_session_type.h" #include "extensions/common/file_util.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/icons_handler.h" @@ -422,7 +424,8 @@ DCHECK(directory.DirName() == temp_dir_.GetPath()); utility_process_mojo_client_->service()->Unpack( - directory, extension_id_, location_, creation_flags_, + GetCurrentChannel(), GetCurrentFeatureSessionType(), directory, + extension_id_, location_, creation_flags_, base::Bind(&SandboxedUnpacker::UnpackDone, this)); }
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index e0529e1..ffd76a7 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -73,6 +73,7 @@ "api/sockets/sockets_manifest_permission.h", "common_manifest_handlers.cc", "common_manifest_handlers.h", + "common_param_traits.h", "csp_validator.cc", "csp_validator.h", "dom_action_types.h", @@ -197,7 +198,6 @@ "manifest_handlers/web_accessible_resources_info.h", "manifest_handlers/webview_info.cc", "manifest_handlers/webview_info.h", - "manifest_location_param_traits.h", "manifest_url_handlers.cc", "manifest_url_handlers.h", "message_bundle.cc",
diff --git a/extensions/common/api/bluetooth_low_energy.idl b/extensions/common/api/bluetooth_low_energy.idl index f0641f57..ee6df3d 100644 --- a/extensions/common/api/bluetooth_low_energy.idl +++ b/extensions/common/api/bluetooth_low_energy.idl
@@ -470,6 +470,11 @@ static void unregisterAdvertisement(long advertisementId, ResultCallback callback); + // Resets advertising on the current device. It will unregister and + // stop all existing advertisements. + // |callback|: Called once the advertisements are reset. + static void resetAdvertising(ResultCallback callback); + // Set's the interval betweeen two consecutive advertisements. Note: // This is a best effort. The actual interval may vary non-trivially // from the requested intervals. On some hardware, there is a minimum
diff --git a/extensions/common/manifest_location_param_traits.h b/extensions/common/common_param_traits.h similarity index 63% rename from extensions/common/manifest_location_param_traits.h rename to extensions/common/common_param_traits.h index c0e8d3d9..fef20024 100644 --- a/extensions/common/manifest_location_param_traits.h +++ b/extensions/common/common_param_traits.h
@@ -4,10 +4,15 @@ // Multiply-included file, hence no include guard. +#include "components/version_info/version_info.h" +#include "extensions/common/features/feature_session_type.h" #include "extensions/common/manifest.h" #include "ipc/ipc_message_macros.h" #include "ipc/param_traits_macros.h" +IPC_ENUM_TRAITS_MAX_VALUE(version_info::Channel, version_info::Channel::STABLE) +IPC_ENUM_TRAITS_MAX_VALUE(extensions::FeatureSessionType, + extensions::FeatureSessionType::LAST) IPC_ENUM_TRAITS_MIN_MAX_VALUE(extensions::Manifest::Location, extensions::Manifest::INVALID_LOCATION, extensions::Manifest::NUM_LOCATIONS - 1)
diff --git a/extensions/common/extension_message_generator.h b/extensions/common/extension_message_generator.h index 9b7ceff8..6607293 100644 --- a/extensions/common/extension_message_generator.h +++ b/extensions/common/extension_message_generator.h
@@ -6,4 +6,3 @@ #include "extensions/common/extension_messages.h" #include "extensions/common/guest_view/extensions_guest_view_messages.h" -#include "extensions/common/manifest_location_param_traits.h"
diff --git a/extensions/common/extension_messages.cc b/extensions/common/extension_messages.cc index c7d25b7..7e2266e 100644 --- a/extensions/common/extension_messages.cc +++ b/extensions/common/extension_messages.cc
@@ -13,7 +13,6 @@ #include "extensions/common/extension.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_handler.h" -#include "extensions/common/manifest_location_param_traits.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/permissions/permissions_info.h"
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 1f257ae..c95da70 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -12,16 +12,15 @@ #include "base/memory/shared_memory.h" #include "base/values.h" -#include "components/version_info/version_info.h" #include "content/public/common/common_param_traits.h" #include "content/public/common/socket_permission_request.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/common_param_traits.h" #include "extensions/common/draggable_region.h" #include "extensions/common/event_filtering_info.h" #include "extensions/common/extension.h" #include "extensions/common/extensions_client.h" -#include "extensions/common/features/feature_session_type.h" #include "extensions/common/host_id.h" #include "extensions/common/permissions/media_galleries_permission_data.h" #include "extensions/common/permissions/permission_set.h" @@ -48,9 +47,6 @@ extensions::UserScript::RUN_LOCATION_LAST - 1) IPC_ENUM_TRAITS_MAX_VALUE(HostID::HostType, HostID::HOST_TYPE_LAST) -IPC_ENUM_TRAITS_MAX_VALUE(version_info::Channel, version_info::Channel::STABLE) -IPC_ENUM_TRAITS_MAX_VALUE(extensions::FeatureSessionType, - extensions::FeatureSessionType::LAST) // Parameters structure for ExtensionHostMsg_AddAPIActionToActivityLog and // ExtensionHostMsg_AddEventToActivityLog.
diff --git a/extensions/common/extension_unpacker.mojom b/extensions/common/extension_unpacker.mojom index c2321c54..47c19c8 100644 --- a/extensions/common/extension_unpacker.mojom +++ b/extensions/common/extension_unpacker.mojom
@@ -24,7 +24,11 @@ // kDecodedImagesFilename and kDecodedMessageCatalogsFilename in |path|. // If Unpack() fails for any reason, |error| contains a user-displayable // explanation of what went wrong. - Unpack(mojo.common.mojom.FilePath path, + // |channel| and |type| are needed to initialize the global state of the + // extension system, which is needed while creating the Extension object. + Unpack(FeatureChannel channel, + FeatureSessionType type, + mojo.common.mojom.FilePath path, string extension_id, ManifestLocation location, int32 creation_flags) @@ -34,3 +38,9 @@ [Native] enum ManifestLocation; + +[Native] +enum FeatureChannel; + +[Native] +enum FeatureSessionType;
diff --git a/extensions/common/extension_unpacker.typemap b/extensions/common/extension_unpacker.typemap new file mode 100644 index 0000000..6fbe4d9 --- /dev/null +++ b/extensions/common/extension_unpacker.typemap
@@ -0,0 +1,19 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//extensions/common/extension_unpacker.mojom" + +public_headers = [ + "//extensions/common/manifest.h", + "//extensions/common/features/feature_session_type.h", + "//components/version_info/version_info.h", +] + +traits_headers = [ "//extensions/common/common_param_traits.h" ] + +type_mappings = [ + "extensions.mojom.ManifestLocation=extensions::Manifest::Location", + "extensions.mojom.FeatureChannel=version_info::Channel", + "extensions.mojom.FeatureSessionType=extensions::FeatureSessionType", +]
diff --git a/extensions/common/manifest_location.typemap b/extensions/common/manifest_location.typemap deleted file mode 100644 index b4c1da53..0000000 --- a/extensions/common/manifest_location.typemap +++ /dev/null
@@ -1,12 +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. - -mojom = "//extensions/common/extension_unpacker.mojom" - -public_headers = [ "//extensions/common/manifest.h" ] - -traits_headers = [ "//extensions/common/manifest_location_param_traits.h" ] - -type_mappings = - [ "extensions.mojom.ManifestLocation=extensions::Manifest::Location" ]
diff --git a/extensions/common/typemaps.gni b/extensions/common/typemaps.gni index 15eaa26..9f9b8cb 100644 --- a/extensions/common/typemaps.gni +++ b/extensions/common/typemaps.gni
@@ -3,6 +3,6 @@ # found in the LICENSE file. typemaps = [ - "//extensions/common/manifest_location.typemap", + "//extensions/common/extension_unpacker.typemap", "//extensions/common/manifest_parser.typemap", ]
diff --git a/extensions/renderer/bindings/api_binding_js_util_unittest.cc b/extensions/renderer/bindings/api_binding_js_util_unittest.cc index f6e8375..c9bd3131 100644 --- a/extensions/renderer/bindings/api_binding_js_util_unittest.cc +++ b/extensions/renderer/bindings/api_binding_js_util_unittest.cc
@@ -27,7 +27,8 @@ } v8::Local<v8::Object> GetLastErrorParent( - v8::Local<v8::Context> context) override { + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent) override { return context->Global(); }
diff --git a/extensions/renderer/bindings/api_bindings_system_unittest.cc b/extensions/renderer/bindings/api_bindings_system_unittest.cc index e5b7bbc..6c0eb0a 100644 --- a/extensions/renderer/bindings/api_bindings_system_unittest.cc +++ b/extensions/renderer/bindings/api_bindings_system_unittest.cc
@@ -144,7 +144,8 @@ } v8::Local<v8::Object> APIBindingsSystemTest::GetLastErrorParent( - v8::Local<v8::Context> context) { + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent) { return v8::Local<v8::Object>(); }
diff --git a/extensions/renderer/bindings/api_bindings_system_unittest.h b/extensions/renderer/bindings/api_bindings_system_unittest.h index d4510fc..2413eef 100644 --- a/extensions/renderer/bindings/api_bindings_system_unittest.h +++ b/extensions/renderer/bindings/api_bindings_system_unittest.h
@@ -45,10 +45,13 @@ // subclasses to return their own specifications. virtual std::vector<FakeSpec> GetAPIs(); - // Returns the object to be used as the parent for the `lastError`. The - // default returns an empty JS object (assumes no last errors will be set). + // Returns the object to be used as the parent for the `lastError`, and, + // optionally, the secondary parent. The default returns an empty JS object + // and does not populate |secondary_parent| (assumes no last errors will be + // set). virtual v8::Local<v8::Object> GetLastErrorParent( - v8::Local<v8::Context> context); + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent); // Returns the DictionaryValue representing the schema with the given API // name.
diff --git a/extensions/renderer/bindings/api_last_error.cc b/extensions/renderer/bindings/api_last_error.cc index 95c9cbdb..660cab61 100644 --- a/extensions/renderer/bindings/api_last_error.cc +++ b/extensions/renderer/bindings/api_last_error.cc
@@ -5,6 +5,7 @@ #include "extensions/renderer/bindings/api_last_error.h" #include "gin/converter.h" +#include "gin/data_object_builder.h" #include "gin/handle.h" #include "gin/object_template_builder.h" #include "gin/wrappable.h" @@ -132,9 +133,92 @@ v8::TryCatch try_catch(isolate); try_catch.SetVerbose(true); - v8::Local<v8::Object> parent = get_parent_.Run(context); + v8::Local<v8::Object> secondary_parent; + v8::Local<v8::Object> parent = get_parent_.Run(context, &secondary_parent); + + SetErrorOnPrimaryParent(context, parent, error); + SetErrorOnSecondaryParent(context, secondary_parent, error); +} + +void APILastError::ClearError(v8::Local<v8::Context> context, + bool report_if_unchecked) { + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + v8::Local<v8::Object> parent; + v8::Local<v8::Object> secondary_parent; + LastErrorObject* last_error = nullptr; + v8::Local<v8::String> key; + v8::Local<v8::Private> private_key; + { + // See comment in SetError(). + v8::TryCatch try_catch(isolate); + try_catch.SetVerbose(true); + + parent = get_parent_.Run(context, &secondary_parent); + if (parent.IsEmpty()) + return; + key = gin::StringToSymbol(isolate, kLastErrorProperty); + private_key = v8::Private::ForApi(isolate, key); + v8::Local<v8::Value> error; + // Access through GetPrivate() so that we don't trigger accessed(). + if (!parent->GetPrivate(context, private_key).ToLocal(&error) || + !gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(), error, + &last_error)) { + return; + } + } + + if (report_if_unchecked && !last_error->accessed()) { + add_console_error_.Run( + context, "Unchecked runtime.lastError: " + last_error->error()); + } + + // See comment in SetError(). + v8::TryCatch try_catch(isolate); + try_catch.SetVerbose(true); + + v8::Maybe<bool> delete_private = parent->DeletePrivate(context, private_key); + if (!delete_private.IsJust() || !delete_private.FromJust()) { + NOTREACHED(); + return; + } + // These Delete()s can fail, but there's nothing to do if it does (the + // exception will be caught by the TryCatch above). + ignore_result(parent->Delete(context, key)); + if (!secondary_parent.IsEmpty()) + ignore_result(secondary_parent->Delete(context, key)); +} + +bool APILastError::HasError(v8::Local<v8::Context> context) { + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + // See comment in SetError(). + v8::TryCatch try_catch(isolate); + try_catch.SetVerbose(true); + + v8::Local<v8::Object> parent = get_parent_.Run(context, nullptr); + if (parent.IsEmpty()) + return false; + v8::Local<v8::Value> error; + v8::Local<v8::Private> key = v8::Private::ForApi( + isolate, gin::StringToSymbol(isolate, kLastErrorProperty)); + // Access through GetPrivate() so we don't trigger accessed(). + if (!parent->GetPrivate(context, key).ToLocal(&error)) + return false; + + LastErrorObject* last_error = nullptr; + return gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(), error, + &last_error); +} + +void APILastError::SetErrorOnPrimaryParent(v8::Local<v8::Context> context, + v8::Local<v8::Object> parent, + const std::string& error) { if (parent.IsEmpty()) return; + v8::Isolate* isolate = context->GetIsolate(); v8::Local<v8::String> key = gin::StringToSymbol(isolate, kLastErrorProperty); v8::Local<v8::Value> v8_error; // Two notes: this Get() is visible to external script, and this will actually @@ -168,82 +252,31 @@ return; } DCHECK(!last_error.IsEmpty()); - // This Set() can fail, but there's nothing to do if it does (the exception - // will be caught by the TryCatch above). + // This SetAccessor() can fail, but there's nothing to do if it does (the + // exception will be caught by the TryCatch in SetError()). ignore_result(parent->SetAccessor(context, key, &LastErrorGetter, &LastErrorSetter, last_error)); } } -void APILastError::ClearError(v8::Local<v8::Context> context, - bool report_if_unchecked) { - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - v8::Local<v8::Object> parent; - LastErrorObject* last_error = nullptr; - v8::Local<v8::String> key; - v8::Local<v8::Private> private_key; - { - // See comment in SetError(). - v8::TryCatch try_catch(isolate); - try_catch.SetVerbose(true); - - parent = get_parent_.Run(context); - if (parent.IsEmpty()) - return; - key = gin::StringToSymbol(isolate, kLastErrorProperty); - private_key = v8::Private::ForApi(isolate, key); - v8::Local<v8::Value> error; - // Access through GetPrivate() so that we don't trigger accessed(). - if (!parent->GetPrivate(context, private_key).ToLocal(&error)) - return; - if (!gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(), error, - &last_error)) { - return; - } - } - - if (report_if_unchecked && !last_error->accessed()) { - add_console_error_.Run( - context, "Unchecked runtime.lastError: " + last_error->error()); - } - - // See comment in SetError(). - v8::TryCatch try_catch(isolate); - try_catch.SetVerbose(true); - - v8::Maybe<bool> delete_private = parent->DeletePrivate(context, private_key); - if (!delete_private.IsJust() || !delete_private.FromJust()) { - NOTREACHED(); +void APILastError::SetErrorOnSecondaryParent( + v8::Local<v8::Context> context, + v8::Local<v8::Object> secondary_parent, + const std::string& error) { + if (secondary_parent.IsEmpty()) return; - } - // This Delete() can fail, but there's nothing to do if it does (the exception - // will be caught by the TryCatch above). - ignore_result(parent->Delete(context, key)); -} -bool APILastError::HasError(v8::Local<v8::Context> context) { + // For the secondary parent, simply set chrome.extension.lastError to + // {message: <error>}. + // TODO(devlin): Gather metrics on how frequently this is checked. It'd be + // nice to get rid of it. v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - // See comment in SetError(). - v8::TryCatch try_catch(isolate); - try_catch.SetVerbose(true); - - v8::Local<v8::Object> parent = get_parent_.Run(context); - if (parent.IsEmpty()) - return false; - v8::Local<v8::Value> error; - v8::Local<v8::Private> key = v8::Private::ForApi( - isolate, gin::StringToSymbol(isolate, kLastErrorProperty)); - // Access through GetPrivate() so we don't trigger accessed(). - if (!parent->GetPrivate(context, key).ToLocal(&error)) - return false; - - LastErrorObject* last_error = nullptr; - return gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(), error, - &last_error); + v8::Local<v8::String> key = gin::StringToSymbol(isolate, kLastErrorProperty); + // This CreateDataProperty() can fail, but there's nothing to do if it does + // (the exception will be caught by the TryCatch in SetError()). + ignore_result(secondary_parent->CreateDataProperty( + context, key, + gin::DataObjectBuilder(isolate).Set("message", error).Build())); } } // namespace extensions
diff --git a/extensions/renderer/bindings/api_last_error.h b/extensions/renderer/bindings/api_last_error.h index f079458..1082409a 100644 --- a/extensions/renderer/bindings/api_last_error.h +++ b/extensions/renderer/bindings/api_last_error.h
@@ -18,9 +18,14 @@ class APILastError { public: // Returns the object the 'lastError' property should be exposed on for the - // given context. - using GetParent = - base::Callback<v8::Local<v8::Object>(v8::Local<v8::Context>)>; + // given context. Also allows for the population of a |secondary_parent|; if + // populated, this object will also have a lastError property, but it will be + // a simple object without getters/setters. This is to accommodate the + // legacy chrome.extension.lastError property. + // Note: |secondary_parent| may be null. + using GetParent = base::Callback<v8::Local<v8::Object>( + v8::Local<v8::Context>, + v8::Local<v8::Object>* secondary_parent)>; // Adds an error message to the context's console. using AddConsoleError = base::Callback<void(v8::Local<v8::Context>, const std::string& error)>; @@ -41,6 +46,18 @@ bool HasError(v8::Local<v8::Context> context); private: + // Sets the lastError property on the primary parent object (in practice, this + // is chrome.runtime.lastError); + void SetErrorOnPrimaryParent(v8::Local<v8::Context> context, + v8::Local<v8::Object> parent, + const std::string& error); + + // Sets the lastError property on the secondary parent object (in practice, + // this is chrome.extension.lastError). + void SetErrorOnSecondaryParent(v8::Local<v8::Context> context, + v8::Local<v8::Object> parent, + const std::string& error); + GetParent get_parent_; AddConsoleError add_console_error_;
diff --git a/extensions/renderer/bindings/api_last_error_unittest.cc b/extensions/renderer/bindings/api_last_error_unittest.cc index 09f42aa..adbd9960 100644 --- a/extensions/renderer/bindings/api_last_error_unittest.cc +++ b/extensions/renderer/bindings/api_last_error_unittest.cc
@@ -41,7 +41,8 @@ using ParentList = std::vector<std::pair<v8::Local<v8::Context>, v8::Local<v8::Object>>>; v8::Local<v8::Object> GetParent(const ParentList& parents, - v8::Local<v8::Context> context) { + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent) { // This would be simpler with a map<context, object>, but Local<> doesn't // define an operator<. for (const auto& parent : parents) { @@ -222,4 +223,55 @@ EXPECT_EQ("undefined", GetLastErrorMessage(parent_b, context_b)); } +TEST_F(APILastErrorTest, SecondaryParent) { + auto get_parents = [](v8::Local<v8::Object> primary_parent, + v8::Local<v8::Object> secondary_parent, + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent_out) { + if (secondary_parent_out) + *secondary_parent_out = secondary_parent; + return primary_parent; + }; + + base::Optional<std::string> console_error; + auto log_error = [](base::Optional<std::string>* console_error, + v8::Local<v8::Context> context, + const std::string& error) { *console_error = error; }; + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + v8::Local<v8::Object> primary_parent = v8::Object::New(isolate()); + v8::Local<v8::Object> secondary_parent = v8::Object::New(isolate()); + + APILastError last_error( + base::Bind(get_parents, primary_parent, secondary_parent), + base::Bind(log_error, &console_error)); + + last_error.SetError(context, "error"); + EXPECT_TRUE(last_error.HasError(context)); + EXPECT_EQ("\"error\"", GetLastErrorMessage(primary_parent, context)); + EXPECT_EQ("\"error\"", GetLastErrorMessage(secondary_parent, context)); + EXPECT_FALSE(console_error); + + last_error.ClearError(context, true); + EXPECT_FALSE(console_error); + EXPECT_EQ("undefined", GetLastErrorMessage(primary_parent, context)); + EXPECT_EQ("undefined", GetLastErrorMessage(secondary_parent, context)); + + // Accessing the primary parent's error should be sufficient to not log the + // error in the console. + last_error.SetError(context, "error"); + EXPECT_EQ("\"error\"", GetLastErrorMessage(primary_parent, context)); + last_error.ClearError(context, true); + EXPECT_FALSE(console_error); + + // Accessing only the secondary parent's error shouldn't count as access on + // the main error, and we should log it. + last_error.SetError(context, "error"); + EXPECT_EQ("\"error\"", GetLastErrorMessage(secondary_parent, context)); + last_error.ClearError(context, true); + ASSERT_TRUE(console_error); + EXPECT_EQ("Unchecked runtime.lastError: error", *console_error); +} + } // namespace extensions
diff --git a/extensions/renderer/bindings/api_request_handler_unittest.cc b/extensions/renderer/bindings/api_request_handler_unittest.cc index ffe963b..28860ef 100644 --- a/extensions/renderer/bindings/api_request_handler_unittest.cc +++ b/extensions/renderer/bindings/api_request_handler_unittest.cc
@@ -373,7 +373,8 @@ v8::Local<v8::Context> context = MainContext(); base::Optional<std::string> logged_error; - auto get_parent = [](v8::Local<v8::Context> context) { + auto get_parent = [](v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent) { return context->Global(); };
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 5d62b9df..0659214c 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -728,7 +728,6 @@ {"messaging", IDR_MESSAGING_JS}, {"messaging_utils", IDR_MESSAGING_UTILS_JS}, {kSchemaUtils, IDR_SCHEMA_UTILS_JS}, - {"sendRequest", IDR_SEND_REQUEST_JS}, {"setIcon", IDR_SET_ICON_JS}, {"test", IDR_TEST_CUSTOM_BINDINGS_JS}, {"test_environment_specific_bindings", @@ -799,6 +798,7 @@ if (!FeatureSwitch::native_crx_bindings()->IsEnabled()) { resources.emplace_back("binding", IDR_BINDING_JS); resources.emplace_back(kEventBindings, IDR_EVENT_BINDINGS_JS); + resources.emplace_back("sendRequest", IDR_SEND_REQUEST_JS); // Custom types sources. resources.emplace_back("StorageArea", IDR_STORAGE_AREA_JS);
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index 4c70d61..73b7125 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -361,7 +361,8 @@ base::Unretained(this)), base::Bind(&NativeExtensionBindingsSystem::OnEventListenerChanged, base::Unretained(this)), - APILastError(base::Bind(&GetRuntime), base::Bind(&AddConsoleError))), + APILastError(base::Bind(&GetLastErrorParents), + base::Bind(&AddConsoleError))), weak_factory_(this) { api_system_.RegisterCustomType("storage.StorageArea", base::Bind(&StorageArea::CreateStorageArea)); @@ -577,8 +578,15 @@ return root_binding; } -v8::Local<v8::Object> NativeExtensionBindingsSystem::GetRuntime( - v8::Local<v8::Context> context) { +v8::Local<v8::Object> NativeExtensionBindingsSystem::GetLastErrorParents( + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent) { + if (secondary_parent && + IsAPIFeatureAvailable(context, "extension.lastError")) { + *secondary_parent = GetAPIHelper( + context, gin::StringToSymbol(context->GetIsolate(), "extension")); + } + return GetAPIHelper(context, gin::StringToSymbol(context->GetIsolate(), "runtime")); }
diff --git a/extensions/renderer/native_extension_bindings_system.h b/extensions/renderer/native_extension_bindings_system.h index a606ba7..a1e66e0b 100644 --- a/extensions/renderer/native_extension_bindings_system.h +++ b/extensions/renderer/native_extension_bindings_system.h
@@ -86,7 +86,9 @@ v8::Local<v8::String> name); // Gets the chrome.runtime API binding. - static v8::Local<v8::Object> GetRuntime(v8::Local<v8::Context> context); + static v8::Local<v8::Object> GetLastErrorParents( + v8::Local<v8::Context> context, + v8::Local<v8::Object>* secondary_parent); // Callback to get an API binding for an internal API. static void GetInternalAPI(const v8::FunctionCallbackInfo<v8::Value>& info);
diff --git a/extensions/renderer/resources/binding.js b/extensions/renderer/resources/binding.js index 83e2418e..d25353b5 100644 --- a/extensions/renderer/resources/binding.js +++ b/extensions/renderer/resources/binding.js
@@ -9,12 +9,12 @@ var GetAvailability = requireNative('v8_context').GetAvailability; var exceptionHandler = require('uncaught_exception_handler'); var lastError = require('lastError'); +var loadTypeSchema = require('json_schema').loadTypeSchema; var logActivity = requireNative('activityLogger'); var logging = requireNative('logging'); var process = requireNative('process'); var schemaRegistry = requireNative('schema_registry'); var schemaUtils = require('schemaUtils'); -var utils = require('utils'); var sendRequestHandler = require('sendRequest'); var contextType = process.GetContextType(); @@ -510,7 +510,7 @@ value = value === 'true'; } else if (propertyDef['$ref']) { var ref = propertyDef['$ref']; - var type = utils.loadTypeSchema(propertyDef['$ref'], schema); + var type = loadTypeSchema(propertyDef['$ref'], schema); logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found'); var constructor = createCustomType(type); var args = value;
diff --git a/extensions/renderer/resources/json_schema.js b/extensions/renderer/resources/json_schema.js index ca351b4..0e4db68 100644 --- a/extensions/renderer/resources/json_schema.js +++ b/extensions/renderer/resources/json_schema.js
@@ -40,9 +40,30 @@ var utils = require('utils'); var loggingNative = requireNative('logging'); -var getObjectType = requireNative('schema_registry').GetObjectType; +var schemaRegistry = requireNative('schema_registry'); var CHECK = loggingNative.CHECK; var DCHECK = loggingNative.DCHECK; +var WARNING = loggingNative.WARNING; + +function loadTypeSchema(typeName, defaultSchema) { + var parts = $String.split(typeName, '.'); + if (parts.length == 1) { + if (defaultSchema == null) { + WARNING('Trying to reference "' + typeName + '" ' + + 'with neither namespace nor default schema.'); + return null; + } + var types = defaultSchema.types; + } else { + var schemaName = $Array.join($Array.slice(parts, 0, parts.length - 1), '.'); + var types = schemaRegistry.GetSchema(schemaName).types; + } + for (var i = 0; i < types.length; ++i) { + if (types[i].id == typeName) + return types[i]; + } + return null; +} function isInstanceOfClass(instance, className) { while ((instance = instance.__proto__)) { @@ -139,7 +160,7 @@ // C++. var s = typeof value; if (s === 'object') - return value === null ? 'null' : getObjectType(value); + return value === null ? 'null' : schemaRegistry.GetObjectType(value); if (s === 'number') return value % 1 === 0 ? 'integer' : 'number'; return s; @@ -190,7 +211,7 @@ JSONSchemaValidator.prototype.getOrAddType = function(typeName) { if (!this.types[typeName]) - this.types[typeName] = utils.loadTypeSchema(typeName); + this.types[typeName] = loadTypeSchema(typeName); return this.types[typeName]; }; @@ -525,3 +546,4 @@ }; exports.$set('JSONSchemaValidator', JSONSchemaValidator); +exports.$set('loadTypeSchema', loadTypeSchema);
diff --git a/extensions/renderer/resources/set_icon.js b/extensions/renderer/resources/set_icon.js index b0ed2b5b..20053f3 100644 --- a/extensions/renderer/resources/set_icon.js +++ b/extensions/renderer/resources/set_icon.js
@@ -3,7 +3,6 @@ // found in the LICENSE file. var SetIconCommon = requireNative('setIcon').SetIconCommon; -var sendRequest = require('sendRequest').sendRequest; function loadImagePath(path, callback) { var img = new Image();
diff --git a/extensions/renderer/resources/utils.js b/extensions/renderer/resources/utils.js index 2cefb15..3b5a68d6 100644 --- a/extensions/renderer/resources/utils.js +++ b/extensions/renderer/resources/utils.js
@@ -3,10 +3,7 @@ // found in the LICENSE file. var nativeDeepCopy = requireNative('utils').deepCopy; -var schemaRegistry = requireNative('schema_registry'); -var CHECK = requireNative('logging').CHECK; var DCHECK = requireNative('logging').DCHECK; -var WARNING = requireNative('logging').WARNING; /** * An object forEach. Calls |f| with each (key, value) pair of |obj|, using @@ -43,26 +40,6 @@ } } -function loadTypeSchema(typeName, defaultSchema) { - var parts = $String.split(typeName, '.'); - if (parts.length == 1) { - if (defaultSchema == null) { - WARNING('Trying to reference "' + typeName + '" ' + - 'with neither namespace nor default schema.'); - return null; - } - var types = defaultSchema.types; - } else { - var schemaName = $Array.join($Array.slice(parts, 0, parts.length - 1), '.'); - var types = schemaRegistry.GetSchema(schemaName).types; - } - for (var i = 0; i < types.length; ++i) { - if (types[i].id == typeName) - return types[i]; - } - return null; -} - /** * Sets a property |value| on |obj| with property name |key|. Like * @@ -230,7 +207,6 @@ } exports.$set('forEach', forEach); -exports.$set('loadTypeSchema', loadTypeSchema); exports.$set('lookup', lookup); exports.$set('defineProperty', defineProperty); exports.$set('expose', expose);
diff --git a/extensions/utility/utility_handler.cc b/extensions/utility/utility_handler.cc index d63e9ec..a726d32 100644 --- a/extensions/utility/utility_handler.cc +++ b/extensions/utility/utility_handler.cc
@@ -11,6 +11,8 @@ #include "extensions/common/extension_l10n_util.h" #include "extensions/common/extension_unpacker.mojom.h" #include "extensions/common/extensions_client.h" +#include "extensions/common/features/feature_channel.h" +#include "extensions/common/features/feature_session_type.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_parser.mojom.h" #include "extensions/common/update_manifest.h" @@ -51,7 +53,9 @@ } } - void Unpack(const base::FilePath& path, + void Unpack(version_info::Channel channel, + extensions::FeatureSessionType type, + const base::FilePath& path, const std::string& extension_id, Manifest::Location location, int32_t creation_flags, @@ -62,6 +66,10 @@ content::UtilityThread::Get()->EnsureBlinkInitialized(); + // Initialize extension system global state. + SetCurrentChannel(channel); + SetCurrentFeatureSessionType(type); + Unpacker unpacker(path.DirName(), path, extension_id, location, creation_flags); if (unpacker.Run()) {
diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc index c74fbf93..f2290795 100644 --- a/google_apis/gaia/fake_gaia.cc +++ b/google_apis/gaia/fake_gaia.cc
@@ -245,7 +245,10 @@ gaia_urls->service_login_url(), HandleServiceLogin); // Handles /embedded/setup/chromeos GAIA call. - REGISTER_RESPONSE_HANDLER(gaia_urls->embedded_setup_chromeos_url(), + REGISTER_RESPONSE_HANDLER(gaia_urls->embedded_setup_chromeos_url(1), + HandleEmbeddedSetupChromeos); + // Handles /embedded/setup/v2/chromeos GAIA call. + REGISTER_RESPONSE_HANDLER(gaia_urls->embedded_setup_chromeos_url(2), HandleEmbeddedSetupChromeos); // Handles /OAuthLogin GAIA call.
diff --git a/google_apis/gaia/gaia_urls.cc b/google_apis/gaia/gaia_urls.cc index bff2ab3..e314a10 100644 --- a/google_apis/gaia/gaia_urls.cc +++ b/google_apis/gaia/gaia_urls.cc
@@ -20,7 +20,8 @@ // API calls from accounts.google.com const char kClientLoginUrlSuffix[] = "ClientLogin"; const char kServiceLoginUrlSuffix[] = "ServiceLogin"; -const char kEmbeddedSetupChromeOsUrlSuffix[] = "embedded/setup/chromeos"; +const char kEmbeddedSetupChromeOsUrlSuffixV1[] = "embedded/setup/chromeos"; +const char kEmbeddedSetupChromeOsUrlSuffixV2[] = "embedded/setup/v2/chromeos"; const char kServiceLoginAuthUrlSuffix[] = "ServiceLoginAuth"; const char kServiceLogoutUrlSuffix[] = "Logout"; const char kIssueAuthTokenUrlSuffix[] = "IssueAuthToken"; @@ -97,8 +98,10 @@ // URLs from accounts.google.com. client_login_url_ = gaia_url_.Resolve(kClientLoginUrlSuffix); service_login_url_ = gaia_url_.Resolve(kServiceLoginUrlSuffix); - embedded_setup_chromeos_url_ = - gaia_url_.Resolve(kEmbeddedSetupChromeOsUrlSuffix); + embedded_setup_chromeos_url_v1_ = + gaia_url_.Resolve(kEmbeddedSetupChromeOsUrlSuffixV1); + embedded_setup_chromeos_url_v2_ = + gaia_url_.Resolve(kEmbeddedSetupChromeOsUrlSuffixV2); service_login_auth_url_ = gaia_url_.Resolve(kServiceLoginAuthUrlSuffix); service_logout_url_ = gaia_url_.Resolve(kServiceLogoutUrlSuffix); issue_auth_token_url_ = gaia_url_.Resolve(kIssueAuthTokenUrlSuffix); @@ -160,8 +163,13 @@ return service_login_url_; } -const GURL& GaiaUrls::embedded_setup_chromeos_url() const { - return embedded_setup_chromeos_url_; +const GURL& GaiaUrls::embedded_setup_chromeos_url(unsigned version) const { + DCHECK_GT(version, 0U); + DCHECK_LE(version, 2U); + if (version == 2U) + return embedded_setup_chromeos_url_v2_; + + return embedded_setup_chromeos_url_v1_; }
diff --git a/google_apis/gaia/gaia_urls.h b/google_apis/gaia/gaia_urls.h index 6268163..b4951d4 100644 --- a/google_apis/gaia/gaia_urls.h +++ b/google_apis/gaia/gaia_urls.h
@@ -22,7 +22,7 @@ const GURL& captcha_base_url() const; const GURL& client_login_url() const; const GURL& service_login_url() const; - const GURL& embedded_setup_chromeos_url() const; + const GURL& embedded_setup_chromeos_url(unsigned version) const; const GURL& service_login_auth_url() const; const GURL& service_logout_url() const; const GURL& issue_auth_token_url() const; @@ -72,7 +72,8 @@ GURL client_login_url_; GURL service_login_url_; - GURL embedded_setup_chromeos_url_; + GURL embedded_setup_chromeos_url_v1_; + GURL embedded_setup_chromeos_url_v2_; GURL service_login_auth_url_; GURL service_logout_url_; GURL issue_auth_token_url_;
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h index 7950779..243e10b8 100644 --- a/gpu/command_buffer/common/capabilities.h +++ b/gpu/command_buffer/common/capabilities.h
@@ -156,6 +156,7 @@ bool disable_webgl_rgb_multisampling_usage = false; bool gpu_rasterization = false; bool avoid_stencil_buffers = false; + bool multisample_compatibility = false; // True if DirectComposition layers are enabled. bool dc_layers = false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index a9f9b685..0c02a1dc 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3823,6 +3823,8 @@ caps.flips_vertically = !is_offscreen && surface_->FlipsVertically(); caps.msaa_is_slow = workarounds().msaa_is_slow; caps.avoid_stencil_buffers = workarounds().avoid_stencil_buffers; + caps.multisample_compatibility = + feature_info_->feature_flags().ext_multisample_compatibility; caps.dc_layers = supports_dc_layers_; caps.blend_equation_advanced =
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index bc07de32..dcb3caaa 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -454,6 +454,8 @@ caps.post_sub_buffer = surface_->SupportsPostSubBuffer(); caps.surfaceless = !offscreen_ && surface_->IsSurfaceless(); caps.flips_vertically = !offscreen_ && surface_->FlipsVertically(); + caps.multisample_compatibility = + feature_info_->feature_flags().ext_multisample_compatibility; // TODO: // caps.commit_overlay_planes
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index 56bf592..d36c9072 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc
@@ -274,6 +274,9 @@ void GpuChannelMessageQueue::Destroy() { // There's no need to reply to sync messages here because the channel is being // destroyed and the client Sends will fail. + base::AutoLock lock(channel_lock_); + channel_ = nullptr; + sync_point_order_data_->Destroy(); if (preempting_flag_) @@ -283,8 +286,6 @@ io_task_runner_->PostTask( FROM_HERE, base::Bind([](std::unique_ptr<base::OneShotTimer>) {}, base::Passed(&timer_))); - - channel_ = nullptr; } bool GpuChannelMessageQueue::IsScheduled() const { @@ -669,9 +670,6 @@ DCHECK(io_thread_checker_.CalledOnValidThread()); DCHECK(ipc_channel_); - if (!gpu_channel_) - return MessageErrorHandler(message, "Channel destroyed"); - if (message.should_unblock() || message.is_reply()) return MessageErrorHandler(message, "Unexpected message type");
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 7cbaef7..57026c97 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -377,10 +377,6 @@ "lib/headless_content_main_delegate.h", "lib/renderer/headless_content_renderer_client.cc", "lib/renderer/headless_content_renderer_client.h", - "lib/renderer/headless_render_frame_controller_impl.cc", - "lib/renderer/headless_render_frame_controller_impl.h", - "lib/renderer/headless_tab_socket_bindings.cc", - "lib/renderer/headless_tab_socket_bindings.h", ] deps += [ @@ -435,17 +431,12 @@ "lib/headless_content_main_delegate.h", "lib/renderer/headless_content_renderer_client.cc", "lib/renderer/headless_content_renderer_client.h", - "lib/renderer/headless_render_frame_controller_impl.cc", - "lib/renderer/headless_render_frame_controller_impl.h", - "lib/renderer/headless_tab_socket_bindings.cc", - "lib/renderer/headless_tab_socket_bindings.h", ] deps = [ ":headless", "//third_party/WebKit/public:blink_headers", "//ui/base", - "//v8", ] if (enable_basic_printing) { deps += [ "//components/printing/renderer" ] @@ -600,8 +591,6 @@ "test/headless_browser_test.cc", "test/headless_browser_test.h", "test/headless_test_launcher.cc", - "test/tab_socket_test.cc", - "test/tab_socket_test.h", "test/test_protocol_handler.cc", "test/test_protocol_handler.h", "test/test_url_request_job.cc",
diff --git a/headless/lib/browser/headless_tab_socket_impl.cc b/headless/lib/browser/headless_tab_socket_impl.cc index 05e562c..1fc89a5 100644 --- a/headless/lib/browser/headless_tab_socket_impl.cc +++ b/headless/lib/browser/headless_tab_socket_impl.cc
@@ -4,153 +4,31 @@ #include "headless/lib/browser/headless_tab_socket_impl.h" -#include "base/stl_util.h" -#include "content/public/browser/devtools_agent_host.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/web_contents.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/interface_provider.h" - namespace headless { -HeadlessTabSocketImpl::HeadlessTabSocketImpl(content::WebContents* web_contents) - : web_contents_(web_contents), - listener_(nullptr), - weak_ptr_factory_(this) {} +HeadlessTabSocketImpl::HeadlessTabSocketImpl() : listener_(nullptr) {} HeadlessTabSocketImpl::~HeadlessTabSocketImpl() {} -// Wrangles the async responses to -// HeadlessRenderFrameControllerImpl::InstallTabSocket for which at most one -// should succeed. -class TabSocketInstallationController - : public base::RefCounted<TabSocketInstallationController> { - public: - TabSocketInstallationController( - int v8_execution_context_id, - size_t render_frame_count, - base::WeakPtr<HeadlessTabSocketImpl> headless_tab_socket_impl, - base::Callback<void(bool)> callback) - : v8_execution_context_id_(v8_execution_context_id), - render_frame_count_(render_frame_count), - headless_tab_socket_impl_(headless_tab_socket_impl), - callback_(callback), - success_(false) {} +void HeadlessTabSocketImpl::SendMessageToTab(const std::string& message) { + AwaitNextMessageFromEmbedderCallback callback; - void InstallTabSocketCallback(content::RenderFrameHost* render_frame_host, - bool success) { - render_frame_count_--; - - // It's possible the HeadlessTabSocketImpl went away, if that happened we - // don't want to pretend TabSocket installation succeeded. - if (!headless_tab_socket_impl_) - success = false; - - if (success) { - CHECK(!success_) << "At most one InstallTabSocket call should succeed!"; - success_ = true; - headless_tab_socket_impl_->v8_execution_context_id_to_render_frame_host_ - .insert(std::make_pair(v8_execution_context_id_, render_frame_host)); - - callback_.Run(true); - } else if (render_frame_count_ == 0 && !success_) { - callback_.Run(false); + { + base::AutoLock lock(lock_); + if (waiting_for_message_cb_.is_null() || !outgoing_message_queue_.empty()) { + outgoing_message_queue_.push_back(message); + return; + } else { + callback = std::move(waiting_for_message_cb_); + DCHECK(waiting_for_message_cb_.is_null()); } } - private: - int v8_execution_context_id_; - size_t render_frame_count_; - - base::WeakPtr<HeadlessTabSocketImpl> headless_tab_socket_impl_; - base::Callback<void(bool)> callback_; - bool success_; - - friend class base::RefCounted<TabSocketInstallationController>; - ~TabSocketInstallationController() {} -}; - -void HeadlessTabSocketImpl::InstallHeadlessTabSocketBindings( - int v8_execution_context_id, - base::Callback<void(bool)> callback) { - // We need to find the right RenderFrameHost to install the bindings on but - // the browser doesn't know which RenderFrameHost |v8_execution_context_id| - // corresponds to if any. So we try all of them. - scoped_refptr<TabSocketInstallationController> - tab_socket_installation_controller = new TabSocketInstallationController( - v8_execution_context_id, render_frame_hosts_.size(), - weak_ptr_factory_.GetWeakPtr(), callback); - for (content::RenderFrameHost* render_frame_host : render_frame_hosts_) { - HeadlessRenderFrameControllerPtr& headless_render_frame_controller = - render_frame_controllers_[render_frame_host]; - if (!headless_render_frame_controller.is_bound()) { - render_frame_host->GetRemoteInterfaces()->GetInterface( - &headless_render_frame_controller); - } - - // This will only succeed if the |render_frame_host_controller| contains - // |v8_execution_context_id|. The TabSocketInstallationController keeps - // track of how many callbacks have been received and if all of them have - // been unsuccessful it runs |callback| with false. If one of them succeeds - // it runs |callback| with true. - headless_render_frame_controller->InstallTabSocket( - v8_execution_context_id, - base::Bind(&TabSocketInstallationController::InstallTabSocketCallback, - tab_socket_installation_controller, render_frame_host)); - } -} - -void HeadlessTabSocketImpl::InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::Callback<void(base::Optional<int>)> callback) { - content::RenderFrameHost* main_frame = web_contents_->GetMainFrame(); - HeadlessRenderFrameControllerPtr& headless_render_frame_controller = - render_frame_controllers_[main_frame]; - if (!headless_render_frame_controller.is_bound()) { - main_frame->GetRemoteInterfaces()->GetInterface( - &headless_render_frame_controller); - } - headless_render_frame_controller->InstallMainWorldTabSocket( - base::Bind(&HeadlessTabSocketImpl::OnInstallMainWorldTabSocket, - weak_ptr_factory_.GetWeakPtr(), callback)); -} - -void HeadlessTabSocketImpl::OnInstallMainWorldTabSocket( - base::Callback<void(base::Optional<int>)> callback, - int v8_execution_context_id) { - if (v8_execution_context_id == -1) { - callback.Run(base::nullopt); - } else { - v8_execution_context_id_to_render_frame_host_.insert( - std::make_pair(v8_execution_context_id, web_contents_->GetMainFrame())); - callback.Run(v8_execution_context_id); - } -} - -void HeadlessTabSocketImpl::SendMessageToContext( - const std::string& message, - int32_t v8_execution_context_id) { - auto render_frame_host = v8_execution_context_id_to_render_frame_host_.find( - v8_execution_context_id); - if (render_frame_host == - v8_execution_context_id_to_render_frame_host_.end()) { - LOG(WARNING) << "Unknown v8_execution_context_id " - << v8_execution_context_id; - return; - } - - auto render_frame_controller = - render_frame_controllers_.find(render_frame_host->second); - if (render_frame_controller == render_frame_controllers_.end()) { - LOG(WARNING) << "Unknown RenderFrameHist " << render_frame_host->second; - return; - } - render_frame_controller->second->SendMessageToTabSocket( - message, v8_execution_context_id); + std::move(callback).Run(message); } void HeadlessTabSocketImpl::SetListener(Listener* listener) { - MessageQueue messages; + std::list<std::string> messages; { base::AutoLock lock(lock_); @@ -158,33 +36,44 @@ if (!listener) return; - std::swap(messages, from_tab_message_queue_); + std::swap(messages, incoming_message_queue_); } - for (const Message& message : messages) { - listener_->OnMessageFromContext(message.first, message.second); + for (const std::string& message : messages) { + listener_->OnMessageFromTab(message); } } -void HeadlessTabSocketImpl::SendMessageToEmbedder( - const std::string& message, - int32_t v8_execution_context_id) { +void HeadlessTabSocketImpl::SendMessageToEmbedder(const std::string& message) { Listener* listener = nullptr; { base::AutoLock lock(lock_); - CHECK(v8_execution_context_id_to_render_frame_host_.find( - v8_execution_context_id) != - v8_execution_context_id_to_render_frame_host_.end()) - << "Unknown v8_execution_context_id " << v8_execution_context_id; if (listener_) { listener = listener_; } else { - from_tab_message_queue_.emplace_back(message, v8_execution_context_id); + incoming_message_queue_.push_back(message); return; } } - listener->OnMessageFromContext(message, v8_execution_context_id); + listener->OnMessageFromTab(message); +} + +void HeadlessTabSocketImpl::AwaitNextMessageFromEmbedder( + AwaitNextMessageFromEmbedderCallback callback) { + std::string message; + { + base::AutoLock lock(lock_); + if (outgoing_message_queue_.empty()) { + waiting_for_message_cb_ = std::move(callback); + DCHECK(!waiting_for_message_cb_.is_null()); + return; + } else { + message = outgoing_message_queue_.front(); + outgoing_message_queue_.pop_front(); + } + } + std::move(callback).Run(message); } void HeadlessTabSocketImpl::CreateMojoService( @@ -192,23 +81,4 @@ mojo_bindings_.AddBinding(this, std::move(request)); } -void HeadlessTabSocketImpl::RenderFrameCreated( - content::RenderFrameHost* render_frame_host) { - render_frame_hosts_.insert(render_frame_host); -} - -void HeadlessTabSocketImpl::RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) { - // Remove all entries from |v8_execution_context_id_to_render_frame_host_| - // where the mapped value is |render_frame_host|. - base::EraseIf(v8_execution_context_id_to_render_frame_host_, - [render_frame_host]( - const std::pair<int, content::RenderFrameHost*>& pair) { - return render_frame_host == pair.second; - }); - - render_frame_controllers_.erase(render_frame_host); - render_frame_hosts_.erase(render_frame_host); -} - } // namespace headless
diff --git a/headless/lib/browser/headless_tab_socket_impl.h b/headless/lib/browser/headless_tab_socket_impl.h index e77f379..45796be 100644 --- a/headless/lib/browser/headless_tab_socket_impl.h +++ b/headless/lib/browser/headless_tab_socket_impl.h
@@ -8,75 +8,38 @@ #include <list> #include "base/synchronization/lock.h" -#include "headless/lib/headless_render_frame_controller.mojom.h" #include "headless/lib/tab_socket.mojom.h" #include "headless/public/headless_tab_socket.h" #include "mojo/public/cpp/bindings/binding_set.h" -namespace content { -class RenderFrameHost; -class WebContents; -} // namespace content - namespace headless { class HeadlessTabSocketImpl : public HeadlessTabSocket, public TabSocket { public: - explicit HeadlessTabSocketImpl(content::WebContents* web_contents); + HeadlessTabSocketImpl(); ~HeadlessTabSocketImpl() override; // HeadlessTabSocket implementation: - void InstallHeadlessTabSocketBindings( - int v8_execution_context_id, - base::Callback<void(bool)> callback) override; - void InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::Callback<void(base::Optional<int>)> callback) override; - void SendMessageToContext(const std::string& message, - int v8_execution_context_id) override; + void SendMessageToTab(const std::string& message) override; void SetListener(Listener* listener) override; // TabSocket implementation: - void SendMessageToEmbedder(const std::string& message, - int32_t v8_execution_context_id) override; + void SendMessageToEmbedder(const std::string& message) override; + void AwaitNextMessageFromEmbedder( + AwaitNextMessageFromEmbedderCallback callback) override; void CreateMojoService(mojo::InterfaceRequest<TabSocket> request); - void RenderFrameCreated(content::RenderFrameHost* render_frame_host); - void RenderFrameDeleted(content::RenderFrameHost* render_frame_host); - private: - friend class TabSocketInstallationController; - - // Called by WebContents::ForEachFrame. If |render_frame_host| matches - // |target_devtools_frame_id|, then the RenderFrameController is used to - // install TabSocket bindings in |world_id|, otherwise it does nothing. - void MaybeInstallTabSocketBindings( - std::string target_devtools_frame_id, - int v8_execution_context_id, - base::Callback<void(bool)> callback, - content::RenderFrameHost* render_frame_host); - - void OnInstallMainWorldTabSocket( - base::Callback<void(base::Optional<int>)> callback, - int world_id); - base::Lock lock_; // Protects everything below. - using Message = std::pair<std::string, int>; - using MessageQueue = std::list<Message>; - - MessageQueue from_tab_message_queue_; - content::WebContents* web_contents_; // NOT OWNED + AwaitNextMessageFromEmbedderCallback waiting_for_message_cb_; + std::list<std::string> outgoing_message_queue_; + std::list<std::string> incoming_message_queue_; Listener* listener_; // NOT OWNED + // Must be listed last so it gets destructed before |waiting_for_message_cb_|. mojo::BindingSet<TabSocket> mojo_bindings_; - std::set<content::RenderFrameHost*> render_frame_hosts_; - std::map<int, content::RenderFrameHost*> - v8_execution_context_id_to_render_frame_host_; - std::map<content::RenderFrameHost*, HeadlessRenderFrameControllerPtr> - render_frame_controllers_; - base::WeakPtrFactory<HeadlessTabSocketImpl> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(HeadlessTabSocketImpl); };
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc index 9b6ba0f..5241fac 100644 --- a/headless/lib/browser/headless_web_contents_impl.cc +++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -33,6 +33,8 @@ #include "headless/lib/browser/headless_devtools_client_impl.h" #include "headless/lib/browser/headless_tab_socket_impl.h" #include "printing/features/features.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/interface_provider.h" #if BUILDFLAG(ENABLE_BASIC_PRINTING) #include "headless/lib/browser/headless_print_manager.h" @@ -130,11 +132,11 @@ content::WebContents::Create(create_params), builder->browser_context_)); - if (builder->tab_sockets_allowed_) { + if (builder->tab_socket_type_ != Builder::TabSocketType::NONE) { headless_web_contents->headless_tab_socket_ = - base::MakeUnique<HeadlessTabSocketImpl>( - headless_web_contents->web_contents_.get()); - headless_web_contents->inject_mojo_services_into_isolated_world_ = true; + base::MakeUnique<HeadlessTabSocketImpl>(); + headless_web_contents->inject_mojo_services_into_isolated_world_ = + builder->tab_socket_type_ == Builder::TabSocketType::ISOLATED_WORLD; builder->mojo_services_.emplace_back( TabSocket::Name_, base::Bind(&CreateTabSocketMojoServiceForContents)); @@ -161,8 +163,7 @@ // Copy mojo services and tab socket settings from parent. child->mojo_services_ = parent->mojo_services_; if (parent->headless_tab_socket_) { - child->headless_tab_socket_ = - base::MakeUnique<HeadlessTabSocketImpl>(child_contents); + child->headless_tab_socket_ = base::MakeUnique<HeadlessTabSocketImpl>(); child->inject_mojo_services_into_isolated_world_ = parent->inject_mojo_services_into_isolated_world_; } @@ -226,6 +227,30 @@ void HeadlessWebContentsImpl::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { + render_frame_host->GetRemoteInterfaces()->GetInterface( + &render_frame_controller_); + if (!mojo_services_.empty()) { + base::Closure callback; + // We only fire DevToolsTargetReady when the tab socket is set up for the + // main frame. + // TODO(eseckler): To indicate tab socket readiness for child frames, we + // need to send an event via the parent frame's DevTools connection instead. + if (render_frame_host == web_contents()->GetMainFrame()) { + callback = + base::Bind(&HeadlessWebContentsImpl::MainFrameTabSocketSetupComplete, + weak_ptr_factory_.GetWeakPtr()); + } + render_frame_controller_->AllowTabSocketBindings( + inject_mojo_services_into_isolated_world_ + ? MojoBindingsPolicy::ISOLATED_WORLD + : MojoBindingsPolicy::MAIN_WORLD, + callback); + } else if (render_frame_host == web_contents()->GetMainFrame()) { + // Pretend we set up the TabSocket, which allows the DevToolsTargetReady + // event to fire. + MainFrameTabSocketSetupComplete(); + } + service_manager::BinderRegistry* interface_registry = render_frame_host->GetInterfaceRegistry(); @@ -240,14 +265,10 @@ browser_context_->SetFrameTreeNodeId(render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID(), render_frame_host->GetFrameTreeNodeId()); - if (headless_tab_socket_) - headless_tab_socket_->RenderFrameCreated(render_frame_host); } void HeadlessWebContentsImpl::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { - if (headless_tab_socket_) - headless_tab_socket_->RenderFrameDeleted(render_frame_host); browser_context_->RemoveFrameTreeNode( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()); @@ -255,6 +276,18 @@ void HeadlessWebContentsImpl::RenderViewReady() { DCHECK(web_contents()->GetMainFrame()->IsRenderFrameLive()); + render_view_ready_ = true; + MaybeIssueDevToolsTargetReady(); +} + +void HeadlessWebContentsImpl::MainFrameTabSocketSetupComplete() { + main_frame_tab_socket_setup_complete_ = true; + MaybeIssueDevToolsTargetReady(); +} + +void HeadlessWebContentsImpl::MaybeIssueDevToolsTargetReady() { + if (!main_frame_tab_socket_setup_complete_ || !render_view_ready_) + return; for (auto& observer : observers_) observer.DevToolsTargetReady(); @@ -391,9 +424,9 @@ return *this; } -HeadlessWebContents::Builder& HeadlessWebContents::Builder::SetAllowTabSockets( - bool tab_sockets_allowed) { - tab_sockets_allowed_ = tab_sockets_allowed; +HeadlessWebContents::Builder& HeadlessWebContents::Builder::SetTabSocketType( + TabSocketType type) { + tab_socket_type_ = type; return *this; }
diff --git a/headless/lib/browser/headless_web_contents_impl.h b/headless/lib/browser/headless_web_contents_impl.h index af14c7a..f8fafb9 100644 --- a/headless/lib/browser/headless_web_contents_impl.h +++ b/headless/lib/browser/headless_web_contents_impl.h
@@ -15,6 +15,7 @@ #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/web_contents_observer.h" #include "headless/lib/browser/headless_window_tree_host.h" +#include "headless/lib/headless_render_frame_controller.mojom.h" #include "headless/public/headless_devtools_target.h" #include "headless/public/headless_export.h" #include "headless/public/headless_web_contents.h" @@ -119,6 +120,9 @@ HeadlessWebContentsImpl(content::WebContents* web_contents, HeadlessBrowserContextImpl* browser_context); + void MainFrameTabSocketSetupComplete(); + void MaybeIssueDevToolsTargetReady(); + void InitializeWindow(const gfx::Rect& initial_bounds); using MojoService = HeadlessWebContents::Builder::MojoService; @@ -131,17 +135,21 @@ std::unique_ptr<HeadlessWindowTreeHost> window_tree_host_; int window_id_ = 0; std::string window_state_; - std::unique_ptr<HeadlessTabSocketImpl> headless_tab_socket_; std::unique_ptr<content::WebContents> web_contents_; scoped_refptr<content::DevToolsAgentHost> agent_host_; std::list<MojoService> mojo_services_; bool inject_mojo_services_into_isolated_world_; + std::unique_ptr<HeadlessTabSocketImpl> headless_tab_socket_; + bool render_view_ready_ = false; + bool main_frame_tab_socket_setup_complete_ = false; HeadlessBrowserContextImpl* browser_context_; // Not owned. // TODO(alexclarke): With OOPIF there may be more than one renderer, we need // to fix this. See crbug.com/715924 content::RenderProcessHost* render_process_host_; // Not owned. + HeadlessRenderFrameControllerPtr render_frame_controller_; + base::ObserverList<HeadlessWebContents::Observer> observers_; base::WeakPtrFactory<HeadlessWebContentsImpl> weak_ptr_factory_;
diff --git a/headless/lib/headless_render_frame_controller.mojom b/headless/lib/headless_render_frame_controller.mojom index 2d71341f1..f8ff294 100644 --- a/headless/lib/headless_render_frame_controller.mojom +++ b/headless/lib/headless_render_frame_controller.mojom
@@ -4,18 +4,17 @@ module headless; +enum MojoBindingsPolicy { + // No access to the TabSocket API from within the frame. + NONE, + // Allow main world JS content within the frame to access the TabSocket API. + MAIN_WORLD, + // Allow access to the TabSocket API only from within DevTools-created + // isolated worlds for the frame. + ISOLATED_WORLD +}; + interface HeadlessRenderFrameController { - // Installs TabSocket bindings into a specified execution context. - InstallTabSocket(int32 v8_execution_context_id) => (bool success); - - // Installs TabSocket bindings into the main world. This is useful if you - // don't know the execution context id (e.g. you don't have devtools - // connected). - InstallMainWorldTabSocket() => (int32 v8_execution_context_id); - - // Send a message from the C++ embedder to the Tab. - SendMessageToTabSocket(string message, int32 v8_execution_context_id); - - // To send a message from tab to the embedder use - // TabSocket::SendMessageToEmbedder. + // Set the bindings policy for TabSocket mojo services for a frame. + AllowTabSocketBindings(MojoBindingsPolicy policy) => (); };
diff --git a/headless/lib/headless_web_contents_browsertest.cc b/headless/lib/headless_web_contents_browsertest.cc index 046d600a..f13774ec 100644 --- a/headless/lib/headless_web_contents_browsertest.cc +++ b/headless/lib/headless_web_contents_browsertest.cc
@@ -8,18 +8,16 @@ #include "base/base64.h" #include "base/json/json_writer.h" -#include "base/strings/stringprintf.h" #include "content/public/test/browser_test.h" #include "headless/lib/browser/headless_web_contents_impl.h" -#include "headless/public/devtools/domains/dom_snapshot.h" #include "headless/public/devtools/domains/page.h" #include "headless/public/devtools/domains/runtime.h" #include "headless/public/devtools/domains/security.h" #include "headless/public/headless_browser.h" #include "headless/public/headless_devtools_client.h" +#include "headless/public/headless_tab_socket.h" #include "headless/public/headless_web_contents.h" #include "headless/test/headless_browser_test.h" -#include "headless/test/tab_socket_test.h" #include "printing/features/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -110,8 +108,7 @@ class HeadlessWindowOpenTabSocketTest : public HeadlessBrowserTest, public HeadlessTabSocket::Listener, public HeadlessBrowserContext::Observer, - public HeadlessWebContents::Observer, - public runtime::Observer { + public HeadlessWebContents::Observer { public: HeadlessWindowOpenTabSocketTest() : devtools_client_(HeadlessDevToolsClient::Create()) {} @@ -122,8 +119,7 @@ } // HeadlessTabSocket::Listener implementation. - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { + void OnMessageFromTab(const std::string& message) override { message_ = message; FinishAsynchronousTest(); } @@ -142,49 +138,6 @@ // Verify tab socket of child_contents works. child_->GetDevToolsTarget()->AttachClient(devtools_client_.get()); - - devtools_client_->GetPage()->Enable(); - devtools_client_->GetPage()->GetExperimental()->GetResourceTree( - page::GetResourceTreeParams::Builder().Build(), - base::Bind(&HeadlessWindowOpenTabSocketTest::OnResourceTree, - base::Unretained(this))); - } - - void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result) { - child_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); - devtools_client_->GetRuntime()->AddObserver(this); - // This will trigger OnExecutionContextCreated getting called for all - // existing contexts. - devtools_client_->GetRuntime()->Enable(); - } - - // runtime::Observer implementation. - void OnExecutionContextCreated( - const runtime::ExecutionContextCreatedParams& params) override { - const base::DictionaryValue* dictionary; - std::string frame_id; - if (params.GetContext()->HasAuxData() && - params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary) && - dictionary->GetString("frameId", &frame_id) && - frame_id == *child_frame_id_) { - child_frame_execution_context_id_ = params.GetContext()->GetId(); - - HeadlessTabSocket* tab_socket = child_->GetHeadlessTabSocket(); - CHECK(tab_socket); - tab_socket->InstallHeadlessTabSocketBindings( - *child_frame_execution_context_id_, - base::Bind(&HeadlessWindowOpenTabSocketTest::OnTabSocketInstalled, - base::Unretained(this))); - } - } - - void OnTabSocketInstalled(bool success) { - ASSERT_TRUE(success); - HeadlessTabSocket* tab_socket = child_->GetHeadlessTabSocket(); - CHECK(tab_socket); - tab_socket->SendMessageToContext("One", *child_frame_execution_context_id_); - tab_socket->SetListener(this); - devtools_client_->GetRuntime()->Evaluate( R"(window.TabSocket.onmessage = function(message) { @@ -197,12 +150,14 @@ void OnEvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { child_->GetDevToolsTarget()->DetachClient(devtools_client_.get()); + + HeadlessTabSocket* tab_socket = child_->GetHeadlessTabSocket(); + tab_socket->SendMessageToTab("One"); + tab_socket->SetListener(this); } protected: std::string message_; - base::Optional<std::string> child_frame_id_; - base::Optional<int> child_frame_execution_context_id_; HeadlessWebContents* child_ = nullptr; std::unique_ptr<HeadlessDevToolsClient> devtools_client_; }; @@ -217,7 +172,8 @@ HeadlessWebContents* web_contents = browser_context->CreateWebContentsBuilder() - .SetAllowTabSockets(true) + .SetTabSocketType( + HeadlessWebContents::Builder::TabSocketType::MAIN_WORLD) .SetInitialURL(embedded_test_server()->GetURL("/window_open.html")) .Build(); EXPECT_TRUE(WaitForLoad(web_contents)); @@ -229,68 +185,6 @@ EXPECT_EQ("Embedder sent us: One", message_); } -class HeadlessNoDevToolsTabSocketTest : public HeadlessBrowserTest, - public HeadlessTabSocket::Listener { - public: - HeadlessNoDevToolsTabSocketTest() {} - - void SetUp() override { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessBrowserTest::SetUp(); - } - - // HeadlessTabSocket::Listener implementation. - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ(*execution_context_id_, execution_context_id); - messages_.push_back(message); - - if (messages_.size() == 2) { - EXPECT_THAT(messages_, - ElementsAre("Hello world!", "Embedder sent us: One")); - FinishAsynchronousTest(); - } - } - - void OnInstalledHeadlessTabSocket(base::Optional<int> execution_context_id) { - EXPECT_TRUE(!!execution_context_id); - if (!execution_context_id) { - FinishAsynchronousTest(); - } else { - fprintf(stderr, "OnInstalledHeadlessTabSocket %d\n", - *execution_context_id); - execution_context_id_ = execution_context_id; - tab_socket_->SendMessageToContext("One", *execution_context_id); - } - } - - std::vector<std::string> messages_; - HeadlessTabSocket* tab_socket_; - base::Optional<int> execution_context_id_; -}; - -IN_PROC_BROWSER_TEST_F(HeadlessNoDevToolsTabSocketTest, Test) { - EXPECT_TRUE(embedded_test_server()->Start()); - - HeadlessBrowserContext* browser_context = - browser()->CreateBrowserContextBuilder().Build(); - - HeadlessWebContents* web_contents = - browser_context->CreateWebContentsBuilder() - .SetAllowTabSockets(true) - .SetInitialURL(embedded_test_server()->GetURL("/tabsocket.html")) - .Build(); - - tab_socket_ = web_contents->GetHeadlessTabSocket(); - CHECK(tab_socket_); - tab_socket_->InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::Bind(&HeadlessNoDevToolsTabSocketTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); - tab_socket_->SetListener(this); - - RunAsynchronousTest(); -} - IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, Focus) { EXPECT_TRUE(embedded_test_server()->Start()); @@ -530,45 +424,40 @@ FinishAsynchronousTest(); } - bool GetAllowTabSockets() override { return false; } + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override { + return HeadlessWebContents::Builder::TabSocketType::NONE; + } }; HEADLESS_ASYNC_DEVTOOLED_TEST_F(GetHeadlessTabSocketButNoTabSocket); -class MainWorldHeadlessTabSocketTest : public TabSocketTest { +class HeadlessMainWorldTabSocketTest : public HeadlessAsyncDevTooledBrowserTest, + public HeadlessTabSocket::Listener { public: - void RunTabSocketTest() override { - CreateMainWorldTabSocket( - main_frame_id(), - base::Bind( - &MainWorldHeadlessTabSocketTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); + void SetUp() override { + options()->mojo_service_names.insert("headless::TabSocket"); + HeadlessAsyncDevTooledBrowserTest::SetUp(); } - void OnInstalledHeadlessTabSocket(int execution_context_id) { + void RunDevTooledTest() override { devtools_client_->GetRuntime()->Evaluate( R"(window.TabSocket.onmessage = function(message) { window.TabSocket.send('Embedder sent us: ' + message); }; - )", - base::Bind(&MainWorldHeadlessTabSocketTest::FailOnJsEvaluateException, - base::Unretained(this))); + )"); HeadlessTabSocket* headless_tab_socket = web_contents_->GetHeadlessTabSocket(); DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext("One", execution_context_id); - headless_tab_socket->SendMessageToContext("Two", execution_context_id); - headless_tab_socket->SendMessageToContext("Three", execution_context_id); + headless_tab_socket->SendMessageToTab("One"); + headless_tab_socket->SendMessageToTab("Two"); + headless_tab_socket->SendMessageToTab("Three"); headless_tab_socket->SetListener(this); - main_frame_execution_context_id_ = execution_context_id; } - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ(execution_context_id, *main_frame_execution_context_id_); + void OnMessageFromTab(const std::string& message) override { messages_.push_back(message); if (messages_.size() == 3u) { EXPECT_THAT(messages_, @@ -578,31 +467,31 @@ } } + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override { + return HeadlessWebContents::Builder::TabSocketType::MAIN_WORLD; + } + private: std::vector<std::string> messages_; - base::Optional<int> main_frame_execution_context_id_; }; -HEADLESS_ASYNC_DEVTOOLED_TEST_F(MainWorldHeadlessTabSocketTest); +HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessMainWorldTabSocketTest); -class MainWorldHeadlessTabSocketBindingsNotInstalledTest - : public TabSocketTest { +class HeadlessMainWorldTabSocketNotThereTest + : public HeadlessAsyncDevTooledBrowserTest, + public HeadlessTabSocket::Listener { public: - void RunTabSocketTest() override { - CreateIsolatedWorldTabSocket( - "Test World", main_frame_id(), - base::Bind(&MainWorldHeadlessTabSocketBindingsNotInstalledTest:: - OnIsolatedWorldCreated, - base::Unretained(this))); + void SetUp() override { + options()->mojo_service_names.insert("headless::TabSocket"); + HeadlessAsyncDevTooledBrowserTest::SetUp(); } - void OnIsolatedWorldCreated(int execution_context_id) { - // We expect this to fail because TabSocket bindings where injected into the - // isolated world not the main world. + void RunDevTooledTest() override { + // We expect this to fail because the TabSocket is being injected into + // isolated worlds. devtools_client_->GetRuntime()->Evaluate( "window.TabSocket.send('This should not work!');", - base::Bind(&MainWorldHeadlessTabSocketBindingsNotInstalledTest:: - ExpectJsException, + base::Bind(&HeadlessMainWorldTabSocketNotThereTest::EvaluateResult, base::Unretained(this))); HeadlessTabSocket* headless_tab_socket = @@ -612,214 +501,182 @@ headless_tab_socket->SetListener(this); } - void OnMessageFromContext(const std::string&, int) override { + void EvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { + EXPECT_TRUE(result->HasExceptionDetails()); + FinishAsynchronousTest(); + } + + void OnMessageFromTab(const std::string&) override { +#ifdef OS_WIN FinishAsynchronousTest(); FAIL() << "Should not receive a message from the tab!"; +#else + FAIL() << "Should not receive a message from the tab!"; + FinishAsynchronousTest(); +#endif + } + + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override { + return HeadlessWebContents::Builder::TabSocketType::ISOLATED_WORLD; } }; -HEADLESS_ASYNC_DEVTOOLED_TEST_F( - MainWorldHeadlessTabSocketBindingsNotInstalledTest); +HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessMainWorldTabSocketNotThereTest); -class IsolatedWorldHeadlessTabSocketTest : public TabSocketTest { +class HeadlessIsolatedWorldTabSocketTest + : public HeadlessAsyncDevTooledBrowserTest, + public HeadlessTabSocket::Listener, + public runtime::Observer { public: - void RunTabSocketTest() override { - CreateIsolatedWorldTabSocket( - "Test World", main_frame_id(), - base::Bind(&IsolatedWorldHeadlessTabSocketTest::OnIsolatedWorldCreated, - base::Unretained(this))); + void SetUp() override { + options()->mojo_service_names.insert("headless::TabSocket"); + HeadlessAsyncDevTooledBrowserTest::SetUp(); } - void OnIsolatedWorldCreated(int execution_context_id) { - main_frame_execution_context_id_ = execution_context_id; + void RunDevTooledTest() override { + devtools_client_->GetRuntime()->AddObserver(this); + devtools_client_->GetRuntime()->Enable(); + + devtools_client_->GetPage()->GetExperimental()->GetResourceTree( + page::GetResourceTreeParams::Builder().Build(), + base::Bind(&HeadlessIsolatedWorldTabSocketTest::OnResourceTree, + base::Unretained(this))); HeadlessTabSocket* headless_tab_socket = web_contents_->GetHeadlessTabSocket(); DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext( - "Hello!!!", *main_frame_execution_context_id_); + headless_tab_socket->SendMessageToTab("Hello!!!"); headless_tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - runtime::EvaluateParams::Builder() - .SetExpression( - R"(window.TabSocket.onmessage = - function(message) { - TabSocket.send('Embedder sent us: ' + message); - }; - )") - .SetContextId(GetV8ExecutionContextIdByWorldName("Test World")) - .Build(), - base::Bind( - &IsolatedWorldHeadlessTabSocketTest::FailOnJsEvaluateException, - base::Unretained(this))); } - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ("Embedder sent us: Hello!!!", message); - EXPECT_EQ(*main_frame_execution_context_id_, execution_context_id); - FinishAsynchronousTest(); + void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result) { + main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); + devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld( + page::CreateIsolatedWorldParams::Builder() + .SetFrameId(main_frame_id_) + .Build()); } - base::Optional<int> main_frame_execution_context_id_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(IsolatedWorldHeadlessTabSocketTest); - -class MultipleIframesIsolatedWorldHeadlessTabSocketTest : public TabSocketTest { - public: - void RunTabSocketTest() override { - EXPECT_TRUE(embedded_test_server()->Start()); - devtools_client_->GetPage()->Navigate( - embedded_test_server()->GetURL("/two_iframes.html").spec()); - } - - void OnLoadEventFired(const page::LoadEventFiredParams& params) override { - devtools_client_->GetPage()->Disable(); - devtools_client_->GetPage()->RemoveObserver(this); - devtools_client_->GetDOMSnapshot()->GetExperimental()->GetSnapshot( - dom_snapshot::GetSnapshotParams::Builder() - .SetComputedStyleWhitelist(std::vector<std::string>()) - .Build(), - base::Bind( - &MultipleIframesIsolatedWorldHeadlessTabSocketTest::OnSnapshot, - base::Unretained(this))); - } - - void OnSnapshot(std::unique_ptr<dom_snapshot::GetSnapshotResult> result) { - bool seen_main_frame = false; - for (const auto& node : *result->GetDomNodes()) { - if (node->HasFrameId()) { - std::string frame_name; - if (node->GetNodeName() == "IFRAME") { - // Use the iframe id attribute for the name. - for (const auto& key_value : *node->GetAttributes()) { - if (key_value->GetName() == "id") { - frame_name = key_value->GetValue(); - } - } - CHECK(!frame_name.empty()); - } else { - if (seen_main_frame) - continue; - seen_main_frame = true; - frame_name = "main frame"; - } - CreateIsolatedWorldTabSocket( - frame_name, node->GetFrameId(), - base::Bind(&MultipleIframesIsolatedWorldHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), frame_name)); - } + void OnExecutionContextCreated( + const runtime::ExecutionContextCreatedParams& params) override { + const base::DictionaryValue* dictionary; + std::string frame_id; + bool is_main_world; + // If the isolated world was created then eval some script in it. + if (params.GetContext()->HasAuxData() && + params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary) && + dictionary->GetString("frameId", &frame_id) && + frame_id == main_frame_id_ && + dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) { + devtools_client_->GetRuntime()->Evaluate( + runtime::EvaluateParams::Builder() + .SetExpression( + R"(window.TabSocket.onmessage = + function(message) { + TabSocket.send('Embedder sent us: ' + message); + }; + )") + .SetContextId(params.GetContext()->GetId()) + .Build()); } } - void OnIsolatedWorldCreated(std::string frame_name, - int execution_context_id) { - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext("Hello!!!", execution_context_id); - headless_tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - runtime::EvaluateParams::Builder() - .SetExpression(base::StringPrintf( - R"(window.TabSocket.onmessage = - function(message) { - TabSocket.send('Echo from %s: ' + message); - }; - )", - frame_name.c_str())) - .SetContextId(execution_context_id) - .Build(), - base::Bind(&MultipleIframesIsolatedWorldHeadlessTabSocketTest:: - FailOnJsEvaluateException, - base::Unretained(this))); - } - - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - messages_.push_back(message); - if (messages_.size() < 3) - return; - EXPECT_THAT(messages_, - UnorderedElementsAre("Echo from main frame: Hello!!!", - "Echo from iframe1: Hello!!!", - "Echo from iframe2: Hello!!!")); + void OnMessageFromTab(const std::string& message) override { + EXPECT_EQ("Embedder sent us: Hello!!!", message); FinishAsynchronousTest(); } - std::vector<std::string> messages_; + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override { + return HeadlessWebContents::Builder::TabSocketType::ISOLATED_WORLD; + } + + private: + std::string main_frame_id_; }; -HEADLESS_ASYNC_DEVTOOLED_TEST_F( - MultipleIframesIsolatedWorldHeadlessTabSocketTest); +HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessIsolatedWorldTabSocketTest); -class SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest - : public TabSocketTest { +class HeadlessIsolatedWorldTabSocketNotThereTest + : public HeadlessAsyncDevTooledBrowserTest, + public HeadlessTabSocket::Listener, + public runtime::Observer { public: - void RunTabSocketTest() override { - CreateIsolatedWorldTabSocket( - "Isolated World 1", main_frame_id(), - base::Bind(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), "Isolated World 1")); - - CreateIsolatedWorldTabSocket( - "Isolated World 2", main_frame_id(), - base::Bind(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), "Isolated World 2")); - - CreateIsolatedWorldTabSocket( - "Isolated World 3", main_frame_id(), - base::Bind(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), "Isolated World 3")); + void SetUp() override { + options()->mojo_service_names.insert("headless::TabSocket"); + HeadlessAsyncDevTooledBrowserTest::SetUp(); } - void OnIsolatedWorldCreated(std::string frame_name, - int execution_context_id) { + void RunDevTooledTest() override { + devtools_client_->GetRuntime()->AddObserver(this); + devtools_client_->GetRuntime()->Enable(); + + devtools_client_->GetPage()->GetExperimental()->GetResourceTree( + page::GetResourceTreeParams::Builder().Build(), + base::Bind(&HeadlessIsolatedWorldTabSocketNotThereTest::OnResourceTree, + base::Unretained(this))); + HeadlessTabSocket* headless_tab_socket = web_contents_->GetHeadlessTabSocket(); DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext("Hello!!!", execution_context_id); + headless_tab_socket->SendMessageToTab("Hello!!!"); headless_tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - runtime::EvaluateParams::Builder() - .SetExpression(base::StringPrintf( - R"(window.TabSocket.onmessage = - function(message) { - TabSocket.send('Echo from %s: ' + message); - }; - )", - frame_name.c_str())) - .SetContextId(execution_context_id) - .Build(), - base::Bind(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - FailOnJsEvaluateException, - base::Unretained(this))); } - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - messages_.push_back(message); - if (messages_.size() < 3) - return; - EXPECT_THAT(messages_, - UnorderedElementsAre("Echo from Isolated World 1: Hello!!!", - "Echo from Isolated World 2: Hello!!!", - "Echo from Isolated World 3: Hello!!!")); + void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result) { + main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); + devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld( + page::CreateIsolatedWorldParams::Builder() + .SetFrameId(main_frame_id_) + .Build()); + } + + void OnExecutionContextCreated( + const runtime::ExecutionContextCreatedParams& params) override { + const base::DictionaryValue* dictionary; + std::string frame_id; + bool is_main_world; + // If the isolated world was created then eval some script in it. + if (params.GetContext()->HasAuxData() && + params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary) && + dictionary->GetString("frameId", &frame_id) && + frame_id == main_frame_id_ && + dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) { + // We expect this to fail because the TabSocket is being injected into the + // main world. + devtools_client_->GetRuntime()->Evaluate( + runtime::EvaluateParams::Builder() + .SetExpression("window.TabSocket.send('This should not work!');") + .SetContextId(params.GetContext()->GetId()) + .Build(), + base::Bind( + &HeadlessIsolatedWorldTabSocketNotThereTest::EvaluateResult, + base::Unretained(this))); + } + } + + void EvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { + EXPECT_TRUE(result->HasExceptionDetails()); FinishAsynchronousTest(); } - std::vector<std::string> messages_; + void OnMessageFromTab(const std::string&) override { +#ifdef OS_WIN + FinishAsynchronousTest(); + FAIL() << "Should not receive a message from the tab!"; +#else + FAIL() << "Should not receive a message from the tab!"; + FinishAsynchronousTest(); +#endif + } + + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override { + return HeadlessWebContents::Builder::TabSocketType::MAIN_WORLD; + } + + private: + std::string main_frame_id_; }; -HEADLESS_ASYNC_DEVTOOLED_TEST_F( - SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest); +HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessIsolatedWorldTabSocketNotThereTest); } // namespace headless
diff --git a/headless/lib/renderer/DEPS b/headless/lib/renderer/DEPS index fedcd88..9e63386 100644 --- a/headless/lib/renderer/DEPS +++ b/headless/lib/renderer/DEPS
@@ -4,5 +4,4 @@ "+gin", "+printing", "+third_party/WebKit/public", - "+v8/include", ]
diff --git a/headless/lib/renderer/headless_content_renderer_client.cc b/headless/lib/renderer/headless_content_renderer_client.cc index a438df4..b6437e4 100644 --- a/headless/lib/renderer/headless_content_renderer_client.cc +++ b/headless/lib/renderer/headless_content_renderer_client.cc
@@ -5,8 +5,25 @@ #include "headless/lib/renderer/headless_content_renderer_client.h" #include "base/memory/ptr_util.h" -#include "headless/lib/renderer/headless_render_frame_controller_impl.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/common/bindings_policy.h" +#include "content/public/common/isolated_world_ids.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_observer.h" +#include "gin/handle.h" +#include "gin/object_template_builder.h" +#include "gin/wrappable.h" +#include "headless/lib/headless_render_frame_controller.mojom.h" +#include "headless/lib/tab_socket.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" #include "printing/features/features.h" +#include "services/service_manager/public/cpp/bind_source_info.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/WebKit/public/platform/WebIsolatedWorldIds.h" +#include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebScriptExecutionCallback.h" #if BUILDFLAG(ENABLE_BASIC_PRINTING) #include "components/printing/renderer/print_web_view_helper.h" @@ -15,6 +32,219 @@ namespace headless { +class HeadlessTabSocketBindings + : public gin::Wrappable<HeadlessTabSocketBindings>, + public blink::WebScriptExecutionCallback { + public: + explicit HeadlessTabSocketBindings(content::RenderFrame* render_frame) + : render_frame_(render_frame), weak_ptr_factory_(this) {} + ~HeadlessTabSocketBindings() override {} + + void SetBindingsPolicy(MojoBindingsPolicy bindings_policy) { + bindings_policy_ = bindings_policy; + + if (world_id_) + return; + + // Update bindings for pre-existing script contexts. + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + if (bindings_policy == MojoBindingsPolicy::MAIN_WORLD) { + InitializeTabSocketBindings( + render_frame_->GetWebFrame()->MainWorldScriptContext(), + content::ISOLATED_WORLD_ID_GLOBAL); + } else if (bindings_policy == MojoBindingsPolicy::ISOLATED_WORLD) { + // TODO(eseckler): We currently only support a single isolated world + // context. InitializeTabSocketBindings will log a warning and ignore any + // but the first isolated world if called multiple times here. + for (const auto& entry : context_map_) { + if (entry.first != content::ISOLATED_WORLD_ID_GLOBAL) + InitializeTabSocketBindings(entry.second.Get(isolate), entry.first); + } + } + } + + void DidCreateScriptContext(v8::Local<v8::Context> context, int world_id) { + bool is_devtools_world = world_id >= blink::kDevToolsFirstIsolatedWorldId && + world_id <= blink::kDevToolsLastIsolatedWorldId; + if (world_id == content::ISOLATED_WORLD_ID_GLOBAL) { + context_map_[world_id].Reset(blink::MainThreadIsolate(), context); + + // For the main world, only inject TabSocket if MAIN_WORLD policy is set. + if (bindings_policy_ != MojoBindingsPolicy::MAIN_WORLD) + return; + } else if (is_devtools_world) { + context_map_[world_id].Reset(blink::MainThreadIsolate(), context); + + // For devtools-created isolated worlds, only inject TabSocket if + // ISOLATED_WORLD policy is set. + if (bindings_policy_ != MojoBindingsPolicy::ISOLATED_WORLD) + return; + } else { + // Other worlds don't receive TabSocket bindings. + return; + } + + InitializeTabSocketBindings(context, world_id); + } + + void WillReleaseScriptContext(v8::Local<v8::Context> context, int world_id) { + context_map_.erase(world_id); + if (world_id_ && *world_id_ == world_id) { + on_message_callback_.Reset(); + world_id_.reset(); + } + } + + // gin::WrappableBase implementation: + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override { + return gin::Wrappable<HeadlessTabSocketBindings>::GetObjectTemplateBuilder( + isolate) + .SetMethod("send", &HeadlessTabSocketBindings::SendImpl) + .SetProperty("onmessage", &HeadlessTabSocketBindings::GetOnMessage, + &HeadlessTabSocketBindings::SetOnMessage); + } + + static gin::WrapperInfo kWrapperInfo; + + private: + void SendImpl(const std::string& message) { + EnsureTabSocketPtr()->SendMessageToEmbedder(message); + } + + v8::Local<v8::Value> GetOnMessage() { return GetOnMessageCallback(); } + + void SetOnMessage(v8::Local<v8::Function> callback) { + on_message_callback_.Reset(blink::MainThreadIsolate(), callback); + + EnsureTabSocketPtr()->AwaitNextMessageFromEmbedder( + base::Bind(&HeadlessTabSocketBindings::OnNextMessageFromEmbedder, + weak_ptr_factory_.GetWeakPtr())); + } + + void OnNextMessageFromEmbedder(const std::string& message) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = GetContext(); + v8::Local<v8::Value> argv[] = { + gin::Converter<std::string>::ToV8(isolate, message), + }; + + render_frame_->GetWebFrame()->RequestExecuteV8Function( + context, GetOnMessageCallback(), context->Global(), arraysize(argv), + argv, this); + + EnsureTabSocketPtr()->AwaitNextMessageFromEmbedder( + base::Bind(&HeadlessTabSocketBindings::OnNextMessageFromEmbedder, + weak_ptr_factory_.GetWeakPtr())); + } + + void InitializeTabSocketBindings(v8::Local<v8::Context> context, + int world_id) { + if (world_id_) { + // TODO(eseckler): Support multiple isolated worlds inside the same frame. + LOG(WARNING) << "TabSocket not created for world id " << world_id + << ". TabSocket only supports a single active world."; + return; + } + + DCHECK(context_map_.find(world_id) != context_map_.end()); + + // Add TabSocket bindings to the context. + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + if (context.IsEmpty()) + return; + + v8::Context::Scope context_scope(context); + gin::Handle<HeadlessTabSocketBindings> bindings = + gin::CreateHandle(isolate, this); + if (bindings.IsEmpty()) + return; + + v8::Local<v8::Object> global = context->Global(); + global->Set(gin::StringToV8(isolate, "TabSocket"), bindings.ToV8()); + world_id_ = world_id; + } + + headless::TabSocketPtr& EnsureTabSocketPtr() { + if (!tab_socket_ptr_.is_bound()) { + render_frame_->GetRemoteInterfaces()->GetInterface( + mojo::MakeRequest(&tab_socket_ptr_)); + } + return tab_socket_ptr_; + } + + v8::Local<v8::Context> GetContext() { + if (!world_id_) + return v8::Local<v8::Context>(); + DCHECK(context_map_.find(*world_id_) != context_map_.end()); + return context_map_[*world_id_].Get(blink::MainThreadIsolate()); + } + + v8::Local<v8::Function> GetOnMessageCallback() { + return v8::Local<v8::Function>::New(blink::MainThreadIsolate(), + on_message_callback_); + } + + content::RenderFrame* render_frame_; + MojoBindingsPolicy bindings_policy_ = MojoBindingsPolicy::NONE; + headless::TabSocketPtr tab_socket_ptr_; + base::Optional<int> world_id_; + base::flat_map<int, v8::UniquePersistent<v8::Context>> context_map_; + v8::UniquePersistent<v8::Function> on_message_callback_; + base::WeakPtrFactory<HeadlessTabSocketBindings> weak_ptr_factory_; +}; + +gin::WrapperInfo HeadlessTabSocketBindings::kWrapperInfo = { + gin::kEmbedderNativeGin}; + +class HeadlessRenderFrameControllerImpl : public HeadlessRenderFrameController, + public content::RenderFrameObserver { + public: + HeadlessRenderFrameControllerImpl(content::RenderFrame* render_frame) + : content::RenderFrameObserver(render_frame), + tab_socket_bindings_(render_frame) { + render_frame->GetInterfaceRegistry()->AddInterface(base::Bind( + &HeadlessRenderFrameControllerImpl::OnRenderFrameControllerRequest, + base::Unretained(this))); + } + + void OnRenderFrameControllerRequest( + const service_manager::BindSourceInfo& source_info, + headless::HeadlessRenderFrameControllerRequest request) { + headless_render_frame_controller_bindings_.AddBinding(this, + std::move(request)); + } + + // HeadlessRenderFrameController implementation: + void AllowTabSocketBindings( + MojoBindingsPolicy policy, + AllowTabSocketBindingsCallback callback) override { + tab_socket_bindings_.SetBindingsPolicy(policy); + std::move(callback).Run(); + } + + // content::RenderFrameObserverW implementation: + void DidCreateScriptContext(v8::Local<v8::Context> context, + int world_id) override { + tab_socket_bindings_.DidCreateScriptContext(context, world_id); + } + + void WillReleaseScriptContext(v8::Local<v8::Context> context, + int world_id) override { + tab_socket_bindings_.WillReleaseScriptContext(context, world_id); + } + + void OnDestruct() override { delete this; } + + private: + mojo::BindingSet<headless::HeadlessRenderFrameController> + headless_render_frame_controller_bindings_; + HeadlessTabSocketBindings tab_socket_bindings_; +}; + HeadlessContentRendererClient::HeadlessContentRendererClient() {} HeadlessContentRendererClient::~HeadlessContentRendererClient() {}
diff --git a/headless/lib/renderer/headless_render_frame_controller_impl.cc b/headless/lib/renderer/headless_render_frame_controller_impl.cc deleted file mode 100644 index 8cd4be8..0000000 --- a/headless/lib/renderer/headless_render_frame_controller_impl.cc +++ /dev/null
@@ -1,119 +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 "headless/lib/renderer/headless_render_frame_controller_impl.h" - -#include "content/public/common/isolated_world_ids.h" -#include "services/service_manager/public/cpp/bind_source_info.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "v8/include/v8-inspector.h" - -namespace headless { - -HeadlessRenderFrameControllerImpl::HeadlessRenderFrameControllerImpl( - content::RenderFrame* render_frame) - : content::RenderFrameObserver(render_frame), - render_frame_(render_frame), - weak_ptr_factory_(this) { - render_frame->GetInterfaceRegistry()->AddInterface(base::Bind( - &HeadlessRenderFrameControllerImpl::OnRenderFrameControllerRequest, - base::Unretained(this))); -} - -HeadlessRenderFrameControllerImpl::~HeadlessRenderFrameControllerImpl() {} - -void HeadlessRenderFrameControllerImpl::OnRenderFrameControllerRequest( - const service_manager::BindSourceInfo& source_info, - headless::HeadlessRenderFrameControllerRequest request) { - headless_render_frame_controller_bindings_.AddBinding(this, - std::move(request)); -} - -void HeadlessRenderFrameControllerImpl::InstallTabSocket( - int32_t execution_context_id, - InstallTabSocketCallback callback) { - auto find_it = tab_socket_bindings_.find(execution_context_id); - if (find_it == tab_socket_bindings_.end()) { - LOG(WARNING) << "InstallTabSocket failed, unknown execution_context_id " - << execution_context_id; - std::move(callback).Run(false); - } else { - std::move(callback).Run(find_it->second.InitializeTabSocketBindings()); - } -} - -void HeadlessRenderFrameControllerImpl::InstallMainWorldTabSocket( - InstallMainWorldTabSocketCallback callback) { - // Check any pre-existing script contexts. - for (auto& pair : tab_socket_bindings_) { - if (pair.second.world_id() == content::ISOLATED_WORLD_ID_GLOBAL) { - std::move(callback).Run( - pair.second.InitializeTabSocketBindings() ? pair.first : -1); - return; - } - } - pending_install_main_world_tab_socket_callback_ = std::move(callback); -} - -void HeadlessRenderFrameControllerImpl::SendMessageToTabSocket( - const std::string& message, - int32_t world_id) { - auto find_it = tab_socket_bindings_.find(world_id); - if (find_it == tab_socket_bindings_.end()) { - LOG(WARNING) << "Dropping message for " << world_id - << " because the world doesn't exist."; - return; - } - - find_it->second.OnMessageFromEmbedder(message); -} - -void HeadlessRenderFrameControllerImpl::DidCreateScriptContext( - v8::Local<v8::Context> context, - int world_id) { - int v8_execution_context_id = - v8_inspector::V8ContextInfo::executionContextId(context); - auto find_it = tab_socket_bindings_.find(v8_execution_context_id); - if (find_it != tab_socket_bindings_.end()) - tab_socket_bindings_.erase(find_it); - - auto emplace_result = tab_socket_bindings_.emplace( - std::piecewise_construct, std::forward_as_tuple(v8_execution_context_id), - std::forward_as_tuple(this, render_frame_, context, world_id)); - - // If main world tab socket bindings have been requested and this is the main - // world then install the bindings. - if (world_id == content::ISOLATED_WORLD_ID_GLOBAL && - !pending_install_main_world_tab_socket_callback_.is_null()) { - std::move(pending_install_main_world_tab_socket_callback_) - .Run(emplace_result.first->second.InitializeTabSocketBindings() - ? emplace_result.first->first - : -1); - pending_install_main_world_tab_socket_callback_ = - InstallMainWorldTabSocketCallback(); - } -} - -void HeadlessRenderFrameControllerImpl::WillReleaseScriptContext( - v8::Local<v8::Context> context, - int world_id) { - tab_socket_bindings_.erase( - v8_inspector::V8ContextInfo::executionContextId(context)); -} - -void HeadlessRenderFrameControllerImpl::OnDestruct() { - delete this; -} - -headless::TabSocketPtr& -HeadlessRenderFrameControllerImpl::EnsureTabSocketPtr() { - if (!tab_socket_ptr_.is_bound()) { - render_frame_->GetRemoteInterfaces()->GetInterface( - mojo::MakeRequest(&tab_socket_ptr_)); - } - return tab_socket_ptr_; -} - -} // namespace headless
diff --git a/headless/lib/renderer/headless_render_frame_controller_impl.h b/headless/lib/renderer/headless_render_frame_controller_impl.h deleted file mode 100644 index 51d9331..0000000 --- a/headless/lib/renderer/headless_render_frame_controller_impl.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 HEADLESS_LIB_RENDERER_HEADLESS_RENDER_FRAME_CONTROLLER_IMPL_H_ -#define HEADLESS_LIB_RENDERER_HEADLESS_RENDER_FRAME_CONTROLLER_IMPL_H_ - -#include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_frame_observer.h" -#include "headless/lib/headless_render_frame_controller.mojom.h" -#include "headless/lib/renderer/headless_tab_socket_bindings.h" -#include "headless/lib/tab_socket.mojom.h" -#include "mojo/public/cpp/bindings/binding_set.h" - -namespace headless { - -class HeadlessRenderFrameControllerImpl : public HeadlessRenderFrameController, - public content::RenderFrameObserver { - public: - explicit HeadlessRenderFrameControllerImpl( - content::RenderFrame* render_frame); - ~HeadlessRenderFrameControllerImpl() override; - - void OnRenderFrameControllerRequest( - const service_manager::BindSourceInfo& source_info, - headless::HeadlessRenderFrameControllerRequest request); - - // HeadlessRenderFrameController implementation: - void InstallTabSocket(int32_t v8_execution_context_id, - InstallTabSocketCallback callback) override; - void InstallMainWorldTabSocket( - InstallMainWorldTabSocketCallback callback) override; - void SendMessageToTabSocket(const std::string& message, - int32_t world_id) override; - - // content::RenderFrameObserver implementation: - void DidCreateScriptContext(v8::Local<v8::Context> context, - int world_id) override; - - void WillReleaseScriptContext(v8::Local<v8::Context> context, - int world_id) override; - - void OnDestruct() override; - - headless::TabSocketPtr& EnsureTabSocketPtr(); - - private: - content::RenderFrame* const render_frame_; // NOT OWNED - mojo::BindingSet<headless::HeadlessRenderFrameController> - headless_render_frame_controller_bindings_; - std::map<int, HeadlessTabSocketBindings> tab_socket_bindings_; - headless::TabSocketPtr tab_socket_ptr_; - InstallMainWorldTabSocketCallback - pending_install_main_world_tab_socket_callback_; - base::WeakPtrFactory<HeadlessRenderFrameControllerImpl> weak_ptr_factory_; -}; - -} // namespace headless - -#endif // HEADLESS_LIB_RENDERER_HEADLESS_RENDER_FRAME_CONTROLLER_IMPL_H_
diff --git a/headless/lib/renderer/headless_tab_socket_bindings.cc b/headless/lib/renderer/headless_tab_socket_bindings.cc deleted file mode 100644 index 94198ab..0000000 --- a/headless/lib/renderer/headless_tab_socket_bindings.cc +++ /dev/null
@@ -1,101 +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 "headless/lib/renderer/headless_tab_socket_bindings.h" - -#include "headless/lib/renderer/headless_render_frame_controller_impl.h" -#include "third_party/WebKit/public/web/WebKit.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "v8/include/v8-inspector.h" - -namespace headless { - -HeadlessTabSocketBindings::HeadlessTabSocketBindings( - HeadlessRenderFrameControllerImpl* parent_controller, - content::RenderFrame* render_frame, - v8::Local<v8::Context> context, - int world_id) - : parent_controller_(parent_controller), - render_frame_(render_frame), - context_(blink::MainThreadIsolate(), context), - world_id_(world_id), - installed_(false) {} - -HeadlessTabSocketBindings::~HeadlessTabSocketBindings() {} - -bool HeadlessTabSocketBindings::InitializeTabSocketBindings() { - if (installed_) - return false; - - v8::Isolate* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - if (context_.IsEmpty()) - return false; - - v8::Local<v8::Context> context = context_.Get(blink::MainThreadIsolate()); - v8::Context::Scope context_scope(context); - gin::Handle<HeadlessTabSocketBindings> bindings = - gin::CreateHandle(isolate, this); - if (bindings.IsEmpty()) - return false; - - v8::Local<v8::Object> global = context->Global(); - global->Set(gin::StringToV8(isolate, "TabSocket"), bindings.ToV8()); - installed_ = true; - return true; -} - -void HeadlessTabSocketBindings::OnMessageFromEmbedder( - const std::string& message) { - if (on_message_callback_.IsEmpty()) { - pending_messages_.push_back(message); - return; - } - - v8::Isolate* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Local<v8::Context> context = context_.Get(isolate); - v8::Local<v8::Value> argv[] = { - gin::Converter<std::string>::ToV8(isolate, message), - }; - - render_frame_->GetWebFrame()->RequestExecuteV8Function( - context, GetOnMessageCallback(), context->Global(), arraysize(argv), argv, - this); -} - -gin::ObjectTemplateBuilder HeadlessTabSocketBindings::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return gin::Wrappable<HeadlessTabSocketBindings>::GetObjectTemplateBuilder( - isolate) - .SetMethod("send", &HeadlessTabSocketBindings::SendImpl) - .SetProperty("onmessage", &HeadlessTabSocketBindings::GetOnMessage, - &HeadlessTabSocketBindings::SetOnMessage); -} - -void HeadlessTabSocketBindings::SendImpl(const std::string& message) { - v8::Local<v8::Context> context = context_.Get(blink::MainThreadIsolate()); - int execution_context_id = - v8_inspector::V8ContextInfo::executionContextId(context); - parent_controller_->EnsureTabSocketPtr()->SendMessageToEmbedder( - message, execution_context_id); -} - -void HeadlessTabSocketBindings::SetOnMessage(v8::Local<v8::Function> callback) { - on_message_callback_.Reset(blink::MainThreadIsolate(), callback); - for (const std::string& message : pending_messages_) { - OnMessageFromEmbedder(message); - } - pending_messages_.clear(); -} - -v8::Local<v8::Function> HeadlessTabSocketBindings::GetOnMessageCallback() { - return v8::Local<v8::Function>::New(blink::MainThreadIsolate(), - on_message_callback_); -} - -gin::WrapperInfo HeadlessTabSocketBindings::kWrapperInfo = { - gin::kEmbedderNativeGin}; - -} // namespace headless
diff --git a/headless/lib/renderer/headless_tab_socket_bindings.h b/headless/lib/renderer/headless_tab_socket_bindings.h deleted file mode 100644 index c284476..0000000 --- a/headless/lib/renderer/headless_tab_socket_bindings.h +++ /dev/null
@@ -1,63 +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 HEADLESS_LIB_RENDERER_HEADLESS_TAB_SOCKET_BINDINGS_H_ -#define HEADLESS_LIB_RENDERER_HEADLESS_TAB_SOCKET_BINDINGS_H_ - -#include "content/public/renderer/render_frame.h" -#include "gin/handle.h" -#include "gin/object_template_builder.h" -#include "gin/wrappable.h" -#include "headless/lib/tab_socket.mojom.h" -#include "third_party/WebKit/public/web/WebScriptExecutionCallback.h" - -namespace headless { -class HeadlessRenderFrameControllerImpl; - -class HeadlessTabSocketBindings - : public gin::Wrappable<HeadlessTabSocketBindings>, - public blink::WebScriptExecutionCallback { - public: - HeadlessTabSocketBindings( - HeadlessRenderFrameControllerImpl* parent_controller, - content::RenderFrame* render_frame, - v8::Local<v8::Context> context, - int world_id); - - ~HeadlessTabSocketBindings() override; - - // Add TabSocket bindings to |context_|. - bool InitializeTabSocketBindings(); - - void OnMessageFromEmbedder(const std::string& message); - - // gin::WrappableBase implementation: - gin::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - - static gin::WrapperInfo kWrapperInfo; - - int world_id() const { return world_id_; } - - private: - void SendImpl(const std::string& message); - - v8::Local<v8::Value> GetOnMessage() { return GetOnMessageCallback(); } - - void SetOnMessage(v8::Local<v8::Function> callback); - - v8::Local<v8::Function> GetOnMessageCallback(); - - HeadlessRenderFrameControllerImpl* const parent_controller_; // NOT OWNED - content::RenderFrame* const render_frame_; // NOT OWNED - const v8::UniquePersistent<v8::Context> context_; - const int world_id_; - bool installed_; - std::list<std::string> pending_messages_; - v8::UniquePersistent<v8::Function> on_message_callback_; -}; - -} // namespace headless - -#endif // HEADLESS_LIB_RENDERER_HEADLESS_TAB_SOCKET_BINDINGS_H_
diff --git a/headless/lib/tab_socket.mojom b/headless/lib/tab_socket.mojom index 2e6665c..cd90e70 100644 --- a/headless/lib/tab_socket.mojom +++ b/headless/lib/tab_socket.mojom
@@ -6,8 +6,9 @@ interface TabSocket { // Send a message from the Tab to C++ embedder. - SendMessageToEmbedder(string message, int32 v8_execution_context_id); + SendMessageToEmbedder(string message); - // To send a message to the tab use - // HeadlessRenderFrameController::SendMessageToTabSocket. + // Waits for the next message to sent from the embedder C++ to the tab. + // NB this is non-blocking. + AwaitNextMessageFromEmbedder() => (string message); };
diff --git a/headless/public/headless_tab_socket.h b/headless/public/headless_tab_socket.h index 262b9fc57..b8f0fa2 100644 --- a/headless/public/headless_tab_socket.h +++ b/headless/public/headless_tab_socket.h
@@ -8,7 +8,6 @@ #include <string> #include "base/macros.h" -#include "base/optional.h" #include "headless/public/headless_export.h" namespace headless { @@ -21,34 +20,15 @@ Listener() {} virtual ~Listener() {} - // The |message| and |v8_execution_context_id| may be potentially sent by - // untrusted web content so it should be validated carefully. - virtual void OnMessageFromContext(const std::string& message, - int v8_execution_context_id) = 0; + // The |message| may be potentially sent by untrusted web content so it + // should be validated carefully. + virtual void OnMessageFromTab(const std::string& message) = 0; private: DISALLOW_COPY_AND_ASSIGN(Listener); }; - // Installs headless tab socket bindings into the specified execution context. - // If the bindings are successfully installed then the |callback| is run with - // |success| = true, otherwise with |success| = false. - virtual void InstallHeadlessTabSocketBindings( - int v8_execution_context_id, - base::Callback<void(bool success)> callback) = 0; - - // Installs headless tab socket bindings into the main frame main world. If - // the bindings were installed correctly then |callback| is run with a - // non-empty base::Optional<int> containing the main world - // v8_execution_context_id, otherwise |callback| is run with an empty - // base::Optional<int>. - virtual void InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::Callback<void(base::Optional<int> v8_execution_context_id)> - callback) = 0; - - // Note this will fail unless the bindings have been installed. - virtual void SendMessageToContext(const std::string& message, - int v8_execution_context_id) = 0; + virtual void SendMessageToTab(const std::string& message) = 0; virtual void SetListener(Listener* listener) = 0;
diff --git a/headless/public/headless_web_contents.h b/headless/public/headless_web_contents.h index dae0d72..01fb232b 100644 --- a/headless/public/headless_web_contents.h +++ b/headless/public/headless_web_contents.h
@@ -80,8 +80,7 @@ // Close this page. |HeadlessWebContents| object will be destroyed. virtual void Close() = 0; - // Returns the headless tab socket interface for C++ <---> JS, or null if tab - // sockets are not allowed. + // Returns the headless tab socket for JS -> C++ if one was created. virtual HeadlessTabSocket* GetHeadlessTabSocket() const = 0; // Returns the devtools frame id corresponding to the |frame_tree_node_id|, if @@ -113,8 +112,15 @@ // Specify the initial window size (default is configured in browser options). Builder& SetWindowSize(const gfx::Size& size); - // Specify whether or not TabSockets are allowed. - Builder& SetAllowTabSockets(bool tab_sockets_allowed); + enum class TabSocketType { + NONE, // No TabSocket binds created (default). + MAIN_WORLD, // TabSocket bindings available only to the main world. + ISOLATED_WORLD // TabSocket bindings available only to isolated worlds + // created via DevTools protocol. + }; + + // Sets the type of TabSocket to be created, if any. + Builder& SetTabSocketType(TabSocketType type); // The returned object is owned by HeadlessBrowser. Call // HeadlessWebContents::Close() to dispose it. @@ -147,7 +153,7 @@ GURL initial_url_ = GURL("about:blank"); gfx::Size window_size_; std::list<MojoService> mojo_services_; - bool tab_sockets_allowed_ = false; + TabSocketType tab_socket_type_ = TabSocketType::NONE; DISALLOW_COPY_AND_ASSIGN(Builder); };
diff --git a/headless/test/data/iframe2.html b/headless/test/data/iframe2.html deleted file mode 100644 index 0826be6c..0000000 --- a/headless/test/data/iframe2.html +++ /dev/null
@@ -1,5 +0,0 @@ -<html> -<body> -<h2>Hello from the second iframe!</h2> -</body> -</html>
diff --git a/headless/test/data/tabsocket.html b/headless/test/data/tabsocket.html deleted file mode 100644 index 91e7661..0000000 --- a/headless/test/data/tabsocket.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> -<script> -window.TabSocket.send('Hello world!'); - -window.TabSocket.onmessage = function(message) { - window.TabSocket.send('Embedder sent us: ' + message); -}; -</script> -</html>
diff --git a/headless/test/data/two_iframes.html b/headless/test/data/two_iframes.html deleted file mode 100644 index cb016d9..0000000 --- a/headless/test/data/two_iframes.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<body> -<iframe id="iframe1" src="/iframe.html" width="400" height="200"></iframe> -<iframe id="iframe2" src="/iframe2.html" width="400" height="200"></iframe> -</body> -</html>
diff --git a/headless/test/headless_browser_test.cc b/headless/test/headless_browser_test.cc index e613010..98e3b8ae7 100644 --- a/headless/test/headless_browser_test.cc +++ b/headless/test/headless_browser_test.cc
@@ -235,7 +235,7 @@ HeadlessBrowserContext::Builder builder = browser()->CreateBrowserContextBuilder(); builder.SetProtocolHandlers(GetProtocolHandlers()); - if (GetAllowTabSockets()) { + if (GetTabSocketType() != HeadlessWebContents::Builder::TabSocketType::NONE) { builder.EnableUnsafeNetworkAccessWithMojoBindings(true); builder.AddTabSocketMojoBindings(); } @@ -245,7 +245,7 @@ browser()->GetDevToolsTarget()->AttachClient(browser_devtools_client_.get()); web_contents_ = browser_context_->CreateWebContentsBuilder() - .SetAllowTabSockets(GetAllowTabSockets()) + .SetTabSocketType(GetTabSocketType()) .Build(); web_contents_->AddObserver(this); @@ -265,8 +265,9 @@ return ProtocolHandlerMap(); } -bool HeadlessAsyncDevTooledBrowserTest::GetAllowTabSockets() { - return false; +HeadlessWebContents::Builder::TabSocketType +HeadlessAsyncDevTooledBrowserTest::GetTabSocketType() { + return HeadlessWebContents::Builder::TabSocketType::NONE; } bool HeadlessAsyncDevTooledBrowserTest::
diff --git a/headless/test/headless_browser_test.h b/headless/test/headless_browser_test.h index b62b4c6..b5ef877 100644 --- a/headless/test/headless_browser_test.h +++ b/headless/test/headless_browser_test.h
@@ -125,8 +125,8 @@ // the map returned is empty. virtual ProtocolHandlerMap GetProtocolHandlers(); - // Whether to allow TabSockets when creating |web_contents_|. - virtual bool GetAllowTabSockets(); + // The TabSocket type to request when creating |web_contents_|. + virtual HeadlessWebContents::Builder::TabSocketType GetTabSocketType(); // Selects between creating the TabSocket only in an isolated world or the // main world.
diff --git a/headless/test/headless_js_bindings_browsertest.cc b/headless/test/headless_js_bindings_browsertest.cc index ed09e13..3d3088f 100644 --- a/headless/test/headless_js_bindings_browsertest.cc +++ b/headless/test/headless_js_bindings_browsertest.cc
@@ -12,7 +12,6 @@ #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" -#include "content/public/common/isolated_world_ids.h" #include "content/public/test/browser_test.h" #include "headless/grit/headless_browsertest_resources.h" #include "headless/public/devtools/domains/runtime.h" @@ -20,7 +19,7 @@ #include "headless/public/headless_devtools_client.h" #include "headless/public/headless_tab_socket.h" #include "headless/public/headless_web_contents.h" -#include "headless/test/tab_socket_test.h" +#include "headless/test/headless_browser_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/resource/resource_bundle.h" @@ -28,9 +27,15 @@ namespace headless { class HeadlessJsBindingsTest - : public TabSocketTest, + : public HeadlessAsyncDevTooledBrowserTest, + public HeadlessTabSocket::Listener, public HeadlessDevToolsClient::RawProtocolListener { public: + void SetUp() override { + options()->mojo_service_names.insert("headless::TabSocket"); + HeadlessAsyncDevTooledBrowserTest::SetUp(); + } + void SetUpOnMainThread() override { base::ThreadRestrictions::SetIOAllowed(true); base::FilePath pak_path; @@ -40,19 +45,15 @@ pak_path, ui::SCALE_FACTOR_NONE); } - void RunTabSocketTest() override { - headless_tab_socket_ = web_contents_->GetHeadlessTabSocket(); - CHECK(headless_tab_socket_); - headless_tab_socket_->SetListener(this); + void RunDevTooledTest() override { devtools_client_->SetRawProtocolListener(this); - CreateMainWorldTabSocket( - main_frame_id(), - base::Bind(&HeadlessJsBindingsTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); + headless_tab_socket_ = web_contents_->GetHeadlessTabSocket(); + DCHECK(headless_tab_socket_); + headless_tab_socket_->SetListener(this); + PrepareToRunJsBindingsTest(); } - void OnInstalledHeadlessTabSocket(int v8_exection_context_id) { - main_world_execution_context_id_ = v8_exection_context_id; + void PrepareToRunJsBindingsTest() { devtools_client_->GetRuntime()->Evaluate( ResourceBundle::GetSharedInstance() .GetRawDataResource(DEVTOOLS_BINDINGS_TEST) @@ -72,9 +73,22 @@ } } - void OnMessageFromContext(const std::string& json_message, - int v8_execution_context_id) override { - EXPECT_EQ(main_world_execution_context_id_, v8_execution_context_id); + void FailOnJsEvaluateException( + std::unique_ptr<runtime::EvaluateResult> result) { + if (!result->HasExceptionDetails()) + return; + + FinishAsynchronousTest(); + + const runtime::ExceptionDetails* exception_details = + result->GetExceptionDetails(); + FAIL() << exception_details->GetText() + << (exception_details->HasException() + ? exception_details->GetException()->GetDescription().c_str() + : ""); + } + + void OnMessageFromTab(const std::string& json_message) override { std::unique_ptr<base::Value> message = base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); const base::DictionaryValue* message_dict; @@ -101,6 +115,10 @@ devtools_client_->SendRawDevToolsMessage(json_message); } + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override { + return HeadlessWebContents::Builder::TabSocketType::MAIN_WORLD; + } + bool OnProtocolMessage(const std::string& devtools_agent_host_id, const std::string& json_message, const base::DictionaryValue& parsed_message) override { @@ -114,8 +132,7 @@ if ((id % 2) == 0) return false; - headless_tab_socket_->SendMessageToContext( - json_message, main_world_execution_context_id_); + headless_tab_socket_->SendMessageToTab(json_message); return true; } @@ -123,8 +140,7 @@ if (!parsed_message.GetString("method", &method)) return false; - headless_tab_socket_->SendMessageToContext( - json_message, main_world_execution_context_id_); + headless_tab_socket_->SendMessageToTab(json_message); // Check which domain the event belongs to, if it's the DOM domain then // assume js handled it. @@ -135,7 +151,6 @@ private: HeadlessTabSocket* headless_tab_socket_; - int main_world_execution_context_id_; }; class SimpleCommandJsBindingsTest : public HeadlessJsBindingsTest {
diff --git a/headless/test/tab_socket_test.cc b/headless/test/tab_socket_test.cc deleted file mode 100644 index e994b59..0000000 --- a/headless/test/tab_socket_test.cc +++ /dev/null
@@ -1,160 +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 "headless/test/tab_socket_test.h" - -#include "headless/public/headless_devtools_client.h" -#include "headless/public/headless_tab_socket.h" - -namespace headless { - -TabSocketTest::TabSocketTest() {} -TabSocketTest::~TabSocketTest() {} - -void TabSocketTest::SetUp() { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessAsyncDevTooledBrowserTest::SetUp(); -} - -void TabSocketTest::RunDevTooledTest() { - devtools_client_->GetRuntime()->AddObserver(this); - devtools_client_->GetRuntime()->Enable(); - // Note we must enable the page domain or the browser won't get told the - // devtools frame ids. - devtools_client_->GetPage()->AddObserver(this); - devtools_client_->GetPage()->Enable( - page::EnableParams::Builder().Build(), - base::Bind(&TabSocketTest::OnPageEnabled, base::Unretained(this))); -} - -void TabSocketTest::OnPageEnabled(std::unique_ptr<page::EnableResult> result) { - devtools_client_->GetPage()->GetExperimental()->GetResourceTree( - page::GetResourceTreeParams::Builder().Build(), - base::Bind(&TabSocketTest::OnResourceTree, base::Unretained(this))); -} - -void TabSocketTest::OnResourceTree( - std::unique_ptr<page::GetResourceTreeResult> result) { - main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); - RunTabSocketTest(); -} - -void TabSocketTest::OnExecutionContextCreated( - const runtime::ExecutionContextCreatedParams& params) { - const base::DictionaryValue* dictionary; - bool is_main_world; - if (params.GetContext()->HasAuxData() && - params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary)) { - if (dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) { - world_name_to_v8_execution_context_id_[params.GetContext()->GetName()] = - params.GetContext()->GetId(); - } - std::string frame_id; - if (dictionary->GetString("frameId", &frame_id)) { - frame_id_to_v8_execution_context_ids_[frame_id].insert( - params.GetContext()->GetId()); - } - } -} - -void TabSocketTest::ExpectJsException( - std::unique_ptr<runtime::EvaluateResult> result) { - EXPECT_TRUE(result->HasExceptionDetails()); - FinishAsynchronousTest(); -} - -void TabSocketTest::FailOnJsEvaluateException( - std::unique_ptr<runtime::EvaluateResult> result) { - if (!result->HasExceptionDetails()) - return; - - FinishAsynchronousTest(); - - const runtime::ExceptionDetails* exception_details = - result->GetExceptionDetails(); - FAIL() << exception_details->GetText() - << (exception_details->HasException() - ? exception_details->GetException()->GetDescription().c_str() - : ""); -} - -bool TabSocketTest::GetAllowTabSockets() { - return true; -} - -int TabSocketTest::GetV8ExecutionContextIdByWorldName(const std::string& name) { - const auto find_it = world_name_to_v8_execution_context_id_.find(name); - if (find_it == world_name_to_v8_execution_context_id_.end()) { - FinishAsynchronousTest(); - CHECK(false) << "Unknown isolated world: " << name; - return -1; - } - return find_it->second; -} - -const std::set<int>* TabSocketTest::GetV8ExecutionContextIdsForFrame( - const std::string& devtools_frame_id) const { - const auto find_it = - frame_id_to_v8_execution_context_ids_.find(devtools_frame_id); - if (find_it == frame_id_to_v8_execution_context_ids_.end()) - return nullptr; - return &find_it->second; -} - -void TabSocketTest::CreateMainWorldTabSocket( - std::string devtools_frame_id, - base::Callback<void(int)> callback) { - const auto find_it = - frame_id_to_v8_execution_context_ids_.find(devtools_frame_id); - CHECK(find_it != frame_id_to_v8_execution_context_ids_.end()); - if (find_it->second.size() != 1u) { - FinishAsynchronousTest(); - FAIL() << "More than one v8 execution context exists for the main frame!"; - } - InstallHeadlessTabSocketBindings(callback, *find_it->second.begin()); -} - -void TabSocketTest::CreateIsolatedWorldTabSocket( - std::string isolated_world_name, - std::string devtools_frame_id, - base::Callback<void(int)> callback) { - devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld( - page::CreateIsolatedWorldParams::Builder() - .SetFrameId(devtools_frame_id) - .SetWorldName(isolated_world_name) - .Build(), - base::Bind(&TabSocketTest::OnCreatedIsolatedWorld, base::Unretained(this), - std::move(callback))); -} - -void TabSocketTest::OnCreatedIsolatedWorld( - base::Callback<void(int)> callback, - std::unique_ptr<page::CreateIsolatedWorldResult> result) { - InstallHeadlessTabSocketBindings(callback, result->GetExecutionContextId()); -} - -void TabSocketTest::InstallHeadlessTabSocketBindings( - base::Callback<void(int)> callback, - int execution_context_id) { - HeadlessTabSocket* tab_socket = web_contents_->GetHeadlessTabSocket(); - CHECK(tab_socket); - tab_socket->InstallHeadlessTabSocketBindings( - execution_context_id, - base::Bind(&TabSocketTest::OnInstalledHeadlessTabSocketBindings, - base::Unretained(this), execution_context_id, - std::move(callback))); -} - -void TabSocketTest::OnInstalledHeadlessTabSocketBindings( - int execution_context_id, - base::Callback<void(int)> callback, - bool success) { - if (!success) { - FinishAsynchronousTest(); - CHECK(false) << "InstallHeadlessTabSocketBindings failed"; - } - callback.Run(execution_context_id); -} - -} // namespace headless
diff --git a/headless/test/tab_socket_test.h b/headless/test/tab_socket_test.h deleted file mode 100644 index da08d56..0000000 --- a/headless/test/tab_socket_test.h +++ /dev/null
@@ -1,91 +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 HEADLESS_TEST_TAB_SOCKET_TEST_H_ -#define HEADLESS_TEST_TAB_SOCKET_TEST_H_ - -#include "headless/public/devtools/domains/page.h" -#include "headless/public/devtools/domains/runtime.h" -#include "headless/public/headless_tab_socket.h" -#include "headless/test/headless_browser_test.h" - -namespace headless { - -class TabSocketTest : public HeadlessAsyncDevTooledBrowserTest, - public headless::HeadlessTabSocket::Listener, - public page::Observer, - public runtime::Observer { - public: - TabSocketTest(); - ~TabSocketTest() override; - - // HeadlessAsyncDevTooledBrowserTest implementation: - void SetUp() override; - void RunDevTooledTest() override; - bool GetAllowTabSockets() override; - - // runtime::Observer implementation: - void OnExecutionContextCreated( - const runtime::ExecutionContextCreatedParams& params) override; - - void ExpectJsException(std::unique_ptr<runtime::EvaluateResult> result); - - void FailOnJsEvaluateException( - std::unique_ptr<runtime::EvaluateResult> result); - - // Note this will fail the test if an execution context corresponding to - // |name| doesn't exist. - int GetV8ExecutionContextIdByWorldName(const std::string& name); - - // Returns a pointer to the set of v8 execution context ids corresponding to - // |devtools_frame_id| or null if none exist. - const std::set<int>* GetV8ExecutionContextIdsForFrame( - const std::string& devtools_frame_id) const; - - // Attempts to install a main world TabSocket in |devtools_frame_id|. - // If successful |callback| will run with the execution context id of the - // main world tab socket. - void CreateMainWorldTabSocket(std::string devtools_frame_id, - base::Callback<void(int)> callback); - - // Attempts to create an isolated world in |isolated_world_name| and then - // install a world TabSocket. If successful |callback| will run with the - // execution context id of the newly created isolated world as a parameter. - // Note |isolated_world_name| must be unique. - void CreateIsolatedWorldTabSocket(std::string isolated_world_name, - std::string devtools_frame_id, - base::Callback<void(int)> callback); - - virtual void RunTabSocketTest() = 0; - - const std::string& main_frame_id() const { return *main_frame_id_; } - - private: - void OnPageEnabled(std::unique_ptr<page::EnableResult> result); - - void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result); - - void CreateMainWorldTabSocketStep2(std::string devtools_frame_id, - base::Callback<void(int)> callback, - int v8_execution_context_id); - - void OnCreatedIsolatedWorld( - base::Callback<void(int)> callback, - std::unique_ptr<page::CreateIsolatedWorldResult> result); - - void InstallHeadlessTabSocketBindings(base::Callback<void(int)> callback, - int execution_context_id); - - void OnInstalledHeadlessTabSocketBindings(int execution_context_id, - base::Callback<void(int)> callback, - bool success); - - std::map<std::string, int> world_name_to_v8_execution_context_id_; - std::map<std::string, std::set<int>> frame_id_to_v8_execution_context_ids_; - base::Optional<std::string> main_frame_id_; -}; - -} // namespace headless - -#endif // HEADLESS_TEST_TAB_SOCKET_TEST_H_
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index 6e0bde12a..4fd031ab 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg
@@ -78,10 +78,6 @@ builders { name: "ios-simulator-xcode-clang" } builders { name: "mac_chromium_compile_dbg_ng" } builders { name: "mac_chromium_rel_ng" } - builders { - name: "mac_chromium_10.10_rel_ng" - experiment_percentage: 10 - } } buckets { name: "master.tryserver.chromium.win"
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 013a617..4f2bb8c 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -286,6 +286,15 @@ if ([defaults boolForKey:@"RequestMobileSiteDisabled"]) command_line->AppendSwitch(switches::kDisableRequestMobileSite); + // Populate command line flag for 3rd party keyboard omnibox workaround. + NSString* enableThirdPartyKeyboardWorkaround = + [defaults stringForKey:@"EnableThirdPartyKeyboardWorkaround"]; + if ([enableThirdPartyKeyboardWorkaround isEqualToString:@"Enabled"]) { + command_line->AppendSwitch(switches::kEnableThirdPartyKeyboardWorkaround); + } else if ([enableThirdPartyKeyboardWorkaround isEqualToString:@"Disabled"]) { + command_line->AppendSwitch(switches::kDisableThirdPartyKeyboardWorkaround); + } + ios::GetChromeBrowserProvider()->AppendSwitchesFromExperimentalSettings( defaults, command_line); }
diff --git a/ios/chrome/browser/bookmarks/bookmarks_utils.cc b/ios/chrome/browser/bookmarks/bookmarks_utils.cc index a7ece33..82a8036 100644 --- a/ios/chrome/browser/bookmarks/bookmarks_utils.cc +++ b/ios/chrome/browser/bookmarks/bookmarks_utils.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/prefs/pref_service.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" @@ -72,11 +73,7 @@ bool IsPrimaryPermanentNode(const BookmarkNode* node, BookmarkModel* model) { std::vector<const BookmarkNode*> primary_nodes(PrimaryPermanentNodes(model)); - if (std::find(primary_nodes.begin(), primary_nodes.end(), node) != - primary_nodes.end()) { - return true; - } - return false; + return base::ContainsValue(primary_nodes, node); } const BookmarkNode* RootLevelFolderForNode(const BookmarkNode* node, @@ -88,9 +85,7 @@ const std::vector<const BookmarkNode*> root_folders(RootLevelFolders(model)); const BookmarkNode* top = node; - while (top && - std::find(root_folders.begin(), root_folders.end(), top) == - root_folders.end()) { + while (top && !base::ContainsValue(root_folders, top)) { top = top->parent(); } return top;
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc index e51438b..ac7a0df 100644 --- a/ios/chrome/browser/chrome_switches.cc +++ b/ios/chrome/browser/chrome_switches.cc
@@ -59,6 +59,10 @@ // Disables the WKBackForwardList based navigation manager experiment. const char kDisableSlimNavigationManager[] = "disable-slim-navigation-manager"; +// Disables the 3rd party keyboard omnibox workaround. +const char kDisableThirdPartyKeyboardWorkaround[] = + "disable-third-party-keyboard-workaround"; + // Enables Contextual Search. const char kEnableContextualSearch[] = "enable-contextual-search"; @@ -105,6 +109,10 @@ // Enables the WKBackForwardList based navigation manager experiment. const char kEnableSlimNavigationManager[] = "enable-slim-navigation-manager"; +// Enables the 3rd party keyboard omnibox workaround. +const char kEnableThirdPartyKeyboardWorkaround[] = + "enable-third-party-keyboard-workaround"; + // Forces additional Chrome Variation Ids that will be sent in X-Client-Data // header, specified as a 64-bit encoded list of numeric experiment ids. Ids // prefixed with the character "t" will be treated as Trigger Variation Ids.
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h index f5f681a..8a6db57c0 100644 --- a/ios/chrome/browser/chrome_switches.h +++ b/ios/chrome/browser/chrome_switches.h
@@ -24,6 +24,7 @@ extern const char kDisableSuggestionsUI[]; extern const char kDisableBookmarkReordering[]; extern const char kDisableSlimNavigationManager[]; +extern const char kDisableThirdPartyKeyboardWorkaround[]; extern const char kEnableContextualSearch[]; extern const char kEnableIOSFastWebScrollViewInsets[]; @@ -40,6 +41,7 @@ extern const char kEnableSuggestionsUI[]; extern const char kEnableBookmarkReordering[]; extern const char kEnableSlimNavigationManager[]; +extern const char kEnableThirdPartyKeyboardWorkaround[]; extern const char kIOSForceVariationIds[]; extern const char kUserAgent[];
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index 6f1800d..39c28ce 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -112,6 +112,9 @@ // Whether the WKBackForwardList based navigation manager is enabled. bool IsSlimNavigationManagerEnabled(); +// Whether the 3rd party keyboard omnibox workaround is enabled. +bool IsThirdPartyKeyboardWorkaroundEnabled(); + } // namespace experimental_flags #endif // IOS_CHROME_BROWSER_EXPERIMENTAL_FLAGS_H_
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index 3880c977..c7760afd 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -44,6 +44,8 @@ NSString* const kWhatsNewPromoStatus = @"WhatsNewPromoStatus"; const base::Feature kEnableSlimNavigationManager{ "EnableSlimNavigationManager", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kEnableThirdPartyKeyboardWorkaround{ + "EnableThirdPartyKeyboardWorkaround", base::FEATURE_ENABLED_BY_DEFAULT}; } // namespace @@ -287,8 +289,8 @@ } bool IsKeyboardAccessoryViewWithCameraSearchEnabled() { - return [[NSUserDefaults standardUserDefaults] - boolForKey:@"NewKeyboardAccessoryViewEnabled"]; + return ![[NSUserDefaults standardUserDefaults] + boolForKey:@"NewKeyboardAccessoryViewDisabled"]; } bool IsSlimNavigationManagerEnabled() { @@ -304,4 +306,18 @@ return base::FeatureList::IsEnabled(kEnableSlimNavigationManager); } +bool IsThirdPartyKeyboardWorkaroundEnabled() { + // Check if the experimental flag is forced on or off. + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnableThirdPartyKeyboardWorkaround)) { + return true; + } else if (command_line->HasSwitch( + switches::kDisableThirdPartyKeyboardWorkaround)) { + return false; + } + + // Check if the Finch experiment is turned on. + return base::FeatureList::IsEnabled(kEnableThirdPartyKeyboardWorkaround); +} + } // namespace experimental_flags
diff --git a/ios/chrome/browser/interstitials/ios_chrome_controller_client.h b/ios/chrome/browser/interstitials/ios_chrome_controller_client.h index d508f06..8ff52e18 100644 --- a/ios/chrome/browser/interstitials/ios_chrome_controller_client.h +++ b/ios/chrome/browser/interstitials/ios_chrome_controller_client.h
@@ -42,6 +42,7 @@ void Proceed() override; void Reload() override; void OpenUrlInCurrentTab(const GURL& url) override; + void OpenUrlInNewForegroundTab(const GURL& url) override; const std::string& GetApplicationLocale() const override; PrefService* GetPrefService() override; const std::string GetExtendedReportingPrefName() const override;
diff --git a/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm b/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm index 1df9dc0..2978808 100644 --- a/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm +++ b/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm
@@ -69,6 +69,12 @@ ui::PAGE_TRANSITION_LINK, false)); } +void IOSChromeControllerClient::OpenUrlInNewForegroundTab(const GURL& url) { + web_state_->OpenURL(web::WebState::OpenURLParams( + url, web::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_LINK, false)); +} + const std::string& IOSChromeControllerClient::GetApplicationLocale() const { return GetApplicationContext()->GetApplicationLocale(); }
diff --git a/ios/chrome/browser/passwords/password_generation_agent.mm b/ios/chrome/browser/passwords/password_generation_agent.mm index 57790216..53248e82 100644 --- a/ios/chrome/browser/passwords/password_generation_agent.mm +++ b/ios/chrome/browser/passwords/password_generation_agent.mm
@@ -8,6 +8,7 @@ #include "base/mac/foundation_util.h" #include "base/mac/scoped_block.h" +#include "base/stl_util.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/password_generator.h" @@ -42,11 +43,6 @@ // an account creation form. const size_t kMinimumTextFieldsForAccountCreation = 3; -// Returns true if |urls| contains |url|. -bool VectorContainsURL(const std::vector<GURL>& urls, const GURL& url) { - return std::find(urls.begin(), urls.end(), url) != urls.end(); -} - // Returns whether |field| should be considered a text field. Implementation // mirrors that of password_controller.js. // TODO(crbug.com/433856): Figure out how to determine if |field| is visible. @@ -292,7 +288,7 @@ // password manager, wait. GURL origin = _possibleAccountCreationForm->origin; if (!experimental_flags::UseOnlyLocalHeuristicsForPasswordGeneration()) { - if (!VectorContainsURL(_allowedGenerationFormOrigins, origin)) + if (!base::ContainsValue(_allowedGenerationFormOrigins, origin)) return; }
diff --git a/ios/chrome/browser/payments/BUILD.gn b/ios/chrome/browser/payments/BUILD.gn index b0521bc..d98a6d1 100644 --- a/ios/chrome/browser/payments/BUILD.gn +++ b/ios/chrome/browser/payments/BUILD.gn
@@ -35,6 +35,7 @@ ":payments", ":test_support", "//base", + "//base/test:test_support", "//components/autofill/core/browser", "//components/autofill/core/browser:test_support", "//components/payments/core",
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h index bbbd8bb8..f2a70a8 100644 --- a/ios/chrome/browser/payments/payment_request.h +++ b/ios/chrome/browser/payments/payment_request.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "components/payments/core/payment_options_provider.h" +#include "components/payments/core/payment_request_base_delegate.h" #include "components/payments/core/payments_profile_comparator.h" #include "ios/web/public/payments/payment_request.h" @@ -23,24 +24,49 @@ } // namespace autofill namespace payments { +class AddressNormalizer; +class AddressNormalizerImpl; class CurrencyFormatter; } // namespace payments +// A protocol implementd by any UI classes that the PaymentRequest object +// needs to communicate with in order to perform certain actions such as +// initiating UI to request full card details for payment. +@protocol PaymentRequestUIDelegate<NSObject> + +- (void)openFullCardRequestUI; + +@end + // Has a copy of web::PaymentRequest as provided by the page invoking the // PaymentRequest API. Also caches credit cards and addresses provided by the // |personal_data_manager| and manages shared resources and user selections for // the current PaymentRequest flow. It must be initialized with a non-null // instance of |personal_data_manager| that outlives this class. -class PaymentRequest : public payments::PaymentOptionsProvider { +class PaymentRequest : public payments::PaymentOptionsProvider, + public payments::PaymentRequestBaseDelegate { public: // |personal_data_manager| should not be null and should outlive this object. PaymentRequest(const web::PaymentRequest& web_payment_request, - autofill::PersonalDataManager* personal_data_manager); + autofill::PersonalDataManager* personal_data_manager, + id<PaymentRequestUIDelegate> payment_request_ui_delegate); ~PaymentRequest() override; - autofill::PersonalDataManager* GetPersonalDataManager() const { - return personal_data_manager_; - } + // PaymentRequestBaseDelegate: + autofill::PersonalDataManager* GetPersonalDataManager() override; + const std::string& GetApplicationLocale() const override; + bool IsIncognito() const override; + bool IsSslCertificateValid() override; + const GURL& GetLastCommittedURL() const override; + void DoFullCardRequest( + const autofill::CreditCard& credit_card, + base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> + result_delegate) override; + payments::AddressNormalizer* GetAddressNormalizer() override; + autofill::RegionDataLoader* GetRegionDataLoader() override; + ukm::UkmRecorder* GetUkmRecorder() override; + std::string GetAuthenticatedEmail() const override; + PrefService* GetPrefService() override; // Returns the web::PaymentRequest that was used to build this PaymentRequest. const web::PaymentRequest& web_payment_request() const { @@ -69,9 +95,6 @@ // hence the CurrencyFormatter is cached here. payments::CurrencyFormatter* GetOrCreateCurrencyFormatter(); - // Returns the autofill::RegionDataLoader instance for this PaymentRequest. - virtual autofill::RegionDataLoader* GetRegionDataLoader(); - // Adds |profile| to the list of cached profiles, updates the list of // available shipping and contact profiles, and returns a reference to the // cached copy of |profile|. @@ -197,6 +220,13 @@ // Never null and outlives this object. autofill::PersonalDataManager* personal_data_manager_; + // The PaymentRequestUIDelegate as provided by the UI object that originally + // created this PaymentRequest object. + __weak id<PaymentRequestUIDelegate> payment_request_ui_delegate_; + + // The address normalizer to use for the duration of the Payment Request. + payments::AddressNormalizerImpl* address_normalizer_; + // The currency formatter instance for this PaymentRequest flow. std::unique_ptr<payments::CurrencyFormatter> currency_formatter_;
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm index 137feb8..21c3ef5 100644 --- a/ios/chrome/browser/payments/payment_request.mm +++ b/ios/chrome/browser/payments/payment_request.mm
@@ -8,6 +8,7 @@ #include "base/containers/adapters.h" #include "base/memory/ptr_util.h" +#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_profile.h" @@ -15,6 +16,7 @@ #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/region_data_loader_impl.h" #include "components/autofill/core/browser/validation.h" +#include "components/payments/core/address_normalizer_impl.h" #include "components/payments/core/currency_formatter.h" #include "components/payments/core/payment_request_data_util.h" #include "ios/chrome/browser/application_context.h" @@ -46,9 +48,15 @@ PaymentRequest::PaymentRequest( const web::PaymentRequest& web_payment_request, - autofill::PersonalDataManager* personal_data_manager) + autofill::PersonalDataManager* personal_data_manager, + id<PaymentRequestUIDelegate> payment_request_ui_delegate) : web_payment_request_(web_payment_request), personal_data_manager_(personal_data_manager), + payment_request_ui_delegate_(payment_request_ui_delegate), + address_normalizer_(new payments::AddressNormalizerImpl( + GetAddressInputSource( + personal_data_manager_->GetURLRequestContextGetter()), + GetAddressInputStorage())), selected_shipping_profile_(nullptr), selected_contact_profile_(nullptr), selected_credit_card_(nullptr), @@ -92,6 +100,66 @@ PaymentRequest::~PaymentRequest() {} +autofill::PersonalDataManager* PaymentRequest::GetPersonalDataManager() { + return personal_data_manager_; +} + +const std::string& PaymentRequest::GetApplicationLocale() const { + return GetApplicationContext()->GetApplicationLocale(); +} + +bool PaymentRequest::IsIncognito() const { + NOTREACHED() << "Implementation is never used"; + return false; +} + +bool PaymentRequest::IsSslCertificateValid() { + NOTREACHED() << "Implementation is never used"; + return false; +} + +const GURL& PaymentRequest::GetLastCommittedURL() const { + NOTREACHED() << "Implementation is never used"; + return GURL::EmptyGURL(); +} + +void PaymentRequest::DoFullCardRequest( + const autofill::CreditCard& credit_card, + base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> + result_delegate) { + // TODO: In the follow-up CL openFullCardRequestUI will take in arguments, + // specifically the |result_delegate| to be used in the + // |payment_request_ui_delegate_| object. + [payment_request_ui_delegate_ openFullCardRequestUI]; +} + +payments::AddressNormalizer* PaymentRequest::GetAddressNormalizer() { + return address_normalizer_; +} + +autofill::RegionDataLoader* PaymentRequest::GetRegionDataLoader() { + return new autofill::RegionDataLoaderImpl( + GetAddressInputSource( + personal_data_manager_->GetURLRequestContextGetter()) + .release(), + GetAddressInputStorage().release(), + GetApplicationContext()->GetApplicationLocale()); +} + +ukm::UkmRecorder* PaymentRequest::GetUkmRecorder() { + return GetApplicationContext()->GetUkmRecorder(); +} + +std::string PaymentRequest::GetAuthenticatedEmail() const { + NOTREACHED() << "Implementation is never used"; + return std::string(); +} + +PrefService* PaymentRequest::GetPrefService() { + NOTREACHED() << "Implementation is never used"; + return nullptr; +} + void PaymentRequest::UpdatePaymentDetails(const web::PaymentDetails& details) { web_payment_request_.details = details; PopulateAvailableShippingOptions(); @@ -129,15 +197,6 @@ return currency_formatter_.get(); } -autofill::RegionDataLoader* PaymentRequest::GetRegionDataLoader() { - return new autofill::RegionDataLoaderImpl( - GetAddressInputSource( - personal_data_manager_->GetURLRequestContextGetter()) - .release(), - GetAddressInputStorage().release(), - GetApplicationContext()->GetApplicationLocale()); -} - autofill::AutofillProfile* PaymentRequest::AddAutofillProfile( const autofill::AutofillProfile& profile) { profile_cache_.push_back( @@ -231,9 +290,7 @@ std::string spec_issuer_network = autofill::data_util::GetPaymentRequestData(credit_card->network()) .basic_card_issuer_network; - if (std::find(supported_card_networks_.begin(), - supported_card_networks_.end(), - spec_issuer_network) != supported_card_networks_.end()) { + if (base::ContainsValue(supported_card_networks_, spec_issuer_network)) { credit_card_cache_.push_back( base::MakeUnique<autofill::CreditCard>(*credit_card)); }
diff --git a/ios/chrome/browser/payments/payment_request_unittest.mm b/ios/chrome/browser/payments/payment_request_unittest.mm index 0ce80550..a63ce95e 100644 --- a/ios/chrome/browser/payments/payment_request_unittest.mm +++ b/ios/chrome/browser/payments/payment_request_unittest.mm
@@ -5,6 +5,7 @@ #include "ios/chrome/browser/payments/payment_request.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/field_types.h" @@ -13,6 +14,7 @@ #include "components/payments/core/payment_method_data.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #include "ios/web/public/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -46,6 +48,8 @@ options.request_shipping = request_shipping; return options; } + + base::test::ScopedTaskEnvironment scoped_task_environment_; }; // Tests that the payments::CurrencyFormatter is constructed with the correct @@ -57,14 +61,16 @@ autofill::TestPersonalDataManager personal_data_manager; web_payment_request.details.total.amount.currency = base::ASCIIToUTF16("USD"); - PaymentRequest payment_request1(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request1(web_payment_request, + &personal_data_manager); payments::CurrencyFormatter* currency_formatter = payment_request1.GetOrCreateCurrencyFormatter(); EXPECT_EQ(base::UTF8ToUTF16("$55.00"), currency_formatter->Format("55.00")); EXPECT_EQ("USD", currency_formatter->formatted_currency_code()); web_payment_request.details.total.amount.currency = base::ASCIIToUTF16("JPY"); - PaymentRequest payment_request2(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request2(web_payment_request, + &personal_data_manager); currency_formatter = payment_request2.GetOrCreateCurrencyFormatter(); EXPECT_EQ(base::UTF8ToUTF16("¥55"), currency_formatter->Format("55.00")); EXPECT_EQ("JPY", currency_formatter->formatted_currency_code()); @@ -72,7 +78,8 @@ web_payment_request.details.total.amount.currency_system = base::ASCIIToUTF16("NOT_ISO4217"); web_payment_request.details.total.amount.currency = base::ASCIIToUTF16("USD"); - PaymentRequest payment_request3(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request3(web_payment_request, + &personal_data_manager); currency_formatter = payment_request3.GetOrCreateCurrencyFormatter(); EXPECT_EQ(base::UTF8ToUTF16("55.00"), currency_formatter->Format("55.00")); EXPECT_EQ("USD", currency_formatter->formatted_currency_code()); @@ -90,7 +97,8 @@ method_datum2.supported_methods.push_back("mastercard"); web_payment_request.method_data.push_back(method_datum2); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); ASSERT_EQ(2U, payment_request.supported_card_networks().size()); EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); @@ -110,7 +118,8 @@ method_datum1.supported_methods.push_back("visa"); web_payment_request.method_data.push_back(method_datum1); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); ASSERT_EQ(2U, payment_request.supported_card_networks().size()); EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); @@ -135,7 +144,8 @@ method_datum4.supported_methods.push_back("visa"); web_payment_request.method_data.push_back(method_datum4); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); ASSERT_EQ(2U, payment_request.supported_card_networks().size()); EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); @@ -150,7 +160,8 @@ method_datum1.supported_methods.push_back("basic-card"); web_payment_request.method_data.push_back(method_datum1); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); // All of the basic card networks are supported. ASSERT_EQ(8U, payment_request.supported_card_networks().size()); @@ -175,7 +186,8 @@ method_datum1.supported_methods.push_back("basic-card"); web_payment_request.method_data.push_back(method_datum1); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); // All of the basic card networks are supported, but JCB is first because it // was specified first. @@ -207,7 +219,8 @@ method_datum2.supported_networks.push_back("unionpay"); web_payment_request.method_data.push_back(method_datum2); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(3u, payment_request.supported_card_networks().size()); EXPECT_EQ("mastercard", payment_request.supported_card_networks()[0]); @@ -227,7 +240,8 @@ method_datum1.supported_networks.push_back("unionpay"); web_payment_request.method_data.push_back(method_datum1); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); // Only the specified networks are supported. EXPECT_EQ(2u, payment_request.supported_card_networks().size()); @@ -249,7 +263,8 @@ autofill::CreditCard credit_card_1 = autofill::test::GetCreditCard(); personal_data_manager.AddTestingCreditCard(&credit_card_1); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(1U, payment_request.credit_cards().size()); autofill::CreditCard credit_card_2 = autofill::test::GetCreditCard2(); @@ -272,7 +287,8 @@ autofill::AutofillProfile profile_1 = autofill::test::GetFullProfile(); personal_data_manager.AddTestingProfile(&profile_1); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(1U, payment_request.shipping_profiles().size()); EXPECT_EQ(1U, payment_request.contact_profiles().size()); @@ -307,7 +323,8 @@ details.shipping_options = std::move(shipping_options); web_payment_request.details = std::move(details); - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); // The last one marked "selected" should be selected. EXPECT_EQ(base::UTF8ToUTF16("option:3"), payment_request.selected_shipping_option()->id); @@ -329,7 +346,8 @@ /*request_payer_email=*/true, /*request_shipping=*/true); // No profiles are selected because none are available! - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(nullptr, payment_request.selected_shipping_profile()); EXPECT_EQ(nullptr, payment_request.selected_contact_profile()); } @@ -351,7 +369,8 @@ /*request_payer_email=*/true, /*request_shipping=*/true); // address2 is selected because it has the most use count (Frecency model). - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(address2.guid(), payment_request.selected_shipping_profile()->guid()); EXPECT_EQ(address2.guid(), @@ -375,7 +394,8 @@ // No shipping profile is selected because the merchant has not selected a // shipping option. However there is a suitable contact profile. - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(nullptr, payment_request.selected_shipping_profile()); EXPECT_EQ(address.guid(), payment_request.selected_contact_profile()->guid()); } @@ -402,7 +422,8 @@ // Even though address1 has more use counts, address2 is selected because it // is complete. - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(address2.guid(), payment_request.selected_shipping_profile()->guid()); EXPECT_EQ(address2.guid(), @@ -437,7 +458,8 @@ // still selected as the contact profile because merchant doesn't require // phone. address2 is selected as the shipping profile because it's the most // complete for shipping. - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(address2.guid(), payment_request.selected_shipping_profile()->guid()); EXPECT_EQ(address1.guid(), @@ -451,7 +473,8 @@ payment_request_test_util::CreateTestWebPaymentRequest(); // No payment methods are selected because none are available! - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(nullptr, payment_request.selected_credit_card()); } @@ -469,7 +492,8 @@ payment_request_test_util::CreateTestWebPaymentRequest(); // credit_card is selected because expired cards are valid for payment. - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(credit_card.guid(), payment_request.selected_credit_card()->guid()); } @@ -492,7 +516,8 @@ // credit_card2 is selected because it has the most use count (Frecency // model). - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(credit_card2.guid(), payment_request.selected_credit_card()->guid()); } @@ -515,6 +540,7 @@ // Even though credit_card2 has more use counts, credit_card is selected // because it is complete. - PaymentRequest payment_request(web_payment_request, &personal_data_manager); + TestPaymentRequest payment_request(web_payment_request, + &personal_data_manager); EXPECT_EQ(credit_card.guid(), payment_request.selected_credit_card()->guid()); }
diff --git a/ios/chrome/browser/payments/test_payment_request.h b/ios/chrome/browser/payments/test_payment_request.h index 1ced6fb..b86f5889 100644 --- a/ios/chrome/browser/payments/test_payment_request.h +++ b/ios/chrome/browser/payments/test_payment_request.h
@@ -27,11 +27,18 @@ public: // |personal_data_manager| should not be null and should outlive this object. TestPaymentRequest(const web::PaymentRequest& web_payment_request, - autofill::PersonalDataManager* personal_data_manager) - : PaymentRequest(web_payment_request, personal_data_manager), + autofill::PersonalDataManager* personal_data_manager, + id<PaymentRequestUIDelegate> payment_request_ui_delegate) + : PaymentRequest(web_payment_request, + personal_data_manager, + payment_request_ui_delegate), region_data_loader_(nullptr), profile_comparator_(nullptr) {} + TestPaymentRequest(const web::PaymentRequest& web_payment_request, + autofill::PersonalDataManager* personal_data_manager) + : TestPaymentRequest(web_payment_request, personal_data_manager, nil) {} + ~TestPaymentRequest() override {} void SetRegionDataLoader(autofill::RegionDataLoader* region_data_loader) {
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc index d87f47e..c1ae2c06 100644 --- a/ios/chrome/browser/pref_names.cc +++ b/ios/chrome/browser/pref_names.cc
@@ -69,6 +69,11 @@ const char kIosBookmarkSigninPromoDisplayedCount[] = "ios.bookmark.signin_promo_displayed_count"; +// Integer to represent the number of time the sign-in promo has been displayed +// in the settings view. +const char kIosSettingsSigninPromoDisplayedCount[] = + "ios.settings.signin_promo_displayed_count"; + // Whether the user has enabled the Physical Web feature to surface URLs // broadcast by nearby devices. const char kIosPhysicalWebEnabled[] = "ios.physical_web_enabled";
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h index 11f3e98..110ffae 100644 --- a/ios/chrome/browser/pref_names.h +++ b/ios/chrome/browser/pref_names.h
@@ -23,6 +23,7 @@ extern const char kIosBookmarkFolderDefault[]; extern const char kIosBookmarkPromoAlreadySeen[]; extern const char kIosBookmarkSigninPromoDisplayedCount[]; +extern const char kIosSettingsSigninPromoDisplayedCount[]; extern const char kIosPhysicalWebEnabled[]; extern const char kLastSessionExitedCleanly[]; extern const char kMetricsReportingWifiOnly[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index 222347f..b30fc9e2 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -126,6 +126,8 @@ [BookmarkInteractionController registerBrowserStatePrefs:registry]; [BookmarkPromoController registerBrowserStatePrefs:registry]; [HandoffManager registerBrowserStatePrefs:registry]; + registry->RegisterIntegerPref(prefs::kIosSettingsSigninPromoDisplayedCount, + 0); registry->RegisterBooleanPref(prefs::kDataSaverEnabled, false); registry->RegisterBooleanPref(
diff --git a/ios/chrome/browser/reading_list/url_downloader.cc b/ios/chrome/browser/reading_list/url_downloader.cc index 35c09342..ddf99e64 100644 --- a/ios/chrome/browser/reading_list/url_downloader.cc +++ b/ios/chrome/browser/reading_list/url_downloader.cc
@@ -11,6 +11,7 @@ #include "base/files/file_util.h" #include "base/memory/ptr_util.h" #include "base/path_service.h" +#include "base/stl_util.h" #include "components/reading_list/core/offline_url_utils.h" #include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/dom_distiller/distiller_viewer.h" @@ -80,8 +81,7 @@ } void URLDownloader::DownloadOfflineURL(const GURL& url) { - if (std::find(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)) == - tasks_.end()) { + if (!base::ContainsValue(tasks_, std::make_pair(DOWNLOAD, url))) { tasks_.push_back(std::make_pair(DOWNLOAD, url)); HandleNextTask(); }
diff --git a/ios/chrome/browser/reading_list/url_downloader_unittest.mm b/ios/chrome/browser/reading_list/url_downloader_unittest.mm index b6090b6..6905af9 100644 --- a/ios/chrome/browser/reading_list/url_downloader_unittest.mm +++ b/ios/chrome/browser/reading_list/url_downloader_unittest.mm
@@ -10,6 +10,7 @@ #import "base/mac/bind_objc_block.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/stl_util.h" #import "base/test/ios/wait_util.h" #include "components/reading_list/core/offline_url_utils.h" #include "ios/chrome/browser/chrome_paths.h" @@ -168,9 +169,7 @@ downloader_->DownloadOfflineURL(url); WaitUntilCondition(^bool { - return std::find(downloader_->downloaded_files_.begin(), - downloader_->downloaded_files_.end(), - url) != downloader_->downloaded_files_.end(); + return base::ContainsValue(downloader_->downloaded_files_, url); }); ASSERT_TRUE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); @@ -189,9 +188,7 @@ downloader_->DownloadOfflineURL(url); WaitUntilCondition(^bool { - return std::find(downloader_->downloaded_files_.begin(), - downloader_->downloaded_files_.end(), - url) != downloader_->downloaded_files_.end(); + return base::ContainsValue(downloader_->downloaded_files_, url); }); EXPECT_TRUE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); @@ -229,14 +226,10 @@ downloader_->FakeEndWorking(); WaitUntilCondition(^bool { - return std::find(downloader_->removed_files_.begin(), - downloader_->removed_files_.end(), - url) != downloader_->removed_files_.end(); + return base::ContainsValue(downloader_->removed_files_, url); }); - ASSERT_TRUE(std::find(downloader_->downloaded_files_.begin(), - downloader_->downloaded_files_.end(), - url) == downloader_->downloaded_files_.end()); + ASSERT_TRUE(!base::ContainsValue(downloader_->downloaded_files_, url)); ASSERT_EQ(1ul, downloader_->downloaded_files_.size()); ASSERT_EQ(1ul, downloader_->removed_files_.size()); ASSERT_FALSE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); @@ -253,17 +246,11 @@ downloader_->FakeEndWorking(); WaitUntilCondition(^bool { - return std::find(downloader_->removed_files_.begin(), - downloader_->removed_files_.end(), - url) != downloader_->removed_files_.end(); + return base::ContainsValue(downloader_->removed_files_, url); }); - ASSERT_TRUE(std::find(downloader_->downloaded_files_.begin(), - downloader_->downloaded_files_.end(), - url) != downloader_->downloaded_files_.end()); - ASSERT_TRUE(std::find(downloader_->removed_files_.begin(), - downloader_->removed_files_.end(), - url) != downloader_->removed_files_.end()); + ASSERT_TRUE(base::ContainsValue(downloader_->downloaded_files_, url)); + ASSERT_TRUE(base::ContainsValue(downloader_->removed_files_, url)); ASSERT_TRUE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); }
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist index 4176a698..a666936 100644 --- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist +++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -436,9 +436,9 @@ <key>Type</key> <string>PSToggleSwitchSpecifier</string> <key>Title</key> - <string>Enabled New Keyboard Accessory View</string> + <string>Disable New Keyboard Accessory View</string> <key>Key</key> - <string>NewKeyboardAccessoryViewEnabled</string> + <string>NewKeyboardAccessoryViewDisabled</string> <key>DefaultValue</key> <false/> </dict>
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm index 11e140d..9e4992c 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/mac/bind_objc_block.h" #include "base/mac/foundation_util.h" +#include "base/stl_util.h" #include "base/strings/sys_string_conversions.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_model_observer.h" @@ -468,9 +469,7 @@ } // A subfolder's children changed. Reload that cell. - std::vector<const BookmarkNode*>::iterator it = - std::find(_subFolders.begin(), _subFolders.end(), bookmarkNode); - if (it != _subFolders.end()) { + if (base::ContainsValue(_subFolders, bookmarkNode)) { // TODO(crbug.com/603661): Ideally, we would only reload the relevant index // path. However, calling reloadItemsAtIndexPaths:(0,0) immediately after // reloadData results in a exception: NSInternalInconsistencyException
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm index 2be9472a..a50fcfd5 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -14,7 +14,9 @@ #include "base/strings/sys_string_conversions.h" #include "components/grit/components_scaled_resources.h" #include "components/omnibox/browser/autocomplete_input.h" +#include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/ui/animation_util.h" #include "ios/chrome/browser/ui/omnibox/omnibox_util.h" #import "ios/chrome/browser/ui/reversed_animation.h" @@ -458,7 +460,30 @@ [self clearAutocompleteText]; } - self.attributedText = fieldText; + // The following BOOL was introduced to workaround a UIKit bug + // (crbug.com/737589, rdar/32817402). The bug relates to third party keyboards + // that check the value of textDocumentProxy.documentContextBeforeInput to + // show keyboard suggestions. It appears that calling setAttributedText during + // an EditingChanged UIControlEvent somehow triggers this bug. The reason we + // update the attributed text here is to change the colors of the omnibox + // (such as host, protocol) when !self.editing, but also to hide real + // UITextField text under the _selection text when self.editing. Since we will + // correct the omnibox editing text color anytime |self.text| is different + // than |fieldText|, it seems it's OK to skip calling self.attributedText + // during the condition added below. If we change mobile omnibox to match + // desktop and also color the omnibox while self.editing, this workaround will + // no longer work. + BOOL updateText = YES; + // Before M61 branch point this should also go behind a Japanese flag, e.g. + // [self.textInputMode.primaryLanguage isEqualToString:@"ja-JP"] to be as + // restrictive as possible. + if (experimental_flags::IsThirdPartyKeyboardWorkaroundEnabled()) { + updateText = + (!self.editing || ![self.text isEqualToString:fieldText.string]); + } + if (updateText) { + self.attributedText = fieldText; + } // iOS changes the font to .LastResort when some unexpected unicode strings // are used (e.g. 𝗲𝗺𝗽𝗵𝗮𝘀𝗶𝘀). Setting the NSFontAttributeName in the
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn index 6ee8b40..c3ee0dba 100644 --- a/ios/chrome/browser/ui/payments/BUILD.gn +++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -157,6 +157,7 @@ "contact_info_selection_mediator_unittest.mm", "country_selection_coordinator_unittest.mm", "credit_card_edit_coordinator_unittest.mm", + "full_card_requester_unittest.mm", "payment_items_display_coordinator_unittest.mm", "payment_items_display_view_controller_unittest.mm", "payment_method_selection_coordinator_unittest.mm", @@ -178,13 +179,16 @@ "//base/test:test_support", "//components/autofill/core/browser", "//components/autofill/core/browser:test_support", + "//components/autofill/ios/browser", "//components/payments/core", "//components/prefs:prefs", "//components/signin/core/browser", "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser", + "//ios/chrome/browser/autofill:autofill_internal", "//ios/chrome/browser/browser_state:test_support", + "//ios/chrome/browser/infobars", "//ios/chrome/browser/payments", "//ios/chrome/browser/payments:test_support", "//ios/chrome/browser/signin", @@ -196,6 +200,7 @@ "//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/browser/ui/collection_view/cells:test_support", "//ios/chrome/browser/ui/payments/cells", + "//ios/chrome/browser/web:test_support", "//ios/chrome/test:test_support", "//ios/testing:ocmock_support", "//ios/third_party/material_components_ios",
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm index 7d39c51c..bc7aa98 100644 --- a/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/country_names.h" @@ -122,6 +123,8 @@ personal_data_manager_.SetTestingPrefService(nullptr); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + std::unique_ptr<PrefService> pref_service_; MockTestPersonalDataManager personal_data_manager_; autofill::TestRegionDataLoader test_region_data_loader_;
diff --git a/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm b/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm index 271335e..3335c86 100644 --- a/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm
@@ -83,7 +83,7 @@ #pragma mark - PaymentRequestSelectorViewControllerDelegate -- (void)paymentRequestSelectorViewController: +- (BOOL)paymentRequestSelectorViewController: (PaymentRequestSelectorViewController*)controller didSelectItemAtIndex:(NSUInteger)index { CollectionViewItem<PaymentsIsSelectable>* selectedItem = @@ -99,8 +99,10 @@ // Update the data source with the selection. self.mediator.selectedItemIndex = index; [self delayedNotifyDelegateOfSelection:billingProfile]; + return YES; } else { [self startAddressEditCoordinatorWithAddress:billingProfile]; + return NO; } } @@ -135,13 +137,20 @@ // Update the data source with the new data. [self.mediator loadItems]; + const std::vector<autofill::AutofillProfile*>& billingProfiles = + self.paymentRequest->billing_profiles(); + const auto position = + std::find(billingProfiles.begin(), billingProfiles.end(), address); + DCHECK(position != billingProfiles.end()); + + // Mark the edited item as complete meaning all required information has been + // filled out. + CollectionViewItem<PaymentsIsSelectable>* editedItem = + self.mediator.selectableItems[position - billingProfiles.begin()]; + editedItem.complete = YES; + if (![self.viewController isEditing]) { // Update the data source with the selection. - const std::vector<autofill::AutofillProfile*>& billingProfiles = - self.paymentRequest->billing_profiles(); - const auto position = - std::find(billingProfiles.begin(), billingProfiles.end(), address); - DCHECK(position != billingProfiles.end()); self.mediator.selectedItemIndex = position - billingProfiles.begin(); } @@ -151,12 +160,6 @@ [self.addressEditCoordinator stop]; self.addressEditCoordinator = nil; - // Mark the item as complete meaning all required information has been - // filled out. - CollectionViewItem<PaymentsIsSelectable>* selectedItem = - self.mediator.selectableItems[self.mediator.selectedItemIndex]; - selectedItem.complete = YES; - if (![self.viewController isEditing]) { // Inform |self.delegate| that |address| has been selected. [self.delegate billingAddressSelectionCoordinator:self
diff --git a/ios/chrome/browser/ui/payments/billing_address_selection_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/billing_address_selection_coordinator_unittest.mm index 15c77b4..1daeba1 100644 --- a/ios/chrome/browser/ui/payments/billing_address_selection_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/billing_address_selection_coordinator_unittest.mm
@@ -7,6 +7,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/autofill_type.h" @@ -71,6 +72,8 @@ BillingAddressSelectionCoordinator* GetCoordinator() { return coordinator_; } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + UINavigationController* navigation_controller_; BillingAddressSelectionCoordinator* coordinator_; @@ -132,14 +135,14 @@ PaymentRequestSelectorViewController* view_controller = base::mac::ObjCCastStrict<PaymentRequestSelectorViewController>( GetNavigationController().visibleViewController); - [GetCoordinator() paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:0]; + EXPECT_TRUE([GetCoordinator() + paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:0]); // Wait for the coordinator delegate to be notified. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); - [GetCoordinator() paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:1]; - // Wait for the coordinator delegate to be notified. - base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); + EXPECT_FALSE([GetCoordinator() + paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:1]); EXPECT_OCMOCK_VERIFY(delegate); }
diff --git a/ios/chrome/browser/ui/payments/billing_address_selection_mediator_unittest.mm b/ios/chrome/browser/ui/payments/billing_address_selection_mediator_unittest.mm index a7e6b80..6a6829df 100644 --- a/ios/chrome/browser/ui/payments/billing_address_selection_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/billing_address_selection_mediator_unittest.mm
@@ -6,6 +6,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" @@ -67,6 +68,8 @@ BillingAddressSelectionMediator* GetMediator() { return mediator_; } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + BillingAddressSelectionMediator* mediator_; autofill::AutofillProfile autofill_profile_1_;
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm index 791d0e1..66f92fbe 100644 --- a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator_unittest.mm
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" @@ -111,6 +112,8 @@ personal_data_manager_.SetTestingPrefService(nullptr); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + std::unique_ptr<PrefService> pref_service_; MockTestPersonalDataManager personal_data_manager_; autofill::TestRegionDataLoader test_region_data_loader_;
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm b/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm index 9b2d54d..3995ef8 100644 --- a/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/contact_info_edit_mediator_unittest.mm
@@ -6,6 +6,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" @@ -32,6 +33,8 @@ payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_)) {} + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::TestPersonalDataManager personal_data_manager_; std::unique_ptr<TestPaymentRequest> payment_request_; };
diff --git a/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm b/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm index b4e6c31..9e3fab3b 100644 --- a/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm
@@ -83,7 +83,7 @@ #pragma mark - PaymentRequestSelectorViewControllerDelegate -- (void)paymentRequestSelectorViewController: +- (BOOL)paymentRequestSelectorViewController: (PaymentRequestSelectorViewController*)controller didSelectItemAtIndex:(NSUInteger)index { // Update the data source with the selection. @@ -92,6 +92,7 @@ DCHECK(index < self.paymentRequest->contact_profiles().size()); [self delayedNotifyDelegateOfSelection:self.paymentRequest ->contact_profiles()[index]]; + return YES; } - (void)paymentRequestSelectorViewControllerDidFinish:
diff --git a/ios/chrome/browser/ui/payments/contact_info_selection_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/contact_info_selection_coordinator_unittest.mm index fdccc17..3e63def 100644 --- a/ios/chrome/browser/ui/payments/contact_info_selection_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/contact_info_selection_coordinator_unittest.mm
@@ -7,11 +7,13 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -30,15 +32,17 @@ // Add testing profiles to autofill::TestPersonalDataManager. personal_data_manager_.AddTestingProfile(&autofill_profile_1_); personal_data_manager_.AddTestingProfile(&autofill_profile_2_); - payment_request_ = base::MakeUnique<PaymentRequest>( + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::AutofillProfile autofill_profile_1_; autofill::AutofillProfile autofill_profile_2_; autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<TestPaymentRequest> payment_request_; }; // Tests that invoking start and stop on the coordinator presents and dismisses @@ -105,8 +109,8 @@ PaymentRequestSelectorViewController* view_controller = base::mac::ObjCCastStrict<PaymentRequestSelectorViewController>( navigation_controller.visibleViewController); - [coordinator paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:1]; + EXPECT_TRUE([coordinator paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:1]); // Wait for the coordinator delegate to be notified. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5));
diff --git a/ios/chrome/browser/ui/payments/contact_info_selection_mediator_unittest.mm b/ios/chrome/browser/ui/payments/contact_info_selection_mediator_unittest.mm index 5e511604..b267333c 100644 --- a/ios/chrome/browser/ui/payments/contact_info_selection_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/contact_info_selection_mediator_unittest.mm
@@ -6,6 +6,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" @@ -50,6 +51,8 @@ ContactInfoSelectionMediator* GetMediator() { return mediator_; } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + ContactInfoSelectionMediator* mediator_; autofill::AutofillProfile autofill_profile_1_;
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm index 403a6a5..c0160bf 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm
@@ -36,7 +36,7 @@ // |error_message| can't be null and will be filled with the appropriate error // message iff the return value is false. bool IsValidCreditCardNumber(const base::string16& card_number, - const PaymentRequest* payment_request, + PaymentRequest* payment_request, const autofill::CreditCard* credit_card_to_edit, base::string16* error_message) { std::set<std::string> supported_card_networks(
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm index 9016fd3..bab831b 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator_unittest.mm
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/test_personal_data_manager.h" #include "ios/chrome/browser/payments/payment_request.h" @@ -37,8 +38,11 @@ class MockPaymentRequest : public PaymentRequest { public: MockPaymentRequest(web::PaymentRequest web_payment_request, - autofill::PersonalDataManager* personal_data_manager) - : PaymentRequest(web_payment_request, personal_data_manager) {} + autofill::PersonalDataManager* personal_data_manager, + id<PaymentRequestUIDelegate> payment_request_ui_delegate) + : PaymentRequest(web_payment_request, + personal_data_manager, + payment_request_ui_delegate) {} MOCK_METHOD1(AddCreditCard, autofill::CreditCard*(const autofill::CreditCard&)); }; @@ -107,9 +111,11 @@ PaymentRequestCreditCardEditCoordinatorTest() { payment_request_ = base::MakeUnique<MockPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), - &personal_data_manager_); + &personal_data_manager_, nil); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + MockTestPersonalDataManager personal_data_manager_; std::unique_ptr<MockPaymentRequest> payment_request_; };
diff --git a/ios/chrome/browser/ui/payments/full_card_requester.h b/ios/chrome/browser/ui/payments/full_card_requester.h index 9214d2a..ea6f1a0 100644 --- a/ios/chrome/browser/ui/payments/full_card_requester.h +++ b/ios/chrome/browser/ui/payments/full_card_requester.h
@@ -23,7 +23,17 @@ class ChromeBrowserState; } // namespace ios -@class PaymentRequestCoordinator; +@protocol FullCardRequesterConsumer + +// Called when a credit card has been successfully unmasked. Note that |card| +// may be different from what passed to GetFullCard method of FullCardRequester, +// because CVC unmasking process may update the credit card number and +// expiration date. +- (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card + verificationCode: + (const base::string16&)verificationCode; + +@end // Receives the full credit card details. Also displays the unmask prompt UI. class FullCardRequester @@ -31,7 +41,7 @@ public autofill::payments::FullCardRequest::UIDelegate, public base::SupportsWeakPtr<FullCardRequester> { public: - FullCardRequester(PaymentRequestCoordinator* owner, + FullCardRequester(id<FullCardRequesterConsumer> consumer, UIViewController* base_view_controller, ios::ChromeBrowserState* browser_state); @@ -53,7 +63,7 @@ autofill::AutofillClient::PaymentsRpcResult result) override; private: - __weak PaymentRequestCoordinator* owner_; + __weak id<FullCardRequesterConsumer> consumer_; __weak UIViewController* base_view_controller_; autofill::CardUnmaskPromptControllerImpl unmask_controller_;
diff --git a/ios/chrome/browser/ui/payments/full_card_requester.mm b/ios/chrome/browser/ui/payments/full_card_requester.mm index c92fec3..74cc6e4 100644 --- a/ios/chrome/browser/ui/payments/full_card_requester.mm +++ b/ios/chrome/browser/ui/payments/full_card_requester.mm
@@ -5,10 +5,8 @@ #include "ios/chrome/browser/ui/payments/full_card_requester.h" #include "components/autofill/core/browser/autofill_manager.h" -#include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h" -#include "ios/chrome/browser/ui/payments/payment_request_coordinator.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -44,10 +42,10 @@ } // namespace -FullCardRequester::FullCardRequester(PaymentRequestCoordinator* owner, +FullCardRequester::FullCardRequester(id<FullCardRequesterConsumer> consumer, UIViewController* base_view_controller, ios::ChromeBrowserState* browser_state) - : owner_(owner), + : consumer_(consumer), base_view_controller_(base_view_controller), unmask_controller_(browser_state->GetPrefs(), browser_state->IsOffTheRecord()) {} @@ -65,8 +63,8 @@ void FullCardRequester::OnFullCardRequestSucceeded( const autofill::CreditCard& card, const base::string16& verificationCode) { - [owner_ fullCardRequestDidSucceedWithCard:card - verificationCode:verificationCode]; + [consumer_ fullCardRequestDidSucceedWithCard:card + verificationCode:verificationCode]; } void FullCardRequester::OnFullCardRequestFailed() {
diff --git a/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm b/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm new file mode 100644 index 0000000..13de877 --- /dev/null +++ b/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
@@ -0,0 +1,141 @@ +// 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. + +#import "ios/chrome/browser/ui/payments/full_card_requester.h" + +#include "base/logging.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/ios/wait_util.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/ios/browser/autofill_driver_ios.h" +#import "ios/chrome/browser/autofill/autofill_agent.h" +#import "ios/chrome/browser/autofill/autofill_controller.h" +#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h" +#import "ios/chrome/browser/web/chrome_web_test.h" +#import "ios/chrome/test/scoped_key_window.h" +#import "ios/testing/ocmock_complex_type_helper.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/ocmock/OCMock/OCMock.h" +#include "third_party/ocmock/gtest_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface FullCardRequesterConsumerMock + : OCMockComplexTypeHelper<FullCardRequesterConsumer> +@end + +@implementation FullCardRequesterConsumerMock + +typedef void (^mock_full_card_request_did_succeed)(const autofill::CreditCard&, + const base::string16&); + +- (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card + verificationCode: + (const base::string16&)verificationCode { + return static_cast<mock_full_card_request_did_succeed>( + [self blockForSelector:_cmd])(card, verificationCode); +} + +@end + +class PaymentRequestFullCardRequesterTest : public ChromeWebTest { + protected: + PaymentRequestFullCardRequesterTest() + : credit_card_(autofill::test::GetCreditCard()) { + TestChromeBrowserState::Builder test_cbs_builder; + chrome_browser_state_ = test_cbs_builder.Build(); + } + + void SetUp() override { + ChromeWebTest::SetUp(); + + // Set up what is needed to have an instance of autofill::AutofillManager. + AutofillAgent* autofill_agent = + [[AutofillAgent alloc] initWithBrowserState:chrome_browser_state_.get() + webState:web_state()]; + InfoBarManagerImpl::CreateForWebState(web_state()); + autofill_controller_ = [[AutofillController alloc] + initWithBrowserState:chrome_browser_state_.get() + webState:web_state() + autofillAgent:autofill_agent + passwordGenerationManager:nullptr + downloadEnabled:NO]; + } + + void TearDown() override { + [autofill_controller_ detachFromWebState]; + + ChromeWebTest::TearDown(); + } + + autofill::CreditCard credit_card_; + std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; + // Manages autofill for a single page. + AutofillController* autofill_controller_; +}; + +// Tests that the FullCardRequester presents and dismisses the card unmask +// prompt view controller, when the full card is requested and when the user +// enters the CVC/expiration information respectively. +TEST_F(PaymentRequestFullCardRequesterTest, PresentAndDismiss) { + UIViewController* base_view_controller = [[UIViewController alloc] init]; + ScopedKeyWindow scoped_key_window_; + [scoped_key_window_.Get() setRootViewController:base_view_controller]; + + FullCardRequester full_card_requester(nil, base_view_controller, + chrome_browser_state_.get()); + + EXPECT_EQ(nil, base_view_controller.presentedViewController); + + autofill::AutofillManager* autofill_manager = + autofill::AutofillDriverIOS::FromWebState(web_state()) + ->autofill_manager(); + full_card_requester.GetFullCard(&credit_card_, autofill_manager); + + // Spin the run loop to trigger the animation. + base::test::ios::SpinRunLoopWithMaxDelay(base::TimeDelta::FromSecondsD(1.0)); + EXPECT_TRUE([base_view_controller.presentedViewController + isMemberOfClass:[CardUnmaskPromptViewController class]]); + + full_card_requester.OnUnmaskVerificationResult( + autofill::AutofillClient::SUCCESS); + + // Wait until the view controller is ordered to be dismissed and the animation + // completes. + WaitForCondition(^bool() { + return !base_view_controller.presentedViewController; + }); + EXPECT_EQ(nil, base_view_controller.presentedViewController); +} + +// Tests that calling the FullCardRequester's delegate method which signals that +// the full credit card details have been successfully received, causes the +// FullCardRequester's delegate method to get called. +TEST_F(PaymentRequestFullCardRequesterTest, FullCardRequestSucceeded) { + // Mock the consumer. + id consumer = + [OCMockObject mockForProtocol:@protocol(FullCardRequesterConsumer)]; + id consumer_mock([[FullCardRequesterConsumerMock alloc] + initWithRepresentedObject:consumer]); + SEL selector = @selector(fullCardRequestDidSucceedWithCard:verificationCode:); + [consumer_mock onSelector:selector + callBlockExpectation:^(const autofill::CreditCard& card, + const base::string16& verificationCode) { + EXPECT_EQ(credit_card_, card); + EXPECT_EQ(base::ASCIIToUTF16("123"), verificationCode); + }]; + + FullCardRequester full_card_requester(consumer_mock, nil, + chrome_browser_state_.get()); + + full_card_requester.OnFullCardRequestSucceeded(credit_card_, + base::ASCIIToUTF16("123")); +}
diff --git a/ios/chrome/browser/ui/payments/payment_items_display_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/payment_items_display_coordinator_unittest.mm index 71e68a93..6d74540d 100644 --- a/ios/chrome/browser/ui/payments/payment_items_display_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_items_display_coordinator_unittest.mm
@@ -7,11 +7,13 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/test_personal_data_manager.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/payments/payment_items_display_view_controller.h" #include "ios/web/public/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -26,13 +28,15 @@ class PaymentRequestPaymentItemsDisplayCoordinatorTest : public PlatformTest { protected: PaymentRequestPaymentItemsDisplayCoordinatorTest() { - payment_request_ = base::MakeUnique<PaymentRequest>( + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<TestPaymentRequest> payment_request_; }; // Tests that invoking start and stop on the coordinator presents and dismisses
diff --git a/ios/chrome/browser/ui/payments/payment_items_display_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_items_display_view_controller_unittest.mm index 02c09a4e..56261ce 100644 --- a/ios/chrome/browser/ui/payments/payment_items_display_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_items_display_view_controller_unittest.mm
@@ -6,10 +6,12 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/test_personal_data_manager.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h" #import "ios/chrome/browser/ui/payments/cells/price_item.h" #import "ios/chrome/browser/ui/payments/payment_items_display_view_controller_data_source.h" @@ -44,7 +46,7 @@ : public CollectionViewControllerTest { protected: CollectionViewController* InstantiateController() override { - payment_request_ = base::MakeUnique<PaymentRequest>( + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); mediator_ = [[TestPaymentItemsDisplayMediator alloc] init]; @@ -59,8 +61,10 @@ controller()); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<TestPaymentRequest> payment_request_; TestPaymentItemsDisplayMediator* mediator_ = nil; };
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm index 89f7e4a..8441248 100644 --- a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm
@@ -80,7 +80,7 @@ #pragma mark - PaymentRequestSelectorViewControllerDelegate -- (void)paymentRequestSelectorViewController: +- (BOOL)paymentRequestSelectorViewController: (PaymentRequestSelectorViewController*)controller didSelectItemAtIndex:(NSUInteger)index { DCHECK(index < self.paymentRequest->credit_cards().size()); @@ -94,8 +94,10 @@ // Update the data source with the selection. self.mediator.selectedItemIndex = index; [self delayedNotifyDelegateOfSelection:creditCard]; + return YES; } else { [self startCreditCardEditCoordinatorWithCreditCard:creditCard]; + return NO; } } @@ -131,13 +133,19 @@ // Update the data source with the new data. [self.mediator loadItems]; + const std::vector<autofill::CreditCard*>& creditCards = + self.paymentRequest->credit_cards(); + auto position = std::find(creditCards.begin(), creditCards.end(), creditCard); + DCHECK(position != creditCards.end()); + + // Mark the edited item as complete meaning all required information has been + // filled out. + CollectionViewItem<PaymentsIsSelectable>* editedItem = + self.mediator.selectableItems[position - creditCards.begin()]; + editedItem.complete = YES; + if (![self.viewController isEditing]) { // Update the data source with the selection. - const std::vector<autofill::CreditCard*>& creditCards = - self.paymentRequest->credit_cards(); - auto position = - std::find(creditCards.begin(), creditCards.end(), creditCard); - DCHECK(position != creditCards.end()); self.mediator.selectedItemIndex = position - creditCards.begin(); }
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm index c0802c8..145efaf 100644 --- a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm
@@ -7,12 +7,14 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/test_personal_data_manager.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h" #include "ios/web/public/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -39,16 +41,18 @@ personal_data_manager_.AddTestingCreditCard(&credit_card1_); credit_card2_.set_use_count(5U); personal_data_manager_.AddTestingCreditCard(&credit_card2_); - payment_request_ = base::MakeUnique<PaymentRequest>( + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::AutofillProfile autofill_profile_; autofill::CreditCard credit_card1_; autofill::CreditCard credit_card2_; autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<TestPaymentRequest> payment_request_; }; // Tests that invoking start and stop on the coordinator presents and dismisses @@ -119,14 +123,12 @@ PaymentRequestSelectorViewController* view_controller = base::mac::ObjCCastStrict<PaymentRequestSelectorViewController>( navigation_controller.visibleViewController); - [coordinator paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:0]; + EXPECT_TRUE([coordinator paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:0]); // Wait for the coordinator delegate to be notified. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); - [coordinator paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:1]; - // Wait for the coordinator delegate to be notified. - base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); + EXPECT_FALSE([coordinator paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:1]); EXPECT_OCMOCK_VERIFY(delegate); }
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.h b/ios/chrome/browser/ui/payments/payment_request_coordinator.h index 9174635f..aa70e22 100644 --- a/ios/chrome/browser/ui/payments/payment_request_coordinator.h +++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.h
@@ -14,6 +14,7 @@ #import "ios/chrome/browser/ui/payments/contact_info_edit_coordinator.h" #import "ios/chrome/browser/ui/payments/contact_info_selection_coordinator.h" #import "ios/chrome/browser/ui/payments/credit_card_edit_coordinator.h" +#include "ios/chrome/browser/ui/payments/full_card_requester.h" #import "ios/chrome/browser/ui/payments/payment_items_display_coordinator.h" #import "ios/chrome/browser/ui/payments/payment_method_selection_coordinator.h" #include "ios/chrome/browser/ui/payments/payment_request_error_coordinator.h" @@ -75,6 +76,7 @@ ContactInfoEditCoordinatorDelegate, ContactInfoSelectionCoordinatorDelegate, CreditCardEditCoordinatorDelegate, + FullCardRequesterConsumer, PaymentItemsDisplayCoordinatorDelegate, PaymentMethodSelectionCoordinatorDelegate, PaymentRequestErrorCoordinatorDelegate, @@ -113,20 +115,15 @@ // The delegate to be notified when the user confirms or cancels the request. @property(nonatomic, weak) id<PaymentRequestCoordinatorDelegate> delegate; +// Initiates the UI that will process payment with a payment method. +- (void)sendPaymentResponse; + // Updates the payment details of the PaymentRequest and updates the UI. - (void)updatePaymentDetails:(web::PaymentDetails)paymentDetails; // Displays an error message. Invokes |callback| when the message is dismissed. - (void)displayErrorWithCallback:(ProceduralBlock)callback; -// Called when a credit card has been successfully unmasked. Note that |card| -// may be different from what's returned by the selected_credit_card() method of -// |paymentRequest|, because CVC unmasking process may update the credit card -// number and expiration date. -- (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card - verificationCode: - (const base::string16&)verificationCode; - @end #endif // IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm index 23cc7c81..dbfd97e 100644 --- a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm +++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
@@ -12,7 +12,6 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_util.h" -#include "ios/chrome/browser/ui/payments/full_card_requester.h" #include "ios/chrome/browser/ui/payments/payment_request_mediator.h" #include "ui/base/l10n/l10n_util.h" @@ -88,6 +87,8 @@ } - (void)stop { + [_updatePaymentSummaryItemTimer invalidate]; + [[_navigationController presentingViewController] dismissViewControllerAnimated:YES completion:nil]; @@ -121,6 +122,8 @@ _fullCardRequester->GetFullCard(card, _autofillManager); } +#pragma mark - FullCardRequesterConsumer + - (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card verificationCode: (const base::string16&)verificationCode { @@ -134,6 +137,8 @@ verificationCode:verificationCode]; } +#pragma mark - Public methods + - (void)updatePaymentDetails:(web::PaymentDetails)paymentDetails { [_updatePaymentSummaryItemTimer invalidate];
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm index 097cc303..3ddcecc1 100644 --- a/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm
@@ -16,6 +16,7 @@ #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/payments/payment_request_view_controller.h" #import "ios/chrome/test/scoped_key_window.h" #import "ios/testing/ocmock_complex_type_helper.h" @@ -85,7 +86,7 @@ personal_data_manager_.AddTestingProfile(&autofill_profile_); personal_data_manager_.AddTestingCreditCard(&credit_card_); - payment_request_ = base::MakeUnique<PaymentRequest>( + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); @@ -96,7 +97,7 @@ autofill::AutofillProfile autofill_profile_; autofill::CreditCard credit_card_; autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<TestPaymentRequest> payment_request_; std::unique_ptr<ios::ChromeBrowserState> browser_state_; }; @@ -134,9 +135,9 @@ EXPECT_EQ(nil, base_view_controller.presentedViewController); } -// Tests that calling the card unmasking delegate method which notifies the -// coordinator about successful unmasking of a credit card invokes the -// appropriate coordinator delegate method with the expected information. +// Tests that calling the FullCardRequesterConsumer delegate method which +// notifies the coordinator about successful unmasking of a credit card invokes +// the appropriate coordinator delegate method with the expected information. TEST_F(PaymentRequestCoordinatorTest, FullCardRequestDidSucceed) { UIViewController* base_view_controller = [[UIViewController alloc] init]; ScopedKeyWindow scoped_key_window_;
diff --git a/ios/chrome/browser/ui/payments/payment_request_manager.mm b/ios/chrome/browser/ui/payments/payment_request_manager.mm index 9816a27..19dd775b 100644 --- a/ios/chrome/browser/ui/payments/payment_request_manager.mm +++ b/ios/chrome/browser/ui/payments/payment_request_manager.mm
@@ -20,8 +20,8 @@ #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/ios/browser/autofill_driver_ios.h" #include "components/payments/core/address_normalization_manager.h" -#include "components/payments/core/address_normalizer_impl.h" #include "components/payments/core/payment_address.h" +#include "components/payments/core/payment_request_base_delegate.h" #include "components/payments/core/payment_request_data_util.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" @@ -81,7 +81,8 @@ } // namespace @interface PaymentRequestManager ()<CRWWebStateObserver, - PaymentRequestCoordinatorDelegate> { + PaymentRequestCoordinatorDelegate, + PaymentRequestUIDelegate> { // View controller used to present the PaymentRequest view controller. __weak UIViewController* _baseViewController; @@ -357,18 +358,8 @@ autofill::PersonalDataManager* personalDataManager = _paymentRequest->GetPersonalDataManager(); - std::unique_ptr<i18n::addressinput::Source> addressNormalizerSource = - base::MakeUnique<autofill::ChromeMetadataSource>( - I18N_ADDRESS_VALIDATION_DATA_URL, - personalDataManager->GetURLRequestContextGetter()); - - std::unique_ptr<i18n::addressinput::Storage> addressNormalizerStorage = - autofill::ValidationRulesStorageFactory::CreateStorage(); - - std::unique_ptr<payments::AddressNormalizer> addressNormalizer = - base::MakeUnique<payments::AddressNormalizerImpl>( - std::move(addressNormalizerSource), - std::move(addressNormalizerStorage)); + payments::AddressNormalizer* addressNormalizer = + _paymentRequest->GetAddressNormalizer(); // Kickoff the process of loading the rules (which is asynchronous) for each // profile's country, to get faster address normalization later. @@ -387,7 +378,7 @@ _addressNormalizationManager = base::MakeUnique<payments::AddressNormalizationManager>( - std::move(addressNormalizer), default_country_code); + addressNormalizer, default_country_code); } // Ensures that |_paymentRequest| is set to the correct value for |message|. @@ -412,8 +403,9 @@ return YES; } - _paymentRequest = - base::MakeUnique<PaymentRequest>(webPaymentRequest, _personalDataManager); + _paymentRequest = base::MakeUnique<PaymentRequest>( + webPaymentRequest, _personalDataManager, self); + return YES; } @@ -634,6 +626,12 @@ securityLevel == security_state::SECURE_WITH_POLICY_INSTALLED_CERT; } +#pragma mark - PaymentRequestUIDelegate + +- (void)openFullCardRequestUI { + [_paymentRequestCoordinator sendPaymentResponse]; +} + #pragma mark - PaymentRequestCoordinatorDelegate methods - (void)paymentRequestCoordinatorDidCancel:
diff --git a/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm index e40dee0..5c6f5aa 100644 --- a/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
@@ -9,6 +9,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/credit_card.h" @@ -29,7 +30,6 @@ #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h" #import "ios/chrome/browser/ui/payments/cells/price_item.h" #include "ios/web/public/payments/payment_request.h" -#include "ios/web/public/test/test_web_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #include "ui/base/l10n/l10n_util.h" @@ -71,7 +71,7 @@ PaymentRequestMediator* GetPaymentRequestMediator() { return mediator_; } - web::TestWebThreadBundle thread_bundle_; + base::test::ScopedTaskEnvironment scoped_task_evironment_; autofill::AutofillProfile autofill_profile_; autofill::CreditCard credit_card_;
diff --git a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h index 9132c960..62233c7a 100644 --- a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h +++ b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h
@@ -16,7 +16,8 @@ @protocol PaymentRequestSelectorViewControllerDelegate<NSObject> // Notifies the delegate that the user has selected an item at the given index. -- (void)paymentRequestSelectorViewController: +// Returns whether the selection can actually be made. +- (BOOL)paymentRequestSelectorViewController: (PaymentRequestSelectorViewController*)controller didSelectItemAtIndex:(NSUInteger)index;
diff --git a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm index 339f5b5..0db5251 100644 --- a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm +++ b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm
@@ -248,7 +248,7 @@ // Notify the delegate of the selection. NSUInteger index = [self.collectionViewModel indexInItemTypeForIndexPath:indexPath]; - DCHECK(index < [[self.dataSource selectableItems] count]); + DCHECK_LT(index, [[self.dataSource selectableItems] count]); if ([self.delegate respondsToSelector:@selector (paymentRequestSelectorViewController:didSelectItemAtIndexForEditing @@ -261,31 +261,30 @@ switch (item.type) { case ItemTypeSelectableItem: { - CollectionViewItem<PaymentsIsSelectable>* newSelectedItem = - reinterpret_cast<CollectionViewItem<PaymentsIsSelectable>*>(item); - // Update the currently selected and the newly selected cells only if the - // newly selected cell corresponds to a complete item and can be selected. - if (newSelectedItem.isComplete) { + NSUInteger currentlySelectedItemIndex = self.dataSource.selectedItemIndex; + // Notify the delegate of the selection. Update the currently selected and + // the newly selected cells only if the selection can actually be made. + NSUInteger index = + [self.collectionViewModel indexInItemTypeForIndexPath:indexPath]; + DCHECK_LT(index, [[self.dataSource selectableItems] count]); + if ([self.delegate paymentRequestSelectorViewController:self + didSelectItemAtIndex:index]) { // Update the currently selected cell, if any. - if (self.dataSource.selectedItemIndex != NSUIntegerMax) { - DCHECK(self.dataSource.selectedItemIndex < + if (currentlySelectedItemIndex != NSUIntegerMax) { + DCHECK(currentlySelectedItemIndex < [[self.dataSource selectableItems] count]); CollectionViewItem<PaymentsIsSelectable>* oldSelectedItem = [[self.dataSource selectableItems] - objectAtIndex:self.dataSource.selectedItemIndex]; + objectAtIndex:currentlySelectedItemIndex]; oldSelectedItem.accessoryType = MDCCollectionViewCellAccessoryNone; [self reconfigureCellsForItems:@[ oldSelectedItem ]]; } // Update the newly selected cell. + CollectionViewItem<PaymentsIsSelectable>* newSelectedItem = + reinterpret_cast<CollectionViewItem<PaymentsIsSelectable>*>(item); newSelectedItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark; [self reconfigureCellsForItems:@[ newSelectedItem ]]; } - // Notify the delegate of the selection. - NSUInteger index = - [self.collectionViewModel indexInItemTypeForIndexPath:indexPath]; - DCHECK(index < [[self.dataSource selectableItems] count]); - [self.delegate paymentRequestSelectorViewController:self - didSelectItemAtIndex:index]; break; } case ItemTypeAddItem: {
diff --git a/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm index 14f2d9c..d823ffe 100644 --- a/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_view_controller_unittest.mm
@@ -9,6 +9,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/credit_card.h" @@ -164,6 +165,8 @@ controller()); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::AutofillProfile autofill_profile_; autofill::CreditCard credit_card_; autofill::TestPersonalDataManager personal_data_manager_;
diff --git a/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm b/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm index 01a8b22..e25258d 100644 --- a/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm
@@ -105,7 +105,7 @@ #pragma mark - PaymentRequestSelectorViewControllerDelegate -- (void)paymentRequestSelectorViewController: +- (BOOL)paymentRequestSelectorViewController: (PaymentRequestSelectorViewController*)controller didSelectItemAtIndex:(NSUInteger)index { CollectionViewItem<PaymentsIsSelectable>* selectedItem = @@ -121,8 +121,10 @@ // Update the data source with the selection. self.mediator.selectedItemIndex = index; [self delayedNotifyDelegateOfSelection:shippingProfile]; + return YES; } else { [self startAddressEditCoordinatorWithAddress:shippingProfile]; + return NO; } } @@ -158,13 +160,20 @@ // Update the data source with the new data. [self.mediator loadItems]; + const std::vector<autofill::AutofillProfile*>& shippingProfiles = + self.paymentRequest->shipping_profiles(); + const auto position = + std::find(shippingProfiles.begin(), shippingProfiles.end(), address); + DCHECK(position != shippingProfiles.end()); + + // Mark the edited item as complete meaning all required information has been + // filled out. + CollectionViewItem<PaymentsIsSelectable>* editedItem = + self.mediator.selectableItems[position - shippingProfiles.begin()]; + editedItem.complete = YES; + if (![self.viewController isEditing]) { // Update the data source with the selection. - const std::vector<autofill::AutofillProfile*>& shippingProfiles = - self.paymentRequest->shipping_profiles(); - const auto position = - std::find(shippingProfiles.begin(), shippingProfiles.end(), address); - DCHECK(position != shippingProfiles.end()); self.mediator.selectedItemIndex = position - shippingProfiles.begin(); } @@ -174,12 +183,6 @@ [self.addressEditCoordinator stop]; self.addressEditCoordinator = nil; - // Mark the item as complete meaning all required information has been - // filled out. - CollectionViewItem<PaymentsIsSelectable>* selectedItem = - self.mediator.selectableItems[self.mediator.selectedItemIndex]; - selectedItem.complete = YES; - if (![self.viewController isEditing]) { // Inform |self.delegate| that |address| has been selected. [self.delegate shippingAddressSelectionCoordinator:self
diff --git a/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator_unittest.mm index a9c3bdb..de88c8e8 100644 --- a/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator_unittest.mm
@@ -7,6 +7,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/autofill_type.h" @@ -55,6 +56,8 @@ personal_data_manager_.SetTestingPrefService(nullptr); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::AutofillProfile autofill_profile1_; autofill::AutofillProfile autofill_profile2_; std::unique_ptr<PrefService> pref_service_; @@ -133,14 +136,12 @@ PaymentRequestSelectorViewController* view_controller = base::mac::ObjCCastStrict<PaymentRequestSelectorViewController>( navigation_controller.visibleViewController); - [coordinator paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:0]; + EXPECT_TRUE([coordinator paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:0]); // Wait for the coordinator delegate to be notified. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); - [coordinator paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:1]; - // Wait for the coordinator delegate to be notified. - base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); + EXPECT_FALSE([coordinator paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:1]); EXPECT_OCMOCK_VERIFY(delegate); }
diff --git a/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm b/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm index 44c1d70..d81b2af 100644 --- a/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm
@@ -85,7 +85,7 @@ #pragma mark - PaymentRequestSelectorViewControllerDelegate -- (void)paymentRequestSelectorViewController: +- (BOOL)paymentRequestSelectorViewController: (PaymentRequestSelectorViewController*)controller didSelectItemAtIndex:(NSUInteger)index { // Update the data source with the selection. @@ -94,6 +94,7 @@ DCHECK(index < self.paymentRequest->shipping_options().size()); [self delayedNotifyDelegateOfSelection:self.paymentRequest ->shipping_options()[index]]; + return YES; } - (void)paymentRequestSelectorViewControllerDidFinish:
diff --git a/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator_unittest.mm index 678bccaf..5afbc80 100644 --- a/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator_unittest.mm
@@ -7,13 +7,16 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" +#include "base/test/scoped_task_environment.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/test_personal_data_manager.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/payments/payment_request_selector_view_controller.h" #include "ios/web/public/payments/payment_request.h" +#include "ios/web/public/test/test_web_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #include "third_party/ocmock/OCMock/OCMock.h" @@ -27,13 +30,15 @@ : public PlatformTest { protected: PaymentRequestShippingOptionSelectionCoordinatorTest() { - payment_request_ = base::MakeUnique<PaymentRequest>( + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); } + base::test::ScopedTaskEnvironment scoped_task_evironment_; + autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<TestPaymentRequest> payment_request_; }; // Tests that invoking start and stop on the coordinator presents and dismisses @@ -101,8 +106,8 @@ PaymentRequestSelectorViewController* view_controller = base::mac::ObjCCastStrict<PaymentRequestSelectorViewController>( navigation_controller.visibleViewController); - [coordinator paymentRequestSelectorViewController:view_controller - didSelectItemAtIndex:1]; + EXPECT_TRUE([coordinator paymentRequestSelectorViewController:view_controller + didSelectItemAtIndex:1]); // Wait for the coordinator delegate to be notified. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5));
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index d9dd70b6..7961440 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -68,6 +68,8 @@ "reading_list_toolbar.mm", "reading_list_view_controller.h", "reading_list_view_controller.mm", + "text_badge_view.h", + "text_badge_view.mm", ] deps = [ ":resources", @@ -102,6 +104,7 @@ "reading_list_collection_view_controller_unittest.mm", "reading_list_coordinator_unittest.mm", "reading_list_mediator_unittest.mm", + "text_badge_view_unittest.mm", ] deps = [ ":reading_list",
diff --git a/ios/chrome/browser/ui/reading_list/text_badge_view.h b/ios/chrome/browser/ui/reading_list/text_badge_view.h new file mode 100644 index 0000000..6605b96 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/text_badge_view.h
@@ -0,0 +1,24 @@ +// 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 IOS_CHROME_BROWSER_UI_READING_LIST_TEXT_BADGE_VIEW_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_TEXT_BADGE_VIEW_H_ + +#import <UIKit/UIKit.h> + +// Pill-shaped view that displays white text. +@interface TextBadgeView : UIView + +// Initialize the text badge with the given display text. +- (instancetype)initWithText:(NSString*)text NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; + +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_TEXT_BADGE_VIEW_H_
diff --git a/ios/chrome/browser/ui/reading_list/text_badge_view.mm b/ios/chrome/browser/ui/reading_list/text_badge_view.mm new file mode 100644 index 0000000..6f78208 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/text_badge_view.mm
@@ -0,0 +1,18 @@ +// 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. + +#import "ios/chrome/browser/ui/reading_list/text_badge_view.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation TextBadgeView + +- (instancetype)initWithText:(NSString*)text { + self = [super initWithFrame:CGRectZero]; + return self; +} + +@end
diff --git a/ios/chrome/browser/ui/reading_list/text_badge_view_unittest.mm b/ios/chrome/browser/ui/reading_list/text_badge_view_unittest.mm new file mode 100644 index 0000000..1fd6c3e --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/text_badge_view_unittest.mm
@@ -0,0 +1,26 @@ +// 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. + +#import "ios/chrome/browser/ui/reading_list/text_badge_view.h" + +#import <Foundation/Foundation.h> + +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gtest_mac.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// Tests the badge's intrinsic content size given short display text. +TEST(TextBadgeViewTest, BadgeSizeShortLabel) {} + +// Tests the badge's intrinsic content size given long display text. +TEST(TextBadgeViewTest, BadgeSizeLongLabel) {} + +// Tests that text and layout flip for RTL languages. +TEST(TextBadgeViewTest, RTL) {} + +// Tests that the accessibility label matches the display text. +TEST(TextBadgeViewTest, Accessibility) {}
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index 8381db4..62bc7a62 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -121,6 +121,7 @@ "//components/password_manager/core/browser", "//components/password_manager/core/common", "//components/physical_web/data_source", + "//components/pref_registry", "//components/prefs", "//components/resources", "//components/search_engines",
diff --git a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm index fea44a81..e6671a9 100644 --- a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm
@@ -7,6 +7,7 @@ #include <memory> #import "base/mac/foundation_util.h" +#include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/scoped_observer.h" #include "base/strings/sys_string_conversions.h" @@ -15,6 +16,7 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "components/search_engines/util.h" @@ -96,6 +98,8 @@ const CGFloat kAccountProfilePhotoDimension = 40.0f; +const int kAutomaticSigninPromoViewDismissCount = 20; + typedef NS_ENUM(NSInteger, SectionIdentifier) { SectionIdentifierSignIn = kSectionIdentifierEnumZero, SectionIdentifierBasics, @@ -224,6 +228,9 @@ CollectionViewDetailItem* _defaultSearchEngineItem; CollectionViewDetailItem* _savePasswordsDetailItem; CollectionViewDetailItem* _autoFillDetailItem; + + // YES if the user used at least once the sign-in promo view buttons. + BOOL _signinStarted; } // Stops observing browser state services. This is required during the shutdown @@ -310,6 +317,18 @@ [self updateSearchCell]; } +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + if (!_signinStarted && _signinPromoViewMediator) { + PrefService* prefs = _browserState->GetPrefs(); + int displayedCount = + prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount); + UMA_HISTOGRAM_COUNTS_100( + "MobileSignInPromo.SettingsManager.ImpressionsTilDismiss", + displayedCount); + } +} + #pragma mark SettingsRootCollectionViewController - (void)loadModel { @@ -329,10 +348,16 @@ base::UserMetricsAction("Signin_Impression_FromSettings")); _hasRecordedSigninImpression = YES; } - if (experimental_flags::IsSigninPromoEnabled()) { + PrefService* prefs = _browserState->GetPrefs(); + int displayedCount = + prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount); + if (experimental_flags::IsSigninPromoEnabled() && + displayedCount < kAutomaticSigninPromoViewDismissCount) { _signinPromoViewMediator = [[SigninPromoViewMediator alloc] initWithBrowserState:_browserState]; _signinPromoViewMediator.consumer = self; + prefs->SetInteger(prefs::kIosSettingsSigninPromoDisplayedCount, + displayedCount + 1); } [model addItem:[self signInTextItem] toSectionWithIdentifier:SectionIdentifierSignIn]; @@ -412,8 +437,7 @@ #pragma mark - Model Items - (CollectionViewItem*)signInTextItem { - if (experimental_flags::IsSigninPromoEnabled()) { - DCHECK(_signinPromoViewMediator); + if (_signinPromoViewMediator) { SigninPromoItem* signinPromoItem = [[SigninPromoItem alloc] initWithType:ItemTypeSigninPromo]; signinPromoItem.configurator = @@ -1161,6 +1185,7 @@ - (void)signinPromoViewDidTapSigninWithNewAccount: (SigninPromoView*)signinPromoView { + [self sendImpressionsTilSigninButtonsHistogram]; DCHECK(!_signinPromoViewMediator.defaultIdentity); base::RecordAction( base::UserMetricsAction("Signin_SigninNewAccount_FromSettings")); @@ -1171,6 +1196,7 @@ - (void)signinPromoViewDidTapSigninWithDefaultAccount: (SigninPromoView*)signinPromoView { + [self sendImpressionsTilSigninButtonsHistogram]; ChromeIdentity* identity = _signinPromoViewMediator.defaultIdentity; DCHECK(identity); base::RecordAction( @@ -1182,6 +1208,7 @@ - (void)signinPromoViewDidTapSigninWithOtherAccount: (SigninPromoView*)signinPromoView { + [self sendImpressionsTilSigninButtonsHistogram]; DCHECK(_signinPromoViewMediator.defaultIdentity); base::RecordAction( base::UserMetricsAction("Signin_SigninNotDefault_FromSettings")); @@ -1190,4 +1217,16 @@ PROMO_ACTION_NOT_DEFAULT]; } +#pragma mark - Metrics + +- (void)sendImpressionsTilSigninButtonsHistogram { + _signinStarted = YES; + PrefService* prefs = _browserState->GetPrefs(); + int displayedCount = + prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount); + UMA_HISTOGRAM_COUNTS_100( + "MobileSignInPromo.SettingsManager.ImpressionsTilSigninButtons", + displayedCount); +} + @end
diff --git a/ios/chrome/browser/voice/speech_input_locale_config_impl.mm b/ios/chrome/browser/voice/speech_input_locale_config_impl.mm index 6a83c23e..067da19d 100644 --- a/ios/chrome/browser/voice/speech_input_locale_config_impl.mm +++ b/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
@@ -9,6 +9,7 @@ #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #include "base/mac/scoped_cftyperef.h" +#include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/voice/speech_input_locale_match_config.h" @@ -83,9 +84,7 @@ bool SpeechInputLocaleConfigImpl::IsTextToSpeechEnabledForCode( const std::string& locale_code) const { std::string language = GetLanguageComponentForLocaleCode(locale_code); - auto found_language = std::find(text_to_speech_languages_.begin(), - text_to_speech_languages_.end(), language); - return found_language != text_to_speech_languages_.end(); + return base::ContainsValue(text_to_speech_languages_, language); } SpeechInputLocale SpeechInputLocaleConfigImpl::GetMatchingLocale(
diff --git a/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn b/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn index 66b56153..6239acd 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab_collection/BUILD.gn
@@ -10,6 +10,7 @@ deps = [ ":tab_collection_ui", "//base", + "//ios/chrome/browser/web", "//ios/chrome/browser/web_state_list", "//ios/web", ] @@ -46,6 +47,7 @@ ":tab_collection_ui", "//base", "//base/test:test_support", + "//ios/chrome/browser/web", "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/test/base",
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.h b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.h index 6f17f83e..3931f45 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.h +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.h
@@ -9,6 +9,7 @@ // The model representing a tab in the tab collection. @interface TabCollectionItem : NSObject +@property(nonatomic, copy) NSString* tabID; @property(nonatomic, copy) NSString* title; @end
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.mm b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.mm index ad74315..2dddb649 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.mm +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.mm
@@ -9,5 +9,6 @@ #endif @implementation TabCollectionItem +@synthesize tabID = _tabID; @synthesize title = _title; @end
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator.mm b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator.mm index 4887222..ae3a900c 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator.mm +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator.mm
@@ -7,6 +7,7 @@ #include "base/memory/ptr_util.h" #include "base/scoped_observer.h" #include "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/clean/chrome/browser/ui/tab_collection/tab_collection_consumer.h" #import "ios/clean/chrome/browser/ui/tab_collection/tab_collection_item.h" @@ -137,8 +138,7 @@ #pragma mark - Private // Constructs a TabCollectionItem from a |webState|. -- (TabCollectionItem*)tabCollectionItemFromWebState: - (const web::WebState*)webState { +- (TabCollectionItem*)tabCollectionItemFromWebState:(web::WebState*)webState { // PLACEHOLDER: Use real webstate title in the future. DCHECK(webState); GURL url = webState->GetVisibleURL(); @@ -146,7 +146,10 @@ if (url.is_valid()) { urlText = base::SysUTF8ToNSString(url.spec()); } + TabIdTabHelper* tabHelper = TabIdTabHelper::FromWebState(webState); + DCHECK(tabHelper); TabCollectionItem* item = [[TabCollectionItem alloc] init]; + item.tabID = tabHelper->tab_id(); item.title = urlText; return item; }
diff --git a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator_unittest.mm b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator_unittest.mm index 827a315..2a74641 100644 --- a/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator_unittest.mm +++ b/ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator_unittest.mm
@@ -5,6 +5,7 @@ #import "ios/clean/chrome/browser/ui/tab_collection/tab_collection_mediator.h" #include "base/memory/ptr_util.h" +#import "ios/chrome/browser/web/tab_id_tab_helper.h" #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" @@ -44,6 +45,7 @@ void InsertWebState(int index) { auto web_state = base::MakeUnique<web::TestWebState>(); + TabIdTabHelper::CreateForWebState(web_state.get()); GURL url("http://test/" + std::to_string(index)); web_state->SetCurrentURL(url); web_state_list_->InsertWebState(index, std::move(web_state)); @@ -77,6 +79,7 @@ // webStateList. TEST_F(TabCollectionMediatorTest, TestReplaceWebState) { auto different_web_state = base::MakeUnique<web::TestWebState>(); + TabIdTabHelper::CreateForWebState(different_web_state.get()); web_state_list_->ReplaceWebStateAt(1, std::move(different_web_state)); [[consumer_ verify] replaceItemAtIndex:1 withItem:[OCMArg any]]; }
diff --git a/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn b/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn index ff74a57..dffab41 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn
@@ -83,6 +83,7 @@ ":tab_grid_ui", "//base", "//base/test:test_support", + "//ios/chrome/browser/web", "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/test/base",
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_mediator_unittest.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_mediator_unittest.mm index 2f514f0..10ddab36 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_mediator_unittest.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_mediator_unittest.mm
@@ -5,6 +5,7 @@ #import "ios/clean/chrome/browser/ui/tab_grid/tab_grid_mediator.h" #include "base/memory/ptr_util.h" +#import "ios/chrome/browser/web/tab_id_tab_helper.h" #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" @@ -37,6 +38,7 @@ void InsertWebStateAt(int index) { auto web_state = base::MakeUnique<web::TestWebState>(); + TabIdTabHelper::CreateForWebState(web_state.get()); web_state_list_->InsertWebState(index, std::move(web_state)); }
diff --git a/ios/shared/chrome/browser/ui/browser_list/BUILD.gn b/ios/shared/chrome/browser/ui/browser_list/BUILD.gn index 692a147a..23f76b5 100644 --- a/ios/shared/chrome/browser/ui/browser_list/BUILD.gn +++ b/ios/shared/chrome/browser/ui/browser_list/BUILD.gn
@@ -29,6 +29,7 @@ "//ios/chrome/browser/sessions", "//ios/chrome/browser/sessions:serialisation", "//ios/chrome/browser/ssl", + "//ios/chrome/browser/web", "//ios/chrome/browser/web_state_list", "//ios/shared/chrome/browser/ui/broadcaster", "//ios/shared/chrome/browser/ui/commands",
diff --git a/ios/shared/chrome/browser/ui/browser_list/browser_web_state_list_delegate.mm b/ios/shared/chrome/browser/ui/browser_list/browser_web_state_list_delegate.mm index d2a102b80..b8c92f3 100644 --- a/ios/shared/chrome/browser/ui/browser_list/browser_web_state_list_delegate.mm +++ b/ios/shared/chrome/browser/ui/browser_list/browser_web_state_list_delegate.mm
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h" #import "ios/chrome/browser/ssl/ios_security_state_tab_helper.h" +#import "ios/chrome/browser/web/tab_id_tab_helper.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -24,6 +25,7 @@ FindTabHelper::CreateForWebState(web_state, nil); IOSChromeSessionTabHelper::CreateForWebState(web_state); IOSSecurityStateTabHelper::CreateForWebState(web_state); + TabIdTabHelper::CreateForWebState(web_state); } void BrowserWebStateListDelegate::WebStateDetached(web::WebState* web_state) {}
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index 56c2a48f..410c0e5 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -194,7 +194,7 @@ "src/components/private/Overlay/src/MDCOverlayObserver.h", "src/components/private/Overlay/src/MDCOverlayObserver.m", "src/components/private/Overlay/src/MDCOverlayTransitioning.h", - "src/components/private/Overlay/src/MaterialOverlays.h", + "src/components/private/Overlay/src/MaterialOverlay.h", "src/components/private/Overlay/src/private/MDCOverlayAnimationObserver.h", "src/components/private/Overlay/src/private/MDCOverlayAnimationObserver.m", "src/components/private/Overlay/src/private/MDCOverlayObserverOverlay.h",
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium index 0abd728..6cdba75 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: f2fbf2501a825c023f2d846aeba4a292f1053c03 +Revision: 3bb89d580683b81001fcfac3dc47651bd2c36bf9 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/ios/web/webui/url_data_manager_ios.cc b/ios/web/webui/url_data_manager_ios.cc index 8cb9a54..ec75991 100644 --- a/ios/web/webui/url_data_manager_ios.cc +++ b/ios/web/webui/url_data_manager_ios.cc
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted_memory.h" #include "base/message_loop/message_loop.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/synchronization/lock.h" #include "ios/web/public/browser_state.h" @@ -129,8 +130,7 @@ base::AutoLock lock(g_delete_lock.Get()); if (!data_sources_) return false; - return std::find(data_sources_->begin(), data_sources_->end(), data_source) != - data_sources_->end(); + return base::ContainsValue(*data_sources_, data_source); } } // namespace web
diff --git a/ios/web/webui/url_data_manager_ios_backend.mm b/ios/web/webui/url_data_manager_ios_backend.mm index a2b618b..519f4ba 100644 --- a/ios/web/webui/url_data_manager_ios_backend.mm +++ b/ios/web/webui/url_data_manager_ios_backend.mm
@@ -18,6 +18,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" @@ -53,17 +54,12 @@ const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY"; -bool SchemeIsInSchemes(const std::string& scheme, - const std::vector<std::string>& schemes) { - return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end(); -} - // Returns whether |url| passes some sanity checks and is a valid GURL. bool CheckURLIsValid(const GURL& url) { std::vector<std::string> additional_schemes; DCHECK(GetWebClient()->IsAppSpecificURL(url) || (GetWebClient()->GetAdditionalWebUISchemes(&additional_schemes), - SchemeIsInSchemes(url.scheme(), additional_schemes))); + base::ContainsValue(additional_schemes, url.scheme()))); if (!url.is_valid()) { NOTREACHED();
diff --git a/ios/web_view/internal/translate/web_view_translate_client.mm b/ios/web_view/internal/translate/web_view_translate_client.mm index e5746d7..591082a 100644 --- a/ios/web_view/internal/translate/web_view_translate_client.mm +++ b/ios/web_view/internal/translate/web_view_translate_client.mm
@@ -67,13 +67,6 @@ const std::string& target_language, translate::TranslateErrors::Type error_type, bool triggered_from_menu) { - translate_manager_->GetLanguageState().SetTranslateEnabled(true); - - if (step == translate::TRANSLATE_STEP_BEFORE_TRANSLATE && - !translate_manager_->GetLanguageState().HasLanguageChanged()) { - return; - } - [translation_controller_ updateTranslateStep:step sourceLanguage:source_language targetLanguage:target_language
diff --git a/ios/web_view/tools/build.py b/ios/web_view/tools/build.py index 58cad8aa..3fe2b9c2 100755 --- a/ios/web_view/tools/build.py +++ b/ios/web_view/tools/build.py
@@ -52,6 +52,7 @@ 'is_component_build=false use_xcode_clang=true ' 'disable_file_support=true disable_ftp_support=true ' 'disable_brotli_filter=true ios_enable_code_signing=false ' + 'enable_dsyms=true ' 'target_cpu="%s" additional_target_cpus = ["%s"] %s %s' % (target_cpu, additional_cpu, build_config_gn_args, extra_gn_options))
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc index b9f9a8ec..6f2b8fa 100644 --- a/ipc/ipc_mojo_bootstrap.cc +++ b/ipc/ipc_mojo_bootstrap.cc
@@ -358,7 +358,7 @@ controller_->lock_.AssertAcquired(); DCHECK(!client_); DCHECK(!closed_); - DCHECK(runner->RunsTasksOnCurrentThread()); + DCHECK(runner->RunsTasksInCurrentSequence()); task_runner_ = std::move(runner); client_ = client; @@ -367,7 +367,7 @@ void DetachClient() { controller_->lock_.AssertAcquired(); DCHECK(client_); - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(!closed_); task_runner_ = nullptr; @@ -401,20 +401,20 @@ // mojo::InterfaceEndpointController: bool SendMessage(mojo::Message* message) override { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); message->set_interface_id(id_); return controller_->SendMessage(message); } void AllowWokenUpBySyncWatchOnSameThread() override { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); EnsureSyncWatcherExists(); sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); } bool SyncWatch(const bool* should_stop) override { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); // It's not legal to make sync calls from the master endpoint's thread, // and in fact they must only happen from the proxy task runner. @@ -437,7 +437,7 @@ } void OnSyncMessageEventReady() { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); scoped_refptr<Endpoint> keepalive(this); scoped_refptr<AssociatedGroupController> controller_keepalive( @@ -484,7 +484,7 @@ } void EnsureSyncWatcherExists() { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (sync_watcher_) return; @@ -627,7 +627,7 @@ void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) { lock_.AssertAcquired(); DCHECK(endpoint->task_runner() && endpoint->client()); - if (endpoint->task_runner()->RunsTasksOnCurrentThread() && !force_async) { + if (endpoint->task_runner()->RunsTasksInCurrentSequence() && !force_async) { mojo::InterfaceEndpointClient* client = endpoint->client(); base::Optional<mojo::DisconnectReason> reason( endpoint->disconnect_reason()); @@ -652,7 +652,7 @@ if (!endpoint->client()) return; - DCHECK(endpoint->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence()); NotifyEndpointOfError(endpoint, false /* force_async */); } @@ -710,7 +710,7 @@ return true; mojo::InterfaceEndpointClient* client = endpoint->client(); - if (!client || !endpoint->task_runner()->RunsTasksOnCurrentThread()) { + if (!client || !endpoint->task_runner()->RunsTasksInCurrentSequence()) { // No client has been bound yet or the client runs tasks on another // thread. We assume the other thread must always be the one on which // |proxy_task_runner_| runs tasks, since that's the only valid scenario. @@ -766,7 +766,7 @@ if (!client) return; - DCHECK(endpoint->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence()); // Sync messages should never make their way to this method. DCHECK(!message.has_flag(mojo::Message::kFlagIsSync)); @@ -795,7 +795,7 @@ if (!client) return; - DCHECK(endpoint->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence()); MessageWrapper message_wrapper = endpoint->PopSyncMessage(message_id); // The message must have already been dequeued by the endpoint waking up
diff --git a/media/BUILD.gn b/media/BUILD.gn index 6d6d9fe..6fbd5a7d 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -115,6 +115,8 @@ "cdm/cdm_adapter.h", "cdm/cdm_allocator.cc", "cdm/cdm_allocator.h", + "cdm/cdm_file_adapter.cc", + "cdm/cdm_file_adapter.h", "cdm/cdm_file_io.cc", "cdm/cdm_file_io.h", "cdm/cdm_helpers.cc", @@ -581,6 +583,10 @@ } } + if (media_use_libvpx) { + sources += [ "filters/vpx_video_decoder_unittest.cc" ] + } + if (current_cpu != "arm" && is_chromeos) { sources += [ "filters/h264_bitstream_buffer_unittest.cc" ] }
diff --git a/media/audio/android/opensles_output.cc b/media/audio/android/opensles_output.cc index 7da308f..5893de3 100644 --- a/media/audio/android/opensles_output.cc +++ b/media/audio/android/opensles_output.cc
@@ -7,6 +7,7 @@ #include "base/android/build_info.h" #include "base/logging.h" #include "base/macros.h" +#include "base/strings/string_util.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "media/audio/android/audio_manager_android.h" @@ -38,8 +39,14 @@ muted_(false), volume_(1.0), samples_per_second_(params.sample_rate()), - have_float_output_(base::android::BuildInfo::GetInstance()->sdk_int() >= - base::android::SDK_VERSION_LOLLIPOP), + have_float_output_( + base::android::BuildInfo::GetInstance()->sdk_int() >= + base::android::SDK_VERSION_LOLLIPOP && + // See http://crbug.com/737188; still shipping Lollipop in 2017, so no + // idea if later phones will be glitch free; thus blacklist all. + !base::EqualsCaseInsensitiveASCII( + base::android::BuildInfo::GetInstance()->manufacturer(), + "vivo")), bytes_per_frame_(have_float_output_ ? params.channels() * sizeof(float) : params.GetBytesPerFrame()), buffer_size_bytes_(have_float_output_
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc index d92dbfd..73114df 100644 --- a/media/base/test_helpers.cc +++ b/media/base/test_helpers.cc
@@ -146,8 +146,8 @@ } // static -VideoDecoderConfig TestVideoConfig::Normal() { - return GetTestConfig(kCodecVP8, kNormalSize, false); +VideoDecoderConfig TestVideoConfig::Normal(VideoCodec codec) { + return GetTestConfig(codec, kNormalSize, false); } // static @@ -161,8 +161,8 @@ } // static -VideoDecoderConfig TestVideoConfig::Large() { - return GetTestConfig(kCodecVP8, kLargeSize, false); +VideoDecoderConfig TestVideoConfig::Large(VideoCodec codec) { + return GetTestConfig(codec, kLargeSize, false); } // static
diff --git a/media/base/test_helpers.h b/media/base/test_helpers.h index b7e8815..e54d0a4 100644 --- a/media/base/test_helpers.h +++ b/media/base/test_helpers.h
@@ -85,12 +85,12 @@ // Returns a configuration that is invalid. static VideoDecoderConfig Invalid(); - static VideoDecoderConfig Normal(); + static VideoDecoderConfig Normal(VideoCodec codec = kCodecVP8); static VideoDecoderConfig NormalH264(); static VideoDecoderConfig NormalEncrypted(); // Returns a configuration that is larger in dimensions than Normal(). - static VideoDecoderConfig Large(); + static VideoDecoderConfig Large(VideoCodec codec = kCodecVP8); static VideoDecoderConfig LargeEncrypted(); // Returns coded size for Normal and Large config. @@ -165,6 +165,12 @@ std::string(track_id)); } +MATCHER(MuxedSequenceModeWarning, "") { + return CONTAINS_STRING(arg, + "Warning: using MSE 'sequence' AppendMode for a " + "SourceBuffer with multiple tracks"); +} + MATCHER(StreamParsingFailed, "") { return CONTAINS_STRING(arg, "Append: stream parsing failed."); }
diff --git a/media/base/video_frame_pool.cc b/media/base/video_frame_pool.cc index e117251..697c81b 100644 --- a/media/base/video_frame_pool.cc +++ b/media/base/video_frame_pool.cc
@@ -4,12 +4,13 @@ #include "media/base/video_frame_pool.h" -#include <list> +#include <deque> #include "base/bind.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" +#include "base/time/default_tick_clock.h" namespace media { @@ -18,7 +19,8 @@ public: PoolImpl(); - // See VideoFramePool::CreateFrame() for usage. + // See VideoFramePool::CreateFrame() for usage. Attempts to keep |frames_| in + // LRU order by always pulling from the back of |frames_|. scoped_refptr<VideoFrame> CreateFrame(VideoPixelFormat format, const gfx::Size& coded_size, const gfx::Rect& visible_rect, @@ -30,25 +32,41 @@ // |frames_|. void Shutdown(); - size_t GetPoolSizeForTesting() const { return frames_.size(); } + size_t get_pool_size_for_testing() const { return frames_.size(); } + + void set_tick_clock_for_testing(base::TickClock* tick_clock) { + tick_clock_ = tick_clock; + } private: friend class base::RefCountedThreadSafe<VideoFramePool::PoolImpl>; ~PoolImpl(); - // Called when the frame wrapper gets destroyed. - // |frame| is the actual frame that was wrapped and is placed - // in |frames_| by this function so it can be reused. - void FrameReleased(const scoped_refptr<VideoFrame>& frame); + // Called when the frame wrapper gets destroyed. |frame| is the actual frame + // that was wrapped and is placed in |frames_| by this function so it can be + // reused. This will attempt to expire frames that haven't been used in some + // time. It relies on |frames_| being in LRU order with the front being the + // least recently used entry. + void FrameReleased(scoped_refptr<VideoFrame> frame); base::Lock lock_; - bool is_shutdown_; - std::list<scoped_refptr<VideoFrame> > frames_; + bool is_shutdown_ = false; + + struct FrameEntry { + base::TimeTicks last_use_time; + scoped_refptr<VideoFrame> frame; + }; + + std::deque<FrameEntry> frames_; + + // |tick_clock_| is always &|default_tick_clock_| outside of testing. + base::DefaultTickClock default_tick_clock_; + base::TickClock* tick_clock_; DISALLOW_COPY_AND_ASSIGN(PoolImpl); }; -VideoFramePool::PoolImpl::PoolImpl() : is_shutdown_(false) {} +VideoFramePool::PoolImpl::PoolImpl() : tick_clock_(&default_tick_clock_) {} VideoFramePool::PoolImpl::~PoolImpl() { DCHECK(is_shutdown_); @@ -64,22 +82,22 @@ DCHECK(!is_shutdown_); scoped_refptr<VideoFrame> frame; - while (!frame.get() && !frames_.empty()) { - scoped_refptr<VideoFrame> pool_frame = frames_.front(); - frames_.pop_front(); + while (!frame && !frames_.empty()) { + scoped_refptr<VideoFrame> pool_frame = std::move(frames_.back().frame); + frames_.pop_back(); - if (pool_frame->format() == format && - pool_frame->coded_size() == coded_size && - pool_frame->visible_rect() == visible_rect && - pool_frame->natural_size() == natural_size) { - frame = pool_frame; - frame->set_timestamp(timestamp); - frame->metadata()->Clear(); - break; - } + if (pool_frame->format() == format && + pool_frame->coded_size() == coded_size && + pool_frame->visible_rect() == visible_rect && + pool_frame->natural_size() == natural_size) { + frame = pool_frame; + frame->set_timestamp(timestamp); + frame->metadata()->Clear(); + break; + } } - if (!frame.get()) { + if (!frame) { frame = VideoFrame::CreateZeroInitializedFrame( format, coded_size, visible_rect, natural_size, timestamp); // This can happen if the arguments are not valid. @@ -91,8 +109,8 @@ scoped_refptr<VideoFrame> wrapped_frame = VideoFrame::WrapVideoFrame( frame, frame->format(), frame->visible_rect(), frame->natural_size()); - wrapped_frame->AddDestructionObserver( - base::Bind(&VideoFramePool::PoolImpl::FrameReleased, this, frame)); + wrapped_frame->AddDestructionObserver(base::Bind( + &VideoFramePool::PoolImpl::FrameReleased, this, std::move(frame))); return wrapped_frame; } @@ -102,17 +120,28 @@ frames_.clear(); } -void VideoFramePool::PoolImpl::FrameReleased( - const scoped_refptr<VideoFrame>& frame) { +void VideoFramePool::PoolImpl::FrameReleased(scoped_refptr<VideoFrame> frame) { base::AutoLock auto_lock(lock_); if (is_shutdown_) return; - frames_.push_back(frame); + const base::TimeTicks now = tick_clock_->NowTicks(); + frames_.push_back({now, std::move(frame)}); + + // After this loop, |stale_index| is the index of the oldest non-stale frame. + // Such an index must exist because |frame| is never stale. + int stale_index = -1; + constexpr base::TimeDelta kStaleFrameLimit = base::TimeDelta::FromSeconds(10); + while (now - frames_[++stale_index].last_use_time > kStaleFrameLimit) { + // Last frame should never be included since we just added it. + DCHECK_LE(static_cast<size_t>(stale_index), frames_.size()); + } + + if (stale_index) + frames_.erase(frames_.begin(), frames_.begin() + stale_index); } -VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) { -} +VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) {} VideoFramePool::~VideoFramePool() { pool_->Shutdown(); @@ -129,7 +158,11 @@ } size_t VideoFramePool::GetPoolSizeForTesting() const { - return pool_->GetPoolSizeForTesting(); + return pool_->get_pool_size_for_testing(); +} + +void VideoFramePool::SetTickClockForTesting(base::TickClock* tick_clock) { + pool_->set_tick_clock_for_testing(tick_clock); } } // namespace media
diff --git a/media/base/video_frame_pool.h b/media/base/video_frame_pool.h index ebd0e249..54631b1 100644 --- a/media/base/video_frame_pool.h +++ b/media/base/video_frame_pool.h
@@ -11,6 +11,10 @@ #include "media/base/media_export.h" #include "media/base/video_frame.h" +namespace base { +class TickClock; +} + namespace media { // Simple VideoFrame pool used to avoid unnecessarily allocating and destroying @@ -37,12 +41,15 @@ const gfx::Size& natural_size, base::TimeDelta timestamp); -protected: + protected: friend class VideoFramePoolTest; // Returns the number of frames in the pool for testing purposes. size_t GetPoolSizeForTesting() const; + // Allows injection of a base::SimpleTestClock for testing. + void SetTickClockForTesting(base::TickClock* tick_clock); + private: class PoolImpl; scoped_refptr<PoolImpl> pool_;
diff --git a/media/base/video_frame_pool_unittest.cc b/media/base/video_frame_pool_unittest.cc index fd373e6..9b3f721 100644 --- a/media/base/video_frame_pool_unittest.cc +++ b/media/base/video_frame_pool_unittest.cc
@@ -6,6 +6,7 @@ #include <stdint.h> #include <memory> +#include "base/test/simple_test_tick_clock.h" #include "media/base/video_frame_pool.h" #include "testing/gmock/include/gmock/gmock.h" @@ -13,7 +14,12 @@ class VideoFramePoolTest : public ::testing::Test { public: - VideoFramePoolTest() : pool_(new VideoFramePool()) {} + VideoFramePoolTest() : pool_(new VideoFramePool()) { + // Seed test clock with some dummy non-zero value to avoid confusion with + // empty base::TimeTicks values. + test_clock_.Advance(base::TimeDelta::FromSeconds(1234)); + pool_->SetTickClockForTesting(&test_clock_); + } scoped_refptr<VideoFrame> CreateFrame(VideoPixelFormat format, int timestamp_ms) { @@ -40,6 +46,7 @@ } protected: + base::SimpleTestTickClock test_clock_; std::unique_ptr<VideoFramePool> pool_; }; @@ -92,4 +99,21 @@ frame->rows(VideoFrame::kYPlane) * frame->stride(VideoFrame::kYPlane)); } +TEST_F(VideoFramePoolTest, StaleFramesAreExpired) { + scoped_refptr<VideoFrame> frame_1 = CreateFrame(PIXEL_FORMAT_YV12, 10); + scoped_refptr<VideoFrame> frame_2 = CreateFrame(PIXEL_FORMAT_YV12, 10); + EXPECT_NE(frame_1.get(), frame_2.get()); + CheckPoolSize(0u); + + // Drop frame and verify that resources are still available for reuse. + frame_1 = nullptr; + CheckPoolSize(1u); + + // Advance clock far enough to hit stale timer; ensure only frame_1 has its + // resources released. + test_clock_.Advance(base::TimeDelta::FromMinutes(1)); + frame_2 = nullptr; + CheckPoolSize(1u); +} + } // namespace media
diff --git a/media/base/win/mf_helpers.cc b/media/base/win/mf_helpers.cc index 9322b0c..94e2fd2 100644 --- a/media/base/win/mf_helpers.cc +++ b/media/base/win/mf_helpers.cc
@@ -4,6 +4,8 @@ #include "media/base/win/mf_helpers.h" +#include "base/metrics/histogram_macros.h" + namespace media { namespace mf { @@ -11,6 +13,7 @@ void LogDXVAError(int line) { LOG(ERROR) << "Error in dxva_video_decode_accelerator_win.cc on line " << line; + UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DXVAVDA.ErrorLine", line); } base::win::ScopedComPtr<IMFSample> CreateEmptySampleWithBuffer(
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index e149677..f7dfca3 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -9,10 +9,12 @@ #include <utility> #include <vector> +#include "base/bind.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" +#include "base/time/time.h" #include "crypto/encryptor.h" #include "crypto/symmetric_key.h" #include "media/base/audio_decoder_config.h" @@ -301,10 +303,8 @@ const std::vector<uint8_t>& init_data, std::unique_ptr<NewSessionCdmPromise> promise) { std::string session_id = GenerateSessionId(); - open_sessions_.insert(session_id); - - // For now, the AesDecryptor does not care about |session_type|. - // TODO(jrummell): Validate |session_type|. + bool session_added = CreateSession(session_id, session_type); + DCHECK(session_added) << "Failed to add new session " << session_id; std::vector<uint8_t> message; std::vector<std::vector<uint8_t>> keys; @@ -358,8 +358,10 @@ void AesDecryptor::LoadSession(CdmSessionType session_type, const std::string& session_id, std::unique_ptr<NewSessionCdmPromise> promise) { - // TODO(xhwang): Change this to NOTREACHED() when blink checks for key systems - // that do not support loadSession. See http://crbug.com/342481 + // LoadSession() is not supported directly, as there is no way to persist + // the session state. Should not be called as blink should not allow + // persistent sessions for ClearKey. + NOTREACHED(); promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); } @@ -379,45 +381,65 @@ return; } - std::string key_string(response.begin(), response.end()); + bool key_added = false; + std::string error_message; + if (!UpdateSessionWithJWK(session_id, + std::string(response.begin(), response.end()), + &key_added, &error_message)) { + promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, error_message); + return; + } + + FinishUpdate(session_id, key_added, std::move(promise)); +} + +bool AesDecryptor::UpdateSessionWithJWK(const std::string& session_id, + const std::string& json_web_key_set, + bool* key_added, + std::string* error_message) { + auto open_session = open_sessions_.find(session_id); + DCHECK(open_session != open_sessions_.end()); + CdmSessionType session_type = open_session->second; KeyIdAndKeyPairs keys; - CdmSessionType session_type = CdmSessionType::TEMPORARY_SESSION; - if (!ExtractKeysFromJWKSet(key_string, &keys, &session_type)) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, - "Response is not a valid JSON Web Key Set."); - return; + if (!ExtractKeysFromJWKSet(json_web_key_set, &keys, &session_type)) { + error_message->assign("Invalid JSON Web Key Set."); + return false; } // Make sure that at least one key was extracted. if (keys.empty()) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, - "Response does not contain any keys."); - return; + error_message->assign("JSON Web Key Set does not contain any keys."); + return false; } - bool key_added = false; + bool local_key_added = false; for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { if (it->second.length() != static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { DVLOG(1) << "Invalid key length: " << it->second.length(); - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, - "Invalid key length."); - return; + error_message->assign("Invalid key length."); + return false; } // If this key_id doesn't currently exist in this session, // a new key is added. if (!HasKey(session_id, it->first)) - key_added = true; + local_key_added = true; if (!AddDecryptionKey(session_id, it->first, it->second)) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, - "Unable to add key."); - return; + error_message->assign("Unable to add key."); + return false; } } + *key_added = local_key_added; + return true; +} + +void AesDecryptor::FinishUpdate(const std::string& session_id, + bool key_added, + std::unique_ptr<SimpleCdmPromise> promise) { { base::AutoLock auto_lock(new_key_cb_lock_); @@ -447,7 +469,7 @@ // // close() is called from a MediaKeySession object, so it is unlikely that // this method will be called with a previously unseen |session_id|. - std::set<std::string>::iterator it = open_sessions_.find(session_id); + auto it = open_sessions_.find(session_id); if (it == open_sessions_.end()) { promise->resolve(); return; @@ -469,7 +491,7 @@ // Runs the parallel steps from https://w3c.github.io/encrypted-media/#remove. void AesDecryptor::RemoveSession(const std::string& session_id, std::unique_ptr<SimpleCdmPromise> promise) { - std::set<std::string>::iterator it = open_sessions_.find(session_id); + auto it = open_sessions_.find(session_id); if (it == open_sessions_.end()) { // Session doesn't exist. Since this should only be called if the session // existed at one time, this must mean the session has been closed. @@ -496,7 +518,18 @@ // "temporary" // Continue with the following steps. // "persistent-license" - // (Not supported, so no need to do anything.) + // Let message be a message containing or reflecting the record + // of license destruction. + std::vector<uint8_t> message; + if (it->second != CdmSessionType::TEMPORARY_SESSION) { + // The license release message is specified in the spec: + // https://w3c.github.io/encrypted-media/#clear-key-release-format. + KeyIdList key_ids; + key_ids.reserve(keys_info.size()); + for (const auto& key_info : keys_info) + key_ids.push_back(key_info->key_id); + CreateKeyIdsInitData(key_ids, &message); + } // 4.5. Queue a task to run the following steps: // 4.5.1 Run the Update Key Statuses algorithm on the session, providing @@ -512,8 +545,9 @@ // 4.5.4 Let message type be "license-release". // 4.5.5 If message is not null, run the Queue a "message" Event algorithm // on the session, providing message type and message. - // (Not needed as message is only set for persistent licenses, and they're - // not supported here.) + if (!message.empty()) + session_message_cb_.Run(session_id, CdmMessageType::LICENSE_RELEASE, + message); // 4.5.6. Resolve promise. promise->resolve(); @@ -617,6 +651,33 @@ // nothing to be done here. } +bool AesDecryptor::CreateSession(const std::string& session_id, + CdmSessionType session_type) { + auto it = open_sessions_.find(session_id); + if (it != open_sessions_.end()) + return false; + + auto result = open_sessions_.emplace(session_id, session_type); + return result.second; +} + +std::string AesDecryptor::GetSessionStateAsJWK(const std::string& session_id) { + // Create the list of all available keys for this session. + KeyIdAndKeyPairs keys; + { + base::AutoLock auto_lock(key_map_lock_); + for (const auto& item : key_map_) { + if (item.second->Contains(session_id)) { + std::string key_id = item.first; + // |key| is the value used to create the decryption key. + std::string key = item.second->LatestDecryptionKey()->secret(); + keys.push_back(std::make_pair(key_id, key)); + } + } + } + return GenerateJWKSet(keys, CdmSessionType::PERSISTENT_LICENSE_SESSION); +} + bool AesDecryptor::AddDecryptionKey(const std::string& session_id, const std::string& key_id, const std::string& key_string) {
diff --git a/media/cdm/aes_decryptor.h b/media/cdm/aes_decryptor.h index feea6e4..b4f5633 100644 --- a/media/cdm/aes_decryptor.h +++ b/media/cdm/aes_decryptor.h
@@ -7,8 +7,8 @@ #include <stdint.h> +#include <map> #include <memory> -#include <set> #include <string> #include <unordered_map> #include <vector> @@ -85,6 +85,37 @@ void DeinitializeDecoder(StreamType stream_type) override; private: + friend class ClearKeyPersistentSessionCdm; + + // Internally this class supports persistent license type sessions so that + // it can be used by ClearKeyPersistentSessionCdm. The following methods + // will be used from ClearKeyPersistentSessionCdm to create and update + // persistent sessions. Note that ClearKeyPersistentSessionCdm is only used + // for testing, so persistent sessions will not be available generally. + + // Creates a new session with ID |session_id| and type |session_type|, and + // adds it to the list of active sessions. Returns false if the session ID + // is already in the list. + bool CreateSession(const std::string& session_id, + CdmSessionType session_type); + + // Gets the state of the session |session_id| as a JWK. + std::string GetSessionStateAsJWK(const std::string& session_id); + + // Update session |session_id| with the JWK provided in |json_web_key_set|. + // Returns true and sets |key_added| if successful, otherwise returns false + // and |error_message| is the reason for failure. + bool UpdateSessionWithJWK(const std::string& session_id, + const std::string& json_web_key_set, + bool* key_added, + std::string* error_message); + + // Performs the final steps of UpdateSession (notify any listeners for keys + // changed, resolve the promise, and generate a keys change event). + void FinishUpdate(const std::string& session_id, + bool key_added, + std::unique_ptr<SimpleCdmPromise> promise); + // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey // as there are no decryptors that are performing an integrity check. // Helper class that manages the decryption key. @@ -96,6 +127,7 @@ // Creates the encryption key. bool Init(); + const std::string& secret() { return secret_; } crypto::SymmetricKey* decryption_key() { return decryption_key_.get(); } private: @@ -152,8 +184,11 @@ KeyIdToSessionKeysMap key_map_; // Protected by |key_map_lock_|. mutable base::Lock key_map_lock_; // Protects the |key_map_|. - // Keeps track of current open sessions. - std::set<std::string> open_sessions_; + // Keeps track of current open sessions and their type. Although publicly + // AesDecryptor only supports temporary sessions, ClearKeyPersistentSessionCdm + // uses this class to also support persistent sessions, so save the + // CdmSessionType for each session. + std::map<std::string, CdmSessionType> open_sessions_; NewKeyCB new_audio_key_cb_; NewKeyCB new_video_key_cb_;
diff --git a/media/cdm/cdm_adapter_unittest.cc b/media/cdm/cdm_adapter_unittest.cc index 0e983fd..9f2e9f1a 100644 --- a/media/cdm/cdm_adapter_unittest.cc +++ b/media/cdm/cdm_adapter_unittest.cc
@@ -152,15 +152,13 @@ if (expected_result == SUCCESS) { EXPECT_CALL(cdm_client_, OnSessionKeysChangeCalled(session_id, new_key_expected)); + EXPECT_CALL(cdm_client_, + OnSessionExpirationUpdate(session_id, IsNullTime())); } else { EXPECT_CALL(cdm_client_, OnSessionKeysChangeCalled(_, _)).Times(0); + EXPECT_CALL(cdm_client_, OnSessionExpirationUpdate(_, _)).Times(0); } - // ClearKeyCdm always call OnSessionExpirationUpdate() for testing purpose. - EXPECT_CALL(cdm_client_, - OnSessionExpirationUpdate(session_id, IsNullTime())) - .Times(1); - adapter_->UpdateSession(session_id, std::vector<uint8_t>(key.begin(), key.end()), CreatePromise(expected_result));
diff --git a/media/cdm/cdm_file_adapter.cc b/media/cdm/cdm_file_adapter.cc new file mode 100644 index 0000000..2927ae4 --- /dev/null +++ b/media/cdm/cdm_file_adapter.cc
@@ -0,0 +1,76 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cdm/cdm_file_adapter.h" + +#include <memory> + +#include "base/bind.h" +#include "base/logging.h" + +namespace media { + +namespace { + +CdmFileAdapter::Status ConvertStatus(cdm::FileIOClient::Status status) { + switch (status) { + case cdm::FileIOClient::kSuccess: + return CdmFileAdapter::Status::kSuccess; + case cdm::FileIOClient::kInUse: + return CdmFileAdapter::Status::kInUse; + case cdm::FileIOClient::kError: + return CdmFileAdapter::Status::kError; + } + + NOTREACHED(); + return CdmFileAdapter::Status::kError; +} + +} // namespace + +CdmFileAdapter::CdmFileAdapter(cdm::ContentDecryptionModule_8::Host* host) { + file_io_ = host->CreateFileIO(this); +} + +CdmFileAdapter::~CdmFileAdapter() { + DCHECK(open_cb_.is_null()); + DCHECK(read_cb_.is_null()); + DCHECK(write_cb_.is_null()); + file_io_->Close(); +} + +void CdmFileAdapter::Open(const std::string& name, FileOpenedCB open_cb) { + DVLOG(2) << __func__; + open_cb_ = std::move(open_cb); + file_io_->Open(name.data(), name.length()); +} + +void CdmFileAdapter::Read(ReadCB read_cb) { + DVLOG(2) << __func__; + read_cb_ = std::move(read_cb); + file_io_->Read(); +} + +void CdmFileAdapter::Write(const std::vector<uint8_t>& data, WriteCB write_cb) { + DVLOG(2) << __func__; + write_cb_ = std::move(write_cb); + file_io_->Write(data.data(), data.size()); +} + +void CdmFileAdapter::OnOpenComplete(cdm::FileIOClient::Status status) { + std::move(open_cb_).Run(ConvertStatus(status)); +} + +void CdmFileAdapter::OnReadComplete(cdm::FileIOClient::Status status, + const uint8_t* data, + uint32_t data_size) { + std::move(read_cb_).Run(status == kSuccess && data_size > 0, + std::vector<uint8_t>(data, data + data_size)); +} + +void CdmFileAdapter::OnWriteComplete(cdm::FileIOClient::Status status) { + std::move(write_cb_).Run(status == kSuccess); +} + +} // namespace media
diff --git a/media/cdm/cdm_file_adapter.h b/media/cdm/cdm_file_adapter.h new file mode 100644 index 0000000..f02324a --- /dev/null +++ b/media/cdm/cdm_file_adapter.h
@@ -0,0 +1,69 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CDM_CDM_FILE_ADAPTER_H_ +#define MEDIA_CDM_CDM_FILE_ADAPTER_H_ + +#include <stdint.h> + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "media/base/media_export.h" +#include "media/cdm/api/content_decryption_module.h" +#include "media/cdm/cdm_file_io.h" + +namespace media { + +// This class provides the ability to read and write a file using cdm::FileIO. +class MEDIA_EXPORT CdmFileAdapter + : NON_EXPORTED_BASE(public cdm::FileIOClient) { + public: + enum class Status { kSuccess, kInUse, kError }; + using FileOpenedCB = base::OnceCallback<void(Status status)>; + using ReadCB = + base::OnceCallback<void(bool success, const std::vector<uint8_t>& data)>; + using WriteCB = base::OnceCallback<void(bool success)>; + + explicit CdmFileAdapter(cdm::ContentDecryptionModule_8::Host* host); + ~CdmFileAdapter() override; + + // Open the file with |name|. |open_cb| will be called when the file is + // available. + void Open(const std::string& name, FileOpenedCB open_cb); + + // Read the contents of the file, calling |read_cb| with the contents when + // done. If the file does not exist Read() will succeed but |data| will + // be empty. + void Read(ReadCB read_cb); + + // Write |data| into the file, replacing any existing contents. Due to the + // way Read() works, files will be considered deleted if the file is empty, + // so write 0 bytes to "delete" the file. + void Write(const std::vector<uint8_t>& data, WriteCB write_cb); + + private: + // cdm::FileIOClient implementation. + // These are private as they should be called by the cdm::FileIO + // implementation only. + void OnOpenComplete(cdm::FileIOClient::Status status) override; + void OnReadComplete(cdm::FileIOClient::Status status, + const uint8_t* data, + uint32_t data_size) override; + void OnWriteComplete(cdm::FileIOClient::Status status) override; + + FileOpenedCB open_cb_; + ReadCB read_cb_; + WriteCB write_cb_; + cdm::FileIO* file_io_; + + DISALLOW_COPY_AND_ASSIGN(CdmFileAdapter); +}; + +} // namespace media + +#endif // MEDIA_CDM_CDM_FILE_ADAPTER_H_
diff --git a/media/cdm/ppapi/BUILD.gn b/media/cdm/ppapi/BUILD.gn index 9a7876b..0b6d6b0 100644 --- a/media/cdm/ppapi/BUILD.gn +++ b/media/cdm/ppapi/BUILD.gn
@@ -18,6 +18,8 @@ "external_clear_key/clear_key_cdm.cc", "external_clear_key/clear_key_cdm.h", "external_clear_key/clear_key_cdm_common.h", + "external_clear_key/clear_key_persistent_session_cdm.cc", + "external_clear_key/clear_key_persistent_session_cdm.h", ] # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
diff --git a/media/cdm/ppapi/cdm_file_io_impl.cc b/media/cdm/ppapi/cdm_file_io_impl.cc index 7a5b67e..240f3d2 100644 --- a/media/cdm/ppapi/cdm_file_io_impl.cc +++ b/media/cdm/ppapi/cdm_file_io_impl.cc
@@ -82,7 +82,7 @@ // Note: This only stores file name and opens the file system. The real file // open is deferred to when Read() or Write() is called. void CdmFileIOImpl::Open(const char* file_name, uint32_t file_name_size) { - CDM_DLOG() << __func__; + CDM_DLOG() << __func__ << " " << std::string(file_name, file_name_size); PP_DCHECK(IsMainThread()); if (state_ != STATE_UNOPENED) { @@ -149,7 +149,7 @@ // Write() -> OpenTempFileForWrite() -> WriteTempFile() -> RenameTempFile(). // The file name of the temporary file is /_<requested_file_name>. void CdmFileIOImpl::Write(const uint8_t* data, uint32_t data_size) { - CDM_DLOG() << __func__; + CDM_DLOG() << __func__ << ": size = " << data_size; PP_DCHECK(IsMainThread()); if (state_ == STATE_READING || state_ == STATE_WRITING) { @@ -288,7 +288,7 @@ } void CdmFileIOImpl::OnFileOpenedForRead(int32_t result) { - CDM_DLOG() << __func__ << ": " << result; + CDM_DLOG() << __func__ << ": result = " << result; PP_DCHECK(IsMainThread()); PP_DCHECK(state_ == STATE_READING); @@ -328,7 +328,7 @@ } void CdmFileIOImpl::OnFileRead(int32_t bytes_read) { - CDM_DLOG() << __func__ << ": " << bytes_read; + CDM_DLOG() << __func__ << ": bytes_read = " << bytes_read; PP_DCHECK(IsMainThread()); PP_DCHECK(state_ == STATE_READING); @@ -404,7 +404,7 @@ } void CdmFileIOImpl::OnTempFileOpenedForWrite(int32_t result) { - CDM_DLOG() << __func__ << ": " << result; + CDM_DLOG() << __func__ << ": result = " << result; PP_DCHECK(IsMainThread()); PP_DCHECK(state_ == STATE_WRITING); @@ -447,7 +447,7 @@ } void CdmFileIOImpl::OnTempFileWritten(int32_t bytes_written) { - CDM_DLOG() << __func__ << ": " << bytes_written; + CDM_DLOG() << __func__ << ": bytes_written = " << bytes_written; PP_DCHECK(IsMainThread()); PP_DCHECK(state_ == STATE_WRITING); @@ -481,7 +481,7 @@ } void CdmFileIOImpl::OnTempFileRenamed(int32_t result) { - CDM_DLOG() << __func__ << ": " << result; + CDM_DLOG() << __func__ << ": result = " << result; PP_DCHECK(IsMainThread()); PP_DCHECK(state_ == STATE_WRITING);
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc index 9ceaf14..e44d50f 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -13,6 +13,7 @@ #include "base/files/file.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "media/base/cdm_callback_promise.h" @@ -69,15 +70,6 @@ const char kExternalClearKeyVerifyCdmHostTestKeySystem[] = "org.chromium.externalclearkey.verifycdmhosttest"; -// Constants for the enumalted session that can be loaded by LoadSession(). -// These constants need to be in sync with -// chrome/test/data/media/encrypted_media_utils.js -const char kLoadableSessionId[] = "LoadableSession"; -const uint8_t kLoadableSessionKeyId[] = "0123456789012345"; -const uint8_t kLoadableSessionKey[] = {0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, - 0xd2, 0x7b, 0x68, 0xef, 0x12, 0x2a, - 0xfc, 0xe4, 0xae, 0x3c}; - const int64_t kSecondsPerMinute = 60; const int64_t kMsPerSecond = 1000; const int64_t kInitialTimerDelayMs = 200; @@ -274,7 +266,7 @@ bool VerifyCdmHost_0(const cdm::HostFile* host_files, uint32_t num_files) { DVLOG(1) << __func__ << ": " << num_files; - // We should always have the CDM and CDM adapter and at lease one common file. + // We should always have the CDM and CDM adapter and at least one common file. // The common CDM host file (e.g. chrome) might not exist since we are running // in browser_tests. const uint32_t kMinNumHostFiles = 3; @@ -326,8 +318,9 @@ ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system, const GURL& origin) - : decryptor_(new AesDecryptor( + : cdm_(new ClearKeyPersistentSessionCdm( origin, + host, base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)), base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)), base::Bind(&ClearKeyCdm::OnSessionKeysChange, base::Unretained(this)), @@ -335,7 +328,7 @@ base::Unretained(this)))), host_(host), key_system_(key_system), - has_received_keys_change_event_for_emulated_loadsession_(false), + allow_persistent_state_(false), timer_delay_ms_(kInitialTimerDelayMs), renewal_timer_set_(false), is_running_output_protection_test_(false), @@ -351,10 +344,11 @@ ClearKeyCdm::~ClearKeyCdm() {} -void ClearKeyCdm::Initialize(bool /* allow_distinctive_identifier */, - bool /* allow_persistent_state */) { - // Implementation doesn't use distinctive identifier nor save persistent data, - // so nothing to do with these values. +void ClearKeyCdm::Initialize(bool allow_distinctive_identifier, + bool allow_persistent_state) { + // Implementation doesn't use distinctive identifier and will only need + // to check persistent state permission. + allow_persistent_state_ = allow_persistent_state; } void ClearKeyCdm::CreateSessionAndGenerateRequest( @@ -365,13 +359,19 @@ uint32_t init_data_size) { DVLOG(1) << __func__; + if (session_type != cdm::kTemporary && !allow_persistent_state_) { + OnPromiseFailed(promise_id, CdmPromise::INVALID_STATE_ERROR, 0, + "Persistent state not allowed."); + return; + } + std::unique_ptr<media::NewSessionCdmPromise> promise( new media::CdmCallbackPromise<std::string>( base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), promise_id), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); - decryptor_->CreateSessionAndGenerateRequest( + cdm_->CreateSessionAndGenerateRequest( ConvertSessionType(session_type), ConvertInitDataType(init_data_type), std::vector<uint8_t>(init_data, init_data + init_data_size), std::move(promise)); @@ -388,39 +388,23 @@ } } -// Loads a emulated stored session. Currently only |kLoadableSessionId| -// (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is -// supported. void ClearKeyCdm::LoadSession(uint32_t promise_id, cdm::SessionType session_type, const char* session_id, uint32_t session_id_length) { DVLOG(1) << __func__; DCHECK_EQ(session_type, cdm::kPersistentLicense); - - if (std::string(kLoadableSessionId) != - std::string(session_id, session_id_length)) { - host_->OnResolveNewSessionPromise(promise_id, nullptr, 0); - return; - } - - // Only allowed to successfully load this session once. - DCHECK(session_id_for_emulated_loadsession_.empty()); + DCHECK(allow_persistent_state_); + std::string web_session_str(session_id, session_id_length); std::unique_ptr<media::NewSessionCdmPromise> promise( new media::CdmCallbackPromise<std::string>( - base::Bind(&ClearKeyCdm::OnSessionLoaded, base::Unretained(this), + base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), promise_id), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); - // AesDecryptor does not support loading, so create a temporary session to - // represent it in other session-related methods. - std::vector<uint8_t> key_id( - kLoadableSessionKeyId, - kLoadableSessionKeyId + arraysize(kLoadableSessionKeyId) - 1); - decryptor_->CreateSessionAndGenerateRequest(CdmSessionType::TEMPORARY_SESSION, - EmeInitDataType::WEBM, key_id, - std::move(promise)); + cdm_->LoadSession(ConvertSessionType(session_type), web_session_str, + std::move(promise)); } void ClearKeyCdm::UpdateSession(uint32_t promise_id, @@ -431,23 +415,23 @@ DVLOG(1) << __func__; std::string web_session_str(session_id, session_id_length); - // If updating the loadable session, use the actual session id generated. - if (web_session_str == std::string(kLoadableSessionId)) - web_session_str = session_id_for_emulated_loadsession_; - std::unique_ptr<media::SimpleCdmPromise> promise( new media::CdmCallbackPromise<>( - base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), - promise_id), + base::Bind(&ClearKeyCdm::OnUpdateSuccess, base::Unretained(this), + promise_id, web_session_str), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); - decryptor_->UpdateSession( - web_session_str, std::vector<uint8_t>(response, response + response_size), - std::move(promise)); + cdm_->UpdateSession(web_session_str, + std::vector<uint8_t>(response, response + response_size), + std::move(promise)); +} - // TODO(xhwang): Only schedule renewal and update expiration change when the - // promise is resolved. +void ClearKeyCdm::OnUpdateSuccess(uint32_t promise_id, + const std::string& session_id) { + // Resolve the promise first. + OnPromiseResolved(promise_id); + // Now create the expiration changed event. cdm::Time expiration = 0.0; // Never expires. if (key_system_ == kExternalClearKeyRenewalKeySystem) { @@ -461,7 +445,7 @@ } } - host_->OnExpirationChange(session_id, session_id_length, expiration); + host_->OnExpirationChange(session_id.data(), session_id.length(), expiration); } void ClearKeyCdm::CloseSession(uint32_t promise_id, @@ -470,17 +454,13 @@ DVLOG(1) << __func__; std::string web_session_str(session_id, session_id_length); - // If closing the loadable session, use the actual session id generated. - if (web_session_str == std::string(kLoadableSessionId)) - web_session_str = session_id_for_emulated_loadsession_; - std::unique_ptr<media::SimpleCdmPromise> promise( new media::CdmCallbackPromise<>( base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); - decryptor_->CloseSession(web_session_str, std::move(promise)); + cdm_->CloseSession(web_session_str, std::move(promise)); } void ClearKeyCdm::RemoveSession(uint32_t promise_id, @@ -489,29 +469,26 @@ DVLOG(1) << __func__; std::string web_session_str(session_id, session_id_length); - // RemoveSession only allowed for the loadable session. - if (web_session_str == std::string(kLoadableSessionId)) - web_session_str = session_id_for_emulated_loadsession_; - std::unique_ptr<media::SimpleCdmPromise> promise( new media::CdmCallbackPromise<>( base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); - decryptor_->RemoveSession(web_session_str, std::move(promise)); + cdm_->RemoveSession(web_session_str, std::move(promise)); } void ClearKeyCdm::SetServerCertificate(uint32_t promise_id, const uint8_t* server_certificate_data, uint32_t server_certificate_data_size) { + DVLOG(1) << __func__; std::unique_ptr<media::SimpleCdmPromise> promise( new media::CdmCallbackPromise<>( base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); - decryptor_->SetServerCertificate( + cdm_->SetServerCertificate( std::vector<uint8_t>( server_certificate_data, server_certificate_data + server_certificate_data_size), @@ -519,11 +496,7 @@ } void ClearKeyCdm::TimerExpired(void* context) { - if (context == &session_id_for_emulated_loadsession_) { - LoadLoadableSession(); - return; - } - + DVLOG(1) << __func__; DCHECK(renewal_timer_set_); std::string renewal_message; if (!next_renewal_message_.empty() && @@ -551,7 +524,7 @@ cdm::Status ClearKeyCdm::Decrypt(const cdm::InputBuffer& encrypted_buffer, cdm::DecryptedBlock* decrypted_block) { - DVLOG(1) << "Decrypt()"; + DVLOG(1) << __func__; DCHECK(encrypted_buffer.data); scoped_refptr<media::DecoderBuffer> buffer; @@ -615,7 +588,7 @@ } void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { - DVLOG(1) << "ResetDecoder()"; + DVLOG(1) << __func__; #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) switch (decoder_type) { case cdm::kStreamTypeVideo: @@ -636,7 +609,7 @@ } void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { - DVLOG(1) << "DeinitializeDecoder()"; + DVLOG(1) << __func__; switch (decoder_type) { case cdm::kStreamTypeVideo: video_decoder_->Deinitialize(); @@ -657,7 +630,7 @@ cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( const cdm::InputBuffer& encrypted_buffer, cdm::VideoFrame* decoded_frame) { - DVLOG(1) << "DecryptAndDecodeFrame()"; + DVLOG(1) << __func__; TRACE_EVENT0("media", "ClearKeyCdm::DecryptAndDecodeFrame"); scoped_refptr<media::DecoderBuffer> buffer; @@ -681,7 +654,7 @@ cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( const cdm::InputBuffer& encrypted_buffer, cdm::AudioFrames* audio_frames) { - DVLOG(1) << "DecryptAndDecodeSamples()"; + DVLOG(1) << __func__; // Trigger a crash on purpose for testing purpose. if (key_system_ == kExternalClearKeyCrashKeySystem) @@ -717,7 +690,7 @@ } void ClearKeyCdm::Destroy() { - DVLOG(1) << "Destroy()"; + DVLOG(1) << __func__; delete this; } @@ -753,9 +726,9 @@ // Callback is called synchronously, so we can use variables on the stack. media::Decryptor::Status status = media::Decryptor::kError; - // The AesDecryptor does not care what the stream type is. Pass kVideo + // The CDM does not care what the stream type is. Pass kVideo // for both audio and video decryption. - decryptor_->Decrypt( + cdm_->GetCdmContext()->GetDecryptor()->Decrypt( media::Decryptor::kVideo, buffer, base::Bind(&CopyDecryptResults, &status, decrypted_buffer)); @@ -813,34 +786,11 @@ OnUnitTestComplete(true); }; -void ClearKeyCdm::LoadLoadableSession() { - std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, - sizeof(kLoadableSessionKey), - kLoadableSessionKeyId, - sizeof(kLoadableSessionKeyId) - 1); - std::unique_ptr<media::SimpleCdmPromise> promise( - new media::CdmCallbackPromise<>( - base::Bind(&ClearKeyCdm::OnLoadSessionUpdated, - base::Unretained(this)), - base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), - promise_id_for_emulated_loadsession_))); - decryptor_->UpdateSession( - session_id_for_emulated_loadsession_, - std::vector<uint8_t>(jwk_set.begin(), jwk_set.end()), std::move(promise)); -} - void ClearKeyCdm::OnSessionMessage(const std::string& session_id, CdmMessageType message_type, const std::vector<uint8_t>& message) { - DVLOG(1) << "OnSessionMessage: " << message.size(); + DVLOG(1) << __func__ << ": size = " << message.size(); - // Ignore the message when we are waiting to update the loadable session. - if (session_id == session_id_for_emulated_loadsession_) - return; - - // OnSessionMessage() only called during CreateSession(), so no promise - // involved (OnSessionCreated() called to resolve the CreateSession() - // promise). host_->OnSessionMessage(session_id.data(), session_id.length(), cdm::kLicenseRequest, reinterpret_cast<const char*>(message.data()), @@ -850,43 +800,23 @@ void ClearKeyCdm::OnSessionKeysChange(const std::string& session_id, bool has_additional_usable_key, CdmKeysInfo keys_info) { - DVLOG(1) << "OnSessionKeysChange: " << keys_info.size(); - - std::string new_session_id = session_id; - if (new_session_id == session_id_for_emulated_loadsession_) { - // Save |keys_info| if the loadable session is still being created. This - // event will then be forwarded on in OnLoadSessionUpdated(). - if (promise_id_for_emulated_loadsession_ != 0) { - has_received_keys_change_event_for_emulated_loadsession_ = true; - keys_info_for_emulated_loadsession_.swap(keys_info); - return; - } - - // Loadable session has already been created, so pass this event on, - // using the session_id callers expect to see. - new_session_id = std::string(kLoadableSessionId); - } + DVLOG(1) << __func__ << ": size = " << keys_info.size(); std::vector<cdm::KeyInformation> keys_vector; ConvertCdmKeysInfo(keys_info, &keys_vector); - host_->OnSessionKeysChange(new_session_id.data(), new_session_id.length(), + host_->OnSessionKeysChange(session_id.data(), session_id.length(), has_additional_usable_key, keys_vector.data(), keys_vector.size()); } void ClearKeyCdm::OnSessionClosed(const std::string& session_id) { - std::string new_session_id = session_id; - if (new_session_id == session_id_for_emulated_loadsession_) - new_session_id = std::string(kLoadableSessionId); - host_->OnSessionClosed(new_session_id.data(), new_session_id.length()); + host_->OnSessionClosed(session_id.data(), session_id.length()); } void ClearKeyCdm::OnSessionExpirationUpdate(const std::string& session_id, base::Time new_expiry_time) { - std::string new_session_id = session_id; - if (new_session_id == session_id_for_emulated_loadsession_) - new_session_id = std::string(kLoadableSessionId); - host_->OnExpirationChange(new_session_id.data(), new_session_id.length(), + DVLOG(1) << __func__ << ": expiry_time = " << new_expiry_time; + host_->OnExpirationChange(session_id.data(), session_id.length(), new_expiry_time.ToDoubleT()); } @@ -899,57 +829,6 @@ session_id.length()); } -void ClearKeyCdm::OnSessionLoaded(uint32_t promise_id, - const std::string& session_id) { - // Save the latest session ID for renewal and file IO test messages. - last_session_id_ = session_id; - - // |decryptor_| created some session as |session_id|, but going forward - // we need to map that to |kLoadableSessionId|, as that is what callers - // expect. - session_id_for_emulated_loadsession_ = session_id; - - // Delay LoadLoadableSession() to test the case where Decrypt*() calls are - // made before the session is fully loaded. - const int64_t kDelayToLoadSessionMs = 500; - - // Defer resolving the promise until the session is loaded. - promise_id_for_emulated_loadsession_ = promise_id; - - // Use the address of |session_id_for_emulated_loadsession_| as the timer - // context so that we can call LoadLoadableSession() when the timer expires. - host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_); -} - -void ClearKeyCdm::OnLoadSessionUpdated() { - // This method is only called to finish loading sessions, so handle - // appropriately. - - // |promise_id_for_emulated_loadsession_| is the LoadSession() promise, - // so resolve appropriately. - host_->OnResolveNewSessionPromise(promise_id_for_emulated_loadsession_, - kLoadableSessionId, - strlen(kLoadableSessionId)); - promise_id_for_emulated_loadsession_ = 0; - - // Generate the KeysChange event now that the session is "loaded" if one - // was seen. - // TODO(jrummell): Once the order of events is fixed in the spec, either - // require the keyschange event to have happened, or remove this code. - // http://crbug.com/448225 - if (has_received_keys_change_event_for_emulated_loadsession_) { - std::vector<cdm::KeyInformation> keys_vector; - CdmKeysInfo keys_info; - keys_info.swap(keys_info_for_emulated_loadsession_); - has_received_keys_change_event_for_emulated_loadsession_ = false; - DCHECK(!keys_vector.empty()); - ConvertCdmKeysInfo(keys_info, &keys_vector); - host_->OnSessionKeysChange(kLoadableSessionId, strlen(kLoadableSessionId), - !keys_vector.empty(), keys_vector.data(), - keys_vector.size()); - } -} - void ClearKeyCdm::OnPromiseResolved(uint32_t promise_id) { host_->OnResolvePromise(promise_id); } @@ -958,6 +837,7 @@ CdmPromise::Exception exception_code, uint32_t system_code, const std::string& error_message) { + DVLOG(1) << __func__ << ": error = " << error_message; host_->OnRejectPromise(promise_id, ConvertException(exception_code), system_code, @@ -968,8 +848,8 @@ #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) int64_t ClearKeyCdm::CurrentTimeStampInMicroseconds() const { return output_timestamp_base_in_microseconds_ + - base::Time::kMicrosecondsPerSecond * - total_samples_generated_ / samples_per_second_; + base::Time::kMicrosecondsPerSecond * total_samples_generated_ / + samples_per_second_; } int ClearKeyCdm::GenerateFakeAudioFramesFromDuration(
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.h b/media/cdm/ppapi/external_clear_key/clear_key_cdm.h index 6d10d30..5932ac73 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.h +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.h
@@ -17,8 +17,8 @@ #include "base/synchronization/lock.h" #include "media/base/cdm_key_information.h" #include "media/base/cdm_promise.h" -#include "media/cdm/aes_decryptor.h" #include "media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h" +#include "media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h" // Enable this to use the fake decoder for testing. // TODO(tomfinegan): Move fake audio decoder into a separate class. @@ -29,10 +29,10 @@ class GURL; namespace media { -class FileIOTestRunner; class CdmVideoDecoder; class DecoderBuffer; class FFmpegCdmAudioDecoder; +class FileIOTestRunner; // Clear key implementation of the cdm::ContentDecryptionModule interface. class ClearKeyCdm : public ClearKeyCdmInterface { @@ -87,11 +87,6 @@ uint32_t output_protection_mask) override; private: - // Emulates a session stored for |session_id_for_emulated_loadsession_|. This - // is necessary since aes_decryptor.cc does not support storing sessions. - void LoadLoadableSession(); - void OnLoadSessionUpdated(); - // ContentDecryptionModule callbacks. void OnSessionMessage(const std::string& session_id, CdmMessageType message_type, @@ -106,13 +101,15 @@ // Handle the success/failure of a promise. These methods are responsible for // calling |host_| to resolve or reject the promise. void OnSessionCreated(uint32_t promise_id, const std::string& session_id); - void OnSessionLoaded(uint32_t promise_id, const std::string& session_id); void OnPromiseResolved(uint32_t promise_id); void OnPromiseFailed(uint32_t promise_id, CdmPromise::Exception exception_code, uint32_t system_code, const std::string& error_message); + // After updating a session send a 'expirationChange' event. + void OnUpdateSuccess(uint32_t promise_id, const std::string& session_id); + // Prepares next renewal message and sets a timer for it. void ScheduleNextRenewal(); @@ -157,44 +154,16 @@ void VerifyCdmHostTest(); - scoped_refptr<AesDecryptor> decryptor_; + scoped_refptr<ContentDecryptionModule> cdm_; ClearKeyCdmHost* host_; const std::string key_system_; + bool allow_persistent_state_; std::string last_session_id_; std::string next_renewal_message_; - // In order to simulate LoadSession(), CreateSession() and then - // UpdateSession() will be called to create a session with known keys. - // |session_id_for_emulated_loadsession_| is used to keep track of the - // session_id allocated by aes_decryptor, as the session_id will be returned - // as |kLoadableSessionId|. Future requests for this simulated session - // need to use |session_id_for_emulated_loadsession_| for all calls - // to aes_decryptor. - // |promise_id_for_emulated_loadsession_| is used to keep track of the - // original LoadSession() promise, as it is not resolved until the - // UpdateSession() call succeeds. - // |has_received_keys_change_event_for_emulated_loadsession_| is used to keep - // track of whether a keyschange event has been received for the loadable - // session in case it happens before the emulated session is fully created. - // |keys_info_for_emulated_loadsession_| is used to keep track of the list - // of keys provided as a result of calling UpdateSession() if it happens, - // since they can't be forwarded on until the LoadSession() promise is - // resolved. - // TODO(xhwang): Extract testing code from main implementation. - // See http://crbug.com/341751 - // TODO(jrummell): Once the order of events is fixed, - // |has_received_keys_change_event_for_emulated_loadsession_| should be - // removed (the event should have either happened or never happened). - // |keys_info_for_emulated_loadsession_| may also go away if the event is - // not expected. See http://crbug.com/448225 - std::string session_id_for_emulated_loadsession_; - uint32_t promise_id_for_emulated_loadsession_; - bool has_received_keys_change_event_for_emulated_loadsession_; - CdmKeysInfo keys_info_for_emulated_loadsession_; - // Timer delay in milliseconds for the next host_->SetTimer() call. int64_t timer_delay_ms_;
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc new file mode 100644 index 0000000..91d02ec --- /dev/null +++ b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc
@@ -0,0 +1,351 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "media/base/cdm_promise.h" + +namespace media { + +namespace { + +// When creating a persistent session, we need to add the session ID to the +// set of open persistent sessions. However, since the session ID is not +// assigned until the end, this promise is needed to capture the resulting +// session ID. +class NewPersistentSessionCdmPromise : public NewSessionCdmPromise { + public: + using SessionCreatedCB = + base::OnceCallback<void(const std::string& session_id)>; + + NewPersistentSessionCdmPromise(SessionCreatedCB session_created_cb, + std::unique_ptr<NewSessionCdmPromise> promise) + : session_created_cb_(std::move(session_created_cb)), + promise_(std::move(promise)) {} + ~NewPersistentSessionCdmPromise() override {} + + // NewSessionCdmPromise implementation. + void resolve(const std::string& session_id) override { + MarkPromiseSettled(); + std::move(session_created_cb_).Run(session_id); + promise_->resolve(session_id); + } + + void reject(CdmPromise::Exception exception_code, + uint32_t system_code, + const std::string& error_message) override { + MarkPromiseSettled(); + promise_->reject(exception_code, system_code, error_message); + } + + private: + SessionCreatedCB session_created_cb_; + std::unique_ptr<NewSessionCdmPromise> promise_; + + DISALLOW_COPY_AND_ASSIGN(NewPersistentSessionCdmPromise); +}; + +// When a session has been loaded, we need to call FinishUpdate() to complete +// the loading of the session (to resolve the promise, generate events, etc. +// in the correct order). UpdateSession() needs a SimpleCdmPromise, but +// LoadSession needs to be resolved with the session ID. This class simply +// maps the resolve/reject call to do the right thing for NewSessionCdmPromise. +class FinishLoadCdmPromise : public SimpleCdmPromise { + public: + FinishLoadCdmPromise(const std::string& session_id, + std::unique_ptr<NewSessionCdmPromise> promise) + : session_id_(session_id), promise_(std::move(promise)) {} + ~FinishLoadCdmPromise() override {} + + // CdmSimplePromise implementation. + void resolve() override { + MarkPromiseSettled(); + promise_->resolve(session_id_); + } + + void reject(CdmPromise::Exception exception_code, + uint32_t system_code, + const std::string& error_message) override { + // Return an empty string to indicate that the session was not found. + MarkPromiseSettled(); + promise_->resolve(std::string()); + } + + private: + std::string session_id_; + std::unique_ptr<NewSessionCdmPromise> promise_; + + DISALLOW_COPY_AND_ASSIGN(FinishLoadCdmPromise); +}; + +} // namespace + +ClearKeyPersistentSessionCdm::ClearKeyPersistentSessionCdm( + const GURL& origin, + ClearKeyCdmHost* host, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb) + : host_(host), session_closed_cb_(session_closed_cb), weak_factory_(this) { + cdm_ = base::MakeRefCounted<AesDecryptor>( + origin, session_message_cb, + base::Bind(&ClearKeyPersistentSessionCdm::OnSessionClosed, + weak_factory_.GetWeakPtr()), + session_keys_change_cb, session_expiration_update_cb); +} + +void ClearKeyPersistentSessionCdm::SetServerCertificate( + const std::vector<uint8_t>& certificate, + std::unique_ptr<SimpleCdmPromise> promise) { + cdm_->SetServerCertificate(certificate, std::move(promise)); +} + +void ClearKeyPersistentSessionCdm::CreateSessionAndGenerateRequest( + CdmSessionType session_type, + EmeInitDataType init_data_type, + const std::vector<uint8_t>& init_data, + std::unique_ptr<NewSessionCdmPromise> promise) { + std::unique_ptr<NewSessionCdmPromise> new_promise; + if (session_type != CdmSessionType::PERSISTENT_LICENSE_SESSION) { + new_promise = std::move(promise); + } else { + // Since it's a persistent session, we need to save the session ID after + // it's been created. + new_promise = base::MakeUnique<NewPersistentSessionCdmPromise>( + base::Bind(&ClearKeyPersistentSessionCdm::AddPersistentSession, + weak_factory_.GetWeakPtr()), + std::move(promise)); + } + cdm_->CreateSessionAndGenerateRequest(session_type, init_data_type, init_data, + std::move(new_promise)); +} + +void ClearKeyPersistentSessionCdm::LoadSession( + CdmSessionType session_type, + const std::string& session_id, + std::unique_ptr<NewSessionCdmPromise> promise) { + DCHECK_EQ(CdmSessionType::PERSISTENT_LICENSE_SESSION, session_type); + + // Load the saved state for |session_id| and then create the session. + std::unique_ptr<CdmFileAdapter> file(new CdmFileAdapter(host_)); + CdmFileAdapter* file_ref = file.get(); + file_ref->Open( + session_id, + base::Bind(&ClearKeyPersistentSessionCdm::OnFileOpenedForLoadSession, + weak_factory_.GetWeakPtr(), session_id, base::Passed(&file), + base::Passed(std::move(promise)))); +} + +void ClearKeyPersistentSessionCdm::OnFileOpenedForLoadSession( + const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<NewSessionCdmPromise> promise, + CdmFileAdapter::Status status) { + if (status != CdmFileAdapter::Status::kSuccess) { + // If unable to get data for the session, we can't load it. Return an empty + // string to indicate that the session was not found. + promise->resolve(std::string()); + return; + } + + CdmFileAdapter* file_reader = file.get(); + file_reader->Read(base::Bind( + &ClearKeyPersistentSessionCdm::OnFileReadForLoadSession, + weak_factory_.GetWeakPtr(), session_id, base::Passed(std::move(file)), + base::Passed(std::move(promise)))); +} + +void ClearKeyPersistentSessionCdm::OnFileReadForLoadSession( + const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<NewSessionCdmPromise> promise, + bool success, + const std::vector<uint8_t>& data) { + if (!success) { + // If unable to get data for the session, so most likely the file doesn't + // exist. Return an empty string to indicate that the session was not found. + promise->resolve(std::string()); + return; + } + + // Add the session to the list of active sessions. + if (!cdm_->CreateSession(session_id, + CdmSessionType::PERSISTENT_LICENSE_SESSION)) { + // If the session can't be created it's due to an already existing session + // with the same name. + promise->reject(CdmPromise::QUOTA_EXCEEDED_ERROR, 0, + "Session already exists."); + return; + } + AddPersistentSession(session_id); + + // Set the session's state using the data just read. + bool key_added = false; + std::string error_message; + if (!cdm_->UpdateSessionWithJWK(session_id, + std::string(data.begin(), data.end()), + &key_added, &error_message)) { + NOTREACHED() << "Saved session data is not usable, error = " + << error_message; + // Return an empty string to indicate that the session was not found. + promise->resolve(std::string()); + return; + } + + // FinishUpdate() needs a SimpleCdmPromise, so create a wrapper promise. + std::unique_ptr<SimpleCdmPromise> simple_promise( + new FinishLoadCdmPromise(session_id, std::move(promise))); + cdm_->FinishUpdate(session_id, key_added, std::move(simple_promise)); +} + +void ClearKeyPersistentSessionCdm::UpdateSession( + const std::string& session_id, + const std::vector<uint8_t>& response, + std::unique_ptr<SimpleCdmPromise> promise) { + CHECK(!response.empty()); + + auto it = persistent_sessions_.find(session_id); + if (it == persistent_sessions_.end()) { + // Not a persistent session, so simply pass the request on. + cdm_->UpdateSession(session_id, response, std::move(promise)); + return; + } + + bool key_added = false; + std::string error_message; + if (!cdm_->UpdateSessionWithJWK(session_id, + std::string(response.begin(), response.end()), + &key_added, &error_message)) { + promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, error_message); + return; + } + + // Persistent session has been updated, so save the current state. + std::unique_ptr<CdmFileAdapter> file(new CdmFileAdapter(host_)); + CdmFileAdapter* file_ref = file.get(); + file_ref->Open( + session_id, + base::Bind(&ClearKeyPersistentSessionCdm::OnFileOpenedForUpdateSession, + weak_factory_.GetWeakPtr(), session_id, key_added, + base::Passed(&file), base::Passed(std::move(promise)))); +} + +void ClearKeyPersistentSessionCdm::OnFileOpenedForUpdateSession( + const std::string& session_id, + bool key_added, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + CdmFileAdapter::Status status) { + if (status != CdmFileAdapter::Status::kSuccess) { + // Unable to open the file, so the state can't be saved. + promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + "Unable to save session state."); + return; + } + + // Grab the current session state and save it. + std::string current_state = cdm_->GetSessionStateAsJWK(session_id); + CdmFileAdapter* file_writer = file.get(); + file_writer->Write( + std::vector<uint8_t>(current_state.begin(), current_state.end()), + base::Bind(&ClearKeyPersistentSessionCdm::OnFileWrittenForUpdateSession, + weak_factory_.GetWeakPtr(), session_id, key_added, + base::Passed(std::move(file)), + base::Passed(std::move(promise)))); +} + +void ClearKeyPersistentSessionCdm::OnFileWrittenForUpdateSession( + const std::string& session_id, + bool key_added, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + bool success) { + if (!success) { + // Unable to save the state. + promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + "Unable to save session state."); + return; + } + + cdm_->FinishUpdate(session_id, key_added, std::move(promise)); +} + +void ClearKeyPersistentSessionCdm::CloseSession( + const std::string& session_id, + std::unique_ptr<SimpleCdmPromise> promise) { + cdm_->CloseSession(session_id, std::move(promise)); +} + +void ClearKeyPersistentSessionCdm::RemoveSession( + const std::string& session_id, + std::unique_ptr<SimpleCdmPromise> promise) { + auto it = persistent_sessions_.find(session_id); + if (it == persistent_sessions_.end()) { + // Not a persistent session, so simply pass the request on. + cdm_->RemoveSession(session_id, std::move(promise)); + return; + } + + // Remove the saved state for |session_id| first. + std::unique_ptr<CdmFileAdapter> file(new CdmFileAdapter(host_)); + CdmFileAdapter* file_ref = file.get(); + file_ref->Open( + session_id, + base::Bind(&ClearKeyPersistentSessionCdm::OnFileOpenedForRemoveSession, + weak_factory_.GetWeakPtr(), session_id, base::Passed(&file), + base::Passed(std::move(promise)))); +} + +void ClearKeyPersistentSessionCdm::OnFileOpenedForRemoveSession( + const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + CdmFileAdapter::Status status) { + if (status != CdmFileAdapter::Status::kSuccess) { + // If no saved data, simply call RemoveSession(). + cdm_->RemoveSession(session_id, std::move(promise)); + return; + } + + // Write out 0 length data to erase the file. + CdmFileAdapter* file_writer = file.get(); + file_writer->Write( + std::vector<uint8_t>(), + base::Bind(&ClearKeyPersistentSessionCdm::OnFileWrittenForRemoveSession, + weak_factory_.GetWeakPtr(), session_id, + base::Passed(std::move(file)), + base::Passed(std::move(promise)))); +} + +void ClearKeyPersistentSessionCdm::OnFileWrittenForRemoveSession( + const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + bool success) { + DCHECK(success); + cdm_->RemoveSession(session_id, std::move(promise)); +} + +CdmContext* ClearKeyPersistentSessionCdm::GetCdmContext() { + return cdm_.get(); +} + +void ClearKeyPersistentSessionCdm::AddPersistentSession( + const std::string& session_id) { + persistent_sessions_.insert(session_id); +} + +void ClearKeyPersistentSessionCdm::OnSessionClosed( + const std::string& session_id) { + persistent_sessions_.erase(session_id); + session_closed_cb_.Run(session_id); +} + +} // namespace media
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h new file mode 100644 index 0000000..5fef3d3 --- /dev/null +++ b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h
@@ -0,0 +1,122 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_PERSISTENT_SESSION_CDM_H_ +#define MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_PERSISTENT_SESSION_CDM_H_ + +#include <stdint.h> + +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "media/base/content_decryption_module.h" +#include "media/cdm/aes_decryptor.h" +#include "media/cdm/cdm_file_adapter.h" +#include "media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h" + +class GURL; + +namespace media { + +// This class is a wrapper on top of AesDecryptor that supports persistent +// sessions. LoadSession(), UpdateSession(), and RemoveSession() have +// special handling. +class ClearKeyPersistentSessionCdm : public ContentDecryptionModule { + public: + ClearKeyPersistentSessionCdm( + const GURL& origin, + ClearKeyCdmHost* host, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb); + + // ContentDecryptionModule implementation. + void SetServerCertificate(const std::vector<uint8_t>& certificate, + std::unique_ptr<SimpleCdmPromise> promise) override; + void CreateSessionAndGenerateRequest( + CdmSessionType session_type, + EmeInitDataType init_data_type, + const std::vector<uint8_t>& init_data, + std::unique_ptr<NewSessionCdmPromise> promise) override; + void LoadSession(CdmSessionType session_type, + const std::string& session_id, + std::unique_ptr<NewSessionCdmPromise> promise) override; + void UpdateSession(const std::string& session_id, + const std::vector<uint8_t>& response, + std::unique_ptr<SimpleCdmPromise> promise) override; + void CloseSession(const std::string& session_id, + std::unique_ptr<SimpleCdmPromise> promise) override; + void RemoveSession(const std::string& session_id, + std::unique_ptr<SimpleCdmPromise> promise) override; + CdmContext* GetCdmContext() override; + + private: + // When LoadSession() is called, first open and read the session state. + // Then call |cdm_| to create the session with the state provided. + void OnFileOpenedForLoadSession(const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<NewSessionCdmPromise> promise, + CdmFileAdapter::Status status); + void OnFileReadForLoadSession(const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<NewSessionCdmPromise> promise, + bool success, + const std::vector<uint8_t>& data); + + // When UpdateSession() is called (on a persistent session), save the + // current session state after it's been updated. + void OnFileOpenedForUpdateSession(const std::string& session_id, + bool key_added, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + CdmFileAdapter::Status status); + void OnFileWrittenForUpdateSession(const std::string& session_id, + bool key_added, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + bool success); + + // When RemoveSession() is called (on a persistent session), delete the + // file (by writing 0 bytes) and then call |cdm_| to actually remove the + // session from memory. + void OnFileOpenedForRemoveSession(const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + CdmFileAdapter::Status status); + void OnFileWrittenForRemoveSession(const std::string& session_id, + std::unique_ptr<CdmFileAdapter> file, + std::unique_ptr<SimpleCdmPromise> promise, + bool success); + + // Add |session_id| to the list of open persistent sessions. + void AddPersistentSession(const std::string& session_id); + + // When the session is closed, remove it from the list of open persistent + // sessions if it was a persistent session. + void OnSessionClosed(const std::string& session_id); + + scoped_refptr<AesDecryptor> cdm_; + ClearKeyCdmHost* host_; + + // Callbacks for firing session events. Other events aren't intercepted. + SessionClosedCB session_closed_cb_; + + // Keep track of current open persistent sessions. + std::set<std::string> persistent_sessions_; + + // NOTE: Weak pointers must be invalidated before all other member variables. + base::WeakPtrFactory<ClearKeyPersistentSessionCdm> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(ClearKeyPersistentSessionCdm); +}; + +} // namespace media + +#endif // MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_PERSISTENT_SESSION_CDM_H_
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index 4dbeba25..43dca04 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc
@@ -4770,6 +4770,34 @@ EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO)); } +TEST_F(ChunkDemuxerTest, SequenceModeMuxedAppendShouldWarn) { + ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); + + demuxer_->SetSequenceMode(kSourceId, true); + EXPECT_MEDIA_LOG(MuxedSequenceModeWarning()); + + AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0D10K"), + MuxedStreamInfo(kVideoTrackNum, "0D10K")); +} + +TEST_F(ChunkDemuxerTest, SequenceModeSingleTrackNoWarning) { + std::string audio_id = "audio1"; + std::string video_id = "video1"; + + EXPECT_MEDIA_LOG(MuxedSequenceModeWarning()).Times(0); + + ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); + + demuxer_->SetSequenceMode(audio_id, true); + demuxer_->SetSequenceMode(video_id, true); + + // Append audio and video data into separate source ids. + ASSERT_TRUE(AppendCluster( + audio_id, GenerateSingleStreamCluster(0, 23, kAudioTrackNum, 23))); + ASSERT_TRUE(AppendCluster( + video_id, GenerateSingleStreamCluster(0, 33, kVideoTrackNum, 33))); +} + TEST_F(ChunkDemuxerTest, Mp4Vp9CodecSupport) { ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported; #if BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/media/filters/frame_processor.cc b/media/filters/frame_processor.cc index e5afa803..6bb03a0 100644 --- a/media/filters/frame_processor.cc +++ b/media/filters/frame_processor.cc
@@ -17,6 +17,7 @@ const int kMaxDroppedPrerollWarnings = 10; const int kMaxDtsBeyondPtsWarnings = 10; +const int kMaxMuxedSequenceModeWarnings = 1; // Helper class to capture per-track details needed by a frame processor. Some // of this information may be duplicated in the short-term in the associated @@ -207,6 +208,16 @@ DCHECK(!frames.empty()); + if (sequence_mode_ && track_buffers_.size() > 1) { + LIMITED_MEDIA_LOG(DEBUG, media_log_, num_muxed_sequence_mode_warnings_, + kMaxMuxedSequenceModeWarnings) + << "Warning: using MSE 'sequence' AppendMode for a SourceBuffer with " + "multiple tracks may cause loss of track synchronization. In some " + "cases, buffered range gaps and playback stalls can occur. It is " + "recommended to instead use 'segments' mode for a multitrack " + "SourceBuffer."; + } + // Implements the coded frame processing algorithm's outer loop for step 1. // Note that ProcessFrame() implements an inner loop for a single frame that // handles "jump to the Loop Top step to restart processing of the current
diff --git a/media/filters/frame_processor.h b/media/filters/frame_processor.h index 71bac67..cd8d662 100644 --- a/media/filters/frame_processor.h +++ b/media/filters/frame_processor.h
@@ -175,6 +175,7 @@ // Counters that limit spam to |media_log_| for frame processor warnings. int num_dropped_preroll_warnings_ = 0; int num_dts_beyond_pts_warnings_ = 0; + int num_muxed_sequence_mode_warnings_ = 0; DISALLOW_COPY_AND_ASSIGN(FrameProcessor); };
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc index 9759019..31c039a 100644 --- a/media/filters/vpx_video_decoder.cc +++ b/media/filters/vpx_video_decoder.cc
@@ -21,11 +21,13 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/sys_byteorder.h" #include "base/sys_info.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/default_tick_clock.h" #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_provider.h" @@ -210,20 +212,31 @@ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) override; + void Shutdown(); + // Reference counted frame buffers used for VP9 decoding. Reference counting // is done manually because both chromium and libvpx has to release this // before a buffer can be re-used. struct VP9FrameBuffer { - VP9FrameBuffer() : ref_cnt(0) {} std::vector<uint8_t> data; std::vector<uint8_t> alpha_data; - uint32_t ref_cnt; + uint32_t ref_cnt = 0; + base::TimeTicks last_use_time; }; + size_t get_pool_size_for_testing() const { return frame_buffers_.size(); } + + void set_tick_clock_for_testing(base::TickClock* tick_clock) { + tick_clock_ = tick_clock; + } + private: friend class base::RefCountedThreadSafe<VpxVideoDecoder::MemoryPool>; ~MemoryPool() override; + // Drop all entries in |frame_buffers_| with a zero |ref_cnt|. + void EraseUnusedResources(); + // Gets the next available frame buffer for use by libvpx. VP9FrameBuffer* GetFreeFrameBuffer(size_t min_size); @@ -234,17 +247,25 @@ // Frame buffers to be used by libvpx for VP9 Decoding. std::vector<std::unique_ptr<VP9FrameBuffer>> frame_buffers_; + bool in_shutdown_ = false; + + // |tick_clock_| is always &|default_tick_clock_| outside of testing. + base::DefaultTickClock default_tick_clock_; + base::TickClock* tick_clock_; + DISALLOW_COPY_AND_ASSIGN(MemoryPool); }; -VpxVideoDecoder::MemoryPool::MemoryPool() { -} +VpxVideoDecoder::MemoryPool::MemoryPool() : tick_clock_(&default_tick_clock_) {} VpxVideoDecoder::MemoryPool::~MemoryPool() { + DCHECK(in_shutdown_); } VpxVideoDecoder::MemoryPool::VP9FrameBuffer* VpxVideoDecoder::MemoryPool::GetFreeFrameBuffer(size_t min_size) { + DCHECK(!in_shutdown_); + // Check if a free frame buffer exists. size_t i = 0; for (; i < frame_buffers_.size(); ++i) { @@ -274,7 +295,7 @@ static_cast<VpxVideoDecoder::MemoryPool*>(user_priv); VP9FrameBuffer* fb_to_use = memory_pool->GetFreeFrameBuffer(min_size); - if (fb_to_use == NULL) + if (!fb_to_use) return -1; fb->data = &fb_to_use->data[0]; @@ -297,6 +318,14 @@ VP9FrameBuffer* frame_buffer = static_cast<VP9FrameBuffer*>(fb->priv); --frame_buffer->ref_cnt; + + if (!frame_buffer->ref_cnt) { + // TODO(dalecurtis): This should be |tick_clock_| but we don't have access + // to the main class from this static function and its only needed for tests + // which all hit the OnVideoFrameDestroyed() path below instead. + frame_buffer->last_use_time = base::TimeTicks::Now(); + } + return 0; } @@ -337,9 +366,40 @@ return true; } +void VpxVideoDecoder::MemoryPool::Shutdown() { + in_shutdown_ = true; + // Drop unused resources. We must maintain ownership of buffers marked as + // used since libvpx may not have cleaned up its refs during shutdown; these + // are safe to release since libvpx is destroyed before the pool. + EraseUnusedResources(); +} + +void VpxVideoDecoder::MemoryPool::EraseUnusedResources() { + base::EraseIf(frame_buffers_, [](const std::unique_ptr<VP9FrameBuffer>& buf) { + return !buf->ref_cnt; + }); +} + void VpxVideoDecoder::MemoryPool::OnVideoFrameDestroyed( VP9FrameBuffer* frame_buffer) { --frame_buffer->ref_cnt; + + if (in_shutdown_) { + DCHECK(!frame_buffer->ref_cnt); + EraseUnusedResources(); + return; + } + + const base::TimeTicks now = tick_clock_->NowTicks(); + if (!frame_buffer->ref_cnt) + frame_buffer->last_use_time = now; + + base::EraseIf( + frame_buffers_, [now](const std::unique_ptr<VP9FrameBuffer>& buf) { + constexpr base::TimeDelta kStaleFrameLimit = + base::TimeDelta::FromSeconds(10); + return !buf->ref_cnt && now - buf->last_use_time > kStaleFrameLimit; + }); } VpxVideoDecoder::VpxVideoDecoder() @@ -462,6 +522,14 @@ ResetHelper(BindToCurrentLoop(closure)); } +size_t VpxVideoDecoder::GetPoolSizeForTesting() const { + return memory_pool_->get_pool_size_for_testing(); +} + +void VpxVideoDecoder::SetTickClockForTesting(base::TickClock* tick_clock) { + memory_pool_->set_tick_clock_for_testing(tick_clock); +} + void VpxVideoDecoder::ResetHelper(const base::Closure& closure) { DCHECK(thread_checker_.CalledOnValidThread()); state_ = kNormal; @@ -540,15 +608,18 @@ vpx_codec_destroy(vpx_codec_); delete vpx_codec_; vpx_codec_ = nullptr; - base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( - memory_pool_.get()); - memory_pool_ = nullptr; } if (vpx_codec_alpha_) { vpx_codec_destroy(vpx_codec_alpha_); delete vpx_codec_alpha_; vpx_codec_alpha_ = nullptr; } + if (memory_pool_) { + base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( + memory_pool_.get()); + memory_pool_->Shutdown(); + memory_pool_ = nullptr; + } } bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer,
diff --git a/media/filters/vpx_video_decoder.h b/media/filters/vpx_video_decoder.h index 2a1d1e5..cba2a613 100644 --- a/media/filters/vpx_video_decoder.h +++ b/media/filters/vpx_video_decoder.h
@@ -20,6 +20,7 @@ namespace base { class SingleThreadTaskRunner; +class TickClock; } namespace media { @@ -47,6 +48,12 @@ const DecodeCB& decode_cb) override; void Reset(const base::Closure& closure) override; + // Returns the number of frames in the pool for testing purposes. + size_t GetPoolSizeForTesting() const; + + // Allows injection of a base::SimpleTestClock for testing. + void SetTickClockForTesting(base::TickClock* tick_clock); + private: enum DecoderState { kUninitialized,
diff --git a/media/filters/vpx_video_decoder_unittest.cc b/media/filters/vpx_video_decoder_unittest.cc new file mode 100644 index 0000000..d456455d --- /dev/null +++ b/media/filters/vpx_video_decoder_unittest.cc
@@ -0,0 +1,329 @@ +// 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 <string> +#include <vector> + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/simple_test_tick_clock.h" +#include "media/base/decoder_buffer.h" +#include "media/base/limits.h" +#include "media/base/test_data_util.h" +#include "media/base/test_helpers.h" +#include "media/base/video_frame.h" +#include "media/filters/vpx_video_decoder.h" +#include "testing/gmock/include/gmock/gmock.h" + +using ::testing::_; + +namespace media { + +class VpxVideoDecoderTest : public testing::Test { + public: + VpxVideoDecoderTest() + : decoder_(new VpxVideoDecoder()), + i_frame_buffer_(ReadTestDataFile("vp9-I-frame-320x240")) {} + + ~VpxVideoDecoderTest() override { Destroy(); } + + void Initialize() { + InitializeWithConfig(TestVideoConfig::Normal(kCodecVP9)); + } + + void InitializeWithConfigWithResult(const VideoDecoderConfig& config, + bool success) { + decoder_->Initialize( + config, false, nullptr, NewExpectedBoolCB(success), + base::Bind(&VpxVideoDecoderTest::FrameReady, base::Unretained(this))); + decoder_->SetTickClockForTesting(&test_clock_); + base::RunLoop().RunUntilIdle(); + } + + void InitializeWithConfig(const VideoDecoderConfig& config) { + InitializeWithConfigWithResult(config, true); + } + + void Reinitialize() { + InitializeWithConfig(TestVideoConfig::Large(kCodecVP9)); + } + + void Reset() { + decoder_->Reset(NewExpectedClosure()); + base::RunLoop().RunUntilIdle(); + } + + void Destroy() { + decoder_.reset(); + base::RunLoop().RunUntilIdle(); + } + + // Sets up expectations and actions to put VpxVideoDecoder in an active + // decoding state. + void ExpectDecodingState() { + EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_)); + ASSERT_EQ(1U, output_frames_.size()); + } + + // Sets up expectations and actions to put VpxVideoDecoder in an end + // of stream state. + void ExpectEndOfStreamState() { + EXPECT_EQ(DecodeStatus::OK, + DecodeSingleFrame(DecoderBuffer::CreateEOSBuffer())); + ASSERT_FALSE(output_frames_.empty()); + } + + using InputBuffers = std::vector<scoped_refptr<DecoderBuffer>>; + using OutputFrames = std::vector<scoped_refptr<VideoFrame>>; + + // Decodes all buffers in |input_buffers| and push all successfully decoded + // output frames into |output_frames|. + // Returns the last decode status returned by the decoder. + DecodeStatus DecodeMultipleFrames(const InputBuffers& input_buffers) { + for (InputBuffers::const_iterator iter = input_buffers.begin(); + iter != input_buffers.end(); ++iter) { + DecodeStatus status = Decode(*iter); + switch (status) { + case DecodeStatus::OK: + break; + case DecodeStatus::ABORTED: + NOTREACHED(); + case DecodeStatus::DECODE_ERROR: + DCHECK(output_frames_.empty()); + return status; + } + } + return DecodeStatus::OK; + } + + // Decodes the single compressed frame in |buffer| and writes the + // uncompressed output to |video_frame|. This method works with single + // and multithreaded decoders. End of stream buffers are used to trigger + // the frame to be returned in the multithreaded decoder case. + DecodeStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { + InputBuffers input_buffers; + input_buffers.push_back(std::move(buffer)); + input_buffers.push_back(DecoderBuffer::CreateEOSBuffer()); + + return DecodeMultipleFrames(input_buffers); + } + + // Decodes |i_frame_buffer_| and then decodes the data contained in + // the file named |test_file_name|. This function expects both buffers + // to decode to frames that are the same size. + void DecodeIFrameThenTestFile(const std::string& test_file_name, + const gfx::Size& expected_size) { + Initialize(); + scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name); + + InputBuffers input_buffers; + input_buffers.push_back(i_frame_buffer_); + input_buffers.push_back(buffer); + input_buffers.push_back(DecoderBuffer::CreateEOSBuffer()); + + DecodeStatus status = DecodeMultipleFrames(input_buffers); + + EXPECT_EQ(DecodeStatus::OK, status); + ASSERT_EQ(2U, output_frames_.size()); + + gfx::Size original_size = TestVideoConfig::NormalCodedSize(); + EXPECT_EQ(original_size.width(), + output_frames_[0]->visible_rect().size().width()); + EXPECT_EQ(original_size.height(), + output_frames_[0]->visible_rect().size().height()); + EXPECT_EQ(expected_size.width(), + output_frames_[1]->visible_rect().size().width()); + EXPECT_EQ(expected_size.height(), + output_frames_[1]->visible_rect().size().height()); + } + + DecodeStatus Decode(scoped_refptr<DecoderBuffer> buffer) { + DecodeStatus status; + EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status)); + + decoder_->Decode( + std::move(buffer), + base::Bind(&VpxVideoDecoderTest::DecodeDone, base::Unretained(this))); + base::RunLoop().RunUntilIdle(); + + return status; + } + + void FrameReady(const scoped_refptr<VideoFrame>& frame) { + DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); + output_frames_.push_back(frame); + } + + MOCK_METHOD1(DecodeDone, void(DecodeStatus)); + + base::MessageLoop message_loop_; + base::SimpleTestTickClock test_clock_; + std::unique_ptr<VpxVideoDecoder> decoder_; + + scoped_refptr<DecoderBuffer> i_frame_buffer_; + OutputFrames output_frames_; + + private: + DISALLOW_COPY_AND_ASSIGN(VpxVideoDecoderTest); +}; + +TEST_F(VpxVideoDecoderTest, Initialize_Normal) { + Initialize(); +} + +TEST_F(VpxVideoDecoderTest, Reinitialize_Normal) { + Initialize(); + Reinitialize(); +} + +TEST_F(VpxVideoDecoderTest, Reinitialize_AfterDecodeFrame) { + Initialize(); + ExpectDecodingState(); + Reinitialize(); +} + +TEST_F(VpxVideoDecoderTest, Reinitialize_AfterReset) { + Initialize(); + ExpectDecodingState(); + Reset(); + Reinitialize(); +} + +TEST_F(VpxVideoDecoderTest, DecodeFrame_Normal) { + Initialize(); + + // Simulate decoding a single frame. + EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_)); + ASSERT_EQ(1U, output_frames_.size()); +} + +// Decode |i_frame_buffer_| and then a frame with a larger width and verify +// the output size was adjusted. +TEST_F(VpxVideoDecoderTest, DecodeFrame_LargerWidth) { + DecodeIFrameThenTestFile("vp9-I-frame-1280x720", gfx::Size(1280, 720)); +} + +// Test resetting when decoder has initialized but not decoded. +TEST_F(VpxVideoDecoderTest, Reset_Initialized) { + Initialize(); + Reset(); +} + +// Test resetting when decoder has decoded single frame. +TEST_F(VpxVideoDecoderTest, Reset_Decoding) { + Initialize(); + ExpectDecodingState(); + Reset(); +} + +// Test resetting when decoder has hit end of stream. +TEST_F(VpxVideoDecoderTest, Reset_EndOfStream) { + Initialize(); + ExpectDecodingState(); + ExpectEndOfStreamState(); + Reset(); +} + +// Test destruction when decoder has initialized but not decoded. +TEST_F(VpxVideoDecoderTest, Destroy_Initialized) { + Initialize(); + Destroy(); +} + +// Test destruction when decoder has decoded single frame. +TEST_F(VpxVideoDecoderTest, Destroy_Decoding) { + Initialize(); + ExpectDecodingState(); + Destroy(); +} + +// Test destruction when decoder has hit end of stream. +TEST_F(VpxVideoDecoderTest, Destroy_EndOfStream) { + Initialize(); + ExpectDecodingState(); + ExpectEndOfStreamState(); + Destroy(); +} + +TEST_F(VpxVideoDecoderTest, SimpleFrameReuse) { + Initialize(); + Decode(i_frame_buffer_); + + ASSERT_EQ(1u, output_frames_.size()); + scoped_refptr<VideoFrame> frame = std::move(output_frames_.front()); + const uint8_t* old_y_data = frame->data(VideoFrame::kYPlane); + output_frames_.pop_back(); + + // Clear frame reference to return the frame to the pool. + frame = nullptr; + EXPECT_EQ(1u, decoder_->GetPoolSizeForTesting()); + + // Since we're decoding I-frames which are marked as having dependent frames, + // libvpx will still have a ref on the previous buffer. So verify we see an + // increase to two frames. + Decode(i_frame_buffer_); + EXPECT_EQ(2u, decoder_->GetPoolSizeForTesting()); + EXPECT_NE(old_y_data, output_frames_.front()->data(VideoFrame::kYPlane)); + + // Issuing another decode should reuse the first buffer now that the refs have + // been dropped by the previous decode. + Decode(i_frame_buffer_); + EXPECT_EQ(2u, decoder_->GetPoolSizeForTesting()); + + ASSERT_EQ(2u, output_frames_.size()); + EXPECT_EQ(old_y_data, output_frames_.back()->data(VideoFrame::kYPlane)); +} + +TEST_F(VpxVideoDecoderTest, SimpleFormatChange) { + scoped_refptr<DecoderBuffer> large_frame = + ReadTestDataFile("vp9-I-frame-1280x720"); + + Initialize(); + Decode(i_frame_buffer_); + Decode(i_frame_buffer_); + EXPECT_EQ(2u, decoder_->GetPoolSizeForTesting()); + output_frames_.clear(); + base::RunLoop().RunUntilIdle(); + + // Verify decoding a larger frame simply resizes one of the existing buffers. + Decode(large_frame); + EXPECT_EQ(2u, decoder_->GetPoolSizeForTesting()); +} + +TEST_F(VpxVideoDecoderTest, FrameValidAfterPoolDestruction) { + Initialize(); + Decode(i_frame_buffer_); + Destroy(); + + // Write to the Y plane. The memory tools should detect a + // use-after-free if the storage was actually removed by pool destruction. + memset(output_frames_.front()->data(VideoFrame::kYPlane), 0xff, + output_frames_.front()->rows(VideoFrame::kYPlane) * + output_frames_.front()->stride(VideoFrame::kYPlane)); +} + +TEST_F(VpxVideoDecoderTest, StaleFramesAreExpired) { + Initialize(); + Decode(i_frame_buffer_); + Decode(i_frame_buffer_); + Decode(i_frame_buffer_); + EXPECT_EQ(3u, decoder_->GetPoolSizeForTesting()); + + output_frames_.pop_back(); + output_frames_.pop_back(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(3u, decoder_->GetPoolSizeForTesting()); + + // Advance clock far enough to hit stale timer. + test_clock_.Advance(base::TimeDelta::FromMinutes(1)); + output_frames_.clear(); + base::RunLoop().RunUntilIdle(); + + // The last frame should still have a ref internal to libvpx and the frame we + // just released isn't stale yet, so only 2 frames should remain. + EXPECT_EQ(2u, decoder_->GetPoolSizeForTesting()); +} + +} // namespace media
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc index d3543f40..305ab83f 100644 --- a/media/formats/mp4/track_run_iterator.cc +++ b/media/formats/mp4/track_run_iterator.cc
@@ -505,7 +505,9 @@ const uint8_t iv_size = GetIvSize(i); const bool has_subsamples = info_size > iv_size; SampleEncryptionEntry& entry = sample_encryption_entries[i]; - RCHECK(entry.Parse(&reader, iv_size, has_subsamples)); + RCHECK_MEDIA_LOGGED( + entry.Parse(&reader, iv_size, has_subsamples), media_log_, + "SampleEncryptionEntry parse failed when caching aux info"); #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) // if we don't have a per-sample IV, get the constant IV. if (!iv_size) {
diff --git a/media/gpu/mojo/OWNERS b/media/gpu/mojo/OWNERS index 08850f4..e806486 100644 --- a/media/gpu/mojo/OWNERS +++ b/media/gpu/mojo/OWNERS
@@ -1,2 +1,6 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_typemap_traits*.*=set noparent +per-file *_typemap_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/media/gpu/mojo/jpeg_decoder.mojom b/media/gpu/mojo/jpeg_decoder.mojom index 3264ee7..c9532a3 100644 --- a/media/gpu/mojo/jpeg_decoder.mojom +++ b/media/gpu/mojo/jpeg_decoder.mojom
@@ -9,7 +9,7 @@ import "ui/gfx/geometry/mojo/geometry.mojom"; // Decode errors (see media/video/jpeg_decode_accelerator.h). -enum Error { +enum DecodeError { NO_ERRORS, INVALID_ARGUMENT, UNREADABLE_INPUT, @@ -51,7 +51,7 @@ // |input_buffer| and |error| is the error code. Decode(BitstreamBuffer input_buffer, gfx.mojom.Size coded_size, handle<shared_buffer> output_handle, uint32 output_buffer_size) - => (int32 bitstream_buffer_id, Error error); + => (int32 bitstream_buffer_id, DecodeError error); // TODO(c.padhi): This method might not be required, see // http://crbug.com/699255.
diff --git a/media/gpu/mojo/jpeg_decoder.typemap b/media/gpu/mojo/jpeg_decoder.typemap new file mode 100644 index 0000000..9375495 --- /dev/null +++ b/media/gpu/mojo/jpeg_decoder.typemap
@@ -0,0 +1,20 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//media/gpu/mojo/jpeg_decoder.mojom" + +public_headers = [ "//media/video/jpeg_decode_accelerator.h" ] + +traits_headers = [ "//media/gpu/mojo/jpeg_decoder_typemap_traits.h" ] + +sources = [ + "//media/gpu/mojo/jpeg_decoder_typemap_traits.cc", +] + +deps = [ + "//base", +] + +type_mappings = + [ "media.mojom.DecodeError=media::JpegDecodeAccelerator::Error" ]
diff --git a/media/gpu/mojo/jpeg_decoder_typemap_traits.cc b/media/gpu/mojo/jpeg_decoder_typemap_traits.cc new file mode 100644 index 0000000..e0cbaf2f --- /dev/null +++ b/media/gpu/mojo/jpeg_decoder_typemap_traits.cc
@@ -0,0 +1,62 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/gpu/mojo/jpeg_decoder_typemap_traits.h" + +#include "base/logging.h" + +namespace mojo { + +// static +media::mojom::DecodeError +EnumTraits<media::mojom::DecodeError, media::JpegDecodeAccelerator::Error>:: + ToMojom(media::JpegDecodeAccelerator::Error error) { + switch (error) { + case media::JpegDecodeAccelerator::NO_ERRORS: + return media::mojom::DecodeError::NO_ERRORS; + case media::JpegDecodeAccelerator::INVALID_ARGUMENT: + return media::mojom::DecodeError::INVALID_ARGUMENT; + case media::JpegDecodeAccelerator::UNREADABLE_INPUT: + return media::mojom::DecodeError::UNREADABLE_INPUT; + case media::JpegDecodeAccelerator::PARSE_JPEG_FAILED: + return media::mojom::DecodeError::PARSE_JPEG_FAILED; + case media::JpegDecodeAccelerator::UNSUPPORTED_JPEG: + return media::mojom::DecodeError::UNSUPPORTED_JPEG; + case media::JpegDecodeAccelerator::PLATFORM_FAILURE: + return media::mojom::DecodeError::PLATFORM_FAILURE; + } + NOTREACHED(); + return media::mojom::DecodeError::NO_ERRORS; +} + +// static +bool EnumTraits<media::mojom::DecodeError, + media::JpegDecodeAccelerator::Error>:: + FromMojom(media::mojom::DecodeError error, + media::JpegDecodeAccelerator::Error* out) { + switch (error) { + case media::mojom::DecodeError::NO_ERRORS: + *out = media::JpegDecodeAccelerator::Error::NO_ERRORS; + return true; + case media::mojom::DecodeError::INVALID_ARGUMENT: + *out = media::JpegDecodeAccelerator::Error::INVALID_ARGUMENT; + return true; + case media::mojom::DecodeError::UNREADABLE_INPUT: + *out = media::JpegDecodeAccelerator::Error::UNREADABLE_INPUT; + return true; + case media::mojom::DecodeError::PARSE_JPEG_FAILED: + *out = media::JpegDecodeAccelerator::Error::PARSE_JPEG_FAILED; + return true; + case media::mojom::DecodeError::UNSUPPORTED_JPEG: + *out = media::JpegDecodeAccelerator::Error::UNSUPPORTED_JPEG; + return true; + case media::mojom::DecodeError::PLATFORM_FAILURE: + *out = media::JpegDecodeAccelerator::Error::PLATFORM_FAILURE; + return true; + } + NOTREACHED(); + return false; +} + +} // namespace mojo
diff --git a/media/gpu/mojo/jpeg_decoder_typemap_traits.h b/media/gpu/mojo/jpeg_decoder_typemap_traits.h new file mode 100644 index 0000000..0e9d612 --- /dev/null +++ b/media/gpu/mojo/jpeg_decoder_typemap_traits.h
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_GPU_MOJO_JPEG_DECODER_TYPEMAP_TRAITS_H_ +#define MEDIA_GPU_MOJO_JPEG_DECODER_TYPEMAP_TRAITS_H_ + +#include "media/gpu/mojo/jpeg_decoder.mojom.h" +#include "media/video/jpeg_decode_accelerator.h" + +namespace mojo { + +template <> +struct EnumTraits<media::mojom::DecodeError, + media::JpegDecodeAccelerator::Error> { + static media::mojom::DecodeError ToMojom( + media::JpegDecodeAccelerator::Error error); + + static bool FromMojom(media::mojom::DecodeError input, + media::JpegDecodeAccelerator::Error* out); +}; + +} // namespace mojo + +#endif // MEDIA_GPU_MOJO_JPEG_DECODER_TYPEMAP_TRAITS_H_
diff --git a/media/gpu/mojo/typemaps.gni b/media/gpu/mojo/typemaps.gni new file mode 100644 index 0000000..d1f2caf --- /dev/null +++ b/media/gpu/mojo/typemaps.gni
@@ -0,0 +1,5 @@ +# 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. + +typemaps = [ "//media/gpu/mojo/jpeg_decoder.typemap" ]
diff --git a/media/renderers/mock_gpu_memory_buffer_video_frame_pool.h b/media/renderers/mock_gpu_memory_buffer_video_frame_pool.h index 79803d80..2305b30 100644 --- a/media/renderers/mock_gpu_memory_buffer_video_frame_pool.h +++ b/media/renderers/mock_gpu_memory_buffer_video_frame_pool.h
@@ -14,6 +14,8 @@ public: MockGpuMemoryBufferVideoFramePool(std::vector<base::Closure>* frame_ready_cbs) : frame_ready_cbs_(frame_ready_cbs) {} + ~MockGpuMemoryBufferVideoFramePool() override {} + void MaybeCreateHardwareFrame(const scoped_refptr<VideoFrame>& video_frame, const FrameReadyCB& frame_ready_cb) override;
diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h index 7f542572..07e6c9a 100644 --- a/media/renderers/video_renderer_impl.h +++ b/media/renderers/video_renderer_impl.h
@@ -219,6 +219,8 @@ std::unique_ptr<VideoFrameStream> video_frame_stream_; // Pool of GpuMemoryBuffers and resources used to create hardware frames. + // Ensure this is destructed after |algorithm_| for optimal memory release + // when a frames are still held by the compositor. std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_; MediaLog* media_log_; @@ -288,7 +290,9 @@ std::unique_ptr<base::TickClock> tick_clock_; // Algorithm for selecting which frame to render; manages frames and all - // timing related information. + // timing related information. Ensure this is destructed before + // |gpu_memory_buffer_pool_| for optimal memory release when a frames are + // still held by the compositor. std::unique_ptr<VideoRendererAlgorithm> algorithm_; // Indicates that Render() was called with |background_rendering| set to true,
diff --git a/media/test/data/eme_player_js/clearkey_player.js b/media/test/data/eme_player_js/clearkey_player.js index 9324c99..2b69199 100644 --- a/media/test/data/eme_player_js/clearkey_player.js +++ b/media/test/data/eme_player_js/clearkey_player.js
@@ -21,10 +21,11 @@ ClearKeyPlayer.prototype.onMessage = function(message) { Utils.timeLog('MediaKeySession onMessage', message); - var mediaKeySession = message.target; - var keyId = Utils.extractFirstLicenseKeyId(message.message); - var key = Utils.getDefaultKey(this.testConfig.forceInvalidResponse); - var jwkSet = Utils.createJWKData(keyId, key); + const mediaKeySession = message.target; + const keyId = Utils.extractFirstLicenseKeyId(message.message); + const key = Utils.getDefaultKey(this.testConfig.forceInvalidResponse); + const jwkSet = Utils.createJWKData(keyId, key); + const keySystem = this.testConfig.keySystem; // Number of milliseconds in 100 years, which is approximately // 100 * 365 * 24 * 60 * 60 * 1000. @@ -40,7 +41,7 @@ // - For other EXTERNAL_CLEARKEY variants, expiration is explicitly set to // NaN. var expiration = mediaKeySession.expiration; - if (this.testConfig.keySystem == EXTERNAL_CLEARKEY_RENEWAL) { + if (keySystem == EXTERNAL_CLEARKEY_RENEWAL) { if (isNaN(expiration) || expiration != ECK_RENEWAL_EXPIRATION) { Utils.timeLog('Unexpected expiration: ', expiration); Utils.failTest(error, EME_UPDATE_FAILED);
diff --git a/media/test/data/eme_player_js/player_utils.js b/media/test/data/eme_player_js/player_utils.js index d48e586..7defd7a 100644 --- a/media/test/data/eme_player_js/player_utils.js +++ b/media/test/data/eme_player_js/player_utils.js
@@ -68,17 +68,39 @@ try { if (player.testConfig.sessionToLoad) { - Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad); - player.session = - message.target.mediaKeys.createSession('persistent-license'); - addMediaKeySessionListeners(player.session); - player.session.load(player.testConfig.sessionToLoad) + // Create a session to load using a new MediaKeys. + // TODO(jrummell): Add a test that covers remove(). + player.access.createMediaKeys() + .then(function(mediaKeys) { + // As the tests run with a different origin every time, there is + // no way currently to create a session in one test and then load + // it in a subsequent test (https://crbug.com/715349). + // So if |sessionToLoad| is 'LoadableSession', create a session + // that can be loaded and use that session to load. Otherwise + // use the name provided (which allows for testing load() on a + // session which doesn't exist). + if (player.testConfig.sessionToLoad == 'LoadableSession') { + return Utils.createSessionToLoad( + mediaKeys, player.testConfig.sessionToLoad); + } else { + return player.testConfig.sessionToLoad; + } + }) + .then(function(sessionId) { + Utils.timeLog('Loading session: ' + sessionId); + player.session = + message.target.mediaKeys.createSession('persistent-license'); + addMediaKeySessionListeners(player.session); + return player.session.load(sessionId); + }) .then( function(result) { if (!result) Utils.failTest('Session not found.', EME_SESSION_NOT_FOUND); }, - function(error) { Utils.failTest(error, EME_LOAD_FAILED); }); + function(error) { + Utils.failTest(error, EME_LOAD_FAILED); + }); } else { Utils.timeLog('Creating new media key session for initDataType: ' + message.initDataType + ', initData: ' + @@ -163,12 +185,19 @@ return navigator .requestMediaKeySystemAccess(player.testConfig.keySystem, [config]) - .then(function(access) { return access.createMediaKeys(); }) + .then(function(access) { + player.access = access; + return access.createMediaKeys(); + }) .then(function(mediaKeys) { return player.video.setMediaKeys(mediaKeys); }) - .then(function(result) { return player; }) - .catch(function(error) { Utils.failTest(error, NOTSUPPORTEDERROR); }); + .then(function(result) { + return player; + }) + .catch(function(error) { + Utils.failTest(error, NOTSUPPORTEDERROR); + }); }; PlayerUtils.setVideoSource = function(player) {
diff --git a/media/test/data/eme_player_js/utils.js b/media/test/data/eme_player_js/utils.js index 653677fa..c74bfb2 100644 --- a/media/test/data/eme_player_js/utils.js +++ b/media/test/data/eme_player_js/utils.js
@@ -42,24 +42,24 @@ return new Uint8Array(msg); }; +// Encodes data (Uint8Array) into base64url string. There is no '=' padding, +// and the characters '-' and '_' must be used instead of '+' and '/', +// respectively. +Utils.base64urlEncode = function(data) { + var result = btoa(String.fromCharCode.apply(null, data)); + return result.replace(/=+$/g, '').replace(/\+/g, '-').replace(/\//g, '_'); +}; + Utils.createJWKData = function(keyId, key) { // JWK routines copied from third_party/WebKit/LayoutTests/media/ // encrypted-media/encrypted-media-utils.js - // Encodes data (Uint8Array) into base64url string. There is no '=' padding, - // and the characters '-' and '_' must be used instead of '+' and '/', - // respectively. - function base64urlEncode(data) { - var result = btoa(String.fromCharCode.apply(null, data)); - return result.replace(/=+$/g, '').replace(/\+/g, "-").replace(/\//g, "_"); - } - // Creates a JWK from raw key ID and key. function createJWK(keyId, key) { var jwk = '{"kty":"oct","alg":"A128KW","kid":"'; - jwk += base64urlEncode(keyId); + jwk += Utils.base64urlEncode(Utils.convertToUint8Array(keyId)); jwk += '","k":"'; - jwk += base64urlEncode(key); + jwk += Utils.base64urlEncode(Utils.convertToUint8Array(key)); jwk += '"}'; return jwk; } @@ -79,6 +79,13 @@ return Utils.convertToUint8Array(createJWKSet(createJWK(keyId, key))); }; +Utils.createKeyIdsInitializationData = function(keyId) { + var initData = '{"kids":["'; + initData += Utils.base64urlEncode(Utils.convertToUint8Array(keyId)); + initData += '"]}'; + return Utils.convertToUint8Array(initData); +}; + Utils.extractFirstLicenseKeyId = function(message) { // Decodes data (Uint8Array) from base64url string. function base64urlDecode(data) { @@ -97,7 +104,7 @@ // Not valid JSON, so return message untouched as Uint8Array. return Utils.convertToUint8Array(message); } -} +}; Utils.documentLog = function(log, success, time) { if (!docLogs) @@ -269,3 +276,47 @@ } console.log(logString); }; + +// Convert an event into a promise. When |event| is fired on |object|, +// call |func| to handle the event and either resolve or reject the promise. +Utils.waitForEvent = function(object, event, func) { + return new Promise(function(resolve, reject) { + object.addEventListener(event, function listener(e) { + object.removeEventListener(event, listener); + func(e, resolve, reject); + }); + }); +}; + +// Create a loadable session and return the session ID of it as a promise. +Utils.createSessionToLoad = function(mediaKeys, request) { + // Create a persistent session and on the message event initialize it + // with key ID |KEY_ID| and key |KEY|. Then close the session, and resolve + // the promise providing the session ID. + const keySession = mediaKeys.createSession('persistent-license'); + var promise = + Utils.waitForEvent(keySession, 'message', function(e, resolve, reject) { + const session = e.target; + return session.update(Utils.createJWKData(KEY_ID, KEY)) + .then(function(result) { + Utils.timeLog( + 'Persistent session ' + session.sessionId + ' created'); + return session.close(); + }) + .then(function(result) { + // Make sure the session is properly closed before continuing on. + return session.closed; + }) + .then(function(result) { + Utils.timeLog( + 'Persistent session ' + session.sessionId + + ' saved and closed'); + resolve(session.sessionId); + }); + }); + return keySession + .generateRequest('keyids', Utils.createKeyIdsInitializationData(KEY_ID)) + .then(function() { + return promise; + }); +};
diff --git a/media/test/data/vp9-I-frame-1280x720 b/media/test/data/vp9-I-frame-1280x720 new file mode 100644 index 0000000..35e3b137 --- /dev/null +++ b/media/test/data/vp9-I-frame-1280x720 Binary files differ
diff --git a/media/test/data/vp9-I-frame-320x240 b/media/test/data/vp9-I-frame-320x240 new file mode 100644 index 0000000..dc3ab5c --- /dev/null +++ b/media/test/data/vp9-I-frame-320x240 Binary files differ
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 3f0f14b..9d7b0ac 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -20,6 +20,7 @@ #include "base/location.h" #include "base/macros.h" #include "base/strings/stringprintf.h" +#include "base/time/default_tick_clock.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/trace_event.h" @@ -51,7 +52,9 @@ : media_task_runner_(media_task_runner), worker_task_runner_(worker_task_runner), gpu_factories_(gpu_factories), - output_format_(GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED) { + output_format_(GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED), + tick_clock_(&default_tick_clock_), + in_shutdown_(false) { DCHECK(media_task_runner_); DCHECK(worker_task_runner_); } @@ -68,6 +71,13 @@ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) override; + // Shuts down the frame pool and releases all frames in |frames_|. + // Once this is called frames will no longer be inserted back into + // |frames_|. + void Shutdown(); + + void SetTickClockForTesting(base::TickClock* tick_clock); + private: friend class base::RefCountedThreadSafe< GpuMemoryBufferVideoFramePool::PoolImpl>; @@ -83,16 +93,28 @@ }; // All the resources needed to compose a frame. + // TODO(dalecurtis): The method of use marking used is very brittle + // and prone to leakage. Switch this to pass around std::unique_ptr + // such that callers own resources explicitly. struct FrameResources { explicit FrameResources(const gfx::Size& size) : size(size) {} - void SetIsInUse(bool in_use) { in_use_ = in_use; } - bool IsInUse() const { return in_use_; } + void MarkUsed() { + is_used_ = true; + last_use_time_ = base::TimeTicks(); + } + void MarkUnused(base::TimeTicks last_use_time) { + is_used_ = false; + last_use_time_ = last_use_time; + } + bool is_used() const { return is_used_; } + base::TimeTicks last_use_time() const { return last_use_time_; } const gfx::Size size; PlaneResource plane_resources[VideoFrame::kMaxPlanes]; private: - bool in_use_ = true; + bool is_used_ = true; + base::TimeTicks last_use_time_; }; // Copy |video_frame| data into |frame_resouces| @@ -154,6 +176,12 @@ GpuVideoAcceleratorFactories::OutputFormat output_format_; + // |tick_clock_| is always &|default_tick_clock_| outside of testing. + base::DefaultTickClock default_tick_clock_; + base::TickClock* tick_clock_; + + bool in_shutdown_; + DISALLOW_COPY_AND_ASSIGN(PoolImpl); }; @@ -470,7 +498,7 @@ buffer_size_in_bytes); dump->AddScalar("free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, - frame_resources->IsInUse() ? 0 : buffer_size_in_bytes); + frame_resources->is_used() ? 0 : buffer_size_in_bytes); auto shared_buffer_guid = plane_resource.gpu_memory_buffer->GetGUIDForTracing( tracing_process_id); @@ -541,6 +569,7 @@ if (!buffer || !buffer->Map()) { DLOG(ERROR) << "Could not get or Map() buffer"; + frame_resources->MarkUnused(tick_clock_->NowTicks()); return; } } @@ -612,6 +641,7 @@ std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock( gpu_factories_->GetGLContextLock()); if (!lock) { + frame_resources->MarkUnused(tick_clock_->NowTicks()); frame_ready_cb.Run(video_frame); return; } @@ -668,6 +698,7 @@ video_frame->timestamp()); if (!frame) { + frame_resources->MarkUnused(tick_clock_->NowTicks()); release_mailbox_callback.Run(gpu::SyncToken()); frame_ready_cb.Run(video_frame); return; @@ -712,14 +743,27 @@ // Destroy all the resources posting one task per FrameResources // to the |media_task_runner_|. GpuMemoryBufferVideoFramePool::PoolImpl::~PoolImpl() { + DCHECK(in_shutdown_); +} + +void GpuMemoryBufferVideoFramePool::PoolImpl::Shutdown() { // Delete all the resources on the media thread. - while (!resources_pool_.empty()) { - FrameResources* frame_resources = resources_pool_.front(); - resources_pool_.pop_front(); + in_shutdown_ = true; + for (auto* frame_resources : resources_pool_) { + // Will be deleted later upon return to pool. + if (frame_resources->is_used()) + continue; + media_task_runner_->PostTask( FROM_HERE, base::Bind(&PoolImpl::DeleteFrameResources, gpu_factories_, base::Owned(frame_resources))); } + resources_pool_.clear(); +} + +void GpuMemoryBufferVideoFramePool::PoolImpl::SetTickClockForTesting( + base::TickClock* tick_clock) { + tick_clock_ = tick_clock; } // Tries to find the resources in the pool or create them. @@ -728,12 +772,14 @@ GpuMemoryBufferVideoFramePool::PoolImpl::GetOrCreateFrameResources( const gfx::Size& size, GpuVideoAcceleratorFactories::OutputFormat format) { + DCHECK(!in_shutdown_); + auto it = resources_pool_.begin(); while (it != resources_pool_.end()) { FrameResources* frame_resources = *it; - if (!frame_resources->IsInUse()) { + if (!frame_resources->is_used()) { if (AreFrameResourcesCompatible(frame_resources, size)) { - frame_resources->SetIsInUse(true); + frame_resources->MarkUsed(); return frame_resources; } else { resources_pool_.erase(it++); @@ -809,14 +855,29 @@ FrameResources* frame_resources, const gpu::SyncToken& release_sync_token) { DCHECK(media_task_runner_->BelongsToCurrentThread()); - auto it = std::find(resources_pool_.begin(), resources_pool_.end(), - frame_resources); - DCHECK(it != resources_pool_.end()); - // We want the pool to behave in a FIFO way. - // This minimizes the chances of locking the buffer that might be - // still needed for drawing. - std::swap(*it, resources_pool_.back()); - frame_resources->SetIsInUse(false); + if (in_shutdown_) { + DeleteFrameResources(gpu_factories_, frame_resources); + delete frame_resources; + return; + } + + const base::TimeTicks now = tick_clock_->NowTicks(); + frame_resources->MarkUnused(now); + auto it = resources_pool_.begin(); + while (it != resources_pool_.end()) { + FrameResources* frame_resources = *it; + + constexpr base::TimeDelta kStaleFrameLimit = + base::TimeDelta::FromSeconds(10); + if (!frame_resources->is_used() && + now - frame_resources->last_use_time() > kStaleFrameLimit) { + resources_pool_.erase(it++); + DeleteFrameResources(gpu_factories_, frame_resources); + delete frame_resources; + } else { + it++; + } + } } GpuMemoryBufferVideoFramePool::GpuMemoryBufferVideoFramePool() {} @@ -832,6 +893,11 @@ } GpuMemoryBufferVideoFramePool::~GpuMemoryBufferVideoFramePool() { + // May be nullptr in tests. + if (!pool_impl_) + return; + + pool_impl_->Shutdown(); base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( pool_impl_.get()); } @@ -843,4 +909,9 @@ pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); } +void GpuMemoryBufferVideoFramePool::SetTickClockForTesting( + base::TickClock* tick_clock) { + pool_impl_->SetTickClockForTesting(tick_clock); +} + } // namespace media
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.h b/media/video/gpu_memory_buffer_video_frame_pool.h index b7c16b5a..fa060a7 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.h +++ b/media/video/gpu_memory_buffer_video_frame_pool.h
@@ -12,6 +12,7 @@ namespace base { class SingleThreadTaskRunner; +class TickClock; } namespace media { @@ -53,6 +54,9 @@ const scoped_refptr<VideoFrame>& video_frame, const FrameReadyCB& frame_ready_cb); + // Allows injection of a base::SimpleTestClock for testing. + void SetTickClockForTesting(base::TickClock* tick_clock); + private: class PoolImpl; scoped_refptr<PoolImpl> pool_impl_;
diff --git a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc index c403dc6c..ede05851 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> #include "base/bind.h" +#include "base/test/simple_test_tick_clock.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "gpu/command_buffer/client/gles2_interface_stub.h" @@ -19,10 +20,9 @@ namespace { class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub { public: - unsigned gen_textures = 0u; void GenTextures(GLsizei n, GLuint* textures) override { DCHECK_EQ(1, n); - *textures = ++gen_textures; + *textures = ++gen_textures_count_; } void ShallowFlushCHROMIUM() override { @@ -59,10 +59,20 @@ *reinterpret_cast<unsigned*>(mailbox) = ++mailbox_; } + void DeleteTextures(GLsizei n, const GLuint* textures) override { + ++deleted_textures_; + DCHECK_LE(deleted_textures_, gen_textures_count_); + } + + unsigned gen_textures_count() const { return gen_textures_count_; } + unsigned deleted_textures_count() const { return deleted_textures_; } + private: uint64_t next_fence_sync_ = 1u; uint64_t flushed_fence_sync_ = 0u; unsigned mailbox_ = 0u; + unsigned gen_textures_count_ = 0u; + unsigned deleted_textures_ = 0u; }; } // unnamed namespace @@ -71,6 +81,10 @@ public: GpuMemoryBufferVideoFramePoolTest() {} void SetUp() override { + // Seed test clock with some dummy non-zero value to avoid confusion with + // empty base::TimeTicks values. + test_clock_.Advance(base::TimeDelta::FromSeconds(1234)); + gles2_.reset(new TestGLES2Interface); media_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner); copy_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner); @@ -81,6 +95,7 @@ gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool( media_task_runner_, copy_task_runner_.get(), mock_gpu_factories_.get())); + gpu_memory_buffer_pool_->SetTickClockForTesting(&test_clock_); } void TearDown() override { @@ -123,6 +138,7 @@ } protected: + base::SimpleTestTickClock test_clock_; std::unique_ptr<MockGpuVideoAcceleratorFactories> mock_gpu_factories_; std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_; scoped_refptr<base::TestSimpleTaskRunner> media_task_runner_; @@ -160,7 +176,7 @@ RunUntilIdle(); EXPECT_NE(software_frame.get(), frame.get()); - EXPECT_EQ(3u, gles2_->gen_textures); + EXPECT_EQ(3u, gles2_->gen_textures_count()); } TEST_F(GpuMemoryBufferVideoFramePoolTest, ReuseFirstResource) { @@ -173,7 +189,7 @@ EXPECT_NE(software_frame.get(), frame.get()); gpu::Mailbox mailbox = frame->mailbox_holder(0).mailbox; const gpu::SyncToken sync_token = frame->mailbox_holder(0).sync_token; - EXPECT_EQ(3u, gles2_->gen_textures); + EXPECT_EQ(3u, gles2_->gen_textures_count()); scoped_refptr<VideoFrame> frame2; gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( @@ -182,7 +198,7 @@ EXPECT_NE(software_frame.get(), frame2.get()); EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox); - EXPECT_EQ(6u, gles2_->gen_textures); + EXPECT_EQ(6u, gles2_->gen_textures_count()); frame = nullptr; frame2 = nullptr; @@ -193,7 +209,7 @@ RunUntilIdle(); EXPECT_NE(software_frame.get(), frame.get()); - EXPECT_EQ(6u, gles2_->gen_textures); + EXPECT_EQ(6u, gles2_->gen_textures_count()); EXPECT_EQ(frame->mailbox_holder(0).mailbox, mailbox); EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token); } @@ -205,7 +221,7 @@ base::Bind(MaybeCreateHardwareFrameCallback, &frame)); RunUntilIdle(); - EXPECT_EQ(3u, gles2_->gen_textures); + EXPECT_EQ(3u, gles2_->gen_textures_count()); frame = nullptr; RunUntilIdle(); @@ -213,7 +229,7 @@ CreateTestYUVVideoFrame(4), base::Bind(MaybeCreateHardwareFrameCallback, &frame)); RunUntilIdle(); - EXPECT_EQ(6u, gles2_->gen_textures); + EXPECT_EQ(6u, gles2_->gen_textures_count()); } TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareUYUVFrame) { @@ -227,7 +243,7 @@ RunUntilIdle(); EXPECT_NE(software_frame.get(), frame.get()); - EXPECT_EQ(1u, gles2_->gen_textures); + EXPECT_EQ(1u, gles2_->gen_textures_count()); EXPECT_TRUE(frame->metadata()->IsTrue( media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); } @@ -243,7 +259,7 @@ RunUntilIdle(); EXPECT_NE(software_frame.get(), frame.get()); - EXPECT_EQ(1u, gles2_->gen_textures); + EXPECT_EQ(1u, gles2_->gen_textures_count()); EXPECT_TRUE(frame->metadata()->IsTrue( media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); } @@ -259,7 +275,7 @@ RunUntilIdle(); EXPECT_NE(software_frame.get(), frame.get()); - EXPECT_EQ(2u, gles2_->gen_textures); + EXPECT_EQ(2u, gles2_->gen_textures_count()); EXPECT_TRUE(frame->metadata()->IsTrue( media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); } @@ -277,7 +293,75 @@ RunUntilIdle(); EXPECT_NE(software_frame.get(), frame.get()); - EXPECT_EQ(3u, gles2_->gen_textures); + EXPECT_EQ(3u, gles2_->gen_textures_count()); +} + +TEST_F(GpuMemoryBufferVideoFramePoolTest, ShutdownReleasesUnusedResources) { + scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); + scoped_refptr<VideoFrame> frame_1; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame_1)); + + RunUntilIdle(); + EXPECT_NE(software_frame.get(), frame_1.get()); + + scoped_refptr<VideoFrame> frame_2; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame_2)); + RunUntilIdle(); + EXPECT_NE(software_frame.get(), frame_2.get()); + EXPECT_NE(frame_1.get(), frame_2.get()); + + EXPECT_EQ(6u, gles2_->gen_textures_count()); + EXPECT_EQ(0u, gles2_->deleted_textures_count()); + + // Drop frame and verify that resources are still available for reuse. + frame_1 = nullptr; + RunUntilIdle(); + EXPECT_EQ(6u, gles2_->gen_textures_count()); + EXPECT_EQ(0u, gles2_->deleted_textures_count()); + + // While still holding onto the second frame, destruct the frame pool and + // verify that the inner pool releases the resources for the first frame. + gpu_memory_buffer_pool_.reset(); + RunUntilIdle(); + + EXPECT_EQ(6u, gles2_->gen_textures_count()); + EXPECT_EQ(3u, gles2_->deleted_textures_count()); +} + +TEST_F(GpuMemoryBufferVideoFramePoolTest, StaleFramesAreExpired) { + scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); + scoped_refptr<VideoFrame> frame_1; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame_1)); + + RunUntilIdle(); + EXPECT_NE(software_frame.get(), frame_1.get()); + + scoped_refptr<VideoFrame> frame_2; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame_2)); + RunUntilIdle(); + EXPECT_NE(software_frame.get(), frame_2.get()); + EXPECT_NE(frame_1.get(), frame_2.get()); + + EXPECT_EQ(6u, gles2_->gen_textures_count()); + EXPECT_EQ(0u, gles2_->deleted_textures_count()); + + // Drop frame and verify that resources are still available for reuse. + frame_1 = nullptr; + RunUntilIdle(); + EXPECT_EQ(6u, gles2_->gen_textures_count()); + EXPECT_EQ(0u, gles2_->deleted_textures_count()); + + // Advance clock far enough to hit stale timer; ensure only frame_1 has its + // resources released. + test_clock_.Advance(base::TimeDelta::FromMinutes(1)); + frame_2 = nullptr; + RunUntilIdle(); + EXPECT_EQ(6u, gles2_->gen_textures_count()); + EXPECT_EQ(3u, gles2_->deleted_textures_count()); } } // namespace media
diff --git a/mojo/android/BUILD.gn b/mojo/android/BUILD.gn index 525e7fc..179eb6f 100644 --- a/mojo/android/BUILD.gn +++ b/mojo/android/BUILD.gn
@@ -140,6 +140,8 @@ "//mojo/public/cpp/test_support:test_utils", ] defines = [ "UNIT_TEST" ] + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + configs += [ "//build/config/android:hide_all_but_jni" ] } instrumentation_test_apk("mojo_test_apk") {
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h index d2f8ecfd72..044b9d0 100644 --- a/mojo/public/cpp/bindings/lib/array_serialization.h +++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -278,8 +278,7 @@ BelongsTo<typename MojomType::Element, MojomTypeCategory::ASSOCIATED_INTERFACE | MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST | - MojomTypeCategory::HANDLE | - MojomTypeCategory::INTERFACE | + MojomTypeCategory::HANDLE | MojomTypeCategory::INTERFACE | MojomTypeCategory::INTERFACE_REQUEST>::value>::type> { using UserType = typename std::remove_const<MaybeConstUserType>::type; using Data = typename MojomTypeTraits<MojomType>::Data; @@ -289,14 +288,10 @@ static size_t GetSerializedSize(UserTypeIterator* input, SerializationContext* context) { size_t element_count = input->GetSize(); - if (BelongsTo<Element, - MojomTypeCategory::ASSOCIATED_INTERFACE | - MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST>::value) { - for (size_t i = 0; i < element_count; ++i) { - typename UserTypeIterator::GetNextResult next = input->GetNext(); - size_t size = PrepareToSerialize<Element>(next, context); - DCHECK_EQ(size, 0u); - } + for (size_t i = 0; i < element_count; ++i) { + typename UserTypeIterator::GetNextResult next = input->GetNext(); + size_t size = PrepareToSerialize<Element>(next, context); + DCHECK_EQ(size, 0u); } return sizeof(Data) + Align(element_count * sizeof(typename Data::Element)); } @@ -509,7 +504,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; ArrayIterator<Traits, MaybeConstUserType> iterator(input); return Impl::GetSerializedSize(&iterator, context); @@ -520,7 +517,7 @@ Data** output, const ContainerValidateParams* validate_params, SerializationContext* context) { - if (!CallIsNullIfExists<Traits>(input)) { + if (!context->IsNextFieldNull()) { MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( validate_params->expected_num_elements != 0 && Traits::GetSize(input) != validate_params->expected_num_elements,
diff --git a/mojo/public/cpp/bindings/lib/handle_interface_serialization.h b/mojo/public/cpp/bindings/lib/handle_interface_serialization.h index 1641d55e..cfc2fd9f 100644 --- a/mojo/public/cpp/bindings/lib/handle_interface_serialization.h +++ b/mojo/public/cpp/bindings/lib/handle_interface_serialization.h
@@ -108,18 +108,18 @@ struct Serializer<InterfacePtrDataView<Base>, InterfacePtr<T>> { static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch."); - static size_t PrepareToSerialize(const InterfacePtr<T>& input, + static size_t PrepareToSerialize(InterfacePtr<T>& input, SerializationContext* context) { + InterfacePtrInfo<T> info = input.PassInterface(); + context->handles.AddInterfaceInfo(info.PassHandle(), info.version()); return 0; } - static void Serialize(InterfacePtr<T>& input, + static void Serialize(const InterfacePtr<T>& input, Interface_Data* output, SerializationContext* context) { - InterfacePtrInfo<T> info = input.PassInterface(); - output->handle = - context->handles.AddHandle(ScopedHandle::From(info.PassHandle())); - output->version = info.version(); + DCHECK(!input.is_bound()); + context->handles.ConsumeNextSerializedInterfaceInfo(output); } static bool Deserialize(Interface_Data* input, @@ -136,16 +136,17 @@ struct Serializer<InterfaceRequestDataView<Base>, InterfaceRequest<T>> { static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch."); - static size_t PrepareToSerialize(const InterfaceRequest<T>& input, + static size_t PrepareToSerialize(InterfaceRequest<T>& input, SerializationContext* context) { + context->handles.AddHandle(ScopedHandle::From(input.PassMessagePipe())); return 0; } - static void Serialize(InterfaceRequest<T>& input, + static void Serialize(const InterfaceRequest<T>& input, Handle_Data* output, SerializationContext* context) { - *output = - context->handles.AddHandle(ScopedHandle::From(input.PassMessagePipe())); + DCHECK(!input.is_pending()); + context->handles.ConsumeNextSerializedHandle(output); } static bool Deserialize(Handle_Data* input, @@ -159,15 +160,17 @@ template <typename T> struct Serializer<ScopedHandleBase<T>, ScopedHandleBase<T>> { - static size_t PrepareToSerialize(const ScopedHandleBase<T>& input, + static size_t PrepareToSerialize(ScopedHandleBase<T>& input, SerializationContext* context) { + context->handles.AddHandle(ScopedHandle::From(std::move(input))); return 0; } - static void Serialize(ScopedHandleBase<T>& input, + static void Serialize(const ScopedHandleBase<T>& input, Handle_Data* output, SerializationContext* context) { - *output = context->handles.AddHandle(ScopedHandle::From(std::move(input))); + DCHECK(!input.is_valid()); + context->handles.ConsumeNextSerializedHandle(output); } static bool Deserialize(Handle_Data* input,
diff --git a/mojo/public/cpp/bindings/lib/map_serialization.h b/mojo/public/cpp/bindings/lib/map_serialization.h index 718a763..08287608 100644 --- a/mojo/public/cpp/bindings/lib/map_serialization.h +++ b/mojo/public/cpp/bindings/lib/map_serialization.h
@@ -97,7 +97,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; size_t struct_overhead = sizeof(Data); @@ -118,7 +120,7 @@ SerializationContext* context) { DCHECK(validate_params->key_validate_params); DCHECK(validate_params->element_validate_params); - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { *output = nullptr; return; }
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc index c543994..6658e60 100644 --- a/mojo/public/cpp/bindings/lib/message.cc +++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -181,9 +181,10 @@ Message::Message(uint32_t name, uint32_t flags, size_t payload_size, - size_t payload_interface_id_count) { + size_t payload_interface_id_count, + std::vector<ScopedHandle>* handles) { CreateSerializedMessageObject(name, flags, payload_size, - payload_interface_id_count, nullptr, &handle_, + payload_interface_id_count, handles, &handle_, &payload_buffer_); data_ = payload_buffer_.data(); data_size_ = payload_buffer_.size(); @@ -274,45 +275,6 @@ return array_pointer ? array_pointer->storage() : nullptr; } -void Message::AttachHandles(std::vector<ScopedHandle>* handles) { - DCHECK(handles); - if (handles->empty()) - return; - - // Sanity-check the current serialized message state. We must have a valid - // message handle and it must have no serialized handles. - DCHECK(handle_.is_valid()); - DCHECK(payload_buffer_.is_valid()); - void* buffer; - uint32_t num_bytes; - uint32_t num_handles = 0; - MojoResult rv = MojoGetSerializedMessageContents( - handle_->value(), &buffer, &num_bytes, nullptr, &num_handles, - MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE); - DCHECK_EQ(MOJO_RESULT_OK, rv); - - MessageInfo new_info(data_size_, handles); - ScopedMessageHandle new_handle; - rv = mojo::CreateMessage(reinterpret_cast<uintptr_t>(&new_info), - &kMessageInfoThunks, &new_handle); - DCHECK_EQ(MOJO_RESULT_OK, rv); - DCHECK(new_handle.is_valid()); - - rv = MojoSerializeMessage(new_handle->value()); - DCHECK_EQ(MOJO_RESULT_OK, rv); - DCHECK(new_info.payload_buffer.is_valid()); - - // Copy the existing payload into the new message. - void* storage = new_info.payload_buffer.Allocate(payload_buffer_.cursor()); - memcpy(storage, data_, data_size_); - - handle_ = std::move(new_handle); - payload_buffer_ = std::move(new_info.payload_buffer); - data_ = payload_buffer_.data(); - data_size_ = payload_buffer_.size(); - transferable_ = true; -} - ScopedMessageHandle Message::TakeMojoMessage() { // If there are associated endpoints transferred, // SerializeAssociatedEndpointHandles() must be called before this method.
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc index d008ea94..a648304 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.cc +++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -86,7 +86,7 @@ router_->AssertLockAcquired(); DCHECK(!client_); DCHECK(!closed_); - DCHECK(runner->RunsTasksOnCurrentThread()); + DCHECK(runner->RunsTasksInCurrentSequence()); task_runner_ = std::move(runner); client_ = client; @@ -97,7 +97,7 @@ void DetachClient() { router_->AssertLockAcquired(); DCHECK(client_); - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(!closed_); task_runner_ = nullptr; @@ -129,20 +129,20 @@ // AttachClient() call. They are called outside of the router's lock. bool SendMessage(Message* message) override { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); message->set_interface_id(id_); return router_->connector_.Accept(message); } void AllowWokenUpBySyncWatchOnSameThread() override { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); EnsureSyncWatcherExists(); sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); } bool SyncWatch(const bool* should_stop) override { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); EnsureSyncWatcherExists(); return sync_watcher_->SyncWatch(should_stop); @@ -161,7 +161,7 @@ } void OnSyncEventSignaled() { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); scoped_refptr<MultiplexRouter> router_protector(router_); MayAutoLock locker(&router_->lock_); @@ -183,7 +183,7 @@ } void EnsureSyncWatcherExists() { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (sync_watcher_) return; @@ -337,7 +337,7 @@ encountered_error_(false), paused_(false), testing_mode_(false) { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (config == MULTI_INTERFACE) lock_.emplace(); @@ -519,7 +519,7 @@ } void MultiplexRouter::RaiseError() { - if (task_runner_->RunsTasksOnCurrentThread()) { + if (task_runner_->RunsTasksInCurrentSequence()) { connector_.RaiseError(); } else { task_runner_->PostTask(FROM_HERE, @@ -772,7 +772,7 @@ ClientCallBehavior client_call_behavior, base::SequencedTaskRunner* current_task_runner) { DCHECK(!current_task_runner || - current_task_runner->RunsTasksOnCurrentThread()); + current_task_runner->RunsTasksInCurrentSequence()); DCHECK(!paused_); AssertLockAcquired(); @@ -786,7 +786,7 @@ return false; } - DCHECK(endpoint->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence()); InterfaceEndpointClient* client = endpoint->client(); base::Optional<DisconnectReason> disconnect_reason( @@ -809,7 +809,7 @@ ClientCallBehavior client_call_behavior, base::SequencedTaskRunner* current_task_runner) { DCHECK(!current_task_runner || - current_task_runner->RunsTasksOnCurrentThread()); + current_task_runner->RunsTasksInCurrentSequence()); DCHECK(!paused_); DCHECK(message); AssertLockAcquired(); @@ -850,7 +850,7 @@ bool can_direct_call; if (message->has_flag(Message::kFlagIsSync)) { can_direct_call = client_call_behavior != NO_DIRECT_CLIENT_CALLS && - endpoint->task_runner()->RunsTasksOnCurrentThread(); + endpoint->task_runner()->RunsTasksInCurrentSequence(); } else { can_direct_call = client_call_behavior == ALLOW_DIRECT_CLIENT_CALLS && endpoint->task_runner() == current_task_runner; @@ -861,7 +861,7 @@ return false; } - DCHECK(endpoint->task_runner()->RunsTasksOnCurrentThread()); + DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence()); InterfaceEndpointClient* client = endpoint->client(); bool result = false;
diff --git a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc index 2f33cb2..d987cf0 100644 --- a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc +++ b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
@@ -192,7 +192,7 @@ group_controller_ = std::move(group_controller); if (!association_event_handler_.is_null()) { - if (runner_->RunsTasksOnCurrentThread()) { + if (runner_->RunsTasksInCurrentSequence()) { handler = std::move(association_event_handler_); runner_ = nullptr; } else { @@ -228,7 +228,7 @@ peer_state_ = nullptr; if (!association_event_handler_.is_null()) { - if (runner_->RunsTasksOnCurrentThread()) { + if (runner_->RunsTasksInCurrentSequence()) { handler = std::move(association_event_handler_); runner_ = nullptr; } else {
diff --git a/mojo/public/cpp/bindings/lib/serialization_context.cc b/mojo/public/cpp/bindings/lib/serialization_context.cc index 8e4d86b..5748d10 100644 --- a/mojo/public/cpp/bindings/lib/serialization_context.cc +++ b/mojo/public/cpp/bindings/lib/serialization_context.cc
@@ -17,7 +17,7 @@ SerializedHandleVector::~SerializedHandleVector() = default; -Handle_Data SerializedHandleVector::AddHandle(mojo::ScopedHandle handle) { +void SerializedHandleVector::AddHandle(mojo::ScopedHandle handle) { Handle_Data data; if (!handle.is_valid()) { data.value = kEncodedInvalidHandleValue; @@ -26,7 +26,29 @@ data.value = static_cast<uint32_t>(handles_.size()); handles_.emplace_back(std::move(handle)); } - return data; + serialized_handles_.emplace_back(data); +} + +void SerializedHandleVector::AddInterfaceInfo( + mojo::ScopedMessagePipeHandle handle, + uint32_t version) { + AddHandle(ScopedHandle::From(std::move(handle))); + serialized_interface_versions_.emplace_back(version); +} + +void SerializedHandleVector::ConsumeNextSerializedHandle( + Handle_Data* out_data) { + DCHECK_LT(next_serialized_handle_index_, serialized_handles_.size()); + *out_data = serialized_handles_[next_serialized_handle_index_++]; +} + +void SerializedHandleVector::ConsumeNextSerializedInterfaceInfo( + Interface_Data* out_data) { + ConsumeNextSerializedHandle(&out_data->handle); + DCHECK_LT(next_serialized_version_index_, + serialized_interface_versions_.size()); + out_data->version = + serialized_interface_versions_[next_serialized_version_index_++]; } mojo::ScopedHandle SerializedHandleVector::TakeHandle( @@ -50,7 +72,6 @@ void SerializationContext::AttachHandlesToMessage(Message* message) { associated_endpoint_handles.swap( *message->mutable_associated_endpoint_handles()); - message->AttachHandles(handles.mutable_handles()); } } // namespace internal
diff --git a/mojo/public/cpp/bindings/lib/serialization_context.h b/mojo/public/cpp/bindings/lib/serialization_context.h index 6a6e5142..bc355044 100644 --- a/mojo/public/cpp/bindings/lib/serialization_context.h +++ b/mojo/public/cpp/bindings/lib/serialization_context.h
@@ -11,6 +11,7 @@ #include <queue> #include <vector> +#include "base/containers/stack_container.h" #include "base/macros.h" #include "mojo/public/cpp/bindings/bindings_export.h" #include "mojo/public/cpp/bindings/lib/bindings_internal.h" @@ -31,9 +32,22 @@ size_t size() const { return handles_.size(); } std::vector<mojo::ScopedHandle>* mutable_handles() { return &handles_; } + std::vector<Handle_Data>* serialized_handles() { + return &serialized_handles_; + } - // Adds a handle to the handle list and returns its index for encoding. - Handle_Data AddHandle(mojo::ScopedHandle handle); + // Adds a handle to the handle and serialized handle data lists. + void AddHandle(mojo::ScopedHandle handle); + + // Adds an interface info to the handle and serialized handle+version data + // lists. + void AddInterfaceInfo(mojo::ScopedMessagePipeHandle handle, uint32_t version); + + // Consumes the next available serialized handle data. + void ConsumeNextSerializedHandle(Handle_Data* out_data); + + // Consumes the next available serialized handle and version data. + void ConsumeNextSerializedInterfaceInfo(Interface_Data* out_data); // Takes a handle from the list of serialized handle data. mojo::ScopedHandle TakeHandle(const Handle_Data& encoded_handle); @@ -52,6 +66,14 @@ // Handles are owned by this object. std::vector<mojo::ScopedHandle> handles_; + // Serialized handle and (optional) version data. This is accumulated during + // pre-serialization by AddHandle and AddInterfaceInfo calls, and later + // consumed during serialization by ConsumeNextSerializedHandle/InterfaceInfo. + size_t next_serialized_handle_index_ = 0; + std::vector<Handle_Data> serialized_handles_; + size_t next_serialized_version_index_ = 0; + std::vector<uint32_t> serialized_interface_versions_; + DISALLOW_COPY_AND_ASSIGN(SerializedHandleVector); }; @@ -61,13 +83,23 @@ ~SerializationContext(); - // Transfers ownership of any accumulated handles and associated endpoint - // handles into |*message|. + bool IsNextFieldNull() { + DCHECK_LT(null_state_index, null_states.container().size()); + return null_states.container()[null_state_index++]; + } + + // Transfers ownership of any accumulated associated endpoint handles into + // |*message|. void AttachHandlesToMessage(Message* message); // Opaque context pointers returned by StringTraits::SetUpContext(). std::unique_ptr<std::queue<void*>> custom_contexts; + // A container for tracking the null-ness of every nullable field as a + // message's arguments are walked during serialization. + base::StackVector<bool, 32> null_states; + size_t null_state_index = 0; + // Stashes handles encoded in a message by index. SerializedHandleVector handles;
diff --git a/mojo/public/cpp/bindings/lib/string_serialization.h b/mojo/public/cpp/bindings/lib/string_serialization.h index 6e0c758..68165dd 100644 --- a/mojo/public/cpp/bindings/lib/string_serialization.h +++ b/mojo/public/cpp/bindings/lib/string_serialization.h
@@ -24,7 +24,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; void* custom_context = CustomContextHelper<Traits>::SetUp(input, context); @@ -36,7 +38,7 @@ Buffer* buffer, String_Data** output, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { *output = nullptr; return; }
diff --git a/mojo/public/cpp/bindings/message.h b/mojo/public/cpp/bindings/message.h index 9fabda4..cfd4664 100644 --- a/mojo/public/cpp/bindings/message.h +++ b/mojo/public/cpp/bindings/message.h
@@ -45,13 +45,13 @@ // This message is fully functional and may be exchanged for a // ScopedMessageHandle for transit over a message pipe. See TakeMojoMessage(). // - // If |handles| are not known at Message construction time, they may be - // attached later by calling |AttachHandles()|. See the note on that method - // regarding performance considerations. + // If |handles| is non-null, any handles in |*handles| are attached to the + // newly constructed message. Message(uint32_t name, uint32_t flags, size_t payload_size, - size_t payload_interface_id_count); + size_t payload_interface_id_count, + std::vector<ScopedHandle>* handles = nullptr); // Constructs a new serialized Message object from an existing // ScopedMessageHandle; e.g., one read from a message pipe. @@ -148,11 +148,6 @@ return &associated_endpoint_handles_; } - // Attaches handles to this Message. Note that this requires the underlying - // message object to be reallocated and the payload to be copied into a new - // buffer. Takes ownership of the contents of |*handles|. - void AttachHandles(std::vector<ScopedHandle>* handles); - // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for // transmission. Note that this invalidates this Message object, taking // ownership of its internal storage and any attached handles.
diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc index adb45ed..1238e54 100644 --- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc +++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
@@ -145,7 +145,7 @@ // Okay to call from any thread. void QuitRunLoop(base::RunLoop* run_loop) { - if (main_runner_->RunsTasksOnCurrentThread()) { + if (main_runner_->RunsTasksInCurrentSequence()) { run_loop->Quit(); } else { main_runner_->PostTask( @@ -255,7 +255,7 @@ void SetUp(IntegerSenderAssociatedPtrInfo ptr_info, TestSender* next_sender, int32_t max_value_to_send) { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); ptr_.Bind(std::move(ptr_info)); next_sender_ = next_sender ? next_sender : this; @@ -263,7 +263,7 @@ } void Send(int32_t value) { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); if (value > max_value_to_send_) return; @@ -276,7 +276,7 @@ } void TearDown() { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); ptr_.reset(); } @@ -301,7 +301,7 @@ AssociatedInterfaceRequest<IntegerSender> request1, size_t expected_calls, const base::Closure& notify_finish) { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); impl0_.reset(new IntegerSenderImpl(std::move(request0))); impl0_->set_notify_send_method_called( @@ -315,7 +315,7 @@ } void TearDown() { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); impl0_.reset(); impl1_.reset();
diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc index 3f5b8f44..a163458d 100644 --- a/mojo/public/cpp/bindings/tests/connector_unittest.cc +++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -91,9 +91,7 @@ public: ConnectorTest() {} - void SetUp() override { - CreateMessagePipe(nullptr, &handle0_, &handle1_); - } + void SetUp() override { CreateMessagePipe(nullptr, &handle0_, &handle1_); } void TearDown() override {} @@ -101,9 +99,8 @@ const char* text, std::vector<ScopedHandle> handles = std::vector<ScopedHandle>()) { const size_t size = strlen(text) + 1; // Plus null terminator. - Message message(1, 0, size, 0); + Message message(1, 0, size, 0, &handles); memcpy(message.payload_buffer()->Allocate(size), text, size); - message.AttachHandles(&handles); return message; } @@ -418,16 +415,14 @@ Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, base::ThreadTaskRunnerHandle::Get()); bool error_handler_called0 = false; - connector0.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called0, - run_loop.QuitClosure())); + connector0.set_connection_error_handler(base::Bind( + &ForwardErrorHandler, &error_handler_called0, run_loop.QuitClosure())); Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, base::ThreadTaskRunnerHandle::Get()); bool error_handler_called1 = false; - connector1.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called1, - run_loop2.QuitClosure())); + connector1.set_connection_error_handler(base::Bind( + &ForwardErrorHandler, &error_handler_called1, run_loop2.QuitClosure())); const char kText[] = "hello world"; Message message = CreateMessage(kText); @@ -489,9 +484,8 @@ base::RunLoop run_loop; // Configure the accumulator such that it pauses after the first message is // received. - MessageAccumulator accumulator( - base::Bind(&PauseConnectorAndRunClosure, &connector1, - run_loop.QuitClosure())); + MessageAccumulator accumulator(base::Bind( + &PauseConnectorAndRunClosure, &connector1, run_loop.QuitClosure())); connector1.set_incoming_receiver(&accumulator); run_loop.Run();
diff --git a/mojo/public/cpp/bindings/tests/struct_unittest.cc b/mojo/public/cpp/bindings/tests/struct_unittest.cc index a687052..fa9b370 100644 --- a/mojo/public/cpp/bindings/tests/struct_unittest.cc +++ b/mojo/public/cpp/bindings/tests/struct_unittest.cc
@@ -124,15 +124,17 @@ TEST_F(StructTest, Serialization_Basic) { RectPtr rect(MakeRect()); - size_t size = mojo::internal::PrepareToSerialize<RectDataView>(rect, nullptr); + mojo::internal::SerializationContext context; + size_t size = + mojo::internal::PrepareToSerialize<RectDataView>(rect, &context); EXPECT_EQ(8U + 16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::Rect_Data* data; - mojo::internal::Serialize<RectDataView>(rect, &buf, &data, nullptr); + mojo::internal::Serialize<RectDataView>(rect, &buf, &data, &context); RectPtr rect2; - mojo::internal::Deserialize<RectDataView>(data, &rect2, nullptr); + mojo::internal::Deserialize<RectDataView>(data, &rect2, &context); CheckRect(*rect2); } @@ -155,16 +157,17 @@ TEST_F(StructTest, Serialization_StructPointers) { RectPairPtr pair(RectPair::New(MakeRect(), MakeRect())); + mojo::internal::SerializationContext context; size_t size = - mojo::internal::PrepareToSerialize<RectPairDataView>(pair, nullptr); + mojo::internal::PrepareToSerialize<RectPairDataView>(pair, &context); EXPECT_EQ(8U + 16U + 2 * (8U + 16U), size); mojo::internal::FixedBufferForTesting buf(size); internal::RectPair_Data* data; - mojo::internal::Serialize<RectPairDataView>(pair, &buf, &data, nullptr); + mojo::internal::Serialize<RectPairDataView>(pair, &buf, &data, &context); RectPairPtr pair2; - mojo::internal::Deserialize<RectPairDataView>(data, &pair2, nullptr); + mojo::internal::Deserialize<RectPairDataView>(data, &pair2, &context); CheckRect(*pair2->first); CheckRect(*pair2->second); @@ -179,8 +182,9 @@ NamedRegionPtr region( NamedRegion::New(std::string("region"), std::move(rects))); + mojo::internal::SerializationContext context; size_t size = - mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr); + mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, &context); EXPECT_EQ(8U + // header 8U + // name pointer 8U + // rects pointer @@ -194,10 +198,10 @@ mojo::internal::FixedBufferForTesting buf(size); internal::NamedRegion_Data* data; - mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr); + mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, &context); NamedRegionPtr region2; - mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, nullptr); + mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, &context); EXPECT_EQ("region", *region2->name); @@ -212,8 +216,9 @@ EXPECT_FALSE(region->name); EXPECT_FALSE(region->rects); + mojo::internal::SerializationContext context; size_t size = - mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr); + mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, &context); EXPECT_EQ(8U + // header 8U + // name pointer 8U, // rects pointer @@ -221,10 +226,10 @@ mojo::internal::FixedBufferForTesting buf(size); internal::NamedRegion_Data* data; - mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr); + mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, &context); NamedRegionPtr region2; - mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, nullptr); + mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, &context); EXPECT_FALSE(region2->name); EXPECT_FALSE(region2->rects); @@ -364,40 +369,42 @@ { // Serialization of a null native struct. NativeStructPtr native; + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); + native, &context); EXPECT_EQ(0u, size); mojo::internal::FixedBufferForTesting buf(size); Data* data = nullptr; mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); + &data, &context); EXPECT_EQ(nullptr, data); NativeStructPtr output_native; mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); + &context); EXPECT_TRUE(output_native.is_null()); } { // Serialization of a native struct with null data. NativeStructPtr native(NativeStruct::New()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); + native, &context); EXPECT_EQ(0u, size); mojo::internal::FixedBufferForTesting buf(size); Data* data = nullptr; mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); + &data, &context); EXPECT_EQ(nullptr, data); NativeStructPtr output_native; mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); + &context); EXPECT_TRUE(output_native.is_null()); } @@ -405,20 +412,21 @@ NativeStructPtr native(NativeStruct::New()); native->data = std::vector<uint8_t>{'X', 'Y'}; + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); + native, &context); EXPECT_EQ(16u, size); mojo::internal::FixedBufferForTesting buf(size); Data* data = nullptr; mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); + &data, &context); EXPECT_NE(nullptr, data); NativeStructPtr output_native; mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); + &context); ASSERT_TRUE(output_native); ASSERT_FALSE(output_native->data->empty()); EXPECT_EQ(2u, output_native->data->size());
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc index 6a5d704..25bb9db 100644 --- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc +++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
@@ -266,7 +266,7 @@ ping_called_(false) {} void SetUp(InterfaceRequest<Interface> request) { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); impl_.reset(new ImplTypeFor<Interface>(std::move(request))); impl_->set_ping_handler( [this](const typename Interface::PingCallback& callback) { @@ -279,7 +279,7 @@ } void TearDown() { - CHECK(task_runner()->RunsTasksOnCurrentThread()); + CHECK(task_runner()->RunsTasksInCurrentSequence()); impl_.reset(); }
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc index 159192f..92e25828 100644 --- a/mojo/public/cpp/bindings/tests/union_unittest.cc +++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -205,14 +205,15 @@ TEST(UnionTest, EnumSerialization) { PodUnionPtr pod1(PodUnion::NewFEnum(AnEnum::SECOND)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>( - pod1, false, nullptr); + pod1, false, &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; mojo::internal::Serialize<PodUnionDataView>(pod1, &buf, &data, false, - nullptr); + &context); PodUnionPtr pod2; mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, nullptr); @@ -226,13 +227,15 @@ PodUnionPtr pod(PodUnion::New()); pod->set_f_int8(10); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -245,18 +248,21 @@ TEST(UnionTest, SerializeNotNull) { PodUnionPtr pod(PodUnion::New()); pod->set_f_int8(0); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); EXPECT_FALSE(data->is_null()); } TEST(UnionTest, SerializeIsNullInlined) { PodUnionPtr pod; - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); @@ -266,7 +272,7 @@ data->tag = PodUnion::Tag::F_UINT16; data->data.f_f_int16 = 20; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, true, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, true, &context); EXPECT_TRUE(data->is_null()); PodUnionPtr pod2; @@ -276,12 +282,14 @@ TEST(UnionTest, SerializeIsNullNotInlined) { PodUnionPtr pod; - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); EXPECT_EQ(nullptr, data); } @@ -336,13 +344,15 @@ TEST(UnionTest, UnknownEnumValueValidation) { PodUnionPtr pod(PodUnion::NewFEnum(static_cast<AnEnum>(0xFFFF))); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -356,13 +366,15 @@ PodUnionPtr pod( PodUnion::NewFExtensibleEnum(static_cast<AnExtensibleEnum>(0xFFFF))); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); + mojo::internal::SerializationContext context; + size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, + &context); EXPECT_EQ(16U, size); mojo::internal::FixedBufferForTesting buf(size); internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); + mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -415,12 +427,13 @@ std::string hello("hello world"); ObjectUnionPtr pod1(ObjectUnion::NewFString(hello)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - pod1, false, nullptr); + pod1, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(pod1, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr pod2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &pod2, nullptr); @@ -500,16 +513,17 @@ array[1]->set_f_int16(12); EXPECT_EQ(2U, array.size()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>( - array, nullptr); + array, &context); EXPECT_EQ(40U, size); mojo::internal::FixedBufferForTesting buf(size); mojo::internal::Array_Data<internal::PodUnion_Data>* data; mojo::internal::ContainerValidateParams validate_params(0, false, nullptr); mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); + array, &buf, &data, &validate_params, &context); std::vector<PodUnionPtr> array2; mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2, @@ -528,16 +542,17 @@ array[0]->set_f_int8(10); EXPECT_EQ(2U, array.size()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>( - array, nullptr); + array, &context); EXPECT_EQ(40U, size); mojo::internal::FixedBufferForTesting buf(size); mojo::internal::Array_Data<internal::PodUnion_Data>* data; mojo::internal::ContainerValidateParams validate_params(0, true, nullptr); mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); + array, &buf, &data, &validate_params, &context); std::vector<PodUnionPtr> array2; mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2, @@ -558,9 +573,10 @@ array[1]->set_f_string("world"); EXPECT_EQ(2U, array.size()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<ObjectUnionDataView>>( - array, nullptr); + array, &context); EXPECT_EQ(72U, size); mojo::internal::FixedBufferForTesting buf(size); @@ -568,7 +584,7 @@ mojo::internal::Array_Data<internal::ObjectUnion_Data>* data; mojo::internal::ContainerValidateParams validate_params(0, false, nullptr); mojo::internal::Serialize<ArrayDataView<ObjectUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); + array, &buf, &data, &validate_params, &context); std::vector<char> new_buf; new_buf.resize(size); @@ -635,13 +651,14 @@ std::string hello("hello world"); obj_struct->obj_union->set_f_string(hello); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<SmallObjStructDataView>( - obj_struct, nullptr); + obj_struct, &context); mojo::internal::FixedBufferForTesting buf(size); internal::SmallObjStruct_Data* data = nullptr; mojo::internal::Serialize<SmallObjStructDataView>(obj_struct, &buf, &data, - nullptr); + &context); SmallObjStructPtr deserialized; mojo::internal::Deserialize<SmallObjStructDataView>(data, &deserialized, @@ -702,9 +719,10 @@ SmallStructNonNullableUnionPtr small_struct( SmallStructNonNullableUnion::New()); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<SmallStructNonNullableUnionDataView>( - small_struct, nullptr); + small_struct, &context); mojo::internal::FixedBufferForTesting buf(size); internal::SmallStructNonNullableUnion_Data* data = @@ -829,14 +847,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_dummy(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr obj2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); @@ -850,13 +869,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_dummy(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -874,13 +894,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_dummy(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -896,13 +917,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_nullable(std::move(dummy)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -932,14 +954,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_array_int8(std::move(array)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr obj2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); @@ -956,12 +979,13 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_array_int8(std::move(array)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -1062,14 +1086,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_pod_union(std::move(pod)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); ObjectUnionPtr obj2; mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); @@ -1083,14 +1108,15 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_pod_union(std::move(pod)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); EXPECT_EQ(32U, size); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context( @@ -1108,13 +1134,14 @@ ObjectUnionPtr obj(ObjectUnion::New()); obj->set_f_pod_union(std::move(pod)); + mojo::internal::SerializationContext context; size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); + obj, false, &context); mojo::internal::FixedBufferForTesting buf(size); internal::ObjectUnion_Data* data = nullptr; mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); + &context); void* raw_buf = buf.Leak(); mojo::internal::ValidationContext validation_context(
diff --git a/mojo/public/cpp/system/simple_watcher.cc b/mojo/public/cpp/system/simple_watcher.cc index 9e34b16..a8b5a0d 100644 --- a/mojo/public/cpp/system/simple_watcher.cc +++ b/mojo/public/cpp/system/simple_watcher.cc
@@ -132,7 +132,7 @@ weak_factory_(this) { MojoResult rv = CreateWatcher(&Context::CallNotify, &watcher_handle_); DCHECK_EQ(MOJO_RESULT_OK, rv); - DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); } SimpleWatcher::~SimpleWatcher() {
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index e605df00..faaef88 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -23,6 +23,7 @@ "//extensions/common/typemaps.gni", "//gpu/ipc/common/typemaps.gni", "//media/capture/mojo/typemaps.gni", + "//media/gpu/mojo/typemaps.gni", "//media/mojo/interfaces/typemaps.gni", "//mojo/common/typemaps.gni", "//mojo/public/cpp/bindings/tests/chromium_typemaps.gni",
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl index fcf1596..bbc1777 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -161,7 +161,8 @@ mojo::Message message( {{message_name}}, mojo::Message::kFlagIsSync | mojo::Message::kFlagExpectsResponse, - size, serialization_context.associated_endpoint_count); + size, serialization_context.associated_endpoint_count, + serialization_context.handles.mutable_handles()); {{build_message(params_struct, "param_%s", params_description, "&serialization_context", "&message")}} @@ -188,7 +189,8 @@ constexpr uint32_t kFlags = 0; {%- endif %} mojo::Message message({{message_name}}, kFlags, size, - serialization_context.associated_endpoint_count); + serialization_context.associated_endpoint_count, + serialization_context.handles.mutable_handles()); {{build_message(params_struct, "in_%s", params_description, "&serialization_context", "&message")}} @@ -270,7 +272,8 @@ uint32_t flags = (is_sync_ ? mojo::Message::kFlagIsSync : 0) | mojo::Message::kFlagIsResponse; mojo::Message message({{message_name}}, flags, size, - serialization_context.associated_endpoint_count); + serialization_context.associated_endpoint_count, + serialization_context.handles.mutable_handles()); {{build_message(response_params_struct, "in_%s", params_description, "&serialization_context", "&message")}} message.set_request_id(request_id_);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl index bb5fb9c..3e43c88a 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl
@@ -20,7 +20,8 @@ input_may_be_temp=False) -%} size_t size = sizeof({{struct|get_qualified_name_for_kind(internal=True)}}); {%- for pf in struct.packed.packed_fields_in_ordinal_order - if pf.field.kind|is_object_kind or pf.field.kind|is_associated_kind %} + if pf.field.kind|is_object_kind or + pf.field.kind|is_any_handle_or_interface_kind %} {%- set name = pf.field.name -%} {%- set kind = pf.field.kind -%} {%- set original_input_field = input_field_pattern|format(name) %} @@ -73,7 +74,14 @@ {%- set input_field = "in_%s"|format(name) if input_may_be_temp else original_input_field %} {%- if input_may_be_temp %} +{%- if kind|is_associated_kind or kind|is_object_kind %} decltype({{original_input_field}}) in_{{name}} = {{original_input_field}}; +{%- else %} + // Dummy input value. The serialized value is already stored in the + // SerializationContext. + typename std::remove_reference<decltype({{original_input_field}})>::type + in_{{name}}; +{%- endif %} {%- endif %} {%- endif %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl index 835178bed..02af440 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
@@ -11,7 +11,9 @@ static size_t PrepareToSerialize(MaybeConstUserType& input, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return 0; void* custom_context = CustomContextHelper<Traits>::SetUp(input, context); @@ -27,7 +29,7 @@ Buffer* buffer, {{data_type}}** output, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { *output = nullptr; return; }
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl index b589ae91..cc513c3 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
@@ -12,8 +12,9 @@ bool inlined, SerializationContext* context) { size_t size = inlined ? 0 : sizeof({{data_type}}); - - if (CallIsNullIfExists<Traits>(input)) + const bool is_null = CallIsNullIfExists<Traits>(input); + context->null_states.container().push_back(is_null); + if (is_null) return size; void* custom_context = CustomContextHelper<Traits>::SetUp(input, context); @@ -23,7 +24,8 @@ {%- for field in union.fields %} {%- set name = field.name %} case {{data_view}}::Tag::{{name|upper}}: { -{%- if field.kind|is_object_kind or field.kind|is_associated_kind %} +{%- if field.kind|is_object_kind or + field.kind|is_any_handle_or_interface_kind %} {%- set kind = field.kind %} {%- set serializer_type = kind|unmapped_type_for_serializer %} decltype(CallWithContext(Traits::{{name}}, input, custom_context)) @@ -49,7 +51,7 @@ {{data_type}}** output, bool inlined, SerializationContext* context) { - if (CallIsNullIfExists<Traits>(input)) { + if (context->IsNextFieldNull()) { if (inlined) (*output)->set_null(); else
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn index f855f47..8ef6f7c 100644 --- a/net/android/BUILD.gn +++ b/net/android/BUILD.gn
@@ -109,6 +109,9 @@ ":java_test_native_support", "//net:test_support", ] + + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + configs += [ "//build/config/android:hide_all_but_jni" ] } android_apk("net_test_support_apk") {
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index 7ae0489..080e7427 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -173,71 +173,73 @@ if (peak_kbps_since_last_connection_change_) { switch (last_connection_type_) { case NetworkChangeNotifier::CONNECTION_UNKNOWN: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnUnknown", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOnUnknown", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_ETHERNET: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnEthernet", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOnEthernet", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_WIFI: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnWifi", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOnWifi", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_2G: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOn2G", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOn2G", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_3G: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOn3G", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOn3G", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_4G: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOn4G", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOn4G", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_NONE: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnNone", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOnNone", + peak_kbps_since_last_connection_change_); break; case NetworkChangeNotifier::CONNECTION_BLUETOOTH: - UMA_HISTOGRAM_COUNTS("NCN.CM.PeakKbpsOnBluetooth", - peak_kbps_since_last_connection_change_); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.PeakKbpsOnBluetooth", + peak_kbps_since_last_connection_change_); break; } } switch (last_connection_type_) { case NetworkChangeNotifier::CONNECTION_UNKNOWN: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnUnknown", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnUnknown", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOnUnknown", kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_ETHERNET: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnEthernet", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnEthernet", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOnEthernet", + kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_WIFI: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnWifi", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnWifi", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOnWifi", kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_2G: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOn2G", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOn2G", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOn2G", kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_3G: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOn3G", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOn3G", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOn3G", kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_4G: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOn4G", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOn4G", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOn4G", kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_NONE: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnNone", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnNone", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOnNone", kilobytes_read); break; case NetworkChangeNotifier::CONNECTION_BLUETOOTH: UMA_HISTOGRAM_LONG_TIMES("NCN.CM.TimeOnBluetooth", state_duration); - UMA_HISTOGRAM_COUNTS("NCN.CM.KBTransferedOnBluetooth", kilobytes_read); + UMA_HISTOGRAM_COUNTS_1M("NCN.CM.KBTransferedOnBluetooth", + kilobytes_read); break; }
diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc index 11e9e3b7..51af589 100644 --- a/net/base/sdch_manager.cc +++ b/net/base/sdch_manager.cc
@@ -255,7 +255,7 @@ if (count == 0) return NULL; - UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); + UMA_HISTOGRAM_COUNTS_1M("Sdch3.Advertisement_Count", count); return result; } @@ -449,7 +449,8 @@ if (rv != SDCH_OK) return rv; - UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size()); + UMA_HISTOGRAM_COUNTS_1M("Sdch3.Dictionary size loaded", + dictionary_text.size()); DVLOG(1) << "Loaded dictionary with client hash " << client_hash << " and server hash " << server_hash; SdchDictionary dictionary(dictionary_text, header_end + 2, client_hash,
diff --git a/net/cert/ct_serialization.cc b/net/cert/ct_serialization.cc index 7bc70838..ff843d0 100644 --- a/net/cert/ct_serialization.cc +++ b/net/cert/ct_serialization.cc
@@ -428,6 +428,22 @@ return true; } +void EncodeSignedCertificateTimestamp( + const scoped_refptr<ct::SignedCertificateTimestamp>& input, + std::string* output) { + // This function only supports serialization of V1 SCTs. + DCHECK_EQ(SignedCertificateTimestamp::V1, input->version); + WriteUint(kVersionLength, input->version, output); + DCHECK_EQ(kLogIdLength, input->log_id.size()); + WriteEncodedBytes( + base::StringPiece(reinterpret_cast<const char*>(input->log_id.data()), + kLogIdLength), + output); + WriteTimeSinceEpoch(input->timestamp, output); + WriteVariableBytes(kExtensionsLengthBytes, input->extensions, output); + EncodeDigitallySigned(input->signature, output); +} + bool EncodeSCTListForTesting(const base::StringPiece& sct, std::string* output) { std::string encoded_sct;
diff --git a/net/cert/ct_serialization.h b/net/cert/ct_serialization.h index 5dfb438..4ade8b5 100644 --- a/net/cert/ct_serialization.h +++ b/net/cert/ct_serialization.h
@@ -85,6 +85,11 @@ base::StringPiece* input, scoped_refptr<ct::SignedCertificateTimestamp>* output); +// Serializes a Signed Certificate Timestamp (SCT) into |output|. +NET_EXPORT void EncodeSignedCertificateTimestamp( + const scoped_refptr<ct::SignedCertificateTimestamp>& input, + std::string* output); + // Writes an SCTList into |output|, containing a single |sct|. NET_EXPORT_PRIVATE bool EncodeSCTListForTesting(const base::StringPiece& sct, std::string* output);
diff --git a/net/cert/ct_serialization_unittest.cc b/net/cert/ct_serialization_unittest.cc index 285643d..004a897 100644 --- a/net/cert/ct_serialization_unittest.cc +++ b/net/cert/ct_serialization_unittest.cc
@@ -153,6 +153,18 @@ ASSERT_FALSE(ct::DecodeSCTList(encoded, &decoded)); } +TEST_F(CtSerializationTest, EncodeSignedCertificateTimestamp) { + std::string encoded_test_sct(ct::GetTestSignedCertificateTimestamp()); + base::StringPiece encoded_sct(encoded_test_sct); + + scoped_refptr<ct::SignedCertificateTimestamp> sct; + ASSERT_TRUE(ct::DecodeSignedCertificateTimestamp(&encoded_sct, &sct)); + + std::string serialized; + ct::EncodeSignedCertificateTimestamp(sct, &serialized); + EXPECT_EQ(serialized, encoded_test_sct); +} + TEST_F(CtSerializationTest, DecodesSignedCertificateTimestamp) { std::string encoded_test_sct(ct::GetTestSignedCertificateTimestamp()); base::StringPiece encoded_sct(encoded_test_sct);
diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h index af5a03a..73e0c3d 100644 --- a/net/cert/x509_certificate.h +++ b/net/cert/x509_certificate.h
@@ -32,7 +32,6 @@ #elif defined(USE_OPENSSL_CERTS) // Forward declaration; real one in <x509.h> typedef struct x509_st X509; -typedef struct x509_store_st X509_STORE; #elif defined(USE_NSS_CERTS) // Forward declaration; real one in <cert.h> struct CERTCertificateStr; @@ -235,12 +234,6 @@ // |valid_issuers| is a list of DER-encoded X.509 DistinguishedNames. bool IsIssuedByEncoded(const std::vector<std::string>& valid_issuers); -#if defined(USE_OPENSSL_CERTS) - // Returns a handle to a global, in-memory certificate store. We - // use it for test code, e.g. importing the test server's certificate. - static X509_STORE* cert_store(); -#endif - // Verifies that |hostname| matches this certificate. // Does not verify that the certificate is valid, only that the certificate // matches this host. @@ -353,12 +346,6 @@ // Common object initialization code. Called by the constructors only. bool Initialize(); -#if defined(USE_OPENSSL_CERTS) - // Resets the store returned by cert_store() to default state. Used by - // TestRootCerts to undo modifications. - static void ResetCertStore(); -#endif - // Verifies that |hostname| matches one of the certificate names or IP // addresses supplied, based on TLS name matching rules - specifically, // following http://tools.ietf.org/html/rfc6125.
diff --git a/net/cert/x509_certificate_mac.cc b/net/cert/x509_certificate_mac.cc index 73dbe46..d86f6cf 100644 --- a/net/cert/x509_certificate_mac.cc +++ b/net/cert/x509_certificate_mac.cc
@@ -19,7 +19,6 @@ #include "base/strings/string_piece.h" #include "base/strings/sys_string_conversions.h" #include "base/synchronization/lock.h" -#include "crypto/cssm_init.h" #include "crypto/mac_security_services_lock.h" #include "net/cert/x509_util_mac.h"
diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc index 1dd46e0c..c85132c 100644 --- a/net/cert/x509_certificate_openssl.cc +++ b/net/cert/x509_certificate_openssl.cc
@@ -5,7 +5,6 @@ #include "net/cert/x509_certificate.h" #include "base/macros.h" -#include "base/memory/singleton.h" #include "base/numerics/safe_conversions.h" #include "base/pickle.h" #include "base/sha1.h" @@ -139,36 +138,6 @@ return has_san; } -class X509InitSingleton { - public: - static X509InitSingleton* GetInstance() { - // We allow the X509 store to leak, because it is used from a non-joinable - // worker that is not stopped on shutdown, hence may still be using - // OpenSSL library after the AtExit runner has completed. - return base::Singleton<X509InitSingleton, base::LeakySingletonTraits< - X509InitSingleton>>::get(); - } - X509_STORE* store() const { return store_.get(); } - - void ResetCertStore() { - store_.reset(X509_STORE_new()); - DCHECK(store_.get()); - X509_STORE_set_default_paths(store_.get()); - // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)). - } - - private: - friend struct base::DefaultSingletonTraits<X509InitSingleton>; - X509InitSingleton() { - crypto::EnsureOpenSSLInit(); - ResetCertStore(); - } - - bssl::UniquePtr<X509_STORE> store_; - - DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); -}; - } // namespace // static @@ -215,11 +184,6 @@ } // static -void X509Certificate::ResetCertStore() { - X509InitSingleton::GetInstance()->ResetCertStore(); -} - -// static SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { SHA256HashValue sha256; unsigned int sha256_size = static_cast<unsigned int>(sizeof(sha256.data)); @@ -297,11 +261,6 @@ } // static -X509_STORE* X509Certificate::cert_store() { - return X509InitSingleton::GetInstance()->store(); -} - -// static bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, std::string* encoded) { base::StringPiece der;
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 4372bde3..9cf9f7a 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -404,14 +404,12 @@ } bool CanonicalCookie::IsCanonical() const { - // Not checking domain against ParsedCookie as it may have come purely - // from the URL. + // Not checking domain or path against ParsedCookie as it may have + // come purely from the URL. if (ParsedCookie::ParseTokenString(name_) != name_ || ParsedCookie::ParseValueString(value_) != value_ || - ParsedCookie::ParseValueString(path_) != path_ || !ParsedCookie::IsValidCookieAttributeValue(name_) || - !ParsedCookie::IsValidCookieAttributeValue(value_) || - !ParsedCookie::IsValidCookieAttributeValue(path_)) { + !ParsedCookie::IsValidCookieAttributeValue(value_)) { return false; }
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc index a2f3cf7..ecbe8a90 100644 --- a/net/cookies/canonical_cookie_unittest.cc +++ b/net/cookies/canonical_cookie_unittest.cc
@@ -44,14 +44,21 @@ EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2->SameSite()); } -TEST(CanonicalCookie, SpaceInName) { - GURL url("http://www.example.com/test/foo.html"); +TEST(CanonicalCookie, CreationCornerCases) { base::Time creation_time = base::Time::Now(); CookieOptions options; - std::unique_ptr<CanonicalCookie> cookie( - CanonicalCookie::Create(url, "A C=2", creation_time, options)); + std::unique_ptr<CanonicalCookie> cookie; + + // Space in name. + cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"), + "A C=2", creation_time, options); EXPECT_TRUE(cookie.get()); EXPECT_EQ("A C", cookie->Name()); + + // Semicolon in path. + cookie = CanonicalCookie::Create(GURL("http://fool/;/"), "*", creation_time, + options); + EXPECT_TRUE(cookie.get()); } TEST(CanonicalCookieTest, Create) { @@ -742,20 +749,6 @@ COOKIE_PRIORITY_LOW) .IsCanonical()); - // Path suffixed with a space. - EXPECT_FALSE(CanonicalCookie("A", "B", "x.y", "/path ", base::Time(), - base::Time(), base::Time(), false, false, - CookieSameSite::NO_RESTRICTION, - COOKIE_PRIORITY_LOW) - .IsCanonical()); - - // Path suffixed with separator. - EXPECT_FALSE(CanonicalCookie("A", "B", "x.y", "/path;", base::Time(), - base::Time(), base::Time(), false, false, - CookieSameSite::NO_RESTRICTION, - COOKIE_PRIORITY_LOW) - .IsCanonical()); - // Simple IPv4 address as domain. EXPECT_TRUE(CanonicalCookie("A", "B", "1.2.3.4", "/path", base::Time(), base::Time(), base::Time(), false, false,
diff --git a/net/disk_cache/blockfile/block_files.cc b/net/disk_cache/blockfile/block_files.cc index a1b9fa03..78d75960 100644 --- a/net/disk_cache/blockfile/block_files.cc +++ b/net/disk_cache/blockfile/block_files.cc
@@ -398,10 +398,10 @@ for (int i = 0; i < kFirstAdditionalBlockFile; i++) { GetFileStats(i, &used_blocks[i], &load[i]); } - UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_0", used_blocks[0]); - UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_1", used_blocks[1]); - UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_2", used_blocks[2]); - UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_3", used_blocks[3]); + UMA_HISTOGRAM_COUNTS_1M("DiskCache.Blocks_0", used_blocks[0]); + UMA_HISTOGRAM_COUNTS_1M("DiskCache.Blocks_1", used_blocks[1]); + UMA_HISTOGRAM_COUNTS_1M("DiskCache.Blocks_2", used_blocks[2]); + UMA_HISTOGRAM_COUNTS_1M("DiskCache.Blocks_3", used_blocks[3]); UMA_HISTOGRAM_ENUMERATION("DiskCache.BlockLoad_0", load[0], 101); UMA_HISTOGRAM_ENUMERATION("DiskCache.BlockLoad_1", load[1], 101); @@ -630,7 +630,7 @@ block_files_[file_index] = NULL; int failure = DeleteCacheFile(name) ? 0 : 1; - UMA_HISTOGRAM_COUNTS("DiskCache.DeleteFailed2", failure); + UMA_HISTOGRAM_COUNTS_1M("DiskCache.DeleteFailed2", failure); if (failure) LOG(ERROR) << "Failed to delete " << name.value() << " from the cache."; continue;
diff --git a/net/disk_cache/blockfile/eviction.cc b/net/disk_cache/blockfile/eviction.cc index 351bbac3..821be2d 100644 --- a/net/disk_cache/blockfile/eviction.cc +++ b/net/disk_cache/blockfile/eviction.cc
@@ -241,7 +241,7 @@ return false; } - UMA_HISTOGRAM_COUNTS("DiskCache.TrimDelays", trim_delays_); + UMA_HISTOGRAM_COUNTS_1M("DiskCache.TrimDelays", trim_delays_); trim_delays_ = 0; return true; }
diff --git a/net/disk_cache/blockfile/histogram_macros.h b/net/disk_cache/blockfile/histogram_macros.h index 61cc6ea..2f30dc8 100644 --- a/net/disk_cache/blockfile/histogram_macros.h +++ b/net/disk_cache/blockfile/histogram_macros.h
@@ -84,8 +84,8 @@ // CACHE_UMA(COUNTS, "MyName", 0, 20); // CACHE_UMA(COUNTS, "MyExperiment", 530, 55); // which roughly translates to: -// UMA_HISTOGRAM_COUNTS("DiskCache.2.MyName", 20); // "2" is the CacheType. -// UMA_HISTOGRAM_COUNTS("DiskCache.2.MyExperiment_530", 55); +// UMA_HISTOGRAM_COUNTS_1M("DiskCache.2.MyName", 20); // "2" is the CacheType. +// UMA_HISTOGRAM_COUNTS_1M("DiskCache.2.MyExperiment_530", 55); // #define CACHE_UMA(type, name, experiment, sample) {\ const std::string my_name =\
diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index c41c829b..3513b598 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc
@@ -336,7 +336,7 @@ ++it; } - SIMPLE_CACHE_UMA(COUNTS, + SIMPLE_CACHE_UMA(COUNTS_1M, "Eviction.EntryCount", cache_type_, entry_hashes.size()); SIMPLE_CACHE_UMA(TIMES, "Eviction.TimeToSelectEntries", cache_type_,
diff --git a/net/disk_cache/simple/simple_index_file.cc b/net/disk_cache/simple/simple_index_file.cc index 01eaba1e..842a569 100644 --- a/net/disk_cache/simple/simple_index_file.cc +++ b/net/disk_cache/simple/simple_index_file.cc
@@ -438,7 +438,7 @@ SyncRestoreFromDisk(cache_directory, index_file_path, out_result); SIMPLE_CACHE_UMA(MEDIUM_TIMES, "IndexRestoreTime", cache_type, base::TimeTicks::Now() - start); - SIMPLE_CACHE_UMA(COUNTS, "IndexEntriesRestored", cache_type, + SIMPLE_CACHE_UMA(COUNTS_1M, "IndexEntriesRestored", cache_type, out_result->entries.size()); if (index_file_existed) { out_result->init_method = SimpleIndex::INITIALIZE_METHOD_RECOVERED; @@ -457,7 +457,7 @@ cache_type); } else { out_result->init_method = SimpleIndex::INITIALIZE_METHOD_NEWCACHE; - SIMPLE_CACHE_UMA(COUNTS, + SIMPLE_CACHE_UMA(COUNTS_1M, "IndexCreatedEntryCount", cache_type, out_result->entries.size()); }
diff --git a/net/dns/dns_hosts.cc b/net/dns/dns_hosts.cc index 7d457113..8de7607c 100644 --- a/net/dns/dns_hosts.cc +++ b/net/dns/dns_hosts.cc
@@ -198,8 +198,8 @@ if (!base::GetFileSize(path, &size)) return false; - UMA_HISTOGRAM_COUNTS("AsyncDNS.HostsSize", - static_cast<base::HistogramBase::Sample>(size)); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.HostsSize", + static_cast<base::HistogramBase::Sample>(size)); // Reject HOSTS files larger than |kMaxHostsSize| bytes. const int64_t kMaxHostsSize = 1 << 25; // 32MB
diff --git a/net/dns/dns_session.cc b/net/dns/dns_session.cc index cdcd7ce..2e7b678 100644 --- a/net/dns/dns_session.cc +++ b/net/dns/dns_session.cc
@@ -252,11 +252,11 @@ for (size_t index = 0; index < server_stats_.size(); ++index) { if (server_stats_[index]->last_failure_count) { if (server_stats_[index]->last_success.is_null()) { - UMA_HISTOGRAM_COUNTS("AsyncDNS.ServerFailuresWithoutSuccess", - server_stats_[index]->last_failure_count); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.ServerFailuresWithoutSuccess", + server_stats_[index]->last_failure_count); } else { - UMA_HISTOGRAM_COUNTS("AsyncDNS.ServerFailuresAfterSuccess", - server_stats_[index]->last_failure_count); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.ServerFailuresAfterSuccess", + server_stats_[index]->last_failure_count); } } }
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc index 3828e6da..1bc1f29 100644 --- a/net/dns/dns_transaction.cc +++ b/net/dns/dns_transaction.cc
@@ -608,7 +608,7 @@ if (result.rv == OK) { qnames_initial_size_ = qnames_.size(); if (qtype_ == dns_protocol::kTypeA) - UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchStart", qnames_.size()); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.SuffixSearchStart", qnames_.size()); result = ProcessAttemptResult(StartQuery()); } @@ -688,14 +688,14 @@ timer_.Stop(); RecordLostPacketsIfAny(); if (result.rv == OK) - UMA_HISTOGRAM_COUNTS("AsyncDNS.AttemptCountSuccess", attempts_count_); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.AttemptCountSuccess", attempts_count_); else - UMA_HISTOGRAM_COUNTS("AsyncDNS.AttemptCountFail", attempts_count_); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.AttemptCountFail", attempts_count_); if (response && qtype_ == dns_protocol::kTypeA) { - UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchRemain", qnames_.size()); - UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchDone", - qnames_initial_size_ - qnames_.size()); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.SuffixSearchRemain", qnames_.size()); + UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.SuffixSearchDone", + qnames_initial_size_ - qnames_.size()); } DnsTransactionFactory::CallbackType callback = callback_;
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index 5b6f2abf..1777486 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -644,7 +644,7 @@ int64_t db_size = 0; if (base::GetFileSize(path_, &db_size)) - UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024); + UMA_HISTOGRAM_COUNTS_1M("Cookie.DBSizeInKB", db_size / 1024); db_.reset(new sql::Connection); db_->set_histogram_tag("Cookie"); @@ -1295,8 +1295,8 @@ UMA_HISTOGRAM_TIMES("Cookie.Startup.TimeSpentDeletingCookies", base::Time::Now() - start_time); - UMA_HISTOGRAM_COUNTS("Cookie.Startup.NumberOfCookiesDeleted", - db_->GetLastChangeCount()); + UMA_HISTOGRAM_COUNTS_1M("Cookie.Startup.NumberOfCookiesDeleted", + db_->GetLastChangeCount()); } void SQLitePersistentCookieStore::Backend::BackgroundDeleteAllInList(
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc index 0cd8705..dbd25301 100644 --- a/net/http/bidirectional_stream.cc +++ b/net/http/bidirectional_stream.cc
@@ -410,10 +410,10 @@ UMA_HISTOGRAM_TIMES( "Net.BidirectionalStream.TimeToSendEnd.HTTP2", load_timing_info_.send_end - load_timing_info_.request_start); - UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.ReceivedBytes.HTTP2", - stream_impl_->GetTotalReceivedBytes()); - UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.SentBytes.HTTP2", - stream_impl_->GetTotalSentBytes()); + UMA_HISTOGRAM_COUNTS_1M("Net.BidirectionalStream.ReceivedBytes.HTTP2", + stream_impl_->GetTotalReceivedBytes()); + UMA_HISTOGRAM_COUNTS_1M("Net.BidirectionalStream.SentBytes.HTTP2", + stream_impl_->GetTotalSentBytes()); } else if (GetProtocol() == kProtoQUIC) { UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.TimeToReadStart.QUIC", load_timing_info_.receive_headers_end - @@ -426,10 +426,10 @@ UMA_HISTOGRAM_TIMES( "Net.BidirectionalStream.TimeToSendEnd.QUIC", load_timing_info_.send_end - load_timing_info_.request_start); - UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.ReceivedBytes.QUIC", - stream_impl_->GetTotalReceivedBytes()); - UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.SentBytes.QUIC", - stream_impl_->GetTotalSentBytes()); + UMA_HISTOGRAM_COUNTS_1M("Net.BidirectionalStream.ReceivedBytes.QUIC", + stream_impl_->GetTotalReceivedBytes()); + UMA_HISTOGRAM_COUNTS_1M("Net.BidirectionalStream.SentBytes.QUIC", + stream_impl_->GetTotalSentBytes()); } }
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 6be3d87..a2d536b0 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -80,7 +80,7 @@ validation_cause_, VALIDATION_CAUSE_MAX); \ } \ if (stale_request) { \ - UMA_HISTOGRAM_COUNTS( \ + UMA_HISTOGRAM_COUNTS_1M( \ "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed" type, \ freshness_periods_since_last_used); \ } \ @@ -3025,16 +3025,16 @@ int64_t age_in_freshness_periods = (stale_entry_age_ * 100) / stale_entry_freshness_; if (cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED) { - UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age", - stale_entry_age_.InSeconds()); - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M("HttpCache.StaleEntry.Validated.Age", + stale_entry_age_.InSeconds()); + UMA_HISTOGRAM_COUNTS_1M( "HttpCache.StaleEntry.Validated.AgeInFreshnessPeriods", age_in_freshness_periods); } else { - UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Updated.Age", - stale_entry_age_.InSeconds()); - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M("HttpCache.StaleEntry.Updated.Age", + stale_entry_age_.InSeconds()); + UMA_HISTOGRAM_COUNTS_1M( "HttpCache.StaleEntry.Updated.AgeInFreshnessPeriods", age_in_freshness_periods); }
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 843a017..46ca41f 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc
@@ -66,10 +66,10 @@ int32_t size_diff = alternative_service_map->size() - alternative_service_map_.size(); if (size_diff > 0) { - UMA_HISTOGRAM_COUNTS("Net.AlternativeServiceServers.MorePrefsEntries", - size_diff); + UMA_HISTOGRAM_COUNTS_1M("Net.AlternativeServiceServers.MorePrefsEntries", + size_diff); } else { - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.AlternativeServiceServers.MoreOrEqualCacheEntries", -size_diff); }
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc index 00a82ed..0561e043 100644 --- a/net/http/http_server_properties_manager.cc +++ b/net/http/http_server_properties_manager.cc
@@ -844,13 +844,13 @@ // preferences. Update the cached data with new data from preferences. DCHECK(network_task_runner_->RunsTasksInCurrentSequence()); - UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers_map->size()); + UMA_HISTOGRAM_COUNTS_1M("Net.CountOfSpdyServers", spdy_servers_map->size()); http_server_properties_impl_->SetSpdyServers(std::move(spdy_servers_map)); // Update the cached data and use the new alternative service list from // preferences. - UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers", - alternative_service_map->size()); + UMA_HISTOGRAM_COUNTS_1M("Net.CountOfAlternateProtocolServers", + alternative_service_map->size()); http_server_properties_impl_->SetAlternativeServiceServers( std::move(alternative_service_map)); @@ -909,8 +909,8 @@ kMaxAlternateProtocolHostsToPersist); const AlternativeServiceMap& map = http_server_properties_impl_->alternative_service_map(); - UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers.Memory", - map.size()); + UMA_HISTOGRAM_COUNTS_1M("Net.CountOfAlternateProtocolServers.Memory", + map.size()); int count = 0; typedef std::map<std::string, bool> CanonicalHostPersistedMap; CanonicalHostPersistedMap persisted_map;
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index c10e224..4ec8970 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -1528,8 +1528,8 @@ if (downstream_throughput_kbps > 0) { RecordExternalEstimateProviderMetrics( EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); - UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", - downstream_throughput_kbps); + UMA_HISTOGRAM_COUNTS_1M("NQE.ExternalEstimateProvider.DownlinkBandwidth", + downstream_throughput_kbps); ThroughputObservation throughput_observation( downstream_throughput_kbps, tick_clock_->NowTicks(), signal_strength_, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE); @@ -1721,7 +1721,7 @@ nqe::internal::CachedNetworkQuality> read_prefs) { DCHECK(thread_checker_.CalledOnValidThread()); - UMA_HISTOGRAM_COUNTS("NQE.Prefs.ReadSize", read_prefs.size()); + UMA_HISTOGRAM_COUNTS_1M("NQE.Prefs.ReadSize", read_prefs.size()); for (auto& it : read_prefs) { EffectiveConnectionType effective_connection_type = it.second.effective_connection_type();
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index 7eec53a..df34c97 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -673,12 +673,13 @@ else RecordHandshakeState(STATE_FAILED); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.NumTotalStreams", num_total_streams_); - UMA_HISTOGRAM_COUNTS("Net.QuicNumSentClientHellos", - crypto_stream_->num_sent_client_hellos()); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.Pushed", streams_pushed_count_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.PushedAndClaimed", - streams_pushed_and_claimed_count_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.NumTotalStreams", + num_total_streams_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicNumSentClientHellos", + crypto_stream_->num_sent_client_hellos()); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.Pushed", streams_pushed_count_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PushedAndClaimed", + streams_pushed_and_claimed_count_); UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PushedBytes", bytes_pushed_count_); DCHECK_LE(bytes_pushed_and_unclaimed_count_, bytes_pushed_count_); UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PushedAndUnclaimedBytes", @@ -717,8 +718,8 @@ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ServerSideMtu", stats.max_received_packet_size); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.MtuProbesSent", - connection()->mtu_probe_count()); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.MtuProbesSent", + connection()->mtu_probe_count()); if (stats.packets_sent >= 100) { // Used to monitor for regressions that effect large uploads. @@ -741,7 +742,7 @@ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.MaxReorderingTimeLongRtt", reordering, 1, kMaxReordering, 50); } - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.MaxReordering", static_cast<base::HistogramBase::Sample>(stats.max_sequence_reordering)); } @@ -769,10 +770,10 @@ void QuicChromiumClientSession::OnStreamFrame(const QuicStreamFrame& frame) { // Record total number of stream frames. - UMA_HISTOGRAM_COUNTS("Net.QuicNumStreamFramesInPacket", 1); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicNumStreamFramesInPacket", 1); // Record number of frames per stream in packet. - UMA_HISTOGRAM_COUNTS("Net.QuicNumStreamFramesPerStreamInPacket", 1); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicNumStreamFramesPerStreamInPacket", 1); return QuicSpdySession::OnStreamFrame(frame); } @@ -891,8 +892,8 @@ new QuicChromiumClientStream(GetNextOutgoingStreamId(), this, net_log_); ActivateStream(base::WrapUnique(stream)); ++num_total_streams_; - UMA_HISTOGRAM_COUNTS("Net.QuicSession.NumOpenStreams", - GetNumOpenOutgoingStreams()); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.NumOpenStreams", + GetNumOpenOutgoingStreams()); // The previous histogram puts 100 in a bucket betweeen 86-113 which does // not shed light on if chrome ever things it has more than 100 streams open. UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.TooManyOpenStreams", @@ -1288,7 +1289,7 @@ } if (error == QUIC_NETWORK_IDLE_TIMEOUT) { - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.ConnectionClose.NumOpenStreams.TimedOut", GetNumOpenOutgoingStreams()); if (IsCryptoHandshakeConfirmed()) { @@ -1296,10 +1297,10 @@ UMA_HISTOGRAM_BOOLEAN( "Net.QuicSession.TimedOutWithOpenStreams.HasUnackedPackets", connection()->sent_packet_manager().HasUnackedPackets()); - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.TimedOutWithOpenStreams.ConsecutiveRTOCount", connection()->sent_packet_manager().GetConsecutiveRtoCount()); - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.TimedOutWithOpenStreams.ConsecutiveTLPCount", connection()->sent_packet_manager().GetConsecutiveTlpCount()); UMA_HISTOGRAM_SPARSE_SLOWLY( @@ -1307,10 +1308,10 @@ connection()->self_address().port()); } } else { - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.ConnectionClose.NumOpenStreams.HandshakeTimedOut", GetNumOpenOutgoingStreams()); - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.ConnectionClose.NumTotalStreams.HandshakeTimedOut", num_total_streams_); }
diff --git a/net/quic/chromium/quic_connection_logger.cc b/net/quic/chromium/quic_connection_logger.cc index 7741b97..e50792c 100644 --- a/net/quic/chromium/quic_connection_logger.cc +++ b/net/quic/chromium/quic_connection_logger.cc
@@ -306,20 +306,20 @@ socket_performance_watcher_(std::move(socket_performance_watcher)) {} QuicConnectionLogger::~QuicConnectionLogger() { - UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderPacketsReceived", - num_out_of_order_received_packets_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderLargePacketsReceived", - num_out_of_order_large_received_packets_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.IncorrectConnectionIDsReceived", - num_incorrect_connection_ids_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.UndecryptablePacketsReceived", - num_undecryptable_packets_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.DuplicatePacketsReceived", - num_duplicate_packets_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.BlockedFrames.Received", - num_blocked_frames_received_); - UMA_HISTOGRAM_COUNTS("Net.QuicSession.BlockedFrames.Sent", - num_blocked_frames_sent_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.OutOfOrderPacketsReceived", + num_out_of_order_received_packets_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.OutOfOrderLargePacketsReceived", + num_out_of_order_large_received_packets_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.IncorrectConnectionIDsReceived", + num_incorrect_connection_ids_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.UndecryptablePacketsReceived", + num_undecryptable_packets_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.DuplicatePacketsReceived", + num_duplicate_packets_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.BlockedFrames.Received", + num_blocked_frames_received_); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.BlockedFrames.Sent", + num_blocked_frames_sent_); const QuicConnectionStats& stats = session_->connection()->GetStats(); UMA_HISTOGRAM_TIMES("Net.QuicSession.MinRTT", @@ -491,8 +491,9 @@ // There is a gap between the largest packet previously received and // the current packet. This indicates either loss, or out-of-order // delivery. - UMA_HISTOGRAM_COUNTS("Net.QuicSession.PacketGapReceived", - static_cast<base::HistogramBase::Sample>(delta - 1)); + UMA_HISTOGRAM_COUNTS_1M( + "Net.QuicSession.PacketGapReceived", + static_cast<base::HistogramBase::Sample>(delta - 1)); } largest_received_packet_number_ = header.packet_number; } @@ -503,12 +504,12 @@ ++num_out_of_order_received_packets_; if (previous_received_packet_size_ < last_received_packet_size_) ++num_out_of_order_large_received_packets_; - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.OutOfOrderGapReceived", static_cast<base::HistogramBase::Sample>(last_received_packet_number_ - header.packet_number)); } else if (no_packet_received_after_ping_) { - UMA_HISTOGRAM_COUNTS( + UMA_HISTOGRAM_COUNTS_1M( "Net.QuicSession.PacketGapReceivedNearPing", static_cast<base::HistogramBase::Sample>(header.packet_number - last_received_packet_number_));
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index c65cced..5665ce49 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -1555,7 +1555,7 @@ QuicChromiumClientSession* session) { const QuicServerId& server_id(key.server_id()); DCHECK(!HasActiveSession(server_id)); - UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicActiveSessions", active_sessions_.size()); active_sessions_[server_id] = session; session_aliases_[session].insert(key); const IPEndPoint peer_address = @@ -1697,8 +1697,8 @@ http_server_properties_->ClearServerNetworkStats(server); - UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", - stats.packets_received); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicHandshakeNotConfirmedNumPacketsReceived", + stats.packets_received); if (!session_was_active) return;
diff --git a/net/quic/core/quic_crypto_client_stream.cc b/net/quic/core/quic_crypto_client_stream.cc index 7f1cd9ef..b9303c4 100644 --- a/net/quic/core/quic_crypto_client_stream.cc +++ b/net/quic/core/quic_crypto_client_stream.cc
@@ -641,8 +641,8 @@ update_ignored = true; next_state_ = STATE_NONE; } - UMA_HISTOGRAM_COUNTS("Net.QuicNumServerConfig.UpdateMessagesIgnored", - update_ignored); + UMA_HISTOGRAM_COUNTS_1M("Net.QuicNumServerConfig.UpdateMessagesIgnored", + update_ignored); } void QuicCryptoClientStream::SetCachedProofValid(
diff --git a/net/sdch/sdch_owner.cc b/net/sdch/sdch_owner.cc index fff251f..bd33662d 100644 --- a/net/sdch/sdch_owner.cc +++ b/net/sdch/sdch_owner.cc
@@ -393,7 +393,7 @@ }; if (!was_from_cache) - UMA_HISTOGRAM_COUNTS("Sdch3.NetworkBytesSpent", dictionary_text.size()); + UMA_HISTOGRAM_COUNTS_1M("Sdch3.NetworkBytesSpent", dictionary_text.size()); // Figure out if there is space for the incoming dictionary; evict // stale dictionaries if needed to make space.
diff --git a/net/spdy/chromium/spdy_stream.cc b/net/spdy/chromium/spdy_stream.cc index 1ec1366..742004a 100644 --- a/net/spdy/chromium/spdy_stream.cc +++ b/net/spdy/chromium/spdy_stream.cc
@@ -827,8 +827,8 @@ UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", recv_last_byte_time_ - effective_send_time); - UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); - UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); + UMA_HISTOGRAM_COUNTS_1M("Net.SpdySendBytes", send_bytes_); + UMA_HISTOGRAM_COUNTS_1M("Net.SpdyRecvBytes", recv_bytes_); } void SpdyStream::QueueNextDataFrame() {
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index b34fbd5..ca79261 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -1522,15 +1522,16 @@ prefilter_bytes_read(), 1, 50000000, 50); if (response_info_->unused_since_prefetch) - UMA_HISTOGRAM_COUNTS("Net.Prefetch.HitBytes", prefilter_bytes_read()); + UMA_HISTOGRAM_COUNTS_1M("Net.Prefetch.HitBytes", + prefilter_bytes_read()); } else { UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeNotCached", total_time); UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpJob.PrefilterBytesRead.Net", prefilter_bytes_read(), 1, 50000000, 50); if (request_info_.load_flags & LOAD_PREFETCH) { - UMA_HISTOGRAM_COUNTS("Net.Prefetch.PrefilterBytesReadFromNetwork", - prefilter_bytes_read()); + UMA_HISTOGRAM_COUNTS_1M("Net.Prefetch.PrefilterBytesReadFromNetwork", + prefilter_bytes_read()); } if (is_https_google) { if (used_quic) {
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index e96f88a..c4f8d644 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -1857,7 +1857,7 @@ FORM_OnLButtonUp(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); } - if (area == PDFiumPage::FORM_TEXT_AREA) + if (area == PDFiumPage::FORM_TEXT_AREA && last_page_mouse_down_ != -1) SetFormSelectedText(form_, pages_[last_page_mouse_down_]->GetPage()); if (!selecting_)
diff --git a/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java b/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java index c8303ef..083a8f52 100644 --- a/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java +++ b/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java
@@ -207,6 +207,8 @@ public void pdfWritingDone(boolean success) { if (mPrintingState == PRINTING_STATE_FINISHED) return; mPrintingState = PRINTING_STATE_READY; + closeFileDescriptor(mFileDescriptor); + mFileDescriptor = -1; if (success) { PageRange[] pageRanges = convertIntegerArrayToPageRanges(mPages); mOnWriteCallback.onWriteFinished(pageRanges); @@ -214,8 +216,6 @@ mOnWriteCallback.onWriteFailed(mErrorMessage); resetCallbacks(); } - closeFileDescriptor(mFileDescriptor); - mFileDescriptor = -1; } @Override @@ -291,9 +291,7 @@ // the state isn't PRINTING_STATE_READY, so we enter here and make this call (no // extra). If we complete the PDF generation successfully from onLayout or onWrite, // we already make the state PRINTING_STATE_READY and call askUserForSettingsReply - // inside pdfWritingDone, thus not entering here. Also, if we get an extra - // AskUserForSettings call, it's handled inside {@link - // PrintingContext#pageCountEstimationDone}. + // inside pdfWritingDone, thus not entering here. mPrintingContext.askUserForSettingsReply(false); } mPrintingContext.updatePrintingContextMap(mFileDescriptor, true);
diff --git a/printing/printed_document.cc b/printing/printed_document.cc index 319b479..8942849 100644 --- a/printing/printed_document.cc +++ b/printing/printed_document.cc
@@ -239,9 +239,10 @@ const base::FilePath::StringType& extension) { if (g_debug_dump_info.Get().empty()) return; - base::PostTaskWithTraits( - FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()}, - base::BindOnce(&DebugDumpDataTask, name(), extension, data)); + base::PostTaskWithTraits(FROM_HERE, + {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&DebugDumpDataTask, name(), extension, + base::RetainedRef(data))); } PrintedDocument::Mutable::Mutable(PrintedPagesSource* source)
diff --git a/remoting/android/BUILD.gn b/remoting/android/BUILD.gn index 248c1ea0..07cbe53 100644 --- a/remoting/android/BUILD.gn +++ b/remoting/android/BUILD.gn
@@ -20,6 +20,16 @@ jni_package = "remoting" } +generate_jni_registration("remoting_jni_registration") { + target = ":remoting_apk" + output = "$root_gen_dir/remoting/client/${target_name}.h" + exception_files = [ + "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", + "//base/android/java/src/org/chromium/base/library_loader/Linker.java", + "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", + ] +} + _raw_resources_base_dir = "$target_gen_dir/credits_resources_raw/res" # The target is named this way, instead of "..._raw_resources", specifically
diff --git a/remoting/client/jni/BUILD.gn b/remoting/client/jni/BUILD.gn index f0f8082..6f10926 100644 --- a/remoting/client/jni/BUILD.gn +++ b/remoting/client/jni/BUILD.gn
@@ -19,6 +19,7 @@ shared_library("remoting_client_jni") { deps = [ "//remoting/android:jni_headers", + "//remoting/android:remoting_jni_registration", "//remoting/base", "//remoting/client", "//remoting/client/display",
diff --git a/remoting/client/jni/remoting_jni_onload.cc b/remoting/client/jni/remoting_jni_onload.cc index 9db79a8..dd1a283d 100644 --- a/remoting/client/jni/remoting_jni_onload.cc +++ b/remoting/client/jni/remoting_jni_onload.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "net/android/net_jni_registrar.h" #include "remoting/client/jni/remoting_jni_registrar.h" +#include "remoting/client/remoting_jni_registration.h" #include "ui/gfx/android/gfx_jni_registrar.h" namespace { @@ -32,6 +33,12 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); + if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) { + return -1; + } + + // TODO(agrieve): Delete this block, this is a no-op now. + // https://crbug.com/683256. if (!RegisterJNI(env) || !base::android::OnJNIOnLoadInit()) { return -1; }
diff --git a/remoting/ios/app/BUILD.gn b/remoting/ios/app/BUILD.gn index 9df6c6f..f1a05251b6 100644 --- a/remoting/ios/app/BUILD.gn +++ b/remoting/ios/app/BUILD.gn
@@ -26,6 +26,8 @@ "host_collection_view_cell.mm", "host_collection_view_controller.h", "host_collection_view_controller.mm", + "host_fetching_view_controller.h", + "host_fetching_view_controller.mm", "host_setup_footer_view.h", "host_setup_footer_view.mm", "host_setup_header_view.h",
diff --git a/remoting/ios/app/host_fetching_view_controller.h b/remoting/ios/app/host_fetching_view_controller.h new file mode 100644 index 0000000..25e23aa --- /dev/null +++ b/remoting/ios/app/host_fetching_view_controller.h
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_IOS_APP_HOST_FETCHING_VIEW_CONTROLLER_H_ +#define REMOTING_IOS_APP_HOST_FETCHING_VIEW_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +// This view controller simply shows the host refresh indicator. +@interface HostFetchingViewController : UIViewController +@end + +#endif // REMOTING_IOS_APP_HOST_FETCHING_VIEW_CONTROLLER_H_
diff --git a/remoting/ios/app/host_fetching_view_controller.mm b/remoting/ios/app/host_fetching_view_controller.mm new file mode 100644 index 0000000..8637500b --- /dev/null +++ b/remoting/ios/app/host_fetching_view_controller.mm
@@ -0,0 +1,36 @@ +// 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. + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#import "remoting/ios/app/host_fetching_view_controller.h" + +#import "ios/third_party/material_components_ios/src/components/ActivityIndicator/src/MDCActivityIndicator.h" +#import "remoting/ios/app/remoting_theme.h" + +static const CGFloat kActivityIndicatorStrokeWidth = 4.f; +static const CGFloat kActivityIndicatorRadius = 32.f; + +@implementation HostFetchingViewController + +- (void)viewDidLoad { + MDCActivityIndicator* activityIndicator = [[MDCActivityIndicator alloc] init]; + activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; + activityIndicator.cycleColors = + @[ RemotingTheme.hostListRefreshIndicatorColor ]; + activityIndicator.radius = kActivityIndicatorRadius; + activityIndicator.strokeWidth = kActivityIndicatorStrokeWidth; + [self.view addSubview:activityIndicator]; + [NSLayoutConstraint activateConstraints:@[ + [activityIndicator.centerXAnchor + constraintEqualToAnchor:self.view.centerXAnchor], + [activityIndicator.centerYAnchor + constraintEqualToAnchor:self.view.centerYAnchor], + ]]; + [activityIndicator startAnimating]; +} + +@end
diff --git a/remoting/ios/app/remoting_ios_tmpl.gni b/remoting/ios/app/remoting_ios_tmpl.gni index 76911e03..9f3e0942 100644 --- a/remoting/ios/app/remoting_ios_tmpl.gni +++ b/remoting/ios/app/remoting_ios_tmpl.gni
@@ -10,6 +10,20 @@ remoting_ios_app_source_dir = get_path_info("./", "abspath") +# Arguments +# +# output_name: +# string, the filename of the generated .app folder +# +# entitlements_path: +# string, ath of the .entitlements file +# +# remoting_source_set: +# The source set to be compiled +# +# bundle_id: +# (optional) string, the bundle_id. If this is not set, it will come from +# either branding_Chromium or branding_Chrome template("ios_remoting_app_tmpl") { info_plist_target_name = "${target_name}_tweak_info_plist" tweak_info_plist(info_plist_target_name) { @@ -30,8 +44,14 @@ entitlements_path = invoker.entitlements_path info_plist_target = ":$info_plist_target_name" + if (defined(invoker.bundle_id)) { + bundle_id = invoker.bundle_id + } else { + bundle_id = remoting_ios_bundle_id + } + extra_substitutions = [ - "BUNDLE_IDENTIFIER=$remoting_ios_bundle_id", + "BUNDLE_IDENTIFIER=$bundle_id", "DISPLAY_NAME=$remoting_ios_display_name", "EXECUTABLE_NAME=$remoting_ios_executable_name", "MINIMUM_OS_VERSION=7.0",
diff --git a/remoting/ios/app/remoting_theme.h b/remoting/ios/app/remoting_theme.h index 6ff50112..a929e82 100644 --- a/remoting/ios/app/remoting_theme.h +++ b/remoting/ios/app/remoting_theme.h
@@ -14,6 +14,7 @@ @property(class, nonatomic, readonly) UIColor* connectionViewBackgroundColor; @property(class, nonatomic, readonly) UIColor* hostListBackgroundColor; +@property(class, nonatomic, readonly) UIColor* hostListRefreshIndicatorColor; @property(class, nonatomic, readonly) UIColor* menuBlueColor; @property(class, nonatomic, readonly) UIColor* offlineHostColor; @property(class, nonatomic, readonly) UIColor* onlineHostColor;
diff --git a/remoting/ios/app/remoting_theme.mm b/remoting/ios/app/remoting_theme.mm index 7fbf87cc..a0306646 100644 --- a/remoting/ios/app/remoting_theme.mm +++ b/remoting/ios/app/remoting_theme.mm
@@ -30,6 +30,15 @@ return color; } ++ (UIColor*)hostListRefreshIndicatorColor { + static UIColor* color; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + color = [UIColor colorWithRed:0.50f green:0.87f blue:0.92f alpha:1.f]; + }); + return color; +} + + (UIColor*)menuBlueColor { static UIColor* color; static dispatch_once_t onceToken;
diff --git a/remoting/ios/app/remoting_view_controller.mm b/remoting/ios/app/remoting_view_controller.mm index db5ec798..637febc 100644 --- a/remoting/ios/app/remoting_view_controller.mm +++ b/remoting/ios/app/remoting_view_controller.mm
@@ -18,6 +18,7 @@ #import "remoting/ios/app/app_delegate.h" #import "remoting/ios/app/client_connection_view_controller.h" #import "remoting/ios/app/host_collection_view_controller.h" +#import "remoting/ios/app/host_fetching_view_controller.h" #import "remoting/ios/app/host_setup_view_controller.h" #import "remoting/ios/app/host_view_controller.h" #import "remoting/ios/app/remoting_menu_view_controller.h" @@ -39,6 +40,7 @@ MDCDialogTransitionController* _dialogTransitionController; MDCAppBar* _appBar; HostCollectionViewController* _collectionViewController; + HostFetchingViewController* _fetchingViewController; HostSetupViewController* _setupViewController; RemotingService* _remotingService; } @@ -67,6 +69,8 @@ _collectionViewController.delegate = self; _collectionViewController.scrollViewDelegate = self.headerViewController; + _fetchingViewController = [[HostFetchingViewController alloc] init]; + _setupViewController = [[HostSetupViewController alloc] init]; _setupViewController.scrollViewDelegate = self.headerViewController; @@ -147,6 +151,9 @@ [super viewWillAppear:animated]; [self nowAuthenticated:_remotingService.authentication.user.isAuthenticated]; + if (_isAuthenticated) { + [_remotingService requestHostListFetch]; + } [self presentStatus]; } @@ -157,8 +164,6 @@ MDCSnackbarMessage* message = [[MDCSnackbarMessage alloc] init]; message.text = @"Please login."; [MDCSnackbarManager showMessage:message]; - } else { - [_remotingService requestHostListFetch]; } } @@ -278,7 +283,8 @@ } if (_remotingService.hostListState == HostListStateFetching) { - NSLog(@"Fetching host list... TODO: Show fetching UI here."); + self.contentViewController = _fetchingViewController; + _fetchingViewController.view.frame = self.view.bounds; return; }
diff --git a/services/device/battery/battery_status_manager_linux_unittest.cc b/services/device/battery/battery_status_manager_linux_unittest.cc index 1b595d4..b5d792e6 100644 --- a/services/device/battery/battery_status_manager_linux_unittest.cc +++ b/services/device/battery/battery_status_manager_linux_unittest.cc
@@ -46,8 +46,9 @@ const std::string& signal_name, dbus::ObjectProxy::SignalCallback signal_callback, dbus::ObjectProxy::OnConnectedCallback on_connected_callback); - dbus::Response* CreateCallMethodResponse(dbus::MethodCall* method_call, - Unused); + std::unique_ptr<dbus::Response> CreateCallMethodResponse( + dbus::MethodCall* method_call, + Unused); void SignalDeviceAdded(const std::string& added_device_path); void SignalDeviceRemoved(const std::string& removed_device_path); @@ -88,7 +89,7 @@ on_connected_callback.Run(interface_name, signal_name, on_connected_success); } -dbus::Response* MockUPowerObject::CreateCallMethodResponse( +std::unique_ptr<dbus::Response> MockUPowerObject::CreateCallMethodResponse( dbus::MethodCall* method_call, Unused) { if (method_call->GetInterface() == kUPowerInterfaceName) { @@ -100,14 +101,14 @@ for (const auto& device : devices) array_writer.AppendObjectPath(dbus::ObjectPath(device)); writer.CloseContainer(&array_writer); - return response.release(); + return response; } else if (method_call->GetMember() == kUPowerMethodGetDisplayDevice) { std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); if (!display_device.empty()) { dbus::MessageWriter writer(response.get()); writer.AppendObjectPath(dbus::ObjectPath(display_device)); } - return response.release(); + return response; } } else if (method_call->GetInterface() == dbus::kPropertiesInterface) { std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); @@ -120,7 +121,7 @@ reader.PopString(&property_name) && property_name == kUPowerPropertyDaemonVersion) { writer.AppendVariantOfString(daemon_version); - return response.release(); + return response; } } else if (method_call->GetMember() == dbus::kPropertiesGetAll) { dbus::MessageWriter array_writer(nullptr); @@ -131,7 +132,7 @@ dict_entry_writer.AppendVariantOfString(daemon_version); array_writer.CloseContainer(&dict_entry_writer); writer.CloseContainer(&array_writer); - return response.release(); + return response; } } @@ -175,8 +176,9 @@ const std::string& signal_name, dbus::ObjectProxy::SignalCallback signal_callback, dbus::ObjectProxy::OnConnectedCallback on_connected_callback); - dbus::Response* CreateCallMethodResponse(dbus::MethodCall* method_call, - Unused); + std::unique_ptr<dbus::Response> CreateCallMethodResponse( + dbus::MethodCall* method_call, + Unused); MockBatteryObject& ExpectConnectToSignalChanged(); MockBatteryObject& ExpectConnectToSignalPropertyChanged(); void SignalChanged(); @@ -226,7 +228,7 @@ on_connected_callback.Run(interface_name, signal_name, on_connected_success); } -dbus::Response* MockBatteryObject::CreateCallMethodResponse( +std::unique_ptr<dbus::Response> MockBatteryObject::CreateCallMethodResponse( dbus::MethodCall* method_call, Unused) { if (method_call->GetInterface() == dbus::kPropertiesInterface) { @@ -243,7 +245,7 @@ dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); AppendPropertyToWriter(&writer, property_name); - return response.release(); + return response; } } else if (method_call->GetMember() == dbus::kPropertiesGetAll) { if (!properties) @@ -252,7 +254,7 @@ std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); AppendAllPropertiesToWriter(&writer); - return response.release(); + return response; } } LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); @@ -400,7 +402,7 @@ mock_upower_.proxy = new NiceMock<dbus::MockObjectProxy>( mock_bus_.get(), kUPowerServiceName, dbus::ObjectPath(kUPowerPath)); ExpectGetObjectProxy(kUPowerPath, mock_upower_.proxy.get()); - EXPECT_CALL(*mock_upower_.proxy.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_upower_.proxy.get(), CallMethodAndBlock(_, _)) .WillRepeatedly( Invoke(&mock_upower_, &MockUPowerObject::CreateCallMethodResponse)); EXPECT_CALL( @@ -514,7 +516,7 @@ std::unique_ptr<MockBatteryObject> mock_object( new MockBatteryObject(mock_bus_.get(), object_path, properties)); ExpectGetObjectProxy(object_path, mock_object.get()); - EXPECT_CALL(*mock_object->proxy.get(), MockCallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_object->proxy.get(), CallMethodAndBlock(_, _)) .WillRepeatedly(Invoke(mock_object.get(), &MockBatteryObject::CreateCallMethodResponse)); return mock_object;
diff --git a/services/device/time_zone_monitor/time_zone_monitor.cc b/services/device/time_zone_monitor/time_zone_monitor.cc index 52e2a52..5065336 100644 --- a/services/device/time_zone_monitor/time_zone_monitor.cc +++ b/services/device/time_zone_monitor/time_zone_monitor.cc
@@ -9,6 +9,10 @@ #include "third_party/icu/source/common/unicode/unistr.h" #include "third_party/icu/source/i18n/unicode/timezone.h" +#if defined(OS_ANDROID) +#include "base/android/timezone_utils.h" // nogncheck +#endif + namespace device { TimeZoneMonitor::TimeZoneMonitor() { @@ -30,24 +34,32 @@ // need to redetect it with detectHostTimeZone(). std::unique_ptr<icu::TimeZone> new_zone(icu::TimeZone::createDefault()); #else - icu::TimeZone* new_zone = icu::TimeZone::detectHostTimeZone(); +#if defined(OS_ANDROID) + base::string16 timezone_id = base::android::GetDefaultTimeZoneId(); + std::unique_ptr<icu::TimeZone> new_zone(icu::TimeZone::createTimeZone( + icu::UnicodeString(FALSE, timezone_id.data(), timezone_id.length()))); +#else + std::unique_ptr<icu::TimeZone> new_zone(icu::TimeZone::detectHostTimeZone()); +#endif #if defined(OS_LINUX) // We get here multiple times on Linux per a single tz change, but // want to update the ICU default zone and notify renderer only once. std::unique_ptr<icu::TimeZone> current_zone(icu::TimeZone::createDefault()); if (*current_zone == *new_zone) { VLOG(1) << "timezone already updated"; - delete new_zone; return; } #endif - icu::TimeZone::adoptDefault(new_zone); -#endif +#endif // OS_CHROMEOS icu::UnicodeString zone_id; std::string zone_id_str; new_zone->getID(zone_id).toUTF8String(zone_id_str); VLOG(1) << "timezone reset to " << zone_id_str; +#if !defined(OS_CHROMEOS) + icu::TimeZone::adoptDefault(new_zone.release()); +#endif + clients_.ForAllPtrs( [&zone_id_str](device::mojom::TimeZoneMonitorClient* client) { client->OnTimeZoneChange(zone_id_str);
diff --git a/services/service_manager/public/cpp/binder_registry.h b/services/service_manager/public/cpp/binder_registry.h index 70034170..42f9b53 100644 --- a/services/service_manager/public/cpp/binder_registry.h +++ b/services/service_manager/public/cpp/binder_registry.h
@@ -31,6 +31,9 @@ BinderRegistryWithParams() : weak_factory_(this) {} ~BinderRegistryWithParams() = default; + // Adds an interface inferring the interface name via the templated + // parameter Interface::Name_ + // Usage example: //services/service_manager/README.md#OnBindInterface template <typename Interface> void AddInterface( const base::Callback<void(const BindSourceInfo&,
diff --git a/services/ui/gpu/gpu_main.cc b/services/ui/gpu/gpu_main.cc index 5f4d90b..426d901 100644 --- a/services/ui/gpu/gpu_main.cc +++ b/services/ui/gpu/gpu_main.cc
@@ -50,7 +50,6 @@ GpuMain::GpuMain(mojom::GpuMainRequest request) : gpu_thread_("GpuThread"), io_thread_("GpuIOThread"), - compositor_thread_("DisplayCompositorThread"), power_monitor_(base::MakeUnique<base::PowerMonitorDeviceSource>()), binding_(this) { base::Thread::Options thread_options; @@ -89,9 +88,7 @@ #endif CHECK(io_thread_.StartWithOptions(thread_options)); - // Start the compositor thread. - compositor_thread_.Start(); - compositor_thread_task_runner_ = compositor_thread_.task_runner(); + compositor_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); // |this| will outlive the gpu thread and so it's safe to use // base::Unretained here. @@ -105,15 +102,9 @@ } GpuMain::~GpuMain() { - // Unretained() is OK here since the thread/task runner is owned by |this|. - compositor_thread_task_runner_->PostTask( - FROM_HERE, - base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this))); - - // Block the main thread until the compositor thread terminates which blocks - // on the gpu thread. The Stop must be initiated from here instead of the gpu - // thread to avoid deadlock. - compositor_thread_.Stop(); + DCHECK(compositor_thread_task_runner_->BelongsToCurrentThread()); + // Tear down the compositor first because it blocks on the gpu service. + TearDownOnCompositorThread(); gpu_thread_task_runner_->PostTask( FROM_HERE,
diff --git a/services/ui/gpu/gpu_main.h b/services/ui/gpu/gpu_main.h index b3afca9..704fc6e 100644 --- a/services/ui/gpu/gpu_main.h +++ b/services/ui/gpu/gpu_main.h
@@ -94,12 +94,6 @@ // The thread that handles IO events for Gpu. base::Thread io_thread_; - // The frame sink manager gets its own thread in mus-gpu. The gpu service, - // where GL commands are processed resides on its own thread. Various - // components of the frame sink manager such as Display, ResourceProvider, - // and GLRenderer block on sync tokens from other command buffers. Thus, - // the gpu service must live on a separate thread. - base::Thread compositor_thread_; scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner_; base::PowerMonitor power_monitor_;
diff --git a/services/ui/public/cpp/bitmap/BUILD.gn b/services/ui/public/cpp/bitmap/BUILD.gn deleted file mode 100644 index 2562f20..0000000 --- a/services/ui/public/cpp/bitmap/BUILD.gn +++ /dev/null
@@ -1,20 +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. - -import("//build/config/ui.gni") - -source_set("bitmap") { - sources = [ - "child_shared_bitmap_manager.cc", - "child_shared_bitmap_manager.h", - ] - - deps = [ - "//base", - "//cc", - "//cc/ipc:interfaces", - "//mojo/public/cpp/bindings", - "//ui/gfx", - ] -}
diff --git a/services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h b/services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h deleted file mode 100644 index 7e8eb3a9..0000000 --- a/services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h +++ /dev/null
@@ -1,51 +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 SERVICES_UI_PUBLIC_CPP_BITMAP_CHILD_CHILD_SHARED_BITMAP_MANAGER_H_ -#define SERVICES_UI_PUBLIC_CPP_BITMAP_CHILD_CHILD_SHARED_BITMAP_MANAGER_H_ - -#include <stdint.h> - -#include <memory> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/shared_memory.h" -#include "cc/ipc/shared_bitmap_manager.mojom.h" -#include "cc/resources/shared_bitmap_manager.h" -#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" - -namespace ui { - -class ChildSharedBitmapManager : public cc::SharedBitmapManager { - public: - explicit ChildSharedBitmapManager( - const scoped_refptr< - cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr>& - shared_bitmap_manager_ptr); - ~ChildSharedBitmapManager() override; - - // cc::SharedBitmapManager implementation. - std::unique_ptr<cc::SharedBitmap> AllocateSharedBitmap( - const gfx::Size& size) override; - std::unique_ptr<cc::SharedBitmap> GetSharedBitmapFromId( - const gfx::Size&, - const cc::SharedBitmapId&) override; - - std::unique_ptr<cc::SharedBitmap> GetBitmapForSharedMemory( - base::SharedMemory* mem); - - private: - void NotifyAllocatedSharedBitmap(base::SharedMemory* memory, - const cc::SharedBitmapId& id); - - scoped_refptr<cc::mojom::ThreadSafeSharedBitmapManagerAssociatedPtr> - shared_bitmap_manager_ptr_; - - DISALLOW_COPY_AND_ASSIGN(ChildSharedBitmapManager); -}; - -} // namespace ui - -#endif // SERVICES_UI_PUBLIC_CPP_BITMAP_CHILD_CHILD_SHARED_BITMAP_MANAGER_H_
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 41b9a807..af12d1a2 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -202,10 +202,6 @@ # define SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE #endif -#ifndef SK_SUPPORT_BLITV_FOR_BLUR_NINE -#define SK_SUPPORT_BLITV_FOR_BLUR_NINE -#endif - // Remove this after we fixed all the issues related to the new SDF algorithm // (https://codereview.chromium.org/1643143002) #ifndef SK_USE_LEGACY_DISTANCE_FIELDS @@ -220,6 +216,10 @@ #define SK_SUPPORT_LEGACY_TILED_BITMAPS #endif +#ifndef SK_SUPPORT_LEGACY_SWIZZLE_SHADER +#define SK_SUPPORT_LEGACY_SWIZZLE_SHADER +#endif + ///////////////////////// Imported from BUILD.gn and skia_common.gypi /* In some places Skia can use static initializers for global initialization,
diff --git a/sql/OWNERS b/sql/OWNERS index a4209042..dc520c7 100644 --- a/sql/OWNERS +++ b/sql/OWNERS
@@ -1,5 +1,8 @@ -michaeln@chromium.org +# Primary pwnall@chromium.org +# Secondary +michaeln@chromium.org + # TEAM: storage-dev@chromium.org # COMPONENT: Blink>Storage
diff --git a/storage/public/interfaces/blobs.mojom b/storage/public/interfaces/blobs.mojom index c89f648f..cba6116e4 100644 --- a/storage/public/interfaces/blobs.mojom +++ b/storage/public/interfaces/blobs.mojom
@@ -68,7 +68,30 @@ // Interface through which the blob registry can request data when it is ready // for it. interface BytesProvider { - // TODO(mek): Define methods. + // Requests all the data provided by this provider as an array in the reply. + // The size of this array must match the length attribute of the + // DataElementBytes struct this provider was associated with. + // If this method is called, it is called exactly once, and none of the other + // methods will be called. + RequestAsReply() => (array<uint8> data); + + // Requests all the data provided by this provider to be transfered on a data + // pipe. The amount of data transfered should match the length attribute of + // the DataElementBytes struct this provider was associated with. + // If this method is called, it is called exactly once, and none of the other + // methods will be called. + RequestAsStream(handle<data_pipe_producer> pipe); + + // Requests the provider to write a slice of the data provided by this + // provider to the given file at the given offset. When the data is written + // the callback should be invoked with the new modification time of the file. + // If this method is called, it can be called multiple times, but none of the + // other methods will be called. + // If writing for whatever reason fails, the callback is called without a + // modification time. + RequestAsFile(uint64 source_offset, uint64 source_size, + mojo.common.mojom.File file, uint64 file_offset) + => (mojo.common.mojom.Time? time_file_modified); }; // A reference to a slice of a file on disk.
diff --git a/styleguide/java/OWNERS b/styleguide/java/OWNERS index 131b31e..d860494c 100644 --- a/styleguide/java/OWNERS +++ b/styleguide/java/OWNERS
@@ -1,5 +1,4 @@ agrieve@chromium.org -dfalcantara@chromium.org nyquist@chromium.org tedchoc@chromium.org yfriedman@chromium.org
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 4d2660a..42f3b8b 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -400,6 +400,46 @@ "test": "components_unittests" }, { + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "content_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "android_devices": "4", + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 1200, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "content_browsertests" + }, + { "args": [ "--gs-results-bucket=chromium-result-details" ],
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 2004c14..05806c9 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -5426,6 +5426,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -5695,6 +5701,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -5964,6 +5976,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -6233,6 +6251,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -6502,6 +6526,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -6771,6 +6801,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -7016,6 +7052,12 @@ "can_use_on_swarming_builders": true }, "test": "views_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -7261,6 +7303,12 @@ "can_use_on_swarming_builders": true }, "test": "views_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -7487,6 +7535,12 @@ "can_use_on_swarming_builders": true }, "test": "views_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -7756,6 +7810,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -8025,6 +8085,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -8294,6 +8360,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -8563,6 +8635,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -8832,6 +8910,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -9101,6 +9185,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -9370,6 +9460,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -9639,6 +9735,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -9902,6 +10004,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -10171,6 +10279,12 @@ "can_use_on_swarming_builders": true }, "test": "wtf_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "zucchini_unittests" } ] }, @@ -12380,6 +12494,12 @@ "can_use_on_swarming_builders": false }, "test": "views_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "zucchini_unittests" } ] }
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 3d548c7e..f239776 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -1,2380 +1,6 @@ { "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, "AAAAA2 See //tools/perf/generate_perf_data.py to make changes": {}, - "Android Nexus5X WebView Perf": { - "isolated_scripts": [ - { - "args": [ - "battor.steady_state", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "battor.steady_state", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "battor.trivial_pages", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "battor.trivial_pages", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.bindings", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.bindings", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.css", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.css", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.dom", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.dom", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.events", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.events", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.layout", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.layout", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.paint", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.paint", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.parser", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.parser", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.shadow_dom", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.shadow_dom", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "blink_perf.svg", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "blink_perf.svg", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dromaeo.domcoreattr", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "dromaeo.domcoreattr", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dromaeo.domcoremodify", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "dromaeo.domcoremodify", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dromaeo.domcorequery", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "dromaeo.domcorequery", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dromaeo.domcoretraverse", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "dromaeo.domcoretraverse", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dummy_benchmark.noisy_benchmark_1", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "dummy_benchmark.noisy_benchmark_1", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dummy_benchmark.stable_benchmark_1", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "dummy_benchmark.stable_benchmark_1", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "image_decoding.image_decoding_measurement", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "image_decoding.image_decoding_measurement", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "jetstream", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "jetstream", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "kraken", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "kraken", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "loading.mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "loading.mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 16200, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "media.android.tough_video_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "media.android.tough_video_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "media.android.tough_video_cases_tbmv2", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "media.android.tough_video_cases_tbmv2", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "media.mse_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "media.mse_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "memory.blink_memory_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "memory.blink_memory_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "memory.long_running_idle_gmail_background_tbmv2", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "memory.long_running_idle_gmail_background_tbmv2", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "memory.long_running_idle_gmail_tbmv2", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "memory.long_running_idle_gmail_tbmv2", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "memory.top_10_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "memory.top_10_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "octane", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "octane", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "oortonline_tbmv2", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "oortonline_tbmv2", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "power.idle_platform", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "power.idle_platform", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "power.steady_state", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "power.steady_state", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "power.trivial_pages", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "power.trivial_pages", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "power.typical_10_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "power.typical_10_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "scheduler.tough_scheduling_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "scheduler.tough_scheduling_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "service_worker.service_worker", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "service_worker.service_worker", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "service_worker.service_worker_micro_benchmark", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "service_worker.service_worker_micro_benchmark", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.desktop_tough_pinch_zoom_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.desktop_tough_pinch_zoom_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.gpu_rasterization.polymer", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.gpu_rasterization.polymer", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.gpu_rasterization.top_25_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.gpu_rasterization.top_25_smooth", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device2", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.gpu_rasterization.tough_filters_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.gpu_rasterization.tough_filters_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.gpu_rasterization.tough_path_rendering_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.gpu_rasterization.tough_path_rendering_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.key_mobile_sites_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.key_mobile_sites_smooth", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device2", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.key_silk_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.key_silk_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.maps", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.maps", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.pathological_mobile_sites", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.pathological_mobile_sites", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.simple_mobile_sites", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.simple_mobile_sites", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.sync_scroll.key_mobile_sites_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.sync_scroll.key_mobile_sites_smooth", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.top_25_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.top_25_smooth", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.tough_ad_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.tough_ad_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.tough_filters_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.tough_filters_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.tough_path_rendering_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.tough_path_rendering_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.tough_scrolling_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.tough_scrolling_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.tough_texture_upload_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.tough_texture_upload_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "smoothness.tough_webgl_ad_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "smoothness.tough_webgl_ad_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "speedometer", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "speedometer", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "start_with_url.cold.startup_pages", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "start_with_url.cold.startup_pages", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "start_with_url.warm.startup_pages", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "start_with_url.warm.startup_pages", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "storage.indexeddb_endure", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "storage.indexeddb_endure", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "storage.indexeddb_endure_tracing", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "storage.indexeddb_endure_tracing", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.common_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "system_health.common_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.memory_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "system_health.memory_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.webview_startup", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "system_health.webview_startup", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.key_hit_test_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.key_hit_test_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.key_idle_power_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.key_idle_power_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.key_mobile_sites_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.key_mobile_sites_smooth", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device2", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.key_noop_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.key_noop_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device3", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.key_silk_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.key_silk_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device2", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.polymer", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.polymer", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device1", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.simple_mobile_sites", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.simple_mobile_sites", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.tough_compositor_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.tough_compositor_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "thread_times.tough_scrolling_cases", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "thread_times.tough_scrolling_cases", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "tracing.tracing_with_background_memory_infra", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "tracing.tracing_with_background_memory_infra", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device4", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "tracing.tracing_with_debug_overhead", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "tracing.tracing_with_debug_overhead", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device5", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "v8.browsing_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "v8.browsing_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device2", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "v8.detached_context_age_in_gc", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "v8.detached_context_age_in_gc", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device6", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "v8.mobile_infinite_scroll_tbmv2", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "v8.mobile_infinite_scroll_tbmv2", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device1", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "v8.runtimestats.browsing_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "v8.runtimestats.browsing_mobile", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device1", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "webrtc", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "webrtc", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build243-m4--device7", - "os": "Android", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - } - ] - }, "Android Swarming N5X Tester": { "isolated_scripts": [ {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 8ce1d5e..3b0b200 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -9376,6 +9376,2380 @@ } ] }, + "Android Nexus5X WebView Perf": { + "isolated_scripts": [ + { + "args": [ + "battor.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "battor.steady_state", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "battor.trivial_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.bindings", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.bindings", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.css", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.css", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.dom", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.events", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.events", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.layout", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.layout", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.paint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.paint", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.parser", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.parser", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.shadow_dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.shadow_dom", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.svg", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.svg", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoreattr", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcoreattr", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoremodify", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcoremodify", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcorequery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcorequery", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoretraverse", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcoretraverse", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.noisy_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dummy_benchmark.noisy_benchmark_1", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.stable_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dummy_benchmark.stable_benchmark_1", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "image_decoding.image_decoding_measurement", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "image_decoding.image_decoding_measurement", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "jetstream", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "jetstream", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "kraken", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "kraken", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "loading.mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "loading.mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 16200, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.android.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "media.android.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.android.tough_video_cases_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "media.android.tough_video_cases_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.mse_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "media.mse_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.blink_memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.blink_memory_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_background_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.long_running_idle_gmail_background_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.long_running_idle_gmail_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.top_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.top_10_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "octane", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "octane", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "oortonline_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "oortonline_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.idle_platform", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.idle_platform", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.steady_state", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.trivial_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.typical_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.typical_10_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "scheduler.tough_scheduling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "scheduler.tough_scheduling_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "service_worker.service_worker", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker_micro_benchmark", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "service_worker.service_worker_micro_benchmark", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.desktop_tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.desktop_tough_pinch_zoom_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.polymer", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.tough_filters_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.tough_path_rendering_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.maps", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.maps", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.pathological_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.pathological_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.simple_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.sync_scroll.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.sync_scroll.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_ad_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_filters_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_path_rendering_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_texture_upload_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_texture_upload_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_webgl_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_webgl_ad_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "speedometer", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.cold.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_url.cold.startup_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.warm.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_url.warm.startup_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "storage.indexeddb_endure", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure_tracing", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "storage.indexeddb_endure_tracing", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.common_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "system_health.common_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "system_health.memory_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.webview_startup", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "system_health.webview_startup", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_hit_test_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_hit_test_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_idle_power_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_idle_power_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_noop_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_noop_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.polymer", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.simple_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_compositor_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.tough_compositor_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_background_memory_infra", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "tracing.tracing_with_background_memory_infra", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_debug_overhead", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "tracing.tracing_with_debug_overhead", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.browsing_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.detached_context_age_in_gc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.detached_context_age_in_gc", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.mobile_infinite_scroll_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.mobile_infinite_scroll_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.runtimestats.browsing_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.runtimestats.browsing_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "webrtc", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + } + ] + }, "Android Nexus6 Perf": { "isolated_scripts": [ { @@ -14071,6 +16445,2380 @@ } ] }, + "Android Nexus6 WebView Perf": { + "isolated_scripts": [ + { + "args": [ + "battor.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "battor.steady_state", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "battor.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "battor.trivial_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.bindings", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.bindings", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.css", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.css", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.dom", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.events", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.events", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.layout", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.layout", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.paint", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.paint", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.parser", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.parser", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.shadow_dom", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.shadow_dom", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "blink_perf.svg", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.svg", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoreattr", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcoreattr", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoremodify", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcoremodify", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcorequery", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcorequery", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dromaeo.domcoretraverse", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dromaeo.domcoretraverse", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.noisy_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dummy_benchmark.noisy_benchmark_1", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "dummy_benchmark.stable_benchmark_1", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "dummy_benchmark.stable_benchmark_1", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "image_decoding.image_decoding_measurement", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "image_decoding.image_decoding_measurement", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "jetstream", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "jetstream", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "kraken", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "kraken", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "loading.mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "loading.mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 16200, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.android.tough_video_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "media.android.tough_video_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.android.tough_video_cases_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "media.android.tough_video_cases_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "media.mse_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "media.mse_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.blink_memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.blink_memory_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_background_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.long_running_idle_gmail_background_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.long_running_idle_gmail_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.long_running_idle_gmail_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "memory.top_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "memory.top_10_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "octane", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "octane", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "oortonline_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "oortonline_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.idle_platform", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.idle_platform", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.steady_state", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.steady_state", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.trivial_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.trivial_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "power.typical_10_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "power.typical_10_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "scheduler.tough_scheduling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "scheduler.tough_scheduling_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "service_worker.service_worker", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "service_worker.service_worker_micro_benchmark", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "service_worker.service_worker_micro_benchmark", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.desktop_tough_pinch_zoom_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.desktop_tough_pinch_zoom_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.polymer", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.tough_filters_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.gpu_rasterization.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.gpu_rasterization.tough_path_rendering_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.maps", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.maps", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.pathological_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.pathological_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.simple_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.sync_scroll.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.sync_scroll.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.top_25_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.top_25_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_ad_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_filters_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_filters_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_path_rendering_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_path_rendering_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_texture_upload_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_texture_upload_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "smoothness.tough_webgl_ad_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_webgl_ad_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "speedometer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "speedometer", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.cold.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_url.cold.startup_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "start_with_url.warm.startup_pages", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_url.warm.startup_pages", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "storage.indexeddb_endure", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "storage.indexeddb_endure_tracing", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "storage.indexeddb_endure_tracing", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.common_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "system_health.common_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.memory_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "system_health.memory_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "system_health.webview_startup", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "system_health.webview_startup", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_hit_test_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_hit_test_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_idle_power_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_idle_power_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_mobile_sites_smooth", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_mobile_sites_smooth", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_noop_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_noop_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.key_silk_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.key_silk_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.polymer", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.polymer", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.simple_mobile_sites", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.simple_mobile_sites", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_compositor_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.tough_compositor_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "thread_times.tough_scrolling_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "thread_times.tough_scrolling_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_background_memory_infra", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "tracing.tracing_with_background_memory_infra", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "tracing.tracing_with_debug_overhead", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "tracing.tracing_with_debug_overhead", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.browsing_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.browsing_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.detached_context_age_in_gc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.detached_context_age_in_gc", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.mobile_infinite_scroll_tbmv2", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.mobile_infinite_scroll_tbmv2", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "v8.runtimestats.browsing_mobile", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "v8.runtimestats.browsing_mobile", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { + "args": [ + "webrtc", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "webrtc", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600 + } + } + ] + }, "Android Nexus7v2 Perf": { "isolated_scripts": [ {
diff --git a/testing/buildbot/filters/ash_unittests_mash.filter b/testing/buildbot/filters/ash_unittests_mash.filter index 34a7b6eb..29ff5d0 100644 --- a/testing/buildbot/filters/ash_unittests_mash.filter +++ b/testing/buildbot/filters/ash_unittests_mash.filter
@@ -295,15 +295,6 @@ -TrayRotationockTest.CreateTrayViewuringMaximizeMode -UnifiedMouseWarpControllerTest.BoundaryTest -UnifiedMouseWarpControllerTest.WarpMouse --VirtualKeyboardAlwaysOnTopControllerTest.NotifyKeyboardBoundsChanged --VirtualKeyboardControllerAlwaysEnabledTest.DoesNotSuppressKeyboard --VirtualKeyboardControllerAutoTest.DisabledIfInternalKeyboardPresent --VirtualKeyboardControllerAutoTest.DisabledIfNoTouchScreen --VirtualKeyboardControllerAutoTest.EnabledDuringMaximizeMode --VirtualKeyboardControllerAutoTest.HandleMultipleKeyboardsPresent --VirtualKeyboardControllerAutoTest.SuppressedIfExternalKeyboardPresent --VirtualKeyboardControllerAutoTest.SuppressedInMaximizedMode --VirtualKeyboardControllerTest.RestoreKeyboardDevices -WindowScreenshotControllerTest.KeyboardOperation -WindowScreenshotControllerTest.MouseOperation -WindowScreenshotControllerTest.MultiDisplays @@ -330,8 +321,20 @@ -WindowTreeHostManagerTest.UpdateMouseocationfterisplayChange -WorkspaceLayoutManagerKeyboardTest2.ChangeWorkAreaInNonStickyMode -WorkspaceLayoutManagerKeyboardTest2.IgnoreWorkAreaChangeinNonStickyMode --WorkspaceayoutManagerKeyboardTest2.ChangeWorkreanNonStickyMode --WorkspaceayoutManagerKeyboardTest2.gnoreWorkreaChangeinNonStickyMode + +# TODO: fix these. They fail because DeviceDataManager isn't created. +# http://crbug.com/734812. +-TrayIMETest.HidesOnA11yEnabled +-TrayIMETest.PerformActionOnDetailedView +-VirtualKeyboardAlwaysOnTopControllerTest.NotifyKeyboardBoundsChanged +-VirtualKeyboardControllerAlwaysEnabledTest.DoesNotSuppressKeyboard +-VirtualKeyboardControllerAutoTest.DisabledIfInternalKeyboardPresent +-VirtualKeyboardControllerAutoTest.DisabledIfNoTouchScreen +-VirtualKeyboardControllerAutoTest.EnabledDuringMaximizeMode +-VirtualKeyboardControllerAutoTest.HandleMultipleKeyboardsPresent +-VirtualKeyboardControllerAutoTest.SuppressedIfExternalKeyboardPresent +-VirtualKeyboardControllerAutoTest.SuppressedInMaximizedMode +-VirtualKeyboardControllerTest.RestoreKeyboardDevices # Timeouts -ToastManagerTest.PositionWithAutoHiddenBottomShelf
diff --git a/testing/buildbot/filters/ash_unittests_mus.filter b/testing/buildbot/filters/ash_unittests_mus.filter index df4e4ca..148a621d 100644 --- a/testing/buildbot/filters/ash_unittests_mus.filter +++ b/testing/buildbot/filters/ash_unittests_mus.filter
@@ -1,14 +1,3 @@ -# TODO: fix these. http://crbug.com/726838 --AppListPresenterDelegateTest.BottomShelfAlignmentTextStateTransitions --AppListPresenterDelegateTest.MaximizeModeTextStateTransitions --AppListPresenterDelegateTest.PeekingToFullscreenWhenMaximizeModeIsActive --AppListPresenterDelegateTest.HalfToFullscreenWhenMaximizeModeIsActive --AppListPresenterDelegateTest.AppListViewDragHandler --AppListPresenterDelegateTest.AppListViewDragHandlerMaximizeModeFromAllApps --AppListPresenterDelegateTest.AppListViewDragHandlerMaximizeModeFromSearch --AppListPresenterDelegateTest.TapAndClickOutsideClosesPeekingAppList --AppListPresenterDelegateTest.TapAndClickOutsideClosesHalfAppList - # TODO: fix these. They fail because wm::CursorManager isn't created. # http://crbug.com/734806. # The following fail as they use wm::CursorManager: @@ -20,10 +9,6 @@ # implemented. http://crbug.com/734808. -ImmersiveFullscreenControllerTest.EndRevealViaGesture -# TODO: fix these. They fail because AshNativeCursorManager isn't created -# http://crbug.com/734809. --WindowManagerTest.MouseEventCursors - # TODO: fix these. They all timeout. http://crbug.com/734811. -ScreenRotationAnimatorSmoothAnimationTest.OverviewButtonTrayHideAnimationAlwaysCompletes -ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalPrimaryDisplayBeforeSecondCopyCallback
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter index f1b5a66..ad08a10 100644 --- a/testing/buildbot/filters/fuchsia.base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -22,13 +22,6 @@ -DiscardableSharedMemoryTest.ZeroSize -FeatureListTest.StoreAndRetrieveAssociatedFeaturesFromSharedMemory -FeatureListTest.StoreAndRetrieveFeaturesFromSharedMemory --FieldTrialListTest.AddTrialsToAllocator --FieldTrialListTest.AssociateFieldTrialParams --FieldTrialListTest.ClearParamsFromSharedMemory --FieldTrialListTest.DoNotAddSimulatedFieldTrialsToAllocator --FieldTrialListTest.DumpAndFetchFromSharedMemory --FieldTrialListTest.InstantiateAllocator --FieldTrialListTest.SerializeSharedMemoryHandleMetadata -FileLockingTest.LockAndUnlock -FileLockingTest.UnlockOnClose -FileLockingTest.UnlockOnExit @@ -53,7 +46,6 @@ -FilePersistentMemoryAllocatorTest.CreationTest -FilePersistentMemoryAllocatorTest.ExtendTest -FileProxyTest.SetTimes --FileTest.Append -FileUtilProxyTest.Touch -FileUtilTest.ChangeDirectoryPermissionsAndEnumerate -FileUtilTest.ChangeFilePermissionsAndRead @@ -180,3 +172,6 @@ -VerifyPathControlledByUserTest.OwnershipChecks -VerifyPathControlledByUserTest.Symlinks -VerifyPathControlledByUserTest.WriteBitChecks + +# TaskScheduler is racy, causing bot instability: https://crbug.com/735701. +-*TaskScheduler*
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 4b9eca3d..e82c4052 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1136,4 +1136,8 @@ "label": "//third_party/WebKit/Source/platform/wtf:wtf_unittests", "type": "console_test_launcher", }, + "zucchini_unittests": { + "label": "//zucchini:zucchini_unittests", + "type": "console_test_launcher", + }, }
diff --git a/testing/test.gni b/testing/test.gni index 36e0d91..64619b3 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -63,7 +63,7 @@ # the default shared_library configs rather than executable configs. configs -= [ "//build/config:shared_library_config", - "//build/config/android:hide_all_but_jni_onload", + "//build/config/android:hide_all_but_jni", ] configs += [ "//build/config:executable_config" ] @@ -321,6 +321,8 @@ set_defaults("test") { if (is_android) { configs = default_shared_library_configs + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] + configs += [ "//build/config/android:hide_all_but_jni" ] } else { configs = default_executable_configs }
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index fa714d04..2b3d1b4 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -128,7 +128,7 @@ crbug.com/591099 accessibility/input-type-range-value-change-event.html [ Crash ] crbug.com/591099 accessibility/input-type-range-value-change.html [ Failure ] crbug.com/591099 accessibility/input-type-text-caret-position.html [ Crash Failure ] -crbug.com/591099 accessibility/input-type-text-selection.html [ Crash Timeout ] +crbug.com/591099 accessibility/input-type-text-selection.html [ Crash Failure Timeout ] crbug.com/591099 accessibility/input-type-text-value-change-event.html [ Crash ] crbug.com/591099 accessibility/insert-selected-option-into-select-causes-crash.html [ Failure ] crbug.com/591099 accessibility/is-richly-editable.html [ Crash Failure ] @@ -342,7 +342,6 @@ crbug.com/591099 animations/interpolation/webkit-transform-origin-interpolation.html [ Crash ] crbug.com/591099 animations/keyframes-cssom-prefixed-02.html [ Failure ] crbug.com/591099 animations/keyframes-cssom-unprefixed-02.html [ Failure ] -crbug.com/591099 animations/keyframes-iteration-count-non-integer.html [ Failure Pass ] crbug.com/591099 animations/keyframes-rule.html [ Failure ] crbug.com/591099 animations/lazy-detached-animation-stop.html [ Failure ] crbug.com/591099 animations/length-zero-percent-crash.html [ Failure Pass ] @@ -539,7 +538,6 @@ crbug.com/591099 compositing/color-matching/image-color-matching.html [ Failure Pass ] crbug.com/591099 compositing/columns/composited-in-paginated.html [ Failure Pass ] crbug.com/591099 compositing/columns/geometry-map-paginated-assert.html [ Failure ] -crbug.com/591099 compositing/composite-scrollable-fixed-position-when-descendants-composite.html [ Failure Pass ] crbug.com/591099 compositing/composited-negative-zindex-child.html [ Failure ] crbug.com/591099 compositing/compositing-visible-descendant.html [ Failure ] crbug.com/591099 compositing/contents-opaque/background-clip.html [ Failure Pass ] @@ -586,7 +584,6 @@ crbug.com/591099 compositing/geometry/fixed-position.html [ Failure ] crbug.com/591099 compositing/geometry/flipped-writing-mode.html [ Failure ] crbug.com/591099 compositing/geometry/foreground-layer.html [ Failure ] -crbug.com/591099 compositing/geometry/foreground-offset-change.html [ Failure Pass ] crbug.com/591099 compositing/geometry/geometry-map-scroll-during-layout-assertion.html [ Failure ] crbug.com/591099 compositing/geometry/horizontal-scroll-composited.html [ Failure ] crbug.com/591099 compositing/geometry/layer-due-to-layer-children-deep-switch.html [ Failure ] @@ -640,7 +637,6 @@ crbug.com/591099 compositing/iframes/iframe-in-composited-layer.html [ Failure ] crbug.com/591099 compositing/iframes/iframe-resize.html [ Failure ] crbug.com/591099 compositing/iframes/iframe-size-from-zero.html [ Failure ] -crbug.com/591099 compositing/iframes/iframe-size-to-zero.html [ Failure Pass ] crbug.com/591099 compositing/iframes/invisible-iframe.html [ Failure ] crbug.com/591099 compositing/iframes/invisible-nested-iframe-hide.html [ Crash ] crbug.com/591099 compositing/iframes/invisible-nested-iframe-show.html [ Failure ] @@ -825,13 +821,10 @@ crbug.com/591099 compositing/shadows/shadow-drawing.html [ Failure ] crbug.com/591099 compositing/sibling-positioning.html [ Failure Pass ] crbug.com/591099 compositing/squashing/add-remove-squashed-layers.html [ Failure ] -crbug.com/591099 compositing/squashing/backing-owner-determines-scroll-parent.html [ Failure Pass ] crbug.com/591099 compositing/squashing/clipping-ancestor.html [ Failure Pass ] crbug.com/591099 compositing/squashing/composited-bounds-for-negative-z.html [ Failure ] crbug.com/591099 compositing/squashing/do-not-squash-non-self-painting-layer.html [ Failure Pass ] crbug.com/591099 compositing/squashing/do-not-squash-scroll-child-with-composited-descendants.html [ Failure ] -crbug.com/591099 compositing/squashing/dont-squash-into-animated-layers.html [ Failure Pass ] -crbug.com/591099 compositing/squashing/dont-squash-into-blend-mode.html [ Failure Pass ] crbug.com/591099 compositing/squashing/dont-squash-into-iframes.html [ Failure Pass ] crbug.com/591099 compositing/squashing/dont-squash-into-videos.html [ Failure Pass ] crbug.com/591099 compositing/squashing/iframes-are-never-squashed.html [ Failure Pass ] @@ -3109,7 +3102,6 @@ crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement09.xhtml [ Crash Pass ] crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement10.xhtml [ Crash Pass ] crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLIFrameElement11.xhtml [ Crash ] -crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLImageElement01.xhtml [ Crash Pass ] crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLImageElement03.xhtml [ Crash Pass ] crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLImageElement04.xhtml [ Crash Pass ] crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLImageElement05.xhtml [ Crash ] @@ -4190,8 +4182,6 @@ crbug.com/591099 external/wpt/css/CSS2/abspos/abspos-containing-block-initial-009a.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats-clear/float-replaced-height-001.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats-clear/float-replaced-width-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/CSS2/floats-clear/floats-001.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/CSS2/floats-clear/floats-006.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/CSS2/floats-clear/floats-026.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats-clear/floats-027.xht [ Crash Failure ] crbug.com/591099 external/wpt/css/CSS2/floats-clear/floats-029.xht [ Failure ] @@ -4249,12 +4239,10 @@ crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-formatting-context-height-001.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-formatting-context-height-002.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-in-inline-percents-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-in-inline-remove-002.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-non-replaced-height-005.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-non-replaced-width-007.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-replaced-width-006.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/blocks-025.xht [ Failure ] -crbug.com/591099 external/wpt/css/CSS2/normal-flow/height-114.xht [ Crash Failure Pass ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-block-non-replaced-height-002.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-block-valign-001.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-block-valign-002.xht [ Failure ] @@ -4368,6 +4356,7 @@ crbug.com/591099 external/wpt/css/css-display-3/display-contents-multicol-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-display-3/display-flow-root-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/Flexible-order.html [ Crash Failure Pass ] +crbug.com/591099 external/wpt/css/css-flexbox-1/auto-margins-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/css-flexbox-row-reverse-wrap-reverse.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/css-flexbox-row-reverse-wrap.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/css-flexbox-row-wrap-reverse.html [ Failure ] @@ -4533,6 +4522,10 @@ crbug.com/591099 external/wpt/css/css-flexbox-1/order/order-with-row-reverse.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/percentage-heights-000.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/percentage-heights-001.html [ Failure ] +crbug.com/591099 external/wpt/css/css-flexbox-1/percentage-widths-001.html [ Failure ] +crbug.com/591099 external/wpt/css/css-flexbox-1/position-absolute-002.html [ Failure ] +crbug.com/591099 external/wpt/css/css-flexbox-1/position-absolute-004.html [ Failure ] +crbug.com/591099 external/wpt/css/css-flexbox-1/position-absolute-005.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/ttwf-reftest-flex-align-content-center.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/ttwf-reftest-flex-align-content-end.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox-1/ttwf-reftest-flex-align-content-space-around.html [ Failure ] @@ -4977,8 +4970,6 @@ crbug.com/591099 external/wpt/css/css-writing-modes-3/block-flow-direction-vrl-019.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/block-flow-direction-vrl-024.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/block-flow-direction-vrl-026.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/block-override-004.html [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/block-override-isolate-004.html [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes-3/block-plaintext-004.html [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/border-vlr-007.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes-3/border-vrl-006.xht [ Failure ] @@ -5019,15 +5010,9 @@ crbug.com/591099 external/wpt/css/css-writing-modes-3/float-lft-orthog-vrl-in-htb-002.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/float-rgt-orthog-htb-in-vlr-003.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/float-rgt-orthog-htb-in-vrl-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vlr-005.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vlr-007.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vlr-009.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vlr-011.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vlr-013.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vrl-004.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vrl-006.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vrl-008.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vrl-010.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes-3/float-vrl-012.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/horizontal-rule-vlr-003.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes-3/horizontal-rule-vrl-002.xht [ Failure ] @@ -5201,7 +5186,6 @@ crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-002.xhtml [ Failure ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-004.xhtml [ Failure ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-002.xhtml [ Failure ] -crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-003.xhtml [ Failure Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-004.xhtml [ Failure ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-margin-auto-horiz-001.xhtml [ Failure ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-margin-auto-horiz-002.xhtml [ Failure ] @@ -5231,7 +5215,6 @@ crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-006.html [ Crash Failure ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-006a.html [ Crash Failure Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-007.html [ Crash Failure Pass ] -crbug.com/591099 external/wpt/cssom-view/HTMLBody-ScrollArea_quirksmode.html [ Failure Pass ] crbug.com/591099 external/wpt/cssom-view/cssom-getClientRects-002.html [ Failure ] crbug.com/591099 external/wpt/cssom-view/elementFromPoint.html [ Crash ] crbug.com/591099 external/wpt/cssom-view/elementsFromPoint.html [ Crash ] @@ -5392,6 +5375,7 @@ crbug.com/591099 external/wpt/html/dom/dynamic-markup-insertion/document-write/iframe_009.html [ Crash ] crbug.com/591099 external/wpt/html/dom/dynamic-markup-insertion/document-write/iframe_010.html [ Crash ] crbug.com/591099 external/wpt/html/dom/dynamic-markup-insertion/document-write/script_013.html [ Crash ] +crbug.com/591099 external/wpt/html/dom/interfaces.html [ Timeout ] crbug.com/591099 external/wpt/html/editing/focus/focus-management/focus-event-targets-simple.html [ Crash ] crbug.com/591099 external/wpt/html/editing/focus/processing-model/focus-fixup-rule-one-no-dialogs.html [ Crash ] crbug.com/591099 external/wpt/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-default-value.html [ Crash ] @@ -5499,7 +5483,6 @@ crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-parent.html [ Crash Failure Pass ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-skip-no-boxes.html [ Crash Failure ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-ul.html [ Crash Failure Pass ] -crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-not-being-rendered.html [ Crash Failure Pass ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li.html [ Crash ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001.html [ Failure ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001.html [ Failure ] @@ -5508,7 +5491,6 @@ crbug.com/591099 external/wpt/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002.html [ Failure ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003.html [ Failure ] crbug.com/591099 external/wpt/html/semantics/grouping-content/the-ol-element/grouping-ol.html [ Crash ] -crbug.com/591099 external/wpt/html/semantics/grouping-content/the-ol-element/reversed-1d.html [ Crash Failure Pass ] crbug.com/591099 external/wpt/html/semantics/interactive-elements/the-dialog-element/centering.html [ Failure ] crbug.com/591099 external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html [ Crash ] crbug.com/591099 external/wpt/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html [ Crash ] @@ -5662,6 +5644,7 @@ crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html [ Crash Timeout ] crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Crash Timeout ] crbug.com/591099 external/wpt/quirks-mode/blocks-ignore-line-height.html [ Failure ] +crbug.com/591099 external/wpt/quirks-mode/classname-query-after-sibling-adoption.html [ Crash ] crbug.com/591099 external/wpt/quirks-mode/hashless-hex-color.html [ Pass Timeout ] crbug.com/591099 external/wpt/quirks-mode/line-height-calculation.html [ Crash ] crbug.com/591099 external/wpt/quirks-mode/table-cell-width-calculation.html [ Crash ] @@ -6590,7 +6573,6 @@ crbug.com/591099 fast/block/block-with-inline-replaced-child-following-text.html [ Crash ] crbug.com/591099 fast/block/borderbox-percent-padding.html [ Failure ] crbug.com/591099 fast/block/child-not-removed-from-parent-lineboxes-crash.html [ Crash ] -crbug.com/591099 fast/block/crash-when-element-becomes-positioned-and-doesnt-clear-floating-objects.html [ Failure Pass ] crbug.com/591099 fast/block/dynamic-padding-border.html [ Failure ] crbug.com/591099 fast/block/float/002.html [ Crash Failure ] crbug.com/591099 fast/block/float/003.html [ Failure ] @@ -6618,7 +6600,6 @@ crbug.com/591099 fast/block/float/034.html [ Failure ] crbug.com/591099 fast/block/float/035.html [ Failure ] crbug.com/591099 fast/block/float/add-float-back-to-anonymous-block.html [ Failure ] -crbug.com/591099 fast/block/float/add-inlines-in-block-children-block.html [ Failure Pass ] crbug.com/591099 fast/block/float/assert-when-moving-float.html [ Crash ] crbug.com/591099 fast/block/float/avoid-floats-when-negative-margin-top-2.html [ Failure ] crbug.com/591099 fast/block/float/avoid-floats-when-negative-margin-top-3.html [ Failure ] @@ -6632,7 +6613,6 @@ crbug.com/591099 fast/block/float/br-with-clear-2.html [ Failure ] crbug.com/591099 fast/block/float/centered-float-avoidance-complexity.html [ Failure ] crbug.com/591099 fast/block/float/checkbox-and-radio-avoid-floats.html [ Failure ] -crbug.com/591099 fast/block/float/clear-intruding-floats-when-moving-to-inline-parent-3.html [ Crash Failure Pass ] crbug.com/591099 fast/block/float/containing-block-change-compositing.html [ Failure ] crbug.com/591099 fast/block/float/crash-on-absolute-positioning.html [ Failure ] crbug.com/591099 fast/block/float/crash-replaced-display-block.html [ Failure ] @@ -6651,14 +6631,12 @@ crbug.com/591099 fast/block/float/float-not-removed-from-next-sibling-crash.html [ Failure ] crbug.com/591099 fast/block/float/float-not-removed-from-next-sibling3.html [ Failure ] crbug.com/591099 fast/block/float/float-not-removed-from-next-sibling5.html [ Crash Failure ] -crbug.com/591099 fast/block/float/float-not-removed-from-pre-block.html [ Failure Pass ] crbug.com/591099 fast/block/float/float-on-empty-line.html [ Failure ] crbug.com/591099 fast/block/float/float-on-line-large-and-small-float-below.html [ Crash ] crbug.com/591099 fast/block/float/float-on-line-obeys-container-padding.html [ Failure ] crbug.com/591099 fast/block/float/float-on-zero-height-line.html [ Failure ] crbug.com/591099 fast/block/float/float-overflow-hidden-containing-block-width.html [ Failure ] crbug.com/591099 fast/block/float/float-overhangs-root.html [ Crash Failure ] -crbug.com/591099 fast/block/float/float-reinsertion-failure.html [ Failure Pass ] crbug.com/591099 fast/block/float/float-reparent-during-detach-crash.html [ Crash ] crbug.com/591099 fast/block/float/floats-and-text-indent-rl.html [ Failure ] crbug.com/591099 fast/block/float/floats-and-text-indent.html [ Failure ] @@ -6719,7 +6697,6 @@ crbug.com/591099 fast/block/hr-with-float.html [ Failure ] crbug.com/591099 fast/block/inflow-bottom-margin.html [ Failure ] crbug.com/591099 fast/block/inline-children-root-linebox-crash.html [ Crash Failure ] -crbug.com/591099 fast/block/line-layout/crash-in-isolate-with-positioned-child.html [ Failure Pass ] crbug.com/591099 fast/block/line-layout/floats-do-not-fit-on-line.html [ Crash Failure ] crbug.com/591099 fast/block/line-layout/negative-max-height.html [ Failure ] crbug.com/591099 fast/block/margin-collapse/006.html [ Failure ] @@ -6747,7 +6724,6 @@ crbug.com/591099 fast/block/margin-collapse/empty-clear-blocks.html [ Failure ] crbug.com/591099 fast/block/margin-collapse/line-beside-float-complex-margin-collapsing.html [ Crash Failure ] crbug.com/591099 fast/block/margin-collapse/self-collapsing-block-creates-block-formatting-context.html [ Failure ] -crbug.com/591099 fast/block/margin-collapse/self-collapsing-block-discards-margin.html [ Failure Pass ] crbug.com/591099 fast/block/margin-collapse/self-collapsing-block-with-float-descendants.html [ Failure ] crbug.com/591099 fast/block/margin-collapse/self-collapsing-block-with-overflow-hidden-and-float-child.html [ Failure ] crbug.com/591099 fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Failure ] @@ -6830,8 +6806,6 @@ crbug.com/591099 fast/block/positioning/positioned-child-inside-relative-positioned-anonymous-block.html [ Failure ] crbug.com/591099 fast/block/positioning/positioned-container-changes-block-direction-border-with-positioned-descendant.html [ Failure ] crbug.com/591099 fast/block/positioning/positioned-layout-in-line.html [ Crash ] -crbug.com/591099 fast/block/positioning/positioned-movement-layout-when-bottom-changes-to-and-from-auto-vertical.html [ Failure Pass ] -crbug.com/591099 fast/block/positioning/positioned-movement-layout-when-bottom-changes-to-and-from-auto.html [ Failure Pass ] crbug.com/591099 fast/block/positioning/rel-positioned-inline-changes-width.html [ Crash Failure ] crbug.com/591099 fast/block/positioning/relative-overflow-block.html [ Failure ] crbug.com/591099 fast/block/positioning/relative-overflow-replaced-float.html [ Crash Failure ] @@ -6844,19 +6818,21 @@ crbug.com/591099 fast/block/positioning/replaced-inside-fixed-top-bottom.html [ Failure ] crbug.com/591099 fast/block/positioning/rtl-static-positioning-inline-block.html [ Crash Failure ] crbug.com/591099 fast/block/positioning/rtl-static-positioning.html [ Failure ] -crbug.com/591099 fast/block/positioning/setting-layout-on-posobjs-while-laying-them-out.html [ Failure Pass ] crbug.com/591099 fast/block/positioning/start-ignoring-before.html [ Failure ] crbug.com/591099 fast/block/positioning/static-to-abspos-parent-is-stf.html [ Crash Failure ] crbug.com/591099 fast/block/positioning/trailing-space-test.html [ Failure ] crbug.com/591099 fast/block/positioning/vertical-lr/001.html [ Failure ] crbug.com/591099 fast/block/positioning/vertical-lr/002.html [ Failure ] +crbug.com/591099 fast/block/positioning/vertical-lr/003.html [ Failure ] +crbug.com/591099 fast/block/positioning/vertical-lr/004.html [ Failure ] crbug.com/591099 fast/block/positioning/vertical-rl/001.html [ Failure ] crbug.com/591099 fast/block/positioning/vertical-rl/002.html [ Crash Failure ] +crbug.com/591099 fast/block/positioning/vertical-rl/003.html [ Failure ] +crbug.com/591099 fast/block/positioning/vertical-rl/004.html [ Failure ] crbug.com/591099 fast/block/positioning/vertical-rl/fixed-positioning.html [ Failure ] crbug.com/591099 fast/block/positioning/window-height-change.html [ Failure ] crbug.com/591099 fast/block/scrollbar-wider-than-border-box.html [ Failure ] crbug.com/591099 fast/block/skip-cleaning-up-anonymous-wrappers-when-subtree-being-destroyed.html [ Crash ] -crbug.com/591099 fast/block/sticky-position-containing-block-crash.html [ Failure Pass ] crbug.com/591099 fast/block/strip-anonymous-blocks-when-block-child-becomes-float.html [ Failure ] crbug.com/591099 fast/body-propagation/background-color/001-xhtml.xhtml [ Failure Pass ] crbug.com/591099 fast/body-propagation/background-color/001.html [ Failure Pass ] @@ -7248,7 +7224,6 @@ crbug.com/591099 fast/css-generated-content/beforeAfter-interdocument.html [ Failure ] crbug.com/591099 fast/css-generated-content/block-after.html [ Failure ] crbug.com/591099 fast/css-generated-content/bug-106384.html [ Failure ] -crbug.com/591099 fast/css-generated-content/bug91547.html [ Failure Pass ] crbug.com/591099 fast/css-generated-content/crash-selection-editing-removes-pseudo.html [ Crash ] crbug.com/591099 fast/css-generated-content/details-before-after-content.html [ Crash Failure ] crbug.com/591099 fast/css-generated-content/drag-state.html [ Failure ] @@ -7267,7 +7242,6 @@ crbug.com/591099 fast/css-generated-content/pseudo-transition-event.html [ Failure ] crbug.com/591099 fast/css-generated-content/pseudo-transition.html [ Failure ] crbug.com/591099 fast/css-generated-content/quote-crash-93750.html [ Failure ] -crbug.com/591099 fast/css-generated-content/quote-first-letter.html [ Failure Pass ] crbug.com/591099 fast/css-generated-content/quote-layout-focus-crash.html [ Failure ] crbug.com/591099 fast/css-generated-content/reset-content-to-initial.html [ Failure ] crbug.com/591099 fast/css-generated-content/spellingToolTip-assert.html [ Failure ] @@ -8389,7 +8363,6 @@ crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-first-line-decoration.html [ Crash Failure ] crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-auto.html [ Failure ] crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk.html [ Crash Failure ] -crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow.html [ Failure Pass ] crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-vertical.html [ Failure Pass ] crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under.html [ Failure ] crbug.com/591099 fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited.html [ Failure ] @@ -8545,8 +8518,6 @@ crbug.com/591099 fast/dom/Element/onclick-case.html [ Failure ] crbug.com/591099 fast/dom/Element/parent-node-interface.html [ Failure ] crbug.com/591099 fast/dom/Element/remove.html [ Failure ] -crbug.com/591099 fast/dom/Element/scroll-width-hidden.html [ Failure Pass ] -crbug.com/591099 fast/dom/Element/scroll-width-visible.html [ Failure Pass ] crbug.com/591099 fast/dom/Element/scrollTop-scrollLeft-body.html [ Failure ] crbug.com/591099 fast/dom/Element/scrollTop-scrollLeft-frameset.html [ Failure ] crbug.com/591099 fast/dom/Element/scrollTop-scrollLeft-strict-quirks-modes.html [ Failure ] @@ -9524,7 +9495,6 @@ crbug.com/591099 fast/dynamic/014.html [ Failure ] crbug.com/591099 fast/dynamic/015.html [ Failure ] crbug.com/591099 fast/dynamic/5872671.html [ Failure ] -crbug.com/591099 fast/dynamic/ancestor-to-absolute.html [ Crash Failure Pass ] crbug.com/591099 fast/dynamic/anchor-lock.html [ Failure ] crbug.com/591099 fast/dynamic/anonymous-block-layer-lost.html [ Failure ] crbug.com/591099 fast/dynamic/anonymous-block-orphaned-lines.html [ Failure ] @@ -9778,7 +9748,7 @@ crbug.com/591099 fast/events/drag-and-drop-set-drag-data-arguments.html [ Failure ] crbug.com/591099 fast/events/drag-and-drop-subframe-dataTransfer.html [ Crash ] crbug.com/591099 fast/events/drag-and-drop.html [ Crash Timeout ] -crbug.com/591099 fast/events/drag-customData.html [ Failure ] +crbug.com/591099 fast/events/drag-customData.html [ Failure Timeout ] crbug.com/591099 fast/events/drag-dataTransferItemList-file-handling.html [ Crash Failure ] crbug.com/591099 fast/events/drag-dataTransferItemList.html [ Failure ] crbug.com/591099 fast/events/drag-downloadURL.html [ Failure ] @@ -10918,20 +10888,20 @@ crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-minimum-font.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-rtl-default.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-rtl.html [ Failure ] -crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-single-option.html [ Failure ] +crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-single-option.html [ Failure Pass ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-styled.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-texttransform.html [ Failure ] -crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-transform.html [ Failure ] +crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-transform.html [ Failure Pass ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-zoom.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-zoom090.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance-zoom110.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-appearance.html [ Failure ] -crbug.com/591099 fast/forms/select-popup/popup-menu-ax.html [ Failure ] +crbug.com/591099 fast/forms/select-popup/popup-menu-ax.html [ Crash Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-crash-on-cancel.html [ Crash ] crbug.com/591099 fast/forms/select-popup/popup-menu-crash-on-close.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-crash-on-select.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-crash-on-style-update.html [ Crash ] -crbug.com/591099 fast/forms/select-popup/popup-menu-key-operations.html [ Failure ] +crbug.com/591099 fast/forms/select-popup/popup-menu-key-operations.html [ Failure Pass ] crbug.com/591099 fast/forms/select-popup/popup-menu-mouse-operations.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-nested-style.html [ Failure ] crbug.com/591099 fast/forms/select-popup/popup-menu-touch-operations.html [ Failure Timeout ] @@ -10971,6 +10941,7 @@ crbug.com/591099 fast/forms/select/listbox-height-with-before.html [ Failure ] crbug.com/591099 fast/forms/select/listbox-hit-test-zoomed.html [ Failure ] crbug.com/591099 fast/forms/select/listbox-in-multi-column.html [ Failure ] +crbug.com/591099 fast/forms/select/listbox-no-force-layout.html [ Crash ] crbug.com/591099 fast/forms/select/listbox-onchange.html [ Failure ] crbug.com/591099 fast/forms/select/listbox-oninput-fired.html [ Failure ] crbug.com/591099 fast/forms/select/listbox-overlay-scrollbar.html [ Failure Pass ] @@ -11299,8 +11270,8 @@ crbug.com/591099 fast/forms/textarea/textarea-placeholder-visibility-2.html [ Crash Failure ] crbug.com/591099 fast/forms/textarea/textarea-placeholder-wrapping.html [ Crash Failure ] crbug.com/591099 fast/forms/textarea/textarea-resize-above-min-size-and-below-initial-size.html [ Crash ] -crbug.com/591099 fast/forms/textarea/textarea-resize-below-min-intrinsic-size.html [ Crash ] -crbug.com/591099 fast/forms/textarea/textarea-resize-below-min-size-zoomed.html [ Crash ] +crbug.com/591099 fast/forms/textarea/textarea-resize-below-min-intrinsic-size.html [ Crash Timeout ] +crbug.com/591099 fast/forms/textarea/textarea-resize-below-min-size-zoomed.html [ Crash Timeout ] crbug.com/591099 fast/forms/textarea/textarea-resize-below-min-size.html [ Crash ] crbug.com/591099 fast/forms/textarea/textarea-resize-orthogonal-containing-block.html [ Crash ] crbug.com/591099 fast/forms/textarea/textarea-rows-cols.html [ Crash Failure ] @@ -11692,11 +11663,8 @@ crbug.com/591099 fast/inline-block/14498-positionForCoordinates.html [ Failure ] crbug.com/591099 fast/inline-block/baseline-vertical.html [ Failure ] crbug.com/591099 fast/inline-block/contenteditable-baseline.html [ Failure ] -crbug.com/591099 fast/inline-block/float-both-whitespace.html [ Failure Pass ] -crbug.com/591099 fast/inline-block/float-leading-whitespace.html [ Failure Pass ] crbug.com/591099 fast/inline-block/inline-block-vertical-align-2.html [ Failure ] crbug.com/591099 fast/inline-block/inline-block-vertical-align.html [ Failure ] -crbug.com/591099 fast/inline-block/multiple-floats-with-whitespace.html [ Crash Failure Pass ] crbug.com/591099 fast/inline-block/overflow-clip.html [ Failure ] crbug.com/591099 fast/inline-block/tricky-baseline.html [ Failure ] crbug.com/591099 fast/inline-block/vertical-align-top-and-bottom-2.html [ Failure ] @@ -12206,6 +12174,7 @@ crbug.com/591099 fast/loader/location-port.html [ Failure ] crbug.com/591099 fast/loader/middle-click-target-blank.html [ Failure Timeout ] crbug.com/591099 fast/loader/navigation-scheduler-user-gesture.html [ Failure ] +crbug.com/591099 fast/loader/object-with-rejected-resource.html [ Failure ] crbug.com/591099 fast/loader/onload-bad-scheme-for-frame.html [ Failure Timeout ] crbug.com/591099 fast/loader/onload-policy-ignore-for-frame.html [ Failure ] crbug.com/591099 fast/loader/opaque-base-url.html [ Crash Failure ] @@ -12665,7 +12634,6 @@ crbug.com/591099 fast/overflow/overflow-clamp-after-visible-rect-resize.html [ Failure ] crbug.com/591099 fast/overflow/overflow-float-stacking.html [ Failure ] crbug.com/591099 fast/overflow/overflow-focus-ring.html [ Failure Pass ] -crbug.com/591099 fast/overflow/overflow-height-float-not-removed-crash.html [ Failure Pass ] crbug.com/591099 fast/overflow/overflow-rtl-inline-scrollbar.html [ Failure ] crbug.com/591099 fast/overflow/overflow-rtl-vertical-origin.html [ Failure ] crbug.com/591099 fast/overflow/overflow-rtl-vertical.html [ Crash Failure ] @@ -12718,6 +12686,12 @@ crbug.com/591099 fast/pagination/multicol.html [ Crash Failure ] crbug.com/591099 fast/pagination/short-pages-tall-content.html [ Crash Failure ] crbug.com/591099 fast/pagination/very-tall-auto-height-crash.html [ Crash Failure ] +crbug.com/591099 fast/pagination/viewport-x-vertical-rl-ltr.html [ Failure ] +crbug.com/591099 fast/pagination/viewport-x-vertical-rl-rtl.html [ Failure ] +crbug.com/591099 fast/pagination/viewport-y-vertical-lr-ltr.html [ Failure ] +crbug.com/591099 fast/pagination/viewport-y-vertical-lr-rtl.html [ Failure ] +crbug.com/591099 fast/pagination/viewport-y-vertical-rl-ltr.html [ Failure ] +crbug.com/591099 fast/pagination/viewport-y-vertical-rl-rtl.html [ Failure ] crbug.com/591099 fast/parser/001.html [ Failure ] crbug.com/591099 fast/parser/ampersand-escaped-parseXMLFragment.xhtml [ Failure ] crbug.com/591099 fast/parser/area-in-div.html [ Failure ] @@ -12916,7 +12890,6 @@ crbug.com/591099 fast/replaced/percent-height-in-anonymous-block.html [ Failure ] crbug.com/591099 fast/replaced/percentage-height-with-dynamic-container-height.html [ Failure ] crbug.com/591099 fast/replaced/preferred-widths.html [ Failure ] -crbug.com/591099 fast/replaced/render-inline-cast-to-render-box-crash.html [ Failure Pass ] crbug.com/591099 fast/replaced/replaced-breaking-mixture.html [ Failure ] crbug.com/591099 fast/replaced/replaced-breaking.html [ Failure ] crbug.com/591099 fast/replaced/replaced-child-of-absolute-with-auto-height.html [ Failure ] @@ -12938,9 +12911,7 @@ crbug.com/591099 fast/replaced/vertical-writing-mode-max-logical-width-replaced.html [ Failure ] crbug.com/591099 fast/replaced/width100percent-checkbox.html [ Failure ] crbug.com/591099 fast/replaced/width100percent-radio.html [ Failure ] -crbug.com/591099 fast/ruby/after-doesnt-crash.html [ Crash Failure Pass ] crbug.com/591099 fast/ruby/base-shorter-than-text.html [ Crash Failure ] -crbug.com/591099 fast/ruby/before-doesnt-crash.html [ Crash Failure Pass ] crbug.com/591099 fast/ruby/float-overhang-from-ruby-text.html [ Crash Failure ] crbug.com/591099 fast/ruby/floating-ruby-text.html [ Crash Failure ] crbug.com/591099 fast/ruby/generated-before-counter-doesnt-crash.html [ Crash Failure ] @@ -13006,12 +12977,10 @@ crbug.com/591099 fast/scroll-behavior/smooth-scroll/scroll-during-selection.html [ Failure ] crbug.com/591099 fast/scroll-behavior/smooth-scroll/track-scroll.html [ Failure ] crbug.com/591099 fast/scroll-behavior/subframe-interrupted-scroll.html [ Failure Pass ] -crbug.com/591099 fast/scrolling/absolute-position-behind-scrollbar.html [ Failure Pass ] crbug.com/591099 fast/scrolling/abspos-relayout-overflow-style-change.html [ Failure ] crbug.com/591099 fast/scrolling/content-box-smaller-than-scrollbar.html [ Crash ] crbug.com/591099 fast/scrolling/custom-scrollbar-style-applied.html [ Failure ] crbug.com/591099 fast/scrolling/editor-command-scroll-page-scale.html [ Failure ] -crbug.com/591099 fast/scrolling/fixed-position-behind-scrollbar.html [ Failure Pass ] crbug.com/591099 fast/scrolling/fractional-scroll-height-chaining.html [ Failure ] crbug.com/591099 fast/scrolling/fractional-scroll-offset-document.html [ Failure ] crbug.com/591099 fast/scrolling/hover-during-scroll.html [ Failure Timeout ] @@ -13029,7 +12998,6 @@ crbug.com/591099 fast/scrolling/scrollbar-mousedown-mouseup.html [ Failure ] crbug.com/591099 fast/scrolling/scrollbar-mousedown-move-mouseup.html [ Failure ] crbug.com/591099 fast/scrolling/scrollbar-prevent-default.html [ Failure ] -crbug.com/591099 fast/scrolling/scrollbar-repaint-two-level-scrollable.html [ Failure Pass ] crbug.com/591099 fast/scrolling/scrollbar-tickmarks-hittest.html [ Failure ] crbug.com/591099 fast/scrolling/scrolling-apis-nan-scroll-position.html [ Failure ] crbug.com/591099 fast/scrolling/scrolling-apis-subpixel.html [ Failure ] @@ -13420,6 +13388,7 @@ crbug.com/591099 fast/table/percent-height-overflow-visible-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/percent-heights.html [ Failure ] crbug.com/591099 fast/table/percent-widths-float.html [ Failure ] +crbug.com/591099 fast/table/percent-widths-stretch-vertical.html [ Failure ] crbug.com/591099 fast/table/percent-widths-total-less-than-one.html [ Failure ] crbug.com/591099 fast/table/prepend-in-anonymous-table.html [ Failure ] crbug.com/591099 fast/table/quirks-mode-ignore-display-inline-table.html [ Crash ] @@ -13619,7 +13588,6 @@ crbug.com/591099 fast/text/emphasis-complex.html [ Failure ] crbug.com/591099 fast/text/emphasis-ellipsis-complextext.html [ Failure ] crbug.com/591099 fast/text/emphasis-overlap.html [ Failure ] -crbug.com/591099 fast/text/empty-bdi-crash.html [ Failure Pass ] crbug.com/591099 fast/text/fake-italic.html [ Failure ] crbug.com/591099 fast/text/fallback-for-custom-font.html [ Failure ] crbug.com/591099 fast/text/find-kana.html [ Timeout ] @@ -13639,12 +13607,11 @@ crbug.com/591099 fast/text/glyph-overflow-with-word-spacing.html [ Failure ] crbug.com/591099 fast/text/glyph-overflow.html [ Failure ] crbug.com/591099 fast/text/glyph-reordering.html [ Failure ] -crbug.com/591099 fast/text/hide-atomic-inlines-after-ellipsis.html [ Failure ] +crbug.com/591099 fast/text/hide-atomic-inlines-after-ellipsis.html [ Crash Failure ] crbug.com/591099 fast/text/hyphenate-character.html [ Failure ] crbug.com/591099 fast/text/hyphens/hyphens-none.html [ Failure ] crbug.com/591099 fast/text/in-rendered-text-rtl.html [ Failure ] crbug.com/591099 fast/text/insert-text-crash.html [ Crash ] -crbug.com/591099 fast/text/international/arabic-digits.html [ Failure Pass ] crbug.com/591099 fast/text/international/arabic-justify.html [ Failure ] crbug.com/591099 fast/text/international/arabic-vertical-offset.html [ Failure ] crbug.com/591099 fast/text/international/bidi-AN-after-empty-run.html [ Failure ] @@ -13672,7 +13639,6 @@ crbug.com/591099 fast/text/international/complex-joining-using-gpos.html [ Failure ] crbug.com/591099 fast/text/international/danda-space.html [ Failure ] crbug.com/591099 fast/text/international/draw-complex-text-from-to.html [ Failure ] -crbug.com/591099 fast/text/international/float-as-only-child-of-isolate-crash.html [ Failure Pass ] crbug.com/591099 fast/text/international/hebrew-vowels.html [ Failure ] crbug.com/591099 fast/text/international/hindi-whitespace.html [ Failure ] crbug.com/591099 fast/text/international/iso-8859-8.html [ Failure ] @@ -13688,8 +13654,6 @@ crbug.com/591099 fast/text/international/text-spliced-font.html [ Failure ] crbug.com/591099 fast/text/international/thai-cursor-position.html [ Crash Failure ] crbug.com/591099 fast/text/international/thai-offsetForPosition-inside-character.html [ Failure ] -crbug.com/591099 fast/text/international/unicode-bidi-isolate-collapsed-whitespace.html [ Failure Pass ] -crbug.com/591099 fast/text/international/unicode-bidi-isolate-nested-crash.html [ Failure Pass ] crbug.com/591099 fast/text/international/unicode-bidi-isolate-nested-with-removes-not-adjacent.html [ Crash ] crbug.com/591099 fast/text/international/unicode-bidi-isolate-nested-with-removes.html [ Crash ] crbug.com/591099 fast/text/international/unicode-bidi-plaintext.html [ Failure ] @@ -13728,7 +13692,6 @@ crbug.com/591099 fast/text/offsetForPosition-cluster-at-zero.html [ Failure ] crbug.com/591099 fast/text/offsetForPosition-complex-fallback.html [ Failure ] crbug.com/591099 fast/text/orientation-sideways.html [ Failure ] -crbug.com/591099 fast/text/output-isolate-at-end-of-line-crash.html [ Crash Failure Pass ] crbug.com/591099 fast/text/place-ellipsis-in-inline-block-adjacent-float-2.html [ Failure ] crbug.com/591099 fast/text/place-ellipsis-in-inline-block-adjacent-float.html [ Failure ] crbug.com/591099 fast/text/place-ellipsis-in-inline-blocks-2.html [ Failure ] @@ -13966,7 +13929,6 @@ crbug.com/591099 fast/writing-mode/background-vertical-rl.html [ Failure ] crbug.com/591099 fast/writing-mode/baseline-inline-replaced-002.html [ Failure ] crbug.com/591099 fast/writing-mode/basic-vertical-line.html [ Failure ] -crbug.com/591099 fast/writing-mode/block-formatting-context.html [ Failure Pass ] crbug.com/591099 fast/writing-mode/block-level-images.html [ Failure ] crbug.com/591099 fast/writing-mode/border-image-vertical-lr.html [ Failure ] crbug.com/591099 fast/writing-mode/border-image-vertical-rl.html [ Failure ] @@ -14179,8 +14141,6 @@ crbug.com/591099 fullscreen/full-screen-iframe-legacy.html [ Failure ] crbug.com/591099 fullscreen/full-screen-iframe-not-allowed.html [ Failure ] crbug.com/591099 fullscreen/full-screen-iframe-without-allow-attribute-allowed-from-parent.html [ Failure ] -crbug.com/591099 fullscreen/full-screen-line-boxes-crash.html [ Failure Pass ] -crbug.com/591099 fullscreen/full-screen-no-style-sharing.html [ Failure Pass ] crbug.com/591099 fullscreen/full-screen-placeholder.html [ Failure ] crbug.com/591099 fullscreen/full-screen-request-removed.html [ Failure ] crbug.com/591099 fullscreen/full-screen-table-section.html [ Failure ] @@ -14190,7 +14150,6 @@ crbug.com/591099 fullscreen/video-controls-override.html [ Failure ] crbug.com/591099 fullscreen/video-controls-timeline.html [ Failure ] crbug.com/591099 fullscreen/video-fail-to-enter-full-screen.html [ Failure ] -crbug.com/591099 fullscreen/video-fixed-at-top-left.html [ Failure Pass ] crbug.com/591099 gamepad/gamepad-api.html [ Failure ] crbug.com/591099 gamepad/gamepad-detached-no-crash.html [ Failure ] crbug.com/591099 gamepad/gamepad-events-basic.html [ Failure ] @@ -14675,7 +14634,7 @@ crbug.com/591099 http/tests/inspector-protocol/network/request-interception.html [ Failure ] crbug.com/591099 http/tests/inspector-protocol/network/xhr-interception-auth-fail.html [ Failure ] crbug.com/591099 http/tests/inspector-protocol/network/xhr-interception.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/ping-redirect.html [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/ping-redirect.html [ Crash Failure Timeout ] crbug.com/591099 http/tests/inspector-protocol/reload-memory-cache.html [ Failure Timeout ] crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Failure Timeout ] crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-none.html [ Failure Timeout ] @@ -14701,7 +14660,7 @@ crbug.com/591099 http/tests/inspector/bindings/dynamic-navigator-frame-attach-detach.html [ Failure Timeout ] crbug.com/591099 http/tests/inspector/bindings/livelocation-main-frame-navigated.html [ Failure ] crbug.com/591099 http/tests/inspector/bindings/navigator-frame-attach-detach.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector/bindings/navigator-frame-navigate.html [ Failure ] +crbug.com/591099 http/tests/inspector/bindings/navigator-frame-navigate.html [ Failure Timeout ] crbug.com/591099 http/tests/inspector/bindings/navigator-main-frame-navigated.html [ Failure ] crbug.com/591099 http/tests/inspector/bindings/navigator-multiple-frames.html [ Crash Timeout ] crbug.com/591099 http/tests/inspector/bindings/shadowdom-bindings.html [ Failure Timeout ] @@ -14737,10 +14696,10 @@ crbug.com/591099 http/tests/inspector/elements/styles/import-added-through-js-crash.html [ Crash ] crbug.com/591099 http/tests/inspector/elements/styles/inline-stylesheet-sourceurl-and-sourcemapurl.html [ Crash Failure ] crbug.com/591099 http/tests/inspector/elements/styles/selector-line-deprecated.html [ Crash ] -crbug.com/591099 http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated.html [ Crash ] +crbug.com/591099 http/tests/inspector/elements/styles/selector-line-sourcemap-header-deprecated.html [ Crash Failure ] crbug.com/591099 http/tests/inspector/elements/styles/selector-line-sourcemap-header.html [ Crash ] crbug.com/591099 http/tests/inspector/elements/styles/selector-line.html [ Crash ] -crbug.com/591099 http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html [ Failure ] +crbug.com/591099 http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html [ Failure Timeout ] crbug.com/591099 http/tests/inspector/elements/styles/styles-redirected-css.html [ Crash ] crbug.com/591099 http/tests/inspector/elements/styles/stylesheet-tracking.html [ Crash Failure Timeout ] crbug.com/591099 http/tests/inspector/elements/styles/xsl-transformed.xml [ Crash ] @@ -16250,7 +16209,6 @@ crbug.com/591099 images/55.html [ Crash Failure ] crbug.com/591099 images/alt-text-wrapping.html [ Crash Failure ] crbug.com/591099 images/animated-background-image-crash.html [ Failure ] -crbug.com/591099 images/busted-oval-does-not-render.html [ Crash Pass ] crbug.com/591099 images/color-jpeg-with-color-profile.html [ Failure ] crbug.com/591099 images/color-profile-background-clip-text.html [ Failure ] crbug.com/591099 images/color-profile-background-image-cover.html [ Failure ] @@ -16405,26 +16363,8 @@ crbug.com/591099 inspector-protocol/debugger/debugger-step-into-dedicated-worker.html [ Failure ] crbug.com/591099 inspector-protocol/debugger/suspend-setTimeout-on-pause-in-dedicated-worker.html [ Failure ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Crash Failure Timeout ] -crbug.com/591099 inspector-protocol/dom/dom-getBoxModel.js [ Failure Pass ] -crbug.com/591099 inspector-protocol/dom/dom-ns-attr-modified.js [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-320-2x.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-320-only-viewport.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-320.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-980-2x.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-980-only-viewport.html [ Crash Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-980.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-controls.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-dw-2x.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-dw.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-initial-scale.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-insets.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-none-2x.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-none.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-partial.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-restore.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-small-dw.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-emulation-small.html [ Failure ] -crbug.com/591099 inspector-protocol/emulation/device-scale-not-persistant.html [ Failure ] +crbug.com/591099 inspector-protocol/emulation/device-emulation-small-dw.js [ Failure ] +crbug.com/591099 inspector-protocol/emulation/device-emulation-small.js [ Failure ] crbug.com/591099 inspector-protocol/emulation/forced-viewport-unobserved.html [ Failure ] crbug.com/591099 inspector-protocol/heap-profiler/heap-objects-tracking.html [ Failure ] crbug.com/591099 inspector-protocol/heap-profiler/heap-samples-in-snapshot.html [ Failure ] @@ -16433,12 +16373,8 @@ crbug.com/591099 inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.html [ Failure ] crbug.com/591099 inspector-protocol/heap-profiler/sampling-heap-profiler.html [ Failure ] crbug.com/591099 inspector-protocol/heap-profiler/take-heap-snapshot.html [ Failure ] -crbug.com/591099 inspector-protocol/input/dispatchKeyEvent-focus.js [ Failure ] -crbug.com/591099 inspector-protocol/layers/paint-profiler.html [ Failure ] +crbug.com/591099 inspector-protocol/layers/paint-profiler.js [ Failure ] crbug.com/591099 inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html [ Failure ] -crbug.com/591099 inspector-protocol/network/resource-type.js [ Crash Failure ] -crbug.com/591099 inspector-protocol/network/websocket-initiator.js [ Failure ] -crbug.com/591099 inspector-protocol/page/get-layout-metrics.js [ Failure ] crbug.com/591099 inspector/agents-enable-disable.html [ Failure ] crbug.com/591099 inspector/animation/animation-KeyframeEffectReadOnly-crash.html [ Crash ] crbug.com/591099 inspector/animation/animation-empty-web-animations.html [ Crash Failure ] @@ -16519,7 +16455,7 @@ crbug.com/591099 inspector/console/console-filter-level-test.html [ Crash ] crbug.com/591099 inspector/console/console-filter-test.html [ Failure ] crbug.com/591099 inspector/console/console-focus.html [ Failure ] -crbug.com/591099 inspector/console/console-format-array-prototype.html [ Failure ] +crbug.com/591099 inspector/console/console-format-array-prototype.html [ Crash Failure ] crbug.com/591099 inspector/console/console-format-broken-unicode.html [ Failure ] crbug.com/591099 inspector/console/console-format-collections.html [ Failure ] crbug.com/591099 inspector/console/console-format-es6-2.html [ Failure ] @@ -16871,7 +16807,7 @@ crbug.com/591099 inspector/network/network-filmstrip-overview-showing.html [ Failure ] crbug.com/591099 inspector/network/network-filter-http-requests.html [ Failure ] crbug.com/591099 inspector/network/network-filter-parser.html [ Crash Failure ] -crbug.com/591099 inspector/network/network-filter-updated-requests.html [ Failure ] +crbug.com/591099 inspector/network/network-filter-updated-requests.html [ Crash Failure ] crbug.com/591099 inspector/network/network-json-parser.html [ Crash Failure ] crbug.com/591099 inspector/network/network-request-parse-query-params.html [ Crash Failure ] crbug.com/591099 inspector/network/network-request-query-string.html [ Failure ] @@ -16924,7 +16860,7 @@ crbug.com/591099 inspector/report-protocol-errors.html [ Failure ] crbug.com/591099 inspector/reveal-objects.html [ Crash ] crbug.com/591099 inspector/runtime.html [ Failure ] -crbug.com/591099 inspector/runtime/runtime-callFunctionOn.html [ Failure ] +crbug.com/591099 inspector/runtime/runtime-callFunctionOn.html [ Crash Failure ] crbug.com/591099 inspector/runtime/runtime-es6-setSymbolPropertyValue.html [ Failure ] crbug.com/591099 inspector/runtime/runtime-getProperties-isOwnProperty.html [ Crash Failure ] crbug.com/591099 inspector/runtime/runtime-getProperties.html [ Failure ] @@ -16960,7 +16896,7 @@ crbug.com/591099 inspector/sources/autocomplete-css.html [ Crash Failure ] crbug.com/591099 inspector/sources/autocomplete-general.html [ Crash Failure ] crbug.com/591099 inspector/sources/autocomplete-hide-on-smart-brace.html [ Crash Failure ] -crbug.com/591099 inspector/sources/autocomplete-scss.html [ Failure ] +crbug.com/591099 inspector/sources/autocomplete-scss.html [ Crash Failure ] crbug.com/591099 inspector/sources/bezier-swatch-position.html [ Failure ] crbug.com/591099 inspector/sources/color-swatch-position.html [ Crash Failure ] crbug.com/591099 inspector/sources/compile-javascript.html [ Crash Failure ] @@ -16982,7 +16918,7 @@ crbug.com/591099 inspector/sources/debugger-async/async-callstack-scripted-scroll.html [ Crash Failure Timeout ] crbug.com/591099 inspector/sources/debugger-async/async-callstack-set-interval.html [ Failure ] crbug.com/591099 inspector/sources/debugger-async/async-callstack-web-sql.html [ Crash Failure ] -crbug.com/591099 inspector/sources/debugger-async/async-callstack-xhrs.html [ Failure ] +crbug.com/591099 inspector/sources/debugger-async/async-callstack-xhrs.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-async/async-callstack.html [ Failure ] crbug.com/591099 inspector/sources/debugger-breakpoints/breakpoint-manager-listeners-count.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-breakpoints/breakpoint-manager.html [ Failure ] @@ -17002,7 +16938,7 @@ crbug.com/591099 inspector/sources/debugger-breakpoints/nodejs-set-breakpoint.html [ Failure ] crbug.com/591099 inspector/sources/debugger-breakpoints/possible-breakpoints.html [ Failure ] crbug.com/591099 inspector/sources/debugger-breakpoints/set-breakpoint.html [ Failure Timeout ] -crbug.com/591099 inspector/sources/debugger-breakpoints/set-conditional-breakpoint.html [ Failure ] +crbug.com/591099 inspector/sources/debugger-breakpoints/set-conditional-breakpoint.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint.html [ Failure ] crbug.com/591099 inspector/sources/debugger-breakpoints/xhr-breakpoints.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-console/debug-console-command.html [ Crash Failure ] @@ -17024,7 +16960,7 @@ crbug.com/591099 inspector/sources/debugger-pause/debugger-eval-on-call-frame.html [ Failure ] crbug.com/591099 inspector/sources/debugger-pause/debugger-eval-while-paused-throws.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-pause/debugger-eval-while-paused.html [ Crash Failure ] -crbug.com/591099 inspector/sources/debugger-pause/debugger-mute-exception.html [ Failure ] +crbug.com/591099 inspector/sources/debugger-pause/debugger-mute-exception.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-pause/debugger-no-nested-pause.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger-pause/debugger-pause-in-eval-script.html [ Failure ] crbug.com/591099 inspector/sources/debugger-pause/debugger-pause-in-internal.html [ Crash Failure ] @@ -17101,7 +17037,7 @@ crbug.com/591099 inspector/sources/debugger/debug-inlined-scripts-fragment-id.html [ Failure ] crbug.com/591099 inspector/sources/debugger/debugger-autocontinue-on-syntax-error.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger/debugger-compile-and-run.html [ Failure ] -crbug.com/591099 inspector/sources/debugger/debugger-completions-on-call-frame.html [ Failure ] +crbug.com/591099 inspector/sources/debugger/debugger-completions-on-call-frame.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger/debugger-cyclic-reference.html [ Failure ] crbug.com/591099 inspector/sources/debugger/debugger-disable-enable.html [ Failure ] crbug.com/591099 inspector/sources/debugger/debugger-es6-harmony-scopes.html [ Crash Failure ] @@ -17136,7 +17072,7 @@ crbug.com/591099 inspector/sources/debugger/source-frame-breakpoint-decorations.html [ Failure ] crbug.com/591099 inspector/sources/debugger/source-frame-inline-breakpoint-decorations.html [ Crash Failure ] crbug.com/591099 inspector/sources/debugger/sources-panel-content-scripts.html [ Crash Failure ] -crbug.com/591099 inspector/sources/formatter-css.html [ Failure ] +crbug.com/591099 inspector/sources/formatter-css.html [ Crash Failure ] crbug.com/591099 inspector/sources/formatter-js.html [ Failure ] crbug.com/591099 inspector/sources/inspect-function.html [ Failure ] crbug.com/591099 inspector/sources/javascript-outline-dialog.html [ Crash Failure ] @@ -17149,7 +17085,7 @@ crbug.com/591099 inspector/sources/pretty-print-css-1.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-css-2.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-css-3.html [ Failure ] -crbug.com/591099 inspector/sources/pretty-print-html-1.html [ Failure ] +crbug.com/591099 inspector/sources/pretty-print-html-1.html [ Crash Failure ] crbug.com/591099 inspector/sources/pretty-print-html-2.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-html-3.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-javascript-1.html [ Failure ] @@ -17159,16 +17095,16 @@ crbug.com/591099 inspector/sources/pretty-print-javascript-5.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-javascript-6.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-javascript-7.html [ Crash Failure ] -crbug.com/591099 inspector/sources/pretty-print-javascript-8.html [ Failure ] +crbug.com/591099 inspector/sources/pretty-print-javascript-8.html [ Crash Failure ] crbug.com/591099 inspector/sources/pretty-print-javascript-9.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-javascript-classes.html [ Failure ] crbug.com/591099 inspector/sources/pretty-print-javascript-template-literals.html [ Failure ] crbug.com/591099 inspector/sources/sass-highlighter.html [ Failure ] -crbug.com/591099 inspector/sources/search-config.html [ Failure ] +crbug.com/591099 inspector/sources/search-config.html [ Crash Failure ] crbug.com/591099 inspector/sources/snippet-storage.html [ Failure ] crbug.com/591099 inspector/sources/source-code-diff.html [ Failure ] crbug.com/591099 inspector/sources/sources-panel-extension-names.html [ Failure ] -crbug.com/591099 inspector/sources/sources-panel-focus-editor-on-select.html [ Failure ] +crbug.com/591099 inspector/sources/sources-panel-focus-editor-on-select.html [ Crash Failure ] crbug.com/591099 inspector/storage-panel-dom-storage-update.html [ Failure ] crbug.com/591099 inspector/storage-panel-dom-storage.html [ Failure ] crbug.com/591099 inspector/syntax-highlight-css.html [ Failure ] @@ -17218,7 +17154,7 @@ crbug.com/591099 inspector/tracing/timeline-misc/timeline-grouped-invalidations.html [ Crash ] crbug.com/591099 inspector/tracing/timeline-misc/timeline-load-event.html [ Crash ] crbug.com/591099 inspector/tracing/timeline-misc/timeline-mark-timeline.html [ Crash ] -crbug.com/591099 inspector/tracing/timeline-misc/timeline-model.html [ Failure ] +crbug.com/591099 inspector/tracing/timeline-misc/timeline-model.html [ Crash Failure ] crbug.com/591099 inspector/tracing/timeline-misc/timeline-node-reference.html [ Crash ] crbug.com/591099 inspector/tracing/timeline-misc/timeline-parse-html.html [ Crash ] crbug.com/591099 inspector/tracing/timeline-misc/timeline-range-stats.html [ Failure ] @@ -17918,6 +17854,7 @@ crbug.com/591099 paint/invalidation/crbug-371640-4.html [ Failure ] crbug.com/591099 paint/invalidation/crbug-371640.html [ Failure ] crbug.com/591099 paint/invalidation/create-layer-repaint.html [ Failure ] +crbug.com/591099 paint/invalidation/css-clip-change-stacking-child.html [ Failure ] crbug.com/591099 paint/invalidation/css-grid-layout/grid-element-change-columns-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/css-grid-layout/grid-element-change-rows-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/css-grid-layout/grid-item-change-column-repaint.html [ Failure ] @@ -18085,6 +18022,7 @@ crbug.com/591099 paint/invalidation/list-marker.html [ Failure ] crbug.com/591099 paint/invalidation/make-children-non-inline.html [ Failure ] crbug.com/591099 paint/invalidation/margin.html [ Failure Pass ] +crbug.com/591099 paint/invalidation/mask-clip-change-stacking-child.html [ Failure ] crbug.com/591099 paint/invalidation/media-audio-no-spurious-repaints.html [ Crash ] crbug.com/591099 paint/invalidation/mix-blend-mode-separate-stacking-context.html [ Failure ] crbug.com/591099 paint/invalidation/multi-subsequence-composited.html [ Failure ] @@ -19130,7 +19068,6 @@ crbug.com/591099 svg/css/opacity-not-supporting-percentage.html [ Failure ] crbug.com/591099 svg/css/parse-length.html [ Failure ] crbug.com/591099 svg/css/path-element.html [ Crash ] -crbug.com/591099 svg/css/path-layout-crash.html [ Failure Pass ] crbug.com/591099 svg/css/rect-system-color.xhtml [ Failure ] crbug.com/591099 svg/css/scientific-numbers.html [ Failure ] crbug.com/591099 svg/css/svg-attribute-length-parsing.html [ Failure ] @@ -20339,8 +20276,6 @@ crbug.com/591099 virtual/android/fullscreen/full-screen-iframe-legacy.html [ Failure ] crbug.com/591099 virtual/android/fullscreen/full-screen-iframe-not-allowed.html [ Failure ] crbug.com/591099 virtual/android/fullscreen/full-screen-iframe-without-allow-attribute-allowed-from-parent.html [ Failure ] -crbug.com/591099 virtual/android/fullscreen/full-screen-line-boxes-crash.html [ Failure Pass ] -crbug.com/591099 virtual/android/fullscreen/full-screen-no-style-sharing.html [ Failure Pass ] crbug.com/591099 virtual/android/fullscreen/full-screen-placeholder.html [ Failure ] crbug.com/591099 virtual/android/fullscreen/full-screen-request-removed.html [ Failure ] crbug.com/591099 virtual/android/fullscreen/full-screen-table-section.html [ Failure ] @@ -20350,7 +20285,6 @@ crbug.com/591099 virtual/android/fullscreen/video-controls-override.html [ Failure ] crbug.com/591099 virtual/android/fullscreen/video-controls-timeline.html [ Failure ] crbug.com/591099 virtual/android/fullscreen/video-fail-to-enter-full-screen.html [ Failure ] -crbug.com/591099 virtual/android/fullscreen/video-fixed-at-top-left.html [ Failure Pass ] crbug.com/591099 virtual/android/media/mediadocument/media-document-with-download-button.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/absolute-inside-out-of-view-fixed.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/animation/busy-indicator.html [ Failure ] @@ -20366,7 +20300,6 @@ crbug.com/591099 virtual/disable-spinvalidation/compositing/color-matching/image-color-matching.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/columns/composited-in-paginated.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/columns/geometry-map-paginated-assert.html [ Failure ] -crbug.com/591099 virtual/disable-spinvalidation/compositing/composite-scrollable-fixed-position-when-descendants-composite.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/composited-negative-zindex-child.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/compositing-visible-descendant.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/contents-opaque/background-clip.html [ Failure Pass ] @@ -20413,7 +20346,6 @@ crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/fixed-position.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/flipped-writing-mode.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/foreground-layer.html [ Failure ] -crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/foreground-offset-change.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/geometry-map-scroll-during-layout-assertion.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/horizontal-scroll-composited.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/geometry/layer-due-to-layer-children-deep-switch.html [ Failure ] @@ -20467,7 +20399,6 @@ crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/iframe-in-composited-layer.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/iframe-resize.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/iframe-size-from-zero.html [ Failure ] -crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/iframe-size-to-zero.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/invisible-iframe.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/invisible-nested-iframe-hide.html [ Crash ] crbug.com/591099 virtual/disable-spinvalidation/compositing/iframes/invisible-nested-iframe-show.html [ Failure ] @@ -20652,13 +20583,10 @@ crbug.com/591099 virtual/disable-spinvalidation/compositing/shadows/shadow-drawing.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/sibling-positioning.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/add-remove-squashed-layers.html [ Failure ] -crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/backing-owner-determines-scroll-parent.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/clipping-ancestor.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/composited-bounds-for-negative-z.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/do-not-squash-non-self-painting-layer.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/do-not-squash-scroll-child-with-composited-descendants.html [ Failure ] -crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/dont-squash-into-animated-layers.html [ Failure Pass ] -crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/dont-squash-into-blend-mode.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/dont-squash-into-iframes.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/dont-squash-into-videos.html [ Failure Pass ] crbug.com/591099 virtual/disable-spinvalidation/compositing/squashing/iframes-are-never-squashed.html [ Failure Pass ] @@ -20883,6 +20811,7 @@ crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/crbug-371640-4.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/crbug-371640.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/create-layer-repaint.html [ Failure ] +crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/css-clip-change-stacking-child.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/css-grid-layout/grid-element-change-columns-repaint.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/css-grid-layout/grid-element-change-rows-repaint.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/css-grid-layout/grid-item-change-column-repaint.html [ Failure ] @@ -21050,6 +20979,7 @@ crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/list-marker.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/make-children-non-inline.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/margin.html [ Failure Pass ] +crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/mask-clip-change-stacking-child.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/media-audio-no-spurious-repaints.html [ Crash ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/mix-blend-mode-separate-stacking-context.html [ Failure ] crbug.com/591099 virtual/disable-spinvalidation/paint/invalidation/multi-subsequence-composited.html [ Failure ] @@ -21999,7 +21929,6 @@ crbug.com/591099 virtual/high-contrast-mode/paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-003r.xht [ Failure Pass ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-width-006.xht [ Failure ] -crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-114.xht [ Crash Failure Pass ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-019.xht [ Crash Failure ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-020.xht [ Crash Failure ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-031.xht [ Crash Failure ] @@ -22021,7 +21950,6 @@ crbug.com/591099 virtual/layout_ng/fast/block/float/002.html [ Failure ] crbug.com/591099 virtual/layout_ng/fast/block/float/014.html [ Crash Failure ] crbug.com/591099 virtual/layout_ng/fast/block/float/017.html [ Failure ] -crbug.com/591099 virtual/layout_ng/fast/block/float/clear-intruding-floats-when-moving-to-inline-parent-3.html [ Crash Failure Pass ] crbug.com/591099 virtual/layout_ng/fast/block/float/formatting-context-changes.html [ Failure ] crbug.com/591099 virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block.html [ Failure Pass ] crbug.com/591099 virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block2.html [ Failure Pass ] @@ -22036,6 +21964,7 @@ crbug.com/591099 virtual/mojo-loading/http/tests/inspector/network/network-filters.html [ Failure Pass ] crbug.com/591099 virtual/mojo-loading/http/tests/inspector/network/waterfall-images.html [ Failure Pass ] crbug.com/591099 virtual/mojo-loading/http/tests/inspector/persistence/automapping-sourcemap.html [ Failure Pass Timeout ] +crbug.com/591099 virtual/mojo-loading/http/tests/misc/image-load-outlives-gc-without-crashing.html [ Failure Pass ] crbug.com/591099 virtual/mojo-loading/http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.html [ Failure Pass Timeout ] crbug.com/591099 virtual/mojo-loading/http/tests/serviceworker/ServiceWorkerGlobalScope/registration-attribute.html [ Failure Pass ] crbug.com/591099 virtual/mojo-localstorage/external/wpt/webstorage/event_no_duplicates.html [ Crash ] @@ -22383,7 +22312,6 @@ crbug.com/591099 virtual/prefer_compositing_to_lcd_text/scrollbars/viewport-scrollbar-corner-with-percent-padding-crash.html [ Failure ] crbug.com/591099 virtual/rootlayerscrolls/fast/history/scroll-restoration/scroll-restoration-fragment-navigation-crossdoc.html [ Crash ] crbug.com/591099 virtual/rootlayerscrolls/fast/history/scroll-restoration/scroll-restoration-navigation.html [ Crash ] -crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/absolute-position-behind-scrollbar.html [ Failure Pass ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/abspos-relayout-overflow-style-change.html [ Failure ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/content-box-smaller-than-scrollbar.html [ Crash ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/custom-scrollbar-style-applied.html [ Failure ] @@ -22406,7 +22334,6 @@ crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrollbar-mousedown-mouseup.html [ Failure ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrollbar-mousedown-move-mouseup.html [ Failure ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default.html [ Failure ] -crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrollbar-repaint-two-level-scrollable.html [ Failure Pass ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrollbar-tickmarks-hittest.html [ Failure ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrolling-apis-nan-scroll-position.html [ Failure ] crbug.com/591099 virtual/rootlayerscrolls/fast/scrolling/scrolling-apis-subpixel.html [ Failure ] @@ -22682,7 +22609,6 @@ crbug.com/591099 virtual/threaded/animations/interpolation/webkit-transform-origin-interpolation.html [ Crash ] crbug.com/591099 virtual/threaded/animations/keyframes-cssom-prefixed-02.html [ Failure ] crbug.com/591099 virtual/threaded/animations/keyframes-cssom-unprefixed-02.html [ Failure ] -crbug.com/591099 virtual/threaded/animations/keyframes-iteration-count-non-integer.html [ Failure Pass ] crbug.com/591099 virtual/threaded/animations/keyframes-rule.html [ Failure ] crbug.com/591099 virtual/threaded/animations/lazy-detached-animation-stop.html [ Failure ] crbug.com/591099 virtual/threaded/animations/length-zero-percent-crash.html [ Failure Pass ] @@ -22790,7 +22716,7 @@ crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-markerUnits-interpolation.html [ Crash ] crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-markerWidth-interpolation.html [ Crash ] crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-maskContentUnits-interpolation.html [ Crash ] -crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-maskUnits-interpolation.html [ Crash ] +crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-maskUnits-interpolation.html [ Crash Timeout ] crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-method-interpolation.html [ Crash ] crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-mode-interpolation.html [ Crash ] crbug.com/591099 virtual/threaded/animations/svg-attribute-interpolation/svg-numOctaves-interpolation.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service index 746779f..82103d8 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-network-service
@@ -1515,6 +1515,9 @@ Bug(none) external/wpt/streams/writable-streams/write.serviceworker.https.html [ Failure Timeout ] Bug(none) external/wpt/url/failure.html [ Failure Timeout ] Bug(none) external/wpt/web-animations/interfaces/AnimationTimeline/document-timeline.html [ Failure ] +Bug(none) external/wpt/web-share/idlharness.https.html [ Failure Timeout ] +Bug(none) external/wpt/web-share/share-url-invalid.https.html [ Failure Timeout ] +Bug(none) external/wpt/web-share/share-without-user-gesture.https.html [ Failure Timeout ] Bug(none) external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html [ Failure Timeout ] Bug(none) external/wpt/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html [ Failure Timeout ] Bug(none) external/wpt/webaudio/the-audio-api/the-audioparam-interface/idl-test.html [ Failure Timeout ] @@ -1688,6 +1691,7 @@ Bug(none) fast/loader/document-destruction-within-unload.html [ Crash ] Bug(none) fast/loader/local-svg-parsed-as-svg.svg [ Timeout ] Bug(none) fast/loader/main-document-url-for-non-http-loads.html [ Failure ] +Bug(none) fast/loader/object-with-rejected-resource.html [ Failure ] Bug(none) fast/loader/reload-zero-byte-plugin.html [ Timeout ] Bug(none) fast/loader/sandboxed-plugin-crash.html [ Crash ] Bug(none) fast/loader/simultaneous-reloads-assert.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 53c3816..bde2f64 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1525,11 +1525,8 @@ crbug.com/644358 fast/css3-text/css3-text-decoration/repaint/repaint-text-decoration-style.html [ Failure ] crbug.com/644358 paint/invalidation/justify-items-overflow-change.html [ Failure ] crbug.com/644358 paint/invalidation/justify-self-overflow-change.html [ Failure ] -crbug.com/644358 paint/invalidation/multi-subsequence-scrolled.html [ Failure ] -crbug.com/644358 paint/invalidation/repaint-subsequence-on-ancestor-clip-change.html [ Failure ] crbug.com/644358 paint/invalidation/svg/overflow-repaint.html [ Failure ] crbug.com/644358 paint/invalidation/video-paint-invalidation.html [ Crash ] -crbug.com/644358 svg/animations/animateMotion_changingPath.html [ Failure ] Bug(none) compositing/layer-creation/main-thread-scrolling-for-non-composited-fixed-position-if-overflow-hidden.html [ Failure ] Bug(none) compositing/layer-creation/main-thread-scrolling-for-non-composited-fixed-position.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls index e8d2d8c..15b72c548 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls +++ b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
@@ -462,8 +462,8 @@ Bug(none) inspector/layers/no-overlay-layers.html [ Crash ] Bug(none) inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Failure ] Bug(none) inspector-protocol/emulation/forced-viewport-far.html [ Failure ] -Bug(none) inspector-protocol/layers/get-layers.html [ Crash ] -Bug(none) inspector-protocol/layers/paint-profiler.html [ Crash ] +Bug(none) inspector-protocol/layers/get-layers.js [ Crash ] +Bug(none) inspector-protocol/layers/paint-profiler.js [ Crash ] Bug(none) inspector-protocol/page/get-layout-metrics.js [ Failure ] Bug(none) inspector/tracing/scroll-invalidations.html [ Failure ] Bug(none) inspector/tracing/timeline-paint/layer-tree.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 01d156e0..60f2dcd1 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -883,7 +883,7 @@ crbug.com/543110 [ Mac ] fast/text/international/text-shaping-arabic.html [ Failure ] -crbug.com/731731 inspector-protocol/layers/paint-profiler-load-empty.html [ Failure Pass ] +crbug.com/731731 inspector-protocol/layers/paint-profiler-load-empty.js [ Failure Pass ] crbug.com/734744 http/tests/inspector/indexeddb/resources-panel.html [ Pass Failure Timeout ] crbug.com/734744 virtual/mojo-loading/http/tests/inspector/indexeddb/resources-panel.html [ Pass Failure Timeout ] @@ -1689,7 +1689,9 @@ crbug.com/611658 [ Win7 ] fast/forms/text/text-font-height-mismatch.html [ Failure ] crbug.com/611658 [ Win ] fast/text/emphasis-combined-text.html [ Failure ] -crbug.com/611658 [ Win7 ] fast/writing-mode/english-lr-text.html [ Failure ] + +# Reenable when 737620 is rebaselined +#crbug.com/611658 [ Win7 ] fast/writing-mode/english-lr-text.html [ Failure ] crbug.com/605059 [ Retina ] fast/text/international/rtl-negative-letter-spacing.html [ Failure ] @@ -1893,6 +1895,22 @@ crbug.com/724251 virtual/threaded/animations/svg-attribute-interpolation/svg-startOffset-interpolation.html [ Failure Pass ] +crbug.com/737620 fast/text/stroking-decorations.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/writing-mode/english-lr-text.html [ NeedsManualRebaseline ] +crbug.com/737620 paint/invalidation/shadow-multiple.html [ NeedsManualRebaseline ] +crbug.com/737620 [ Mac ] fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/borders/border-radius-split-inline.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/box-shadow/basic-shadows.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/box-shadow/box-shadow-radius.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/box-shadow/box-shadow-transformed.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/box-shadow/box-shadow.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/box-shadow/inset-box-shadow-radius.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/box-shadow/scaled-box-shadow.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/canvas/canvas-composite-shadow.html [ NeedsManualRebaseline ] +crbug.com/737620 fast/css/color-correction-on-box-shadow.html [ NeedsManualRebaseline ] +crbug.com/737620 transforms/shadows.html [ NeedsManualRebaseline ] +crbug.com/737620 virtual/display_list_2d_canvas/fast/canvas/canvas-composite-shadow.html [ NeedsManualRebaseline ] + crbug.com/736050 external/wpt/IndexedDB/idbcursor_advance_index.htm [ Pass Failure ] crbug.com/736050 external/wpt/IndexedDB/idbcursor-continue-exception-order.htm [ Pass Failure ] crbug.com/736050 external/wpt/IndexedDB/idbcursor_continue_index2.htm [ Pass Failure ] @@ -2031,6 +2049,22 @@ crbug.com/626703 virtual/threaded/transitions/transition-end-event-multiple-03.html [ Pass Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Android Mac ] external/wpt/css/css-flexbox-1/auto-margins-001.html [ Failure ] +crbug.com/626703 external/wpt/web-share/share-cancel-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-empty-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-extra-argument-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-extra-field-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-non-string-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-null-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-simple-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-unicode-strings-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-unicode-strings-nonutf8-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-url-data-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-url-empty-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-url-encoding-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-url-noscheme-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-url-pathonly-manual.html [ Skip ] +crbug.com/626703 external/wpt/web-share/share-url-relative-manual.html [ Skip ] crbug.com/626703 external/wpt/workers/name-property.html [ Timeout ] crbug.com/626703 external/wpt/pointerevents/pointerevent_disabled_form_control-manual.html [ Timeout Pass ] crbug.com/626703 external/wpt/css/CSS2/text/text-align-white-space-003.xht [ Failure ] @@ -2103,7 +2137,6 @@ crbug.com/626703 external/wpt/screen-orientation/onchange-event.html [ Timeout ] crbug.com/626703 external/wpt/screen-orientation/onchange-event-subframe.html [ Timeout ] crbug.com/626703 external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html [ Timeout ] -crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html [ Timeout ] crbug.com/626703 [ Mac ] external/wpt/2dcontext/the-canvas-state/canvas_state_restore_001.htm [ Failure ] crbug.com/626703 [ Mac ] external/wpt/pointerevents/extension/pointerevent_coalesced_events_attributes-manual.html [ Timeout ] crbug.com/626703 [ Mac ] external/wpt/WebCryptoAPI/generateKey/test_successes_RSA-OAEP.https.html [ Timeout ] @@ -2915,6 +2948,7 @@ crbug.com/v8/6504 fast/js/mozilla/strict/B.1.2.html [ NeedsManualRebaseline ] crbug.com/v8/6529 inspector/console/console-dir.html [ NeedsManualRebaseline ] +crbug.com/v8/6529 inspector/console/console-format.html [ NeedsManualRebaseline ] # These tests are failing on Mac-10.12 when using an Intel GPU. crbug.com/736177 [ Mac ] css2.1/t1202-counter-04-b.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/custom-properties/registered-property-initial.html b/third_party/WebKit/LayoutTests/custom-properties/registered-property-initial.html index 91dcd4b..dfc338a 100644 --- a/third_party/WebKit/LayoutTests/custom-properties/registered-property-initial.html +++ b/third_party/WebKit/LayoutTests/custom-properties/registered-property-initial.html
@@ -13,6 +13,8 @@ CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)'}); CSS.registerProperty({name: '--inherited-color', syntax: '<color>', initialValue: 'pink', inherits: true}); CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple'}); +CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))'}); +CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))'}); test(function() { computedStyle = getComputedStyle(target); @@ -20,6 +22,8 @@ assert_equals(computedStyle.getPropertyValue('--length-percentage'), 'calc(100px + 10%)'); assert_equals(computedStyle.getPropertyValue('--inherited-color'), 'pink'); assert_equals(computedStyle.getPropertyValue('--non-inherited-color'), 'purple'); + assert_equals(computedStyle.getPropertyValue('--single-transform-list'), 'scale(4)'); + assert_equals(computedStyle.getPropertyValue('--multiple-transform-list'), 'scale(3) translateX(4px)'); assert_equals(computedStyle.backgroundColor, 'rgb(255, 192, 203)'); assert_equals(computedStyle.color, 'rgb(128, 0, 128)');
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index d16116c0..dc10df6 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -4105,6 +4105,96 @@ {} ] ], + "web-share/share-cancel-manual.html": [ + [ + "/web-share/share-cancel-manual.html", + {} + ] + ], + "web-share/share-empty-manual.html": [ + [ + "/web-share/share-empty-manual.html", + {} + ] + ], + "web-share/share-extra-argument-manual.html": [ + [ + "/web-share/share-extra-argument-manual.html", + {} + ] + ], + "web-share/share-extra-field-manual.html": [ + [ + "/web-share/share-extra-field-manual.html", + {} + ] + ], + "web-share/share-non-string-manual.html": [ + [ + "/web-share/share-non-string-manual.html", + {} + ] + ], + "web-share/share-null-manual.html": [ + [ + "/web-share/share-null-manual.html", + {} + ] + ], + "web-share/share-simple-manual.html": [ + [ + "/web-share/share-simple-manual.html", + {} + ] + ], + "web-share/share-unicode-strings-manual.html": [ + [ + "/web-share/share-unicode-strings-manual.html", + {} + ] + ], + "web-share/share-unicode-strings-nonutf8-manual.html": [ + [ + "/web-share/share-unicode-strings-nonutf8-manual.html", + {} + ] + ], + "web-share/share-url-data-manual.html": [ + [ + "/web-share/share-url-data-manual.html", + {} + ] + ], + "web-share/share-url-empty-manual.html": [ + [ + "/web-share/share-url-empty-manual.html", + {} + ] + ], + "web-share/share-url-encoding-manual.html": [ + [ + "/web-share/share-url-encoding-manual.html", + {} + ] + ], + "web-share/share-url-noscheme-manual.html": [ + [ + "/web-share/share-url-noscheme-manual.html", + {} + ] + ], + "web-share/share-url-pathonly-manual.html": [ + [ + "/web-share/share-url-pathonly-manual.html", + {} + ] + ], + "web-share/share-url-relative-manual.html": [ + [ + "/web-share/share-url-relative-manual.html", + {} + ] + ], "webstorage/storage_local-manual.html": [ [ "/webstorage/storage_local-manual.html", @@ -26873,6 +26963,18 @@ {} ] ], + "css/css-flexbox-1/auto-margins-001.html": [ + [ + "/css/css-flexbox-1/auto-margins-001.html", + [ + [ + "/css/css-flexbox-1/auto-margins-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-flexbox-1/css-box-justify-content.html": [ [ "/css/css-flexbox-1/css-box-justify-content.html", @@ -30605,6 +30707,42 @@ {} ] ], + "css/css-flexbox-1/percentage-heights-002.html": [ + [ + "/css/css-flexbox-1/percentage-heights-002.html", + [ + [ + "/css/css-flexbox-1/percentage-heights-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox-1/percentage-widths-001.html": [ + [ + "/css/css-flexbox-1/percentage-widths-001.html", + [ + [ + "/css/css-flexbox-1/percentage-widths-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox-1/position-absolute-005.html": [ + [ + "/css/css-flexbox-1/position-absolute-005.html", + [ + [ + "/css/css-flexbox-1/position-absolute-005-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-flexbox-1/ttwf-reftest-flex-align-content-center.html": [ [ "/css/css-flexbox-1/ttwf-reftest-flex-align-content-center.html", @@ -30761,6 +30899,18 @@ {} ] ], + "css/css-flexbox-1/whitespace-in-flexitem-001.html": [ + [ + "/css/css-flexbox-1/whitespace-in-flexitem-001.html", + [ + [ + "/css/css-flexbox-1/whitespace-in-flexitem-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-grid-1/abspos/orthogonal-positioned-grid-items-001.html": [ [ "/css/css-grid-1/abspos/orthogonal-positioned-grid-items-001.html", @@ -58725,18 +58875,6 @@ {} ] ], - "html/rendering/non-replaced-elements/tables/table-direction.html": [ - [ - "/html/rendering/non-replaced-elements/tables/table-direction.html", - [ - [ - "/html/rendering/non-replaced-elements/tables/table-direction-ref.html", - "==" - ] - ], - {} - ] - ], "html/rendering/non-replaced-elements/tables/table-layout.html": [ [ "/html/rendering/non-replaced-elements/tables/table-layout.html", @@ -58749,30 +58887,6 @@ {} ] ], - "html/rendering/non-replaced-elements/tables/table-row-direction.html": [ - [ - "/html/rendering/non-replaced-elements/tables/table-row-direction.html", - [ - [ - "/html/rendering/non-replaced-elements/tables/table-row-direction-ref.html", - "==" - ] - ], - {} - ] - ], - "html/rendering/non-replaced-elements/tables/table-row-group-direction.html": [ - [ - "/html/rendering/non-replaced-elements/tables/table-row-group-direction.html", - [ - [ - "/html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html", - "==" - ] - ], - {} - ] - ], "html/rendering/non-replaced-elements/tables/table-width-150percent.html": [ [ "/html/rendering/non-replaced-elements/tables/table-width-150percent.html", @@ -72487,6 +72601,11 @@ {} ] ], + "css/css-flexbox-1/auto-margins-001-ref.html": [ + [ + {} + ] + ], "css/css-flexbox-1/css-flexbox-column-ref.html": [ [ {} @@ -73347,6 +73466,21 @@ {} ] ], + "css/css-flexbox-1/percentage-heights-002-ref.html": [ + [ + {} + ] + ], + "css/css-flexbox-1/percentage-widths-001-ref.html": [ + [ + {} + ] + ], + "css/css-flexbox-1/position-absolute-005-ref.html": [ + [ + {} + ] + ], "css/css-flexbox-1/reference/Flexible-order-ref.html": [ [ {} @@ -73772,6 +73906,11 @@ {} ] ], + "css/css-flexbox-1/whitespace-in-flexitem-001-ref.html": [ + [ + {} + ] + ], "css/css-grid-1/README.md": [ [ {} @@ -83562,11 +83701,6 @@ {} ] ], - "dom/events/EventListener-invoke-legacy-expected.txt": [ - [ - {} - ] - ], "dom/historical-expected.txt": [ [ {} @@ -88877,6 +89011,11 @@ {} ] ], + "html/dom/interfaces-expected.txt": [ + [ + {} + ] + ], "html/dom/new-harness.js": [ [ {} @@ -94067,11 +94206,6 @@ {} ] ], - "html/rendering/non-replaced-elements/tables/table-direction-ref.html": [ - [ - {} - ] - ], "html/rendering/non-replaced-elements/tables/table-layout-notref.html": [ [ {} @@ -94082,16 +94216,6 @@ {} ] ], - "html/rendering/non-replaced-elements/tables/table-row-direction-ref.html": [ - [ - {} - ] - ], - "html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html": [ - [ - {} - ] - ], "html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html": [ [ {} @@ -97992,6 +98116,11 @@ {} ] ], + "interfaces/web-share.idl": [ + [ + {} + ] + ], "interfaces/webrtc-pc.idl": [ [ {} @@ -103182,6 +103311,11 @@ {} ] ], + "service-workers/service-worker/claim-fetch.https-expected.txt": [ + [ + {} + ] + ], "service-workers/service-worker/clients-get-client-types.https-expected.txt": [ [ {} @@ -105452,11 +105586,6 @@ {} ] ], - "url/urlsearchparams-sort-expected.txt": [ - [ - {} - ] - ], "url/urltestdata.json": [ [ {} @@ -105742,6 +105871,11 @@ {} ] ], + "web-share/resources/manual-helper.js": [ + [ + {} + ] + ], "webaudio/.gitignore": [ [ {} @@ -120950,6 +121084,30 @@ {} ] ], + "css/css-flexbox-1/position-absolute-001.html": [ + [ + "/css/css-flexbox-1/position-absolute-001.html", + {} + ] + ], + "css/css-flexbox-1/position-absolute-002.html": [ + [ + "/css/css-flexbox-1/position-absolute-002.html", + {} + ] + ], + "css/css-flexbox-1/position-absolute-003.html": [ + [ + "/css/css-flexbox-1/position-absolute-003.html", + {} + ] + ], + "css/css-flexbox-1/position-absolute-004.html": [ + [ + "/css/css-flexbox-1/position-absolute-004.html", + {} + ] + ], "css/css-grid-1/alignment/grid-self-alignment-stretch-001.html": [ [ "/css/css-grid-1/alignment/grid-self-alignment-stretch-001.html", @@ -131838,6 +131996,14 @@ {} ] ], + "html/dom/interfaces.html": [ + [ + "/html/dom/interfaces.html", + { + "timeout": "long" + } + ] + ], "html/dom/interfaces.worker.js": [ [ "/html/dom/interfaces.worker.html", @@ -149462,6 +149628,12 @@ {} ] ], + "quirks-mode/classname-query-after-sibling-adoption.html": [ + [ + "/quirks-mode/classname-query-after-sibling-adoption.html", + {} + ] + ], "quirks-mode/hashless-hex-color.html": [ [ "/quirks-mode/hashless-hex-color.html", @@ -161802,6 +161974,30 @@ {} ] ], + "web-share/idlharness.https.html": [ + [ + "/web-share/idlharness.https.html", + {} + ] + ], + "web-share/share-securecontext.http.html": [ + [ + "/web-share/share-securecontext.http.html", + {} + ] + ], + "web-share/share-url-invalid.https.html": [ + [ + "/web-share/share-url-invalid.https.html", + {} + ] + ], + "web-share/share-without-user-gesture.https.html": [ + [ + "/web-share/share-without-user-gesture.https.html", + {} + ] + ], "webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html": [ [ "/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html", @@ -162570,6 +162766,12 @@ {} ] ], + "webrtc/RTCPeerConnection-addTrack.html": [ + [ + "/webrtc/RTCPeerConnection-addTrack.html", + {} + ] + ], "webrtc/RTCPeerConnection-addTransceiver.html": [ [ "/webrtc/RTCPeerConnection-addTransceiver.html", @@ -180204,7 +180406,7 @@ "testharness" ], "content-security-policy/connect-src/connect-src-beacon-blocked.sub.html": [ - "0965458e1d32dacec7a9379a7f0e484277389398", + "4d88ea8d1c46369639c32b8301cfface99c0bef2", "testharness" ], "content-security-policy/connect-src/connect-src-eventsource-blocked.sub.html": [ @@ -195347,6 +195549,14 @@ "55ac1cc272d6feaba627f45e402671e7bc83487d", "reftest" ], + "css/css-flexbox-1/auto-margins-001-ref.html": [ + "dfc6fe046906c564110225d01572aa6aa1e40858", + "support" + ], + "css/css-flexbox-1/auto-margins-001.html": [ + "2c9ced81462c263bafbc1ebc6024529e26f23e95", + "reftest" + ], "css/css-flexbox-1/css-box-justify-content.html": [ "a3e68485221a64b4197da0ea9e4e56352406098f", "reftest" @@ -197736,7 +197946,7 @@ "reftest" ], "css/css-flexbox-1/negative-margins-001.html": [ - "f9f00cac79a95072abb682ac20ab040e61141d6d", + "b180f3d5054d7dea5c878cb1519c1ba48e2cbf7c", "reftest" ], "css/css-flexbox-1/order-001.htm": [ @@ -197771,6 +197981,46 @@ "5c3c576ee34a20e61e33a9851d332c743a9f078a", "testharness" ], + "css/css-flexbox-1/percentage-heights-002-ref.html": [ + "63dfc89a1635f0f283e7513c58ba225f44be5739", + "support" + ], + "css/css-flexbox-1/percentage-heights-002.html": [ + "1b41b57b585955953e6c5ae2bc3b0bfdd1e63cf9", + "reftest" + ], + "css/css-flexbox-1/percentage-widths-001-ref.html": [ + "a139951dbeb1676b7add9a43d154595dc2e9859b", + "support" + ], + "css/css-flexbox-1/percentage-widths-001.html": [ + "22e1681cfb553f1c1e5242f02319f22d75a12de4", + "reftest" + ], + "css/css-flexbox-1/position-absolute-001.html": [ + "bcf0ce321b9aca0fba213f677e9db92d595175fc", + "testharness" + ], + "css/css-flexbox-1/position-absolute-002.html": [ + "459087f00f8417a3345f0bfc25b6d66d44364a5f", + "testharness" + ], + "css/css-flexbox-1/position-absolute-003.html": [ + "25d21bf70a43936b159001b9a405e9df65e0f222", + "testharness" + ], + "css/css-flexbox-1/position-absolute-004.html": [ + "222c04822ec756d6f4f504ed507aa678c7960b75", + "testharness" + ], + "css/css-flexbox-1/position-absolute-005-ref.html": [ + "f1bcb4c179fb298384a33b2f9d9723544fef4459", + "support" + ], + "css/css-flexbox-1/position-absolute-005.html": [ + "438bbc49265086b53018e830694c1fbd3887bde3", + "reftest" + ], "css/css-flexbox-1/reference/Flexible-order-ref.html": [ "a6a2ef286c9c2abd0456056ad17cbb0ece7dc2d4", "support" @@ -198171,6 +198421,14 @@ "3c6673e9c9040b93d5a841a0368a95f57dbb553b", "visual" ], + "css/css-flexbox-1/whitespace-in-flexitem-001-ref.html": [ + "09714cc32e9189de91ac4644e2651d90b080a20e", + "support" + ], + "css/css-flexbox-1/whitespace-in-flexitem-001.html": [ + "62ff3e2eac64bb2057391e4dcc4664a4839bbbe8", + "reftest" + ], "css/css-grid-1/README.md": [ "f7a5738de1e8c4231afad100668cf18ba46a7b51", "support" @@ -218287,10 +218545,6 @@ "35ffc948502021b3367ae759b5f5ac362fd7acaa", "support" ], - "dom/events/EventListener-invoke-legacy-expected.txt": [ - "1f3f82bd8ce8c74e0ad975685ffcf6e009c27580", - "support" - ], "dom/events/EventListener-invoke-legacy.html": [ "e56b332acb454ab76964b78588536777946ddff8", "testharness" @@ -227875,6 +228129,14 @@ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "html/dom/interfaces-expected.txt": [ + "69c9f72c602a581ea237b6e3a69ad1e0d6da1e36", + "support" + ], + "html/dom/interfaces.html": [ + "4c0db96824033d94b98123954254930fb742d7e3", + "testharness" + ], "html/dom/interfaces.worker.js": [ "9e91d411453d4fdbcead08ad9daccbe2d9d7a975", "testharness" @@ -232743,14 +233005,6 @@ "699050ab3bcc8fc11d51c2ae4b9b10aee46876a5", "reftest" ], - "html/rendering/non-replaced-elements/tables/table-direction-ref.html": [ - "97b303c46c7afcc29e0c56856028409c34682baa", - "support" - ], - "html/rendering/non-replaced-elements/tables/table-direction.html": [ - "4c890c9b43bfec7a82a6abeee94d558db2b8f83e", - "reftest" - ], "html/rendering/non-replaced-elements/tables/table-layout-notref.html": [ "a05fad3c06f94c3a617f2efdc589bbb3f5525983", "support" @@ -232763,22 +233017,6 @@ "ec05c435cfd09291184360db7e8b0c5af9c7ba31", "reftest" ], - "html/rendering/non-replaced-elements/tables/table-row-direction-ref.html": [ - "5cf01204381d870738a7454080ea40904b2d0f0c", - "support" - ], - "html/rendering/non-replaced-elements/tables/table-row-direction.html": [ - "433565959474b716d385c2d98d0976ae2121d6d5", - "reftest" - ], - "html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html": [ - "23616d2840feaafbc6d06b1a1db18dd75d221a23", - "support" - ], - "html/rendering/non-replaced-elements/tables/table-row-group-direction.html": [ - "d4b5cf18545eb48780d9a9a9bfa62ded7dc076bc", - "reftest" - ], "html/rendering/non-replaced-elements/tables/table-vspace-hspace-s.html": [ "a93cbe26a0c5b9a7aeda1faf9db618f79aae8715", "testharness" @@ -239319,6 +239557,10 @@ "3fabcfa40caf9c66bc74bcd83663eddb0f385051", "support" ], + "interfaces/web-share.idl": [ + "0f43a814700a62e8f5ea54056ae901e1bdb3a610", + "support" + ], "interfaces/webrtc-pc.idl": [ "2e9e783362e8ea80cbad3c9c688d63b9c8256163", "support" @@ -241928,11 +242170,11 @@ "testharness" ], "navigation-timing/nav2_test_attributes_exist.html": [ - "9cbe8d9f7bf8c959c810ebee65a245f2de6f2943", + "6ed5a8f92b282d956d7d946cf031296ed7bfef50", "testharness" ], "navigation-timing/nav2_test_attributes_values.html": [ - "f13d01f6c6cfa90b2bd92312b3c2e1c1b3aeed59", + "400c53f8d907e4eb8c9854ba73437510126d9074", "testharness" ], "navigation-timing/nav2_test_document_open.html": [ @@ -249395,6 +249637,10 @@ "01c5b2e89c88d4145429e8860eaa88f728d0601b", "testharness" ], + "quirks-mode/classname-query-after-sibling-adoption.html": [ + "a9fd790c46562057d00b9a042f548d28259042d0", + "testharness" + ], "quirks-mode/hashless-hex-color.html": [ "161c0bfaabbfb59c426e855b9dcfa746ea9e8f95", "testharness" @@ -257060,7 +257306,7 @@ "support" ], "resource-timing/test_resource_timing-expected.txt": [ - "a77bf35e3c070c54ab8a7c1f0a1ceb5ce1d8bbc6", + "66cb6b2e80040b036b7923a3e7389f6f7016eadd", "support" ], "resource-timing/test_resource_timing.html": [ @@ -257851,8 +258097,12 @@ "96ffb6f3376a5fa73abd405e123d019d8cac694d", "testharness" ], + "service-workers/service-worker/claim-fetch.https-expected.txt": [ + "3e8688f2e8a82a93770a06f99fcece6d09e4e118", + "support" + ], "service-workers/service-worker/claim-fetch.https.html": [ - "adec77bbeec2ec9ea7da3aba94375bc92e1b4f6f", + "69100d1070d261e9819217fd7a6531f48b343e14", "testharness" ], "service-workers/service-worker/claim-not-using-registration.https.html": [ @@ -261668,7 +261918,7 @@ "testharness" ], "url/urlsearchparams-constructor-expected.txt": [ - "cbda1c074f16785092466e8656b7d972350d3f0a", + "01912a3a76126c02c16cff2ac2a641973938e2dc", "support" ], "url/urlsearchparams-constructor.html": [ @@ -261703,10 +261953,6 @@ "2a540fed628b86c8a59766a83c57fbb3e73dd620", "testharness" ], - "url/urlsearchparams-sort-expected.txt": [ - "3dfeef6d059ae4cd8e85de1c2c1cad4cbfad8f95", - "support" - ], "url/urlsearchparams-sort.html": [ "6a3904b5dada6b1e071b16529e75c6ce18ce45d6", "testharness" @@ -261868,83 +262114,83 @@ "support" ], "viewport/viewport-dimensions-custom-scrollbars-manual.html": [ - "34e5aa69477e51f2102eacb1295de1296eaf3662", + "ccef0829da2e4ebcad983235f97a6f3f767a0f51", "manual" ], "viewport/viewport-dimensions-scrollbars-manual.html": [ - "f6d7ef74f10b94ece1d3a7f0fc7573bf7672baca", + "465eb63a9f09880f98636502d4b3ee3b5e3ec794", "manual" ], "viewport/viewport-no-resize-event-on-overflow-recalc.html": [ - "9605e8e77cf652aa62c3730a3a5b4fa2f4e38011", + "f4d6cb3f76e4cf790875b3be90de821a279b3d82", "testharness" ], "viewport/viewport-offset-manual.html": [ - "f54fd0381984ca28532808d36e9c6806c3bfa09a", + "1d39d721a49e44d87583cb173cf0bba648fba352", "manual" ], "viewport/viewport-page-manual.html": [ - "4d0aabf3b0c75711d3978e9dec4d91f3f144755d", + "1431cc6a8495343697c01ef62d237c31a5850e99", "manual" ], "viewport/viewport-read-size-causes-layout.html": [ - "a5f89da7f731ad1627089dbd0df1ad292e53ccff", + "64a511ff2dd9c0381588b56b15fe1c82e0b1e07a", "testharness" ], "viewport/viewport-read-size-in-iframe-causes-layout.html": [ - "8bb04e31e5d5cb7e8ba152507b4b94471d38bfe8", + "8bf7b6c1a5721da2c1d1fc896d62a44893446a73", "testharness" ], "viewport/viewport-resize-event-manual.html": [ - "f3d9b990138377eaf0d7ccb0a5e3ff6b2a5bb3b1", + "38280c144ed74af990ebf9b65ad1d68052f93372", "manual" ], "viewport/viewport-resize-event-on-load-overflowing-page.html": [ - "906f44dee3be5931400b2b99dd8b4b4c3f6f6020", + "cd13682091b00c182e570a87eac642613a3c05c2", "testharness" ], "viewport/viewport-scale-iframe-manual.html": [ - "fe01308f32fe030aa4fcb442a3119bc40397cfcf", + "4ccf4a4bb7d13bc12afc6d9bbbc8072b460f87ec", "manual" ], "viewport/viewport-scale-manual.html": [ - "2350441e77ffb40ff0ace6ab565700eb605cbbbe", + "fd089f974778969d95cd7f6aa6389a6cf9dfb543", "manual" ], "viewport/viewport-scroll-event-manual.html": [ - "3119a8ede3338afe24583d3f79b6cba699ef0ad0", + "43e7031d3734a1c377e64d0f6a8247fef0782ceb", "manual" ], "viewport/viewport-scrollbars-cause-resize.html": [ - "b0a563926aedc95ce27182369b9921bea30b6ac6", + "a1017cff8faadfdcae008fd5f27e9c8e7c5383d3", "testharness" ], "viewport/viewport-type.html": [ - "f6c1ff74ac054612661a741ed63cc9e38c704b02", + "45334f4775607cd8547788e4107e81b03fad319f", "testharness" ], "viewport/viewport-unscaled-scale-iframe.html": [ - "9026a7bc429e19def5d082405a44e39a106652f2", + "d88c0bd1ce525137fb739182a35ae22bd6455c0f", "testharness" ], "viewport/viewport-unscaled-scale.html": [ - "68d25c2233a4e35bb6e0d24a07c39a3c23908e7b", + "eb5a1e32e015808651f008ebaaa785ec84d7a1f3", "testharness" ], "viewport/viewport-unscaled-scroll-iframe.html": [ - "f55662f1b5cbfc460014a13eabe470295555a98f", + "14e88914da4ce92b90cb191278aaa0a26e00ee7a", "testharness" ], "viewport/viewport-unscaled-scroll.html": [ - "9e5e473de8a4d0ff7cacf1b4f0fb8b45281a6285", + "12f4366f75a8fb078e1691c3ad091ea15a8561f9", "testharness" ], "viewport/viewport-unscaled-size-iframe.html": [ - "f2ab6df04eda125567a93c3221ba482cf2464875", + "937198c3bf9f26413c35e48f90b5b3b35e1c96a2", "testharness" ], "viewport/viewport-unscaled-size.html": [ - "ab196264ebd9d4deb1d7b510d5a08f4abf45fa5d", + "e92beb18c8adcf1f7d89cfa0512df46765440a5a", "testharness" ], "viewport/viewport_support.js": [ @@ -262096,7 +262342,7 @@ "testharness" ], "web-animations/interfaces/Animatable/animate-expected.txt": [ - "904c6eafbc17ff15068dd5c3e8ae569716d982dd", + "49ecf5fa20817e35b3dad88bebd86ee76bf82b84", "support" ], "web-animations/interfaces/Animatable/animate.html": [ @@ -262236,7 +262482,7 @@ "testharness" ], "web-animations/interfaces/Document/getAnimations-expected.txt": [ - "d386431895bce43f102ea90762ae1d10d9a5c508", + "6c83f6c96d17c800765ffee1ef0739f2955b6cad", "support" ], "web-animations/interfaces/Document/getAnimations.html": [ @@ -262455,6 +262701,86 @@ "83c52be8280bba314116ff1337028ea7835ddf43", "testharness" ], + "web-share/idlharness.https.html": [ + "17e370aefd324ffac6a6f4b0211fbaecd1781ad4", + "testharness" + ], + "web-share/resources/manual-helper.js": [ + "d3e545c3b6c0d10d904adc7595b9cb51de5ce9d2", + "support" + ], + "web-share/share-cancel-manual.html": [ + "b4dcc0ac05c2a14907d55058f7d51190842fe0d3", + "manual" + ], + "web-share/share-empty-manual.html": [ + "0a465dc66c930601d611ea3cfef0a271b6cc0b0a", + "manual" + ], + "web-share/share-extra-argument-manual.html": [ + "d0d2e67e49c16b874e5c5cbe4d1c6920b6b70a17", + "manual" + ], + "web-share/share-extra-field-manual.html": [ + "78fd9fb76a1760402c74f64250e9b26790451ebc", + "manual" + ], + "web-share/share-non-string-manual.html": [ + "32c960f32291cf120334f2099042b4c5d7caa56b", + "manual" + ], + "web-share/share-null-manual.html": [ + "d2866b0401cecafdb590e2b6f57d0b934e32160a", + "manual" + ], + "web-share/share-securecontext.http.html": [ + "6fd79e8f54c17f73406452e2a79c6eb3a45b4e41", + "testharness" + ], + "web-share/share-simple-manual.html": [ + "cfdd2d3d767a8bbfb888291cdd274852baca7093", + "manual" + ], + "web-share/share-unicode-strings-manual.html": [ + "bf6dcec872839af760c0a679eb503d36f0b3bb48", + "manual" + ], + "web-share/share-unicode-strings-nonutf8-manual.html": [ + "905b702262f0ace4e6e9958d67b18a1f71f691c6", + "manual" + ], + "web-share/share-url-data-manual.html": [ + "da8db7178175e818ab285c5efeb529e397ae42a8", + "manual" + ], + "web-share/share-url-empty-manual.html": [ + "7f45e7a4c7b2da28e292cde168623f53311893ae", + "manual" + ], + "web-share/share-url-encoding-manual.html": [ + "6c8790abb9dea90bff649ad9716c5eadf3fd9032", + "manual" + ], + "web-share/share-url-invalid.https.html": [ + "965504e6db948e198ce01448af04c5d9a3ba26f9", + "testharness" + ], + "web-share/share-url-noscheme-manual.html": [ + "d6457b424901d125a7aac579c3b1e2b4f9c8c851", + "manual" + ], + "web-share/share-url-pathonly-manual.html": [ + "cbdedbd4265fd27194f4d938c0c7462a707f241f", + "manual" + ], + "web-share/share-url-relative-manual.html": [ + "41dd5d1a50c21f9e77c6832b56195561ee29106f", + "manual" + ], + "web-share/share-without-user-gesture.https.html": [ + "aaa84c716125c6332b3a5c114a97d5986af38c37", + "testharness" + ], "webaudio/.gitignore": [ "11bc81247643b0a9fc665f1e4b1f592cc1f4c670", "support" @@ -263176,7 +263502,11 @@ "testharness" ], "webrtc/RTCPeerConnection-addIceCandidate.html": [ - "6ca52e2e6ec19dc38a7cc0a4ce132f7c5de9e398", + "811905bc5d380baac18b9ddc2bd96728ffac7597", + "testharness" + ], + "webrtc/RTCPeerConnection-addTrack.html": [ + "841320f0521a34d84ebd4dd8375e641a0d693c15", "testharness" ], "webrtc/RTCPeerConnection-addTransceiver-expected.txt": [ @@ -263184,7 +263514,7 @@ "support" ], "webrtc/RTCPeerConnection-addTransceiver.html": [ - "0ce85d1a83181d1bd0f337c7dbb5443efbda32cd", + "b4721c2afe4e50a9dc2c01a8f9f786029f6f81d2", "testharness" ], "webrtc/RTCPeerConnection-canTrickleIceCandidates-expected.txt": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/auto-margins-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/auto-margins-001-ref.html new file mode 100644 index 0000000..04f32f5d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/auto-margins-001-ref.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<style> + +#circles, #circles div { + border: 1em solid blue; + border-radius:50%; + margin: auto; +} + +#circles { width:9em; height:9em; } + +</style> +</head> +<body> +<p>These tests are from the spec: <a href="http://dev.w3.org/csswg/css3-flexbox/#auto-margins">http://dev.w3.org/csswg/css3-flexbox/#auto-margins</a>.</p> + +<p>The word OK should be centered vertically and horizontally.</p> +<div style="width: 4em; height: 4em; background: silver"> + <table style="width: 100%; height: 100%;"><tr><td style="text-align: center">OK</td></tr></table> +</div> + +<div style="width: 4em; height: 4em; margin-top: 10px; background: silver; writing-mode: vertical-rl"> + <table style="width: 100%; height: 100%;"><tr><td style="text-align: center">OK</td></tr></table> +</div> + +<p>You should see 3 blue concentric circles.</p> +<div id="circles"> + <div style="width: 5em; height: 5em; margin-top: 1em;"> + <div style="width: 1em; height: 1em; margin-top: 1em;"></div> + </div> +</div> + +<p>The computed style of each margin should not be 0.<br>OK: PASS<br>Vertical OK: PASS</p> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/auto-margins-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/auto-margins-001.html new file mode 100644 index 0000000..3a90ef2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/auto-margins-001.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> +<title>CSS Test: Aligning with auto margins</title> +<link href="support/flexbox.css" rel="stylesheet"> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#auto-margins"> +<link rel="match" href="auto-margins-001-ref.html"> +<meta name="flags" content=""> +<style> + +#circles, #circles div { + display: flex; + width: -webkit-calc(100% - 4em); + width: calc(100% - 4em); + height: -webkit-calc(100% - 4em); + height: calc(100% - 4em); + border: 1em solid blue; + border-radius:50%; + margin: auto; +} + +#circles { width:9em; height:9em; } + +</style> +</head> +<body> +<p>These tests are from the spec: <a href="http://dev.w3.org/csswg/css3-flexbox/#auto-margins">http://dev.w3.org/csswg/css3-flexbox/#auto-margins</a>.</p> + +<p>The word OK should be centered vertically and horizontally.</p> +<div class="flexbox" style="width: 4em; height: 4em; background: silver"> + <p id="ok" style="margin: auto;">OK</p> +</div> + +<div class="flexbox" style="width: 4em; height: 4em; margin-top: 10px; background: silver; writing-mode: vertical-rl"> + <p id="okVertical" style="margin: auto;">OK</p> +</div> + +<p>You should see 3 blue concentric circles.</p> +<div id="circles"><div><div></div></div></div> + +<p id="log">The computed style of each margin should not be 0.</p> +<script> +var okStyle = getComputedStyle(document.getElementById('ok')); +document.getElementById("log").innerHTML += "<br>OK: " + + ((parseInt(okStyle.marginTop) && parseInt(okStyle.marginRight) && parseInt(okStyle.marginBottom) && parseInt(okStyle.marginLeft)) ? "PASS" : "FAIL"); + +var okVerticalStyle = getComputedStyle(document.getElementById('okVertical')); +document.getElementById("log").innerHTML += "<br>Vertical OK: " + + ((parseInt(okVerticalStyle.marginTop) && parseInt(okVerticalStyle.marginRight) && parseInt(okVerticalStyle.marginBottom) && parseInt(okVerticalStyle.marginLeft)) ? "PASS" : "FAIL"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/negative-margins-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/negative-margins-001.html index 8546072..851c75fd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/negative-margins-001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/negative-margins-001.html
@@ -4,7 +4,8 @@ <link rel="author" title="Google Inc." href="https://www.google.com/"> <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#item-margins"> <link rel="match" href="reference/negative-margins-001-ref.html"> -<meta name="assert" content="Negative margins get floored at zero for intrinsic size computations"> +<meta name="assert" content="Tests that for intrinsic size computations, +an item will not take up less than zero space even with negative margins."> <style> .container { width: 60px;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-heights-002-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-heights-002-ref.html new file mode 100644 index 0000000..55ec381d2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-heights-002-ref.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<style> +body { + position: relative; + width: 800px; + height: 600px; +} + +#container { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +#top-bar { + background-color: green; + height: 100px; +} + +#content { + background-color: blue; + height: 500px; +} +</style> + + +<div id="container"> + <div id="top-bar"> + Tests that percentage heights get resolved correctly when the flexbox is + </div> + <div id="content"> + absolutely positioned without an explicit height. You should see no red. + </div> +</div> + +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-heights-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-heights-002.html new file mode 100644 index 0000000..cfdf5be --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-heights-002.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<title>CSS Test: Percentage sizing in flexboxes</title> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#definite-sizes"> +<link rel="match" href="percentage-heights-002-ref.html"> +<meta name="assert" content="Checks that we correctly size percentage-sized +children of absolute-positioned flex boxes"> +<style> +body { + position: relative; + width: 800px; + height: 600px; +} + +#container { + background-color: red; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; +} + +#top-bar { + background-color: green; + height: 20%; +} + +#content { + background-color: blue; + flex-basis: 100%; +} +</style> + + +<div id="container"> + <div id="top-bar"> + Tests that percentage heights get resolved correctly when the flexbox is + </div> + <div id="content"> + absolutely positioned without an explicit height. You should see no red. + </div> +</div> + +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-widths-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-widths-001-ref.html new file mode 100644 index 0000000..ca0c4d9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-widths-001-ref.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<style> +body { + position: relative; + width: 600px; + height: 800px; +} + +#container { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; +} + +#top-bar { + background-color: green; + width: 100px; +} + +#content { + background-color: blue; + width: 500px; +} +</style> + + +<div id="container"> + <div id="top-bar"> + Tests that percentage widths get resolved correctly when the flexbox is + </div> + <div id="content"> + absolutely positioned without an explicit width. You should see no red. + </div> +</div> + +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-widths-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-widths-001.html new file mode 100644 index 0000000..b1b5acff --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/percentage-widths-001.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<title>CSS Test: Absolutely positioned children of flexboxes</title> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#definite-sizes"> +<link rel="match" href="percentage-widths-001-ref.html"> +<meta name="assert" content="Checks that we correctly size percentage-sized +children of absolute-positioned flex boxes"> +<style> +body { + position: relative; + width: 600px; + height: 800px; +} + +#container { + background-color: red; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: row; +} + +#top-bar { + background-color: green; + width: 20%; +} + +#content { + background-color: blue; + flex-basis: 100%; +} +</style> + + +<div id="container"> + <div id="top-bar"> + Tests that percentage widths get resolved correctly when the flexbox is + </div> + <div id="content"> + absolutely positioned without an explicit width. You should see no red. + </div> +</div> + +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-001.html new file mode 100644 index 0000000..d3d8089 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-001.html
@@ -0,0 +1,709 @@ +<!DOCTYPE html> +<html> +<title>CSS Test: Absolutely positioned children of flexboxes</title> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items"> +<meta name="flags" content="dom"> +<meta name="assert" content="Checks that we correctly position abspos children +in a number of writing modes and alignments"> +<style> +body { + margin: 0; +} + +.title { + margin-top: 1em; +} + +.flexbox { + display: flex; + background-color: #aaa; + position: relative; +} +.flexbox div { + border: 0; + flex: none; +} + +.horizontal-tb { + writing-mode: horizontal-tb; +} +.vertical-rl { + writing-mode: vertical-rl; +} +.vertical-lr { + writing-mode: vertical-lr; +} + +.row { + flex-flow: row; +} +.row-reverse { + flex-flow: row-reverse; +} +.column { + flex-flow: column; +} +.column-reverse { + flex-flow: column-reverse; +} + +.flexbox :nth-child(1) { + background-color: blue; +} +.flexbox :nth-child(2) { + background-color: green; +} + +.rtl { + direction: rtl; +} +.ltr { + direction: ltr; +} + +.justify-content-flex-start { + justify-content: flex-start; +} +.justify-content-flex-end { + justify-content: flex-end; +} +.justify-content-center { + justify-content: center; +} +.justify-content-space-between { + justify-content: space-between; +} +.justify-content-space-around { + justify-content: space-around; +} +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/check-layout-th.js"></script> +<body onload="checkLayout('.flexbox')"> +<div id=log></div> +<script> +// Each flexbox has two abspos children - one is 40x10, the other 10x20. +// The flexbox itself is 80x20. +// All that is flipped for vertical flows. +var expectations = { + 'horizontal-tb': { + 'row': { + 'ltr': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + }, + 'column': { + 'ltr': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'center': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'center': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + }, + }, + 'row-reverse': { + 'ltr': { + 'flex-start': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + }, + 'column-reverse': { + 'ltr': { + 'flex-start': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'space-around': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'flex-end': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'space-around': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + }, + }, + }, + 'vertical-rl': { + 'row': { + 'ltr': { + 'flex-start': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'center': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'flex-end': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'space-around': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + }, + }, + 'column': { + 'ltr': { + 'flex-start': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [40, 10], + 'child2': [70, 0], + }, + 'flex-end': { + 'child1': [0, 10], + 'child2': [0, 0], + }, + 'center': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [40, 10], + 'child2': [70, 0], + }, + 'space-around': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + }, + }, + 'row-reverse': { + 'ltr': { + 'flex-start': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'flex-end': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'space-around': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [10, 40], + 'child2': [0, 70], + }, + 'center': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [10, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [10, 20], + 'child2': [0, 35], + }, + }, + }, + 'column-reverse': { + 'ltr': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [0, 10], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [40, 10], + 'child2': [70, 0], + }, + 'center': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [0, 10], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + }, + }, + }, + 'vertical-lr': { + 'row': { + 'ltr': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'center': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'space-around': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + }, + }, + 'column': { + 'ltr': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [0, 10], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [40, 10], + 'child2': [70, 0], + }, + 'center': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [0, 10], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + }, + }, + 'row-reverse': { + 'ltr': { + 'flex-start': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'space-around': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'flex-end': { + 'child1': [0, 40], + 'child2': [0, 70], + }, + 'center': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + 'space-between': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'space-around': { + 'child1': [0, 20], + 'child2': [0, 35], + }, + }, + }, + 'column-reverse': { + 'ltr': { + 'flex-start': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'flex-end': { + 'child1': [0, 0], + 'child2': [0, 0], + }, + 'center': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [40, 0], + 'child2': [70, 0], + }, + 'space-around': { + 'child1': [20, 0], + 'child2': [35, 0], + }, + }, + 'rtl': { + 'flex-start': { + 'child1': [40, 10], + 'child2': [70, 0], + }, + 'flex-end': { + 'child1': [0, 10], + 'child2': [0, 0], + }, + 'center': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + 'space-between': { + 'child1': [40, 10], + 'child2': [70, 0], + }, + 'space-around': { + 'child1': [20, 10], + 'child2': [35, 0], + }, + }, + }, + }, +}; + +var writingModes = ['horizontal-tb', 'vertical-rl', 'vertical-lr']; +var flexDirections = ['row', 'column', 'row-reverse', 'column-reverse']; +var directions = ['ltr', 'rtl']; +var justifyContents = ['flex-start', 'flex-end', 'center', 'space-between', 'space-around']; + +function mainAxisDirection(writingMode, flexDirection) +{ + if ((writingMode.indexOf('horizontal') != -1 && flexDirection.indexOf('row') != -1) + || (writingMode.indexOf('vertical') != -1 && flexDirection.indexOf('column') != -1)) + return 'width'; + return 'height'; +} + +function addChild(flexbox, mainAxis, crossAxis, mainAxisLength, crossAxisLength, expectations) +{ + var child = document.createElement('div'); + child.setAttribute('style', mainAxis + ': ' + mainAxisLength + 'px;' + + crossAxis + ': ' + crossAxisLength + 'px; position: absolute;'); + + child.setAttribute("data-expected-" + mainAxis, mainAxisLength); + child.setAttribute("data-expected-" + crossAxis, crossAxisLength); + child.setAttribute("data-offset-x", expectations[0]); + child.setAttribute("data-offset-y", expectations[1]); + + flexbox.appendChild(child); +} + +writingModes.forEach(function(writingMode) { + flexDirections.forEach(function(flexDirection) { + directions.forEach(function(direction) { + justifyContents.forEach(function(justifyContent) { + var flexboxClassName = writingMode + ' ' + direction + ' ' + flexDirection + ' justify-content-' + justifyContent; + var title = document.createElement('div'); + title.className = 'title'; + title.innerHTML = flexboxClassName; + document.body.appendChild(title); + + var mainAxis = mainAxisDirection(writingMode, flexDirection); + var crossAxis = (mainAxis == 'width') ? 'height' : 'width'; + + var flexbox = document.createElement('div'); + flexbox.className = 'flexbox ' + flexboxClassName; + flexbox.setAttribute('style', mainAxis + ': 80px;' + crossAxis + ': 20px'); + + var baselineMargin = (flexDirection.indexOf('row') != -1) ? '-webkit-margin-before: 5px' : '-webkit-margin-start: 5px'; + + var testExpectations = expectations[writingMode][flexDirection][direction][justifyContent]; + addChild(flexbox, mainAxis, crossAxis, 40, 10, testExpectations['child1']); + addChild(flexbox, mainAxis, crossAxis, 10, 20, testExpectations['child2']); + + document.body.appendChild(flexbox); + }) + }) + }) +}) + +</script> + +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-002.html new file mode 100644 index 0000000..bf69765 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-002.html
@@ -0,0 +1,160 @@ +<!DOCTYPE html> +<html> +<title>CSS Test: Absolutely positioned children of flexboxes</title> +<link href="support/flexbox.css" rel="stylesheet"> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items"> +<meta name="flags" content="dom"> +<meta name="assert" content="Checks that we correctly position abspos children +with different alignments and dynamic changes"> +<style> +body { + margin: 0; +} +.flexbox { + background-color: green; + height: 100px; + width: 100px; + margin: 10px; +} +.flexbox > * { + flex: none; +} +.relative { + position: relative; +} +.flexbox > div { + width: 20px; + height: 20px; +} +.absolute { + position: absolute; +} +#placed-absolute { + top: 20px; + left: 20px; +} + +.rtl { + direction: rtl; +} +.ltr { + direction: ltr; +} + +.flexbox :nth-child(1) { + background-color: blue; +} +.flexbox :nth-child(2) { + background-color: yellow; +} +.flexbox :nth-child(3) { + background-color: salmon; +} +.flexbox :nth-child(4) { + background-color: grey; +} +.flexbox :nth-child(5) { + background-color: red; +} +.flexbox :nth-child(6) { + background-color: orange; +} +.flexbox :nth-child(7) { + background-color: purple; +} +</style> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/check-layout-th.js"></script> + +<body onload="checkLayout('.flexbox')"> +<div id=log></div> + +<div class='flexbox relative align-items-center'> + <div id='placed-absolute' class='absolute' data-offset-x=20 data-offset-y=20></div> +</div> + +<div class='flexbox relative align-items-center'> + <div data-offset-x=0 data-offset-y=40></div> + <div class='absolute' data-offset-x=0 data-offset-y=40></div> + <div data-offset-x=20 data-offset-y=40></div> + <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div> +</div> + +<div class="relative"> +<div class='flexbox align-items-center'> + <div data-offset-x=10 data-offset-y=40></div> + <div class='absolute' data-offset-x=10 data-offset-y=40></div> + <div data-offset-x=30 data-offset-y=40></div> + <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div> +</div> +</div> + +<div class='flexbox relative column rtl'> + <div data-offset-x=80 data-offset-y=0></div> + <div class='absolute' data-offset-x=80 data-offset-y=0></div> + <div data-offset-x=80 data-offset-y=20></div> + <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div> +</div> + +<div class="relative"> +<div class='flexbox wrap-reverse'> + <div style="width:90px" data-offset-x=10 data-offset-y=80></div> + <div class="absolute" data-offset-x=10 data-offset-y=80></div> + <div data-offset-x=10 data-offset-y=30></div> + <div class="absolute" data-offset-x=10 data-offset-y=80></div> + <div data-offset-x=30 data-offset-y=30></div> + <div class="absolute" data-offset-x=10 data-offset-y=80></div> + <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div> +</div> +</div> + +<div class='flexbox relative'> + <div style="margin: auto;" data-offset-x=40 data-offset-y=40></div> + <div class="absolute" style="margin: auto;" data-offset-x=0 data-offset-y=0></div> + <div class="absolute" style="margin: auto;" data-offset-x=0 data-offset-y=0></div> + <div class="absolute" style="margin: auto; top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div> +</div> + +<div class='flexbox align-items-stretch relative'> + <div style="height: auto" data-offset-x=0 data-offset-y=0 data-expected-height=100></div> + <div class="absolute" style="height: auto" data-offset-x=0 data-offset-y=0 data-expected-height=0></div> + <div class="absolute" style="height: auto; top: 5px; left: 5px" data-offset-x=5 data-offset-y=5 data-expected-height=0></div> +</div> + +<div class="flexbox wrap relative"> + <div style="width: 100px;" data-offset-x=0 data-offset-y=0></div> + <div class="absolute" data-offset-x=0 data-offset-y=0></div> + <div style="width: 50px;" data-offset-x=0 data-offset-y=50></div> + <div class="absolute" data-offset-x=0 data-offset-y=0></div> + <div style="width: 50px;" data-offset-x=50 data-offset-y=50></div> + <div class="absolute" data-offset-x=0 data-offset-y=0></div> +</div> + +<div class="flexbox wrap relative align-items-flex-end"> + <div style="width: 100px;" data-offset-x=0 data-offset-y=30></div> + <div class="absolute" data-offset-x=0 data-offset-y=80></div> + <div style="width: 50px;" data-offset-x=0 data-offset-y=80></div> + <div class="absolute" data-offset-x=0 data-offset-y=80></div> + <div style="width: 50px;" data-offset-x=50 data-offset-y=80></div> + <div class="absolute" data-offset-x=0 data-offset-y=80></div> +</div> + + +<script> +var absolute = document.getElementById('placed-absolute'); +var beforePosition = absolute.getBoundingClientRect(); +document.querySelector('.flexbox').style.height = '101px'; +var afterPosition = absolute.getBoundingClientRect(); + +// Positioned element should not change position when the height of it's parent flexbox is changed. +for (key in beforePosition) { + test(function() { + assert_equals(beforePosition[key], afterPosition[key]); + }, 'position of ' + key); +} +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-003.html new file mode 100644 index 0000000..025aef6f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-003.html
@@ -0,0 +1,96 @@ +<!DOCTYPE html> +<title>CSS Test: Absolutely positioned children of flexboxes</title> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items"> +<meta name="flags" content="dom"> +<meta name="assert" content="Checks that we correctly handle border and +padding in combination with abspos items"> +<style> +.rect { + position: absolute; + width: 50px; + height: 50px; + background-color: green; +} + +.flexbox { + position: relative; + width: 100px; + height: 100px; + outline: 3px solid black; +} +</style> + +<link rel="stylesheet" href="support/flexbox.css"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/check-layout-th.js"></script> + +<body onload="checkLayout('.rect')"> +<div id=log></div> + +<div class="flexbox" style="padding-top: 10px; padding-left: 20px;"> + <div class="rect" data-offset-x="20" data-offset-y="10"></div> +</div> + +<div class="flexbox column" style="padding-top: 10px; padding-left: 20px;"> + <div class="rect" data-offset-x="20" data-offset-y="10"></div> +</div> + +<div class="flexbox" style="writing-mode: vertical-lr; padding-top: 10px; padding-left: 20px;"> + <div class="rect" data-offset-x="20" data-offset-y="10"></div> +</div> + +<div class="flexbox column" style="writing-mode: vertical-lr; padding-top: 10px; padding-left: 20px;"> + <div class="rect" data-offset-x="20" data-offset-y="10"></div> +</div> + +<div class="flexbox" style="direction: rtl; padding-top: 10px; padding-right: 20px;"> + <div class="rect" data-offset-x="50" data-offset-y="10"></div> +</div> + +<div class="flexbox column" style="direction: rtl; padding-top: 10px; padding-right: 20px;"> + <div class="rect" data-offset-x="50" data-offset-y="10"></div> +</div> + +<div class="flexbox" style="direction: rtl; writing-mode: vertical-lr; padding-bottom: 10px; padding-left: 20px;"> + <div class="rect" data-offset-x="20" data-offset-y="50"></div> +</div> + +<div class="flexbox column" style="direction: rtl; writing-mode: vertical-lr; padding-bottom: 10px; padding-left: 20px;"> + <div class="rect" data-offset-x="20" data-offset-y="50"></div> +</div> + +<hr> +<div class="flexbox" style="border-top: 10px solid; border-left: 20px solid;"> + <div class="rect" data-offset-x="0" data-offset-y="0"></div> +</div> + +<div class="flexbox column" style="border-top: 10px solid; border-left: 20px solid;"> + <div class="rect" data-offset-x="0" data-offset-y="0"></div> +</div> + +<div class="flexbox" style="writing-mode: vertical-lr; border-top: 10px solid; border-left: 20px solid;"> + <div class="rect" data-offset-x="0" data-offset-y="0"></div> +</div> + +<div class="flexbox column" style="writing-mode: vertical-lr; border-top: 10px solid; border-left: 20px solid;"> + <div class="rect" data-offset-x="0" data-offset-y="0"></div> +</div> + +<div class="flexbox" style="direction: rtl; border-top: 10px solid; border-right: 20px solid;"> + <div class="rect" data-offset-x="50" data-offset-y="0"></div> +</div> + +<div class="flexbox column" style="direction: rtl; border-top: 10px solid; border-right: 20px solid;"> + <div class="rect" data-offset-x="50" data-offset-y="0"></div> +</div> + +<div class="flexbox" style="direction: rtl; writing-mode: vertical-lr; border-bottom: 10px solid; border-left: 20px solid;"> + <div class="rect" data-offset-x="0" data-offset-y="50"></div> +</div> + +<div class="flexbox column" style="direction: rtl; writing-mode: vertical-lr; border-bottom: 10px solid; border-left: 20px solid;"> + <div class="rect" data-offset-x="0" data-offset-y="50"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-004.html new file mode 100644 index 0000000..ff14f35b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-004.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<title>CSS Test: Absolutely positioned children of flexboxes</title> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items"> +<meta name="flags" content="dom"> +<meta name="assert" content="Checks that we correctly handle when a flex item +becomes absolutely positioned"> +<style> +#flex { + display: flex; + position: relative; + background: red; + width: 500px; + height: 200px; +} + +#item { + background: green; + left: 0; + right: 0; + top: 0; + bottom: 0; +} +</style> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/check-layout-th.js"></script> + +<script> +function update() { + var item = document.getElementById("item"); + item.offsetHeight; + item.style.position = "absolute"; + item.offsetHeight; + checkLayout("#flex"); +} +</script> + +<body onload="update();"> + +<div id="flex"> + <div id="item" data-expected-width="500"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-005-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-005-ref.html new file mode 100644 index 0000000..2f7e669 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-005-ref.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<p>This test should not have a horizontal scrollbar</p> + +<div style="width: 400px; height: 100px; overflow-x: hidden; overflow-y: scroll;"> +<br> +<br> +<br> +<br> +<br> +<br> +<br> +<br> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-005.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-005.html new file mode 100644 index 0000000..3199dfb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/position-absolute-005.html
@@ -0,0 +1,66 @@ +<!DOCTYPE html> +<title>CSS Test: Absolutely positioned children of flexboxes</title> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items"> +<link rel="match" href="position-absolute-005-ref.html"> +<meta name="assert" content="Checks that we correctly handle overflow: auto in +abspos nodes in flexbox"> + +<style> + body { + width: 400px; + height: 300px; + } + + .flexbox { + display: flex; + } + + .column { + flex-direction: column; + } + + .flex11a { + flex: 1 1 auto; + } + + .root { + height: 100px; + overflow-y: auto; + position: relative; + } + + #abspos { + position: absolute; + left: 0; + right: 0; + top: 0; + height: 10px; + } +</style> + + +<p>This test should not have a horizontal scrollbar</p> + +<div class="flexbox column"> + <div class="flexbox"> + <div class="flex11a"> + <div class="root"> + <div> + <div> + <div id="history"></div> + <div id="abspos"></div> + </div> + </div> + </div> + </div> + </div> +</div> + +<script> +onload = function() { + var historyEl = document.getElementById('history'); + historyEl.offsetWidth; + historyEl.innerText = '\n\n\n\n\n\n\n\n'; +}; +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/whitespace-in-flexitem-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/whitespace-in-flexitem-001-ref.html new file mode 100644 index 0000000..f7ab7ba --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/whitespace-in-flexitem-001-ref.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<link href="support/flexbox.css" rel="stylesheet"> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<style> + .a { + flex: none; + width: 30px; + background: salmon; + } +</style> +<body> + <div class="flexbox justify-content-space-around"> + <div class="a"></div> + </div> + + <div class="flexbox"> + <b>foo</b><b>bar</b> + </div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/whitespace-in-flexitem-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/whitespace-in-flexitem-001.html new file mode 100644 index 0000000..bec931a4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox-1/whitespace-in-flexitem-001.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<title>CSS Test: Whitespace-only nodes in Flexboxes</title> +<link href="support/flexbox.css" rel="stylesheet"> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#flex-items"> +<link rel="match" href="whitespace-in-flexitem-001-ref.html"> +<meta name="flags" content=""> +<meta name="assert" content="Whitespace-only nodes in a flexbox should not +be rendered and not influence justify-content, even in the presence of +white-space: pre"> +<style> + .flexbox { white-space: pre; } + .a { + flex: none; + width: 30px; + background: salmon; + } +</style> +<body> + <div class="flexbox justify-content-space-around"> + <div class="a"></div> 	 + </div> + + <div class="flexbox"> + <b>foo</b> <b>bar</b> + </div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/credentials.sub.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/credentials.sub.html new file mode 100644 index 0000000..1293d7f6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/credentials.sub.html
@@ -0,0 +1,71 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> + +<script type="text/javascript"> +host_info = get_host_info(); + +document.cookie = 'same=1'; + +const setCookiePromise = fetch( + 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=cross&path=/html/semantics/scripting-1/the-script-element/module/', + { + mode: 'no-cors', + credentials: 'include', + }); + +const windowLoadPromise = new Promise(resolve => { + window.addEventListener('load', () => { + resolve(); + }); +}); + +promise_test(t => { + const iframe = document.createElement('iframe'); + + return Promise.all([setCookiePromise, windowLoadPromise]).then(() => { + const messagePromise = new Promise(resolve => { + window.addEventListener('message', event => { + resolve(); + }); + }); + + iframe.src = 'resources/credentials-iframe.sub.html'; + document.body.appendChild(iframe); + + return messagePromise; + }).then(() => { + const w = iframe.contentWindow; + + assert_equals(w.sameOriginNone, 'not found', + 'Modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is same-origin'); + assert_equals(w.sameOriginAnonymous, 'found', + 'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin'); + assert_equals(w.sameOriginUseCredentials, 'found', + 'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin'); + assert_equals(w.crossOriginNone, 'not found', + 'Modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is cross-origin'); + assert_equals(w.crossOriginAnonymous, 'not found', + 'Modules should be loaded without the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin'); + assert_equals(w.crossOriginUseCredentials, 'found', + 'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin'); + + assert_equals(w.sameOriginNoneDecendent, 'not found', + 'Decendent modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is same-origin'); + assert_equals(w.sameOriginAnonymousDecendent, 'found', + 'Decendent modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin'); + assert_equals(w.sameOriginUseCredentialsDecendent, 'found', + 'Decendent modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin'); + assert_equals(w.crossOriginNoneDecendent, 'not found', + 'Decendent modules should be loaded without the credentials when the crossOrigin attribute is not specified and the target is cross-origin'); + assert_equals(w.crossOriginAnonymousDecendent, 'not found', + 'Decendent modules should be loaded without the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin'); + assert_equals(w.crossOriginUseCredentialsDecendent, 'found', + 'Decendent modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin'); +}); +}, 'Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute'); +</script> +<body> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py new file mode 100644 index 0000000..cf6f72f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py
@@ -0,0 +1,20 @@ +def main(request, response): + headers = [ + ("Content-Type", "text/javascript"), + ("Access-Control-Allow-Origin", request.headers.get("Origin")), + ("Access-Control-Allow-Credentials", "true") + ] + identifier = request.GET.first("id") + cookie_name = request.GET.first("cookieName") + cookie = request.cookies.first(cookie_name, None) + if identifier is None or cookie_name is None: + return headers, "" + + if cookie is None: + result = "not found" + elif cookie.value == "1": + result = "found" + else: + result = "different value: " + cookie.value + + return headers, "window." + identifier + " = '" + result + "';"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html new file mode 100644 index 0000000..f086e70 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html
@@ -0,0 +1,50 @@ +<!DOCTYPE html> +<meta charset="utf-8"> + +<script type="module" + src="check-cookie.py?id=sameOriginNone&cookieName=same"> +</script> +<script type="module" + src="check-cookie.py?id=sameOriginAnonymous&cookieName=same" + crossOrigin="anonymous"> +</script> +<script type="module" + src="check-cookie.py?id=sameOriginUseCredentials&cookieName=same" + crossOrigin="use-credentials"> +</script> +<script type="module" + src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNone&cookieName=cross"> +</script> +<script type="module" + src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymous&cookieName=cross" + crossOrigin="anonymous"> +</script> +<script type="module" + src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentials&cookieName=cross" + crossOrigin="use-credentials"> +</script> + +<script type="module"> +import "./check-cookie.py?id=sameOriginNoneDecendent&cookieName=same"; +</script> +<script type="module" crossOrigin="anonymous"> +import "./check-cookie.py?id=sameOriginAnonymousDecendent&cookieName=same"; +</script> +<script type="module" crossOrigin="use-credentials"> +import "./check-cookie.py?id=sameOriginUseCredentialsDecendent&cookieName=same"; +</script> +<script type="module"> +import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNoneDecendent&cookieName=cross"; +</script> +<script type="module" crossOrigin="anonymous"> +import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymousDecendent&cookieName=cross"; +</script> +<script type="module" crossOrigin="use-credentials"> +import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentialsDecendent&cookieName=cross"; +</script> + +<script type="text/javascript"> +window.addEventListener('load', event => { + window.parent.postMessage({}, '*'); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-share.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-share.idl new file mode 100644 index 0000000..df0bd88 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-share.idl
@@ -0,0 +1,12 @@ +// https://wicg.github.io/web-share/ + +partial interface Navigator { + [SecureContext] + Promise<void> share(ShareData data); +}; + +dictionary ShareData { + USVString title; + USVString text; + USVString url; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/quirks-mode/classname-query-after-sibling-adoption.html b/third_party/WebKit/LayoutTests/external/wpt/quirks-mode/classname-query-after-sibling-adoption.html new file mode 100644 index 0000000..0fcad36 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/quirks-mode/classname-query-after-sibling-adoption.html
@@ -0,0 +1,32 @@ +<!-- quirks mode --> +<html> + <head> + <title>Quirks mode elements with class names should remain queriable regardless of sibling adoption into standards mode documents</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <div> + <button class="Foo"></button> + <button class="Foo"></button> + </div> + <template><div class="Bar"></div></template> + <script> + test(function () { + var templateDocument = document.querySelector("template").content.ownerDocument; + assert_equals(templateDocument.compatMode, "CSS1Compat"); + assert_equals(document.compatMode, "BackCompat"); + var container = document.querySelector("div"); + var button1 = container.querySelector(".foo"); + assert_true(button1 instanceof Element); + templateDocument.appendChild(button1); + assert_true(templateDocument.querySelector(".Foo") instanceof Element); + assert_false(templateDocument.querySelector(".foo") instanceof Element); + var button2byHierarchy = container.firstElementChild; + var button2bySelector = container.querySelector(".foo"); + assert_true(button2bySelector instanceof Element); + assert_equals(button2bySelector, button2byHierarchy); + }); + </script> + </body> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https-expected.txt deleted file mode 100644 index f6a2141..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL fetch() should be intercepted after the client is claimed. promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'appendChild' of null" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https.html index ddb7428..050c1ea 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/claim-fetch.https.html
@@ -4,11 +4,12 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="resources/test-helpers.sub.js"></script> +<body> <script> promise_test(function(t) { var frame; - var resource = 'resources/simple.txt'; + var resource = 'simple.txt'; var worker; var scope = 'resources/'; @@ -65,3 +66,4 @@ }, 'fetch() should be intercepted after the client is claimed.') </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.html new file mode 100644 index 0000000..f68e51e5e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare IDL test</title> + <link rel="help" href="https://wicg.github.io/web-share/"> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/resources/WebIDLParser.js></script> + <script src=/resources/idlharness.js></script> + </head> + <body> + <script> + "use strict"; + var idl_array = new IdlArray(); + + function doTest(idl) { + idl_array.add_untested_idls('interface Navigator {};'); + idl_array.add_idls(idl); + idl_array.add_objects({ + Navigator: ['navigator'] + }); + idl_array.test(); + } + + promise_test(async () => { + const response = await fetch('../interfaces/web-share.idl'); + doTest(await response.text()); + }, 'Test driver'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/resources/manual-helper.js b/third_party/WebKit/LayoutTests/external/wpt/web-share/resources/manual-helper.js new file mode 100644 index 0000000..2c38eab3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/resources/manual-helper.js
@@ -0,0 +1,78 @@ +// Internal function. Returns [instruction, list] DOM elements. +function setupManualShareTestCommon() { + const div = document.createElement('div'); + document.body.appendChild(div); + + const instruction = document.createElement('div'); + instruction.id = 'instruction'; + div.appendChild(instruction); + + const shareButton = document.createElement('input'); + shareButton.id = 'share_button'; + shareButton.value = 'Share button'; + shareButton.type = 'button'; + div.appendChild(shareButton); + + let heading = document.createElement('h2'); + heading.innerText = 'Instructions:'; + instruction.appendChild(heading); + let list = document.createElement('ol'); + instruction.appendChild(list); + let item = document.createElement('li'); + list.appendChild(item); + item.innerText = 'Click the Share button.'; + + return [instruction, list]; +} + +// Sets up the page for running manual tests. Automatically creates the +// instructions (based on the parameters) and the share button. +function setupManualShareTest(expected_share_data) { + const {title, text, url} = expected_share_data; + let [instruction, list] = setupManualShareTestCommon(); + let item = document.createElement('li'); + list.appendChild(item); + item.innerText = 'Choose a valid share target.'; + + heading = document.createElement('h2'); + heading.innerText = 'Pass the test iff the target app received:'; + instruction.appendChild(heading); + + list = document.createElement('ul'); + instruction.appendChild(list); + + item = document.createElement('li'); + list.appendChild(item); + item.innerText = `title = "${title}"`; + item = document.createElement('li'); + list.appendChild(item); + item.innerText = `text = "${text}"`; + item = document.createElement('li'); + list.appendChild(item); + item.innerText = `url = "${url}"`; +} + +function setupManualShareTestRequiringCancellation() { + const [instruction, list] = setupManualShareTestCommon(); + const item = document.createElement('li'); + list.appendChild(item); + item.innerText = 'Cancel the share dialog.'; +} + +// Returns a promise. When the user clicks the button, calls +// |click_handler| and resolves the promise with the result. +function callWhenButtonClicked(click_handler) { + return new Promise((resolve, reject) => { + document.querySelector('#share_button').onclick = () => { + try { + resolve(click_handler()); + } catch (e) { + reject(e); + } + }; + }); +} + +function getAbsoluteUrl(url) { + return new URL(url, document.baseURI).toString(); +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-cancel-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-cancel-manual.html new file mode 100644 index 0000000..b523fb5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-cancel-manual.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share cancelled by user</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + setupManualShareTestRequiringCancellation(); + + promise_test(t => { + return callWhenButtonClicked(() => promise_rejects( + t, 'AbortError', + navigator.share({title: 'the title', text: 'the message', + url: 'data:the url'}))); + }, 'share with user cancellation'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-empty-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-empty-manual.html new file mode 100644 index 0000000..63b2d4d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-empty-manual.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with empty ShareData</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + setupManualShareTest({title: '', text: '', url: ''}); + callWhenButtonClicked(() => navigator.share({})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-extra-argument-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-extra-argument-manual.html new file mode 100644 index 0000000..29e7a564 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-extra-argument-manual.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Surplus arguments ignored</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + setupManualShareTest( + {title: 'the title', text: 'the message', url: 'data:the url'}); + callWhenButtonClicked(() => navigator.share( + {title: 'the title', text: 'the message', url: 'data:the url'}, + 'more than required')); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-extra-field-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-extra-field-manual.html new file mode 100644 index 0000000..d601c7df --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-extra-field-manual.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Surplus fields ignored</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + setupManualShareTest( + {title: 'the title', text: 'the message', url: 'data:the url'}); + callWhenButtonClicked(() => navigator.share( + {title: 'the title', text: 'the message', url: 'data:the url', + unused: 'unexpected field'})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-non-string-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-non-string-manual.html new file mode 100644 index 0000000..b70f8fc2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-non-string-manual.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share non-string types (test implicit conversion)</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + // Expect that each of the non-string values is converted into a string. + setupManualShareTest( + {title: 'true', text: 'the object', url: getAbsoluteUrl('384957')}); + + const objectWithToString = {toString() { return 'the object'; }}; + callWhenButtonClicked(() => navigator.share( + {title: true, text: objectWithToString, url: 384957})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-null-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-null-manual.html new file mode 100644 index 0000000..4c74225 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-null-manual.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share null and undefined values</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + // Expect null to be converted into the string 'null'. On the other + // hand, undefined should be equivalent to omitting the attribute. + setupManualShareTest( + {title: 'null', text: '', url: getAbsoluteUrl('null')}); + callWhenButtonClicked(() => navigator.share( + {title: null, text: undefined, url: null})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-securecontext.http.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-securecontext.http.html new file mode 100644 index 0000000..8139c41 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-securecontext.http.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share from non-secure context</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <script> + test(() => { + assert_false('share' in navigator, 'navigator has attribute \'share\'.'); + }, 'navigator.share must be undefined in non-secure context'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-simple-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-simple-manual.html new file mode 100644 index 0000000..d88beda8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-simple-manual.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Simple share</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + const url = 'https://www.example.com/some/path?some_query#some_fragment'; + setupManualShareTest({title: 'the title', text: 'the message', url}); + callWhenButtonClicked(() => navigator.share( + {title: 'the title', text: 'the message', url})).then( + result => { + // Check that promise resolved with undefined. This is guarded + // by an if statement because we do not want it to register as a + // test if it passes (since this is a manual test). + if (result !== undefined) { + assert_equals(result, undefined); + } + }); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-unicode-strings-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-unicode-strings-manual.html new file mode 100644 index 0000000..8cdaa87 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-unicode-strings-manual.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with non-ASCII Unicode strings</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + // Title is a string with BMP and non-BMP characters. + // Text contains invalid surrogates which should be converted into U+FFFD. + // URL contains non-ASCII characters in host and path. + const title = 'fáncy 写作 😱'; + const url = 'https://测试.example.com/📄'; + // Host is IDNA-encoded. Path is percent-encoded. + const url_ascii = 'https://xn--0zwm56d.example.com/%F0%9F%93%84'; + setupManualShareTest({title, text: '\ufffdx', url: url_ascii}); + callWhenButtonClicked(() => navigator.share({title, text: '\ud9a3x', url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.html new file mode 100644 index 0000000..deabec3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-unicode-strings-nonutf8-manual.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="windows-1252"> + <title>WebShare Test: Share with non-ASCII Unicode strings in a Latin-1-encoded page</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + assert_equals(document.characterSet, 'windows-1252'); + + // Exact same test as in share-unicode-strings-manual.html, with same + // expectations. This tests that the page's encoding (ISO-8859-1) is + // ignored and Unicode characters are always percent-encoded in UTF-8. + const title = 'f\xe1ncy \u5199\u4f5c \ud83d\ude31'; + const url = 'https://\u6d4b\u8bd5.example.com/\ud83d\udcc4'; + // Host is IDNA-encoded. Path is percent-encoded with UTF-8. + const url_ascii = 'https://xn--0zwm56d.example.com/%F0%9F%93%84'; + setupManualShareTest({title, text: '\ufffdx', url: url_ascii}); + callWhenButtonClicked(() => navigator.share({title, text: '\ud9a3x', url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-data-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-data-manual.html new file mode 100644 index 0000000..e634c0c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-data-manual.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with data URL</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + const url = 'data:foo'; + setupManualShareTest({title: '', text: '', url: getAbsoluteUrl(url)}); + callWhenButtonClicked(() => navigator.share({url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-empty-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-empty-manual.html new file mode 100644 index 0000000..4038dab8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-empty-manual.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with empty URL</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + setupManualShareTest({title: '', text: '', url: document.baseURI}); + callWhenButtonClicked(() => navigator.share({url: ''})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-encoding-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-encoding-manual.html new file mode 100644 index 0000000..0f03b5a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-encoding-manual.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share URL with illegal characters (test percent encoding)</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + const url = 'http://example.com/foo\\ab%63\r\n\t "<>`{}'; + // Expect '\' to normalize to '/', "%63" to normalize to 'c', '\r\n\t' + // to be removed, and all the other illegal characters to be percent-escaped. + const url_encoded = 'http://example.com/foo/abc%20%22%3C%3E%60%7B%7D'; + setupManualShareTest({title: '', text: '', url: url_encoded}); + callWhenButtonClicked(() => navigator.share({url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-invalid.https.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-invalid.https.html new file mode 100644 index 0000000..5f2545d5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-invalid.https.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with an invalid URL</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <script> + promise_test(t => { + // URL is invalid in that the URL Parser returns failure (port is too + // large). + const url = 'http://example.com:65536'; + return promise_rejects( + t, new TypeError(), navigator.share({url})); + }, 'share with an invalid URL'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-noscheme-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-noscheme-manual.html new file mode 100644 index 0000000..e9d7eef --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-noscheme-manual.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with URL without a scheme</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + const url = '//www.example.com/some/path?some_query#some_fragment'; + setupManualShareTest({title: '', text: '', url: getAbsoluteUrl(url)}); + callWhenButtonClicked(() => navigator.share({url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-pathonly-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-pathonly-manual.html new file mode 100644 index 0000000..0487bc8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-pathonly-manual.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with absolute path-only URL</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + const url = '/some/path?some_query#some_fragment'; + setupManualShareTest({title: '', text: '', url: getAbsoluteUrl(url)}); + callWhenButtonClicked(() => navigator.share({url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-relative-manual.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-relative-manual.html new file mode 100644 index 0000000..bbea3860a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-url-relative-manual.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share with relative URL</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="resources/manual-helper.js"></script> + <base href="https://www.example.com/some/path.html"> + </head> + <body> + <script> + setup({explicit_timeout: true}); + + const url = 'foo'; + setupManualShareTest({title: '', text: '', url: getAbsoluteUrl(url)}); + callWhenButtonClicked(() => navigator.share({url})); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-without-user-gesture.https.html b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-without-user-gesture.https.html new file mode 100644 index 0000000..fc87a4af --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-without-user-gesture.https.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>WebShare Test: Share without user gesture error</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <script> + promise_test(t => { + return promise_rejects( + t, 'SecurityError', + navigator.share({title: 'the title', text: 'the message', + url: 'data:the url'})); + }, 'share without a user gesture'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt new file mode 100644 index 0000000..8f24152 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-expected.txt
@@ -0,0 +1,31 @@ +This is a testharness.js-based test. +FAIL Add null candidate should reject with TypeError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add ICE candidate before setting remote description should reject with InvalidStateError assert_unreached: Should have rejected: undefined Reached unreachable code +PASS Add candidate when remote description is null should never resolve when pc is closed +FAIL Add ICE candidate after setting remote description should succeed promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add ICE candidate with RTCIceCandidate should succeed promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with only valid sdpMid should succeed promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with only valid sdpMLineIndex should succeed promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL addIceCandidate with first sdpMid and sdpMLineIndex add candidate to first media stream promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL addIceCandidate with second sdpMid and sdpMLineIndex should add candidate to second media stream promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate for first media stream with null ufrag should add candidate to first media stream promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Adding multiple candidates should add candidates to their corresponding media stream promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add with empty candidate string (end of candidate) should succeed promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with both sdpMid and sdpMLineIndex manually set to null should reject with TypeError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with only valid candidate string should reject with TypeError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with invalid candidate string and both sdpMid and sdpMLineIndex null should reject with TypeError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with empty dict should reject with TypeError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with manually filled default values should reject with TypeError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with invalid sdpMid should reject with OperationError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with invalid sdpMLineIndex should reject with OperationError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Invalid sdpMLineIndex should be ignored if valid sdpMid is provided promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate for media stream 2 with null ufrag should succeed promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with invalid ufrag should reject with OperationError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with invalid candidate string should reject with OperationError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add candidate with sdpMid belonging to different ufrag should reject with OperationError promise_test: Unhandled rejection with value: object "OperationError: TEST_ERROR" +FAIL Add valid candidate should never resolve when pc is closed assert_unreached: Pending promise should never be resolved. Instead it is rejected with: OperationError: TEST_ERROR Reached unreachable code +FAIL Add candidate with invalid candidate string should never resolve when pc is closed assert_unreached: Pending promise should never be resolved. Instead it is rejected with: OperationError: TEST_ERROR Reached unreachable code +FAIL Add candidate with invalid sdpMid should never resolve when pc is closed assert_unreached: Pending promise should never be resolved. Instead it is rejected with: OperationError: TEST_ERROR Reached unreachable code +FAIL Add candidate with invalid sdpMLineIndex should never resolve when pc is closed assert_unreached: Pending promise should never be resolved. Instead it is rejected with: OperationError: TEST_ERROR Reached unreachable code +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html index 541e2b3..1e27f27 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html
@@ -2,9 +2,39 @@ <title>Test RTCPeerConnection.prototype.addIceCandidate</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="RTCPeerConnection-helper.js"></script> <script> 'use strict'; + // Test is based on the following editor draft: + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.htm + + // The following helper functions are called from RTCPeerConnection-helper.js: + // test_never_resolve + + /* + 4.3.2. Interface Definition + interface RTCPeerConnection : EventTarget { + ... + Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate); + }; + + interface RTCIceCandidate { + readonly attribute DOMString candidate; + readonly attribute DOMString? sdpMid; + readonly attribute unsigned short? sdpMLineIndex; + readonly attribute DOMString? ufrag; + ... + }; + + dictionary RTCIceCandidateInit { + DOMString candidate = ""; + DOMString? sdpMid = null; + unsigned short? sdpMLineIndex = null; + DOMString ufrag; + }; + */ + // SDP copied from JSEP Example 7.1 // It contains two media streams with different ufrags // to test if candidate is added to the correct stream @@ -110,6 +140,24 @@ `Expect candidate line to be found after media line ${beforeMediaLine}`); } + // Reject because WebIDL for addIceCandidate does not allow null argument + // null can be accidentally passed from onicecandidate event handler + // when null is used to indicate end of candidate + promise_test(t => { + const pc = new RTCPeerConnection(); + + return pc.setRemoteDescription(sessionDesc) + .then(() => + promise_rejects(t, new TypeError(), + pc.addIceCandidate(null))); + }, 'Add null candidate should reject with TypeError'); + + /* + 4.3.2. addIceCandidate + 4. Return the result of enqueuing the following steps: + 1. If remoteDescription is null return a promise rejected with a + newly created InvalidStateError. + */ promise_test(t => { const pc = new RTCPeerConnection(); @@ -120,6 +168,30 @@ })); }, 'Add ICE candidate before setting remote description should reject with InvalidStateError'); + /* + 4.3.1.2. Enqueue an operation + 7.1. If connection's [[isClosed]] slot is true, abort these steps. + + 4.3.2. addIceCandidate + 4. Return the result of enqueuing the following steps: + 1. If remoteDescription is null return a promise rejected with a + newly created InvalidStateError. + */ + test_never_resolve(t => { + const pc = new RTCPeerConnection(); + + const promise = pc.addIceCandidate({ + candidate: candidateStr1, + sdpMid, sdpMLineIndex, ufrag + }); + + pc.close(); + return promise; + }, 'Add candidate when remote description is null should never resolve when pc is closed'); + + /* + Success cases + */ promise_test(t => { const pc = new RTCPeerConnection(); @@ -144,6 +216,28 @@ const pc = new RTCPeerConnection(); return pc.setRemoteDescription(sessionDesc) + .then(() => pc.addIceCandidate({ sdpMid })); + }, 'Add candidate with only valid sdpMid should succeed'); + + promise_test(t => { + const pc = new RTCPeerConnection(); + + return pc.setRemoteDescription(sessionDesc) + .then(() => pc.addIceCandidate({ sdpMLineIndex })); + }, 'Add candidate with only valid sdpMLineIndex should succeed'); + + /* + 4.3.2. addIceCandidate + 4.6.2. If candidate is applied successfully, the user agent MUST queue + a task that runs the following steps: + 2. Let remoteDescription be connection's pendingRemoteDescription + if not null, otherwise connection's currentRemoteDescription. + 3. Add candidate to remoteDescription. + */ + promise_test(t => { + const pc = new RTCPeerConnection(); + + return pc.setRemoteDescription(sessionDesc) .then(() => pc.addIceCandidate({ candidate: candidateStr1, sdpMid, sdpMLineIndex, ufrag @@ -152,7 +246,7 @@ assert_candidate_line_between(pc.remoteDescription.sdp, mediaLine1, candidateLine1, mediaLine2); }); - }, 'Added candidate should be found in first media stream'); + }, 'addIceCandidate with first sdpMid and sdpMLineIndex add candidate to first media stream'); promise_test(t => { const pc = new RTCPeerConnection(); @@ -168,7 +262,22 @@ assert_candidate_line_after(pc.remoteDescription.sdp, mediaLine2, candidateLine2); }); - }, 'Added candidate should be found in second media stream'); + }, 'addIceCandidate with second sdpMid and sdpMLineIndex should add candidate to second media stream'); + + promise_test(t => { + const pc = new RTCPeerConnection(); + + return pc.setRemoteDescription(sessionDesc) + .then(() => pc.addIceCandidate({ + candidate: candidateStr1, + sdpMid, sdpMLineIndex, + ufrag: null + })) + .then(() => { + assert_candidate_line_between(pc.remoteDescription.sdp, + mediaLine1, candidateLine1, mediaLine2); + }); + }, 'Add candidate for first media stream with null ufrag should add candidate to first media stream'); promise_test(t => { const pc = new RTCPeerConnection(); @@ -191,8 +300,19 @@ assert_candidate_line_after(pc.remoteDescription.sdp, mediaLine2, candidateLine2); }); - }, 'Multiple candidates should be added to their corresponding media stream'); + }, 'Adding multiple candidates should add candidates to their corresponding media stream'); + /* + 4.3.2. addIceCandidate + 4.6. If candidate.candidate is an empty string, process candidate as an + end-of-candidates indication for the corresponding media description + and ICE candidate generation. + 2. If candidate is applied successfully, the user agent MUST queue + a task that runs the following steps: + 2. Let remoteDescription be connection's pendingRemoteDescription + if not null, otherwise connection's currentRemoteDescription. + 3. Add candidate to remoteDescription. + */ promise_test(t => { const pc = new RTCPeerConnection(); @@ -215,18 +335,11 @@ }); }, 'Add with empty candidate string (end of candidate) should succeed'); - // Reject because WebIDL for addIceCandidate does not allow null argument - // null can be accidentally passed from onicecandidate event handler - // when null is used to indicate end of candidate - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.setRemoteDescription(sessionDesc) - .then(() => - promise_rejects(t, new TypeError(), - pc.addIceCandidate(null))); - }, 'Add null candidate should reject withTypeError'); - + /* + 4.3.2. addIceCandidate + 3. If both sdpMid and sdpMLineIndex are null, return a promise rejected + with a newly created TypeError. + */ promise_test(t => { const pc = new RTCPeerConnection(); @@ -245,12 +358,11 @@ return pc.setRemoteDescription(sessionDesc) .then(() => - promise_rejects(t, 'OperationError', + promise_rejects(t, new TypeError(), pc.addIceCandidate({ - candidate: invalidCandidateStr, - sdpMid, sdpMLineIndex, ufrag + candidate: candidateStr1 }))); - }, 'Add candidate with invalid candidate string should reject with OperationError'); + }, 'Add candidate with only valid candidate string should reject with TypeError'); promise_test(t => { const pc = new RTCPeerConnection(); @@ -271,17 +383,6 @@ return pc.setRemoteDescription(sessionDesc) .then(() => promise_rejects(t, new TypeError(), - pc.addIceCandidate({ - candidate: candidateStr1 - }))); - }, 'Add candidate with only valid candidate string should reject with TypeError'); - - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.setRemoteDescription(sessionDesc) - .then(() => - promise_rejects(t, new TypeError(), pc.addIceCandidate({}))); }, 'Add candidate with empty dict should reject with TypeError'); @@ -299,20 +400,13 @@ }))); }, 'Add candidate with manually filled default values should reject with TypeError'); - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.setRemoteDescription(sessionDesc) - .then(() => pc.addIceCandidate({ sdpMid })); - }, 'Add candidate with only valid sdpMid should succeed'); - - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.setRemoteDescription(sessionDesc) - .then(() => pc.addIceCandidate({ sdpMLineIndex })); - }, 'Add candidate with only valid sdpMLineIndex should succeed'); - + /* + 4.3.2. addIceCandidate + 4.3. If candidate.sdpMid is not null, run the following steps: + 1. If candidate.sdpMid is not equal to the mid of any media + description in remoteDescription , reject p with a newly + created OperationError and abort these steps. + */ promise_test(t => { const pc = new RTCPeerConnection(); @@ -325,6 +419,14 @@ }))); }, 'Add candidate with invalid sdpMid should reject with OperationError'); + /* + 4.3.2. addIceCandidate + 4.4. Else, if candidate.sdpMLineIndex is not null, run the following + steps: + 1. If candidate.sdpMLineIndex is equal to or larger than the + number of media descriptions in remoteDescription , reject p + with a newly created OperationError and abort these steps. + */ promise_test(t => { const pc = new RTCPeerConnection(); @@ -356,34 +458,6 @@ const pc = new RTCPeerConnection(); return pc.setRemoteDescription(sessionDesc) - .then(() => - promise_rejects(t, 'OperationError', - pc.addIceCandidate({ - candidate: candidateStr1, - sdpMid, sdpMLineIndex, - ufrag: 'invalid' - }))); - }, 'Add candidate with invalid ufrag should reject with OperationError'); - - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.setRemoteDescription(sessionDesc) - .then(() => pc.addIceCandidate({ - candidate: candidateStr1, - sdpMid, sdpMLineIndex, - ufrag: null - })) - .then(() => { - assert_candidate_line_between(pc.remoteDescription.sdp, - mediaLine1, candidateLine1, mediaLine2); - }); - }, 'Add candidate for media stream 1 with null ufrag should succeed'); - - promise_test(t => { - const pc = new RTCPeerConnection(); - - return pc.setRemoteDescription(sessionDesc) .then(() => pc.addIceCandidate({ candidate: candidateStr2, sdpMid: sdpMid2, @@ -396,6 +470,45 @@ }); }, 'Add candidate for media stream 2 with null ufrag should succeed'); + /* + 4.3.2. addIceCandidate + 4.5. If candidate.ufrag is neither undefined nor null, and is not equal + to any ufrag present in the corresponding media description of an + applied remote description, reject p with a newly created + OperationError and abort these steps. + */ + promise_test(t => { + const pc = new RTCPeerConnection(); + + return pc.setRemoteDescription(sessionDesc) + .then(() => + promise_rejects(t, 'OperationError', + pc.addIceCandidate({ + candidate: candidateStr1, + sdpMid, sdpMLineIndex, + ufrag: 'invalid' + }))); + }, 'Add candidate with invalid ufrag should reject with OperationError'); + + /* + 4.3.2. addIceCandidate + 4.6.1. If candidate could not be successfully added the user agent MUST + queue a task that runs the following steps: + 2. Reject p with a DOMException object whose name attribute has + the value OperationError and abort these steps. + */ + promise_test(t => { + const pc = new RTCPeerConnection(); + + return pc.setRemoteDescription(sessionDesc) + .then(() => + promise_rejects(t, 'OperationError', + pc.addIceCandidate({ + candidate: invalidCandidateStr, + sdpMid, sdpMLineIndex, ufrag + }))); + }, 'Add candidate with invalid candidate string should reject with OperationError'); + promise_test(t => { const pc = new RTCPeerConnection(); @@ -410,8 +523,16 @@ }))); }, 'Add candidate with sdpMid belonging to different ufrag should reject with OperationError'); - // The check for sdpMid and sdpMLineIndex being null is done outside - // of enqueuing task, so it rejects even when pc is closed. + /* + 4.3.2. addIceCandidate + 3. If both sdpMid and sdpMLineIndex are null, return a promise rejected + with a newly created TypeError. + 4. Return the result of enqueuing the following steps + + (Rejects because step 3 comes first) + + this test is being deferred until w3c/webrtc-pc#1345 is resolved + promise_test(t => { const pc = new RTCPeerConnection(); @@ -427,29 +548,24 @@ return promise_rejects(t, new TypeError(), promise); }); }, 'Add candidate with both sdpMid and sdpMLineIndex null should still reject with TypeError after pc is closed'); + */ - function assert_never_resolves(t, promise) { - promise.then( - t.step_func(result => { - assert_unreached(`Pending promise should never be resolved. Instead it is fulfilled with: ${result}`); - }), - t.step_func(err => { - assert_unreached(`Pending promise should never be resolved. Instead it is rejected with: ${err}`); - })); + /* + 4.3.1.2. Enqueue an operation + 7.1. If connection's [[isClosed]] slot is true, abort these steps. - t.step_timeout(t.step_func_done(), 100); - } - - async_test(t => { + 4.3.2. addIceCandidate + 4. Return the result of enqueuing the following steps + */ + test_never_resolve(t => { const pc = new RTCPeerConnection(); - pc.setRemoteDescription(sessionDesc) + return pc.setRemoteDescription(sessionDesc) .then(() => { - assert_never_resolves(t, - pc.addIceCandidate({ - candidate: candidateStr1, - sdpMid, sdpMLineIndex, ufrag - })); + const promise = pc.addIceCandidate({ + candidate: candidateStr1, + sdpMid, sdpMLineIndex, ufrag + }); pc.close(); @@ -459,66 +575,100 @@ assert_false(pc.remoteDescription.sdp.includes(candidateLine1), 'Candidate should not be added to SDP because pc is closed'); }), 80); + + return promise; }); }, 'Add valid candidate should never resolve when pc is closed'); - async_test(t => { + test_never_resolve(t => { const pc = new RTCPeerConnection(); - assert_never_resolves(t, pc.addIceCandidate({ - candidate: candidateStr1, - sdpMid, sdpMLineIndex, ufrag - })); - - pc.close(); - }, 'Add candidate when remote description is null should never resolve when pc is closed'); - - async_test(t => { - const pc = new RTCPeerConnection(); - - pc.setRemoteDescription(sessionDesc) + return pc.setRemoteDescription(sessionDesc) .then(() => { - assert_never_resolves(t, pc.addIceCandidate({ + const promise = pc.addIceCandidate({ candidate: invalidCandidateStr, sdpMid, sdpMLineIndex, ufrag - })); + }); + pc.close(); + return promise; }); }, 'Add candidate with invalid candidate string should never resolve when pc is closed'); - async_test(t => { + test_never_resolve(t => { const pc = new RTCPeerConnection(); - pc.setRemoteDescription(sessionDesc) + return pc.setRemoteDescription(sessionDesc) .then(() => { - assert_never_resolves(t, pc.addIceCandidate({ + const promise = pc.addIceCandidate({ candidate: candidateStr1, sdpMid: 'invalid', sdpMLineIndex, ufrag - })); + }); + pc.close(); + return promise; }); }, 'Add candidate with invalid sdpMid should never resolve when pc is closed'); - async_test(t => { + test_never_resolve(t => { const pc = new RTCPeerConnection(); - pc.setRemoteDescription(sessionDesc) + return pc.setRemoteDescription(sessionDesc) .then(() => { - assert_never_resolves(t, pc.addIceCandidate({ + const promise = pc.addIceCandidate({ candidate: candidateStr1, sdpMLineIndex: 2, ufrag - })); + }); + pc.close(); + return promise; }); }, 'Add candidate with invalid sdpMLineIndex should never resolve when pc is closed'); - // TODO: More tests need to be added: - // - Set pc with both current and pending remote descriptions with different ufrags, - // Check that addIceCandidate with specific ufrag adds candidate to the correct - // remote description. - // - Call with candidate string containing partial malformed syntax, i.e. malformed IP. - // Some browsers may ignore the syntax error and add it to the SDP regardless. + /* + TODO + 4.3.2. addIceCandidate + 4.6. In parallel, add the ICE candidate candidate as described in [JSEP] + (section 4.1.17.). Use candidate.ufrag to identify the ICE generation; + If the ufrag is null, process the candidate for the most recent ICE + generation. + + - Call with candidate string containing partial malformed syntax, i.e. malformed IP. + Some browsers may ignore the syntax error and add it to the SDP regardless. + + Non-Testable + 4.3.2. addIceCandidate + 4.6. (The steps are non-testable because the abort step in enqueue operation + steps in before they can reach here): + 1. If candidate could not be successfully added the user agent MUST + queue a task that runs the following steps: + 1. If connection's [[isClosed]] slot is true, then abort + these steps. + + 2. If candidate is applied successfully, the user agent MUST queue + a task that runs the following steps: + 1. If connection's [[isClosed]] slot is true, then abort these steps. + + Issues + w3c/webrtc-pc#1213 + addIceCandidate end of candidates woes + + w3c/webrtc-pc#1216 + Clarify addIceCandidate behavior when adding candidate after end of candidate + + w3c/webrtc-pc#1227 + addIceCandidate may add ice candidate to the wrong remote description + + w3c/webrtc-pc#1345 + Make promise rejection/enqueing consistent + + Coverage Report + Total: 23 + Tested: 19 + Not Tested: 2 + Non-Testable: 2 + */ </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt new file mode 100644 index 0000000..8f983ad5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +FAIL addTrack when pc is closed should throw InvalidStateError assert_own_property: expected property "addTrack" missing +FAIL addTrack with single track argument should succeed assert_own_property: expected property "addTrack" missing +FAIL Adding the same track multiple times should throw InvalidAccessError assert_own_property: expected property "addTrack" missing +FAIL addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender assert_own_property: expected property "addTrack" missing +FAIL addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender assert_own_property: expected property "addTrack" missing +FAIL addTrack with existing sender with null track, different kind, and recvonly direction should create new sender assert_own_property: expected property "addTrack" missing +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html new file mode 100644 index 0000000..9b74b76 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html
@@ -0,0 +1,232 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerConnection.prototype.addTrack</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="RTCPeerConnection-helper.js"></script> +<script> + 'use strict'; + + // Test is based on the following editor draft: + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html + + // The following helper functions are called from RTCPeerConnection-helper.js: + // generateMediaStreamTrack + + /* + 5.1. RTCPeerConnection Interface Extensions + partial interface RTCPeerConnection { + ... + sequence<RTCRtpSender> getSenders(); + sequence<RTCRtpReceiver> getReceivers(); + sequence<RTCRtpTransceiver> getTransceivers(); + RTCRtpSender addTrack(MediaStreamTrack track, + MediaStream... streams); + RTCRtpTransceiver addTransceiver((MediaStreamTrack or DOMString) trackOrKind, + optional RTCRtpTransceiverInit init); + }; + + Note + While addTrack checks if the MediaStreamTrack given as an argument is + already being sent to avoid sending the same MediaStreamTrack twice, + the other ways do not, allowing the same MediaStreamTrack to be sent + several times simultaneously. + */ + + /* + 5.1. addTrack + 4. If connection's [[isClosed]] slot is true, throw an InvalidStateError. + */ + test(t => { + const pc = new RTCPeerConnection(); + assert_own_property(pc, 'addTrack'); + + const track = generateMediaStreamTrack('audio'); + pc.close(); + assert_throws('InvalidStateError', () => pc.addTrack(track)) + }, 'addTrack when pc is closed should throw InvalidStateError'); + + /* + 5.1. addTrack + 8. If sender is null, run the following steps: + 1. Create an RTCRtpSender with track and streams and let sender be + the result. + 2. Create an RTCRtpReceiver with track.kind as kind and let receiver + be the result. + 3. Create an RTCRtpTransceiver with sender and receiver and let + transceiver be the result. + 4. Add transceiver to connection's set of transceivers. + */ + test(t => { + const pc = new RTCPeerConnection(); + assert_own_property(pc, 'addTrack'); + + const track = generateMediaStreamTrack('audio'); + const sender = pc.addTrack(track); + + assert_true(sender instanceof RTCRtpSender, + 'Expect sender to be instance of RTCRtpSender'); + + assert_equals(sender.track, track, + `Expect sender's track to be the added track`); + + const transceivers = pc.getTransceivers(); + assert_equals(transceivers.length, 1, + 'Expect only one transceiver with sender added'); + + const [transceiver] = transceivers; + assert_equals(transceiver.sender, sender); + + assert_array_equals([sender], pc.getSenders(), + 'Expect only one sender with given track added'); + + const { receiver } = transceiver; + assert_equals(receiver.track.kind, 'audio'); + assert_array_equals([transceiver.receiver], pc.getReceivers(), + 'Expect only one receiver associated with transceiver added'); + + }, 'addTrack with single track argument should succeed'); + + /* + 5.1. addTrack + 5. Let senders be the result of executing the CollectSenders algorithm. + If an RTCRtpSender for track already exists in senders, throw an + InvalidAccessError. + */ + test(t => { + const pc = new RTCPeerConnection(); + assert_own_property(pc, 'addTrack'); + + const track = generateMediaStreamTrack('audio'); + pc.addTrack(track); + + assert_throws('InvalidAccessError', () => pc.addTrack(track)); + + }, 'Adding the same track multiple times should throw InvalidAccessError'); + + /* + 5.1. addTrack + 6. The steps below describe how to determine if an existing sender can + be reused. + + If any RTCRtpSender object in senders matches all the following + criteria, let sender be that object, or null otherwise: + - The sender's track is null. + - The transceiver kind of the RTCRtpTransceiver, associated with + the sender, matches track's kind. + - The sender has never been used to send. More precisely, the + RTCRtpTransceiver associated with the sender has never had a + currentDirection of sendrecv or sendonly. + 7. If sender is not null, run the following steps to use that sender: + 1. Set sender.track to track. + 3. Enable sending direction on the RTCRtpTransceiver associated + with sender. + */ + test(t => { + const pc = new RTCPeerConnection(); + assert_own_property(pc, 'addTrack'); + + const transceiver = pc.addTransceiver('audio', { direction: 'recvonly' }); + assert_equals(transceiver.sender.track, null); + assert_equals(transceiver.direction, 'recvonly'); + + const track = generateMediaStreamTrack('audio'); + const sender = pc.addTrack(track); + + assert_equals(sender, transceiver.sender); + assert_equals(sender.track, track); + assert_equals(transceiver.direction, 'sendrecv'); + assert_array_equals([sender], pc.getSenders()); + + }, 'addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender'); + + test(t => { + const pc = new RTCPeerConnection(); + assert_own_property(pc, 'addTrack'); + assert_own_property(pc, 'addTransceiver'); + + const transceiver = pc.addTransceiver('audio'); + assert_equals(transceiver.sender.track, null); + assert_equals(transceiver.direction, 'sendrecv'); + + const track = generateMediaStreamTrack('audio'); + const sender = pc.addTrack(track); + + assert_equals(sender.track, track); + assert_not_equals(sender, transceiver.sender); + + const senders = pc.getSenders(); + assert_equals(senders.length, 2, + 'Expect 2 senders added to connection'); + + assert_true(senders.includes(sender), + 'Expect senders list to include sender'); + + assert_true(senders.includes(transceiver.sender), + `Expect senders list to include first transceiver's sender`); + + }, 'addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender'); + + test(t => { + const pc = new RTCPeerConnection(); + assert_own_property(pc, 'addTrack'); + assert_own_property(pc, 'addTransceiver'); + + const transceiver = pc.addTransceiver('video', { direction: 'recvonly' }); + assert_equals(transceiver.sender.track, null); + assert_equals(transceiver.direction, 'recvonly'); + + const track = generateMediaStreamTrack('audio'); + const sender = pc.addTrack(track); + + assert_equals(sender.track, track); + assert_not_equals(sender, transceiver.sender); + + const senders = pc.getSenders(); + assert_equals(senders.length, 2, + 'Expect 2 senders added to connection'); + + assert_true(senders.includes(sender), + 'Expect senders list to include sender'); + + assert_true(senders.includes(transceiver.sender), + `Expect senders list to include first transceiver's sender`); + + }, 'addTrack with existing sender with null track, different kind, and recvonly direction should create new sender'); + + /* + TODO + 5.1. addTrack + 3. Let streams be a list of MediaStream objects constructed from the + method's remaining arguments, or an empty list if the method was + called with a single argument. + 6. The steps below describe how to determine if an existing sender can + be reused. Doing so will cause future calls to createOffer and + createAnswer to mark the corresponding media description as sendrecv + or sendonly and add the MSID of the track added, as defined in [JSEP] + (section 5.2.2. and section 5.3.2.). + 9. A track could have contents that are inaccessible to the application. + This can be due to being marked with a peerIdentity option or anything + that would make a track CORS cross-origin. These tracks can be supplied + to the addTrack method, and have an RTCRtpSender created for them, but + content must not be transmitted, unless they are also marked with + peerIdentity and they meet the requirements for sending (see isolated + streams and RTCPeerConnection). + + All other tracks that are not accessible to the application must not be + sent to the peer, with silence (audio), black frames (video) or + equivalently absent content being sent in place of track content. + + Note that this property can change over time. + + Non-Testable + 5.1. addTrack + 7. If sender is not null, run the following steps to use that sender: + 2. Set sender's [[associated MediaStreams]] to streams. + + Tested in RTCPeerConnection-onnegotiationneeded.html: + 5.1. addTrack + 10. Update the negotiation-needed flag for connection. + + */ +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt index c6bfee4..d278bd4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt
@@ -2,5 +2,7 @@ FAIL addTransceiver('audio') should return an audio transceiver assert_own_property: expected property "addTransceiver" missing FAIL addTransceiver('video') should return a video transceiver assert_own_property: expected property "addTransceiver" missing FAIL addTransceiver() with string argument as invalid kind should throw TypeError assert_own_property: expected property "addTransceiver" missing +FAIL addTransceiver(track) should have result with sender.track be given track assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing +FAIL addTransceiver(track) multiple times should create multiple transceivers assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html index 0c69652..1336fea9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html
@@ -3,11 +3,15 @@ <title>RTCPeerConnection.prototype.addTransceiver</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="RTCPeerConnection-helper.js"></script> <script> 'use strict'; // Test is based on the following editor draft: - // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html + + // The following helper function is called from RTCPeerConnection-helper.js: + // generateMediaStreamTrack /* * 5.1. RTCPeerConnection Interface Extensions @@ -25,6 +29,12 @@ * sequence<MediaStream> streams; * sequence<RTCRtpEncodingParameters> sendEncodings; * }; + + Note + While addTrack checks if the MediaStreamTrack given as an argument is + already being sent to avoid sending the same MediaStreamTrack twice, + the other ways do not, allowing the same MediaStreamTrack to be sent + several times simultaneously. */ /* @@ -33,12 +43,12 @@ * * 3. If the first argument is a string, let it be kind and run the following steps: * 2. Let track be null. - * 5. Create an RTCRtpSender with track, streams and sendEncodings and let sender + * 7. Create an RTCRtpSender with track, streams and sendEncodings and let sender * be the result. - * 6. Create an RTCRtpReceiver with kind and let receiver be the result. - * 7. Create an RTCRtpTransceiver with sender and receiver and let transceiver + * 8. Create an RTCRtpReceiver with kind and let receiver be the result. + * 9. Create an RTCRtpTransceiver with sender and receiver and let transceiver * be the result. - * 8. Add transceiver to connection's set of transceivers. + * 10. Add transceiver to connection's set of transceivers. * * 5.3. RTCRtpReceiver Interface * Create an RTCRtpReceiver @@ -49,6 +59,7 @@ * with kind. * 6. Initialize track.readyState to live. * 7. Initialize track.muted to true. + * 8. Set receiver.track to track. * * 5.4. RTCRtpTransceiver Interface * Create an RTCRtpTransceiver @@ -154,4 +165,140 @@ assert_throws(new TypeError(), () => pc.addTransceiver('invalid')); }, 'addTransceiver() with string argument as invalid kind should throw TypeError'); + /* + 5.1. addTransceiver + 3. If the first argument is a MediaStreamTrack , let it be track and let + kind be track.kind. + 7. Create an RTCRtpSender with track, streams and sendEncodings and let sender + be the result. + 8. Create an RTCRtpReceiver with kind and let receiver be the result. + */ + test(t => { + const pc = new RTCPeerConnection(); + const track = generateMediaStreamTrack('audio'); + + const transceiver = pc.addTransceiver(track); + const { sender, receiver } = transceiver; + + assert_true(sender instanceof RTCRtpSender, + 'Expect sender to be instance of RTCRtpSender'); + + assert_true(receiver instanceof RTCRtpReceiver, + 'Expect receiver to be instance of RTCRtpReceiver'); + + assert_equals(sender.track, track, + 'Expect sender.track should be the track that is added'); + + const receiverTrack = receiver.track + assert_true(receiverTrack instanceof MediaStreamTrack, + 'Expect receiver.track to be instance of MediaStreamTrack'); + + assert_equals(receiverTrack.kind, 'audio', + `receiver.track should have the same kind as added track's kind`); + + assert_equals(receiverTrack.label, 'remote audio'); + assert_equals(receiverTrack.readyState, 'live'); + assert_equals(receiverTrack.muted, true); + + assert_array_equals([transceiver], pc.getTransceivers(), + `Expect added transceiver to be the only element in connection's list of transceivers`); + + assert_array_equals([sender], pc.getSenders(), + `Expect added sender to be the only element in connection's list of senders`); + + assert_array_equals([receiver], pc.getReceivers(), + `Expect added receiver to be the only element in connection's list of receivers`); + + }, 'addTransceiver(track) should have result with sender.track be given track'); + + test(t => { + const pc = new RTCPeerConnection(); + const track = generateMediaStreamTrack('audio'); + + const transceiver1 = pc.addTransceiver(track); + const transceiver2 = pc.addTransceiver(track); + + assert_not_equals(transceiver1, transceiver2); + + const sender1 = transceiver1.sender; + const sender2 = transceiver2.sender; + + assert_not_equals(sender1, sender2); + assert_equals(transceiver1.sender.track, track); + assert_equals(transceiver2.sender.track, track); + + const transceivers = pc.getTransceivers(); + assert_equals(transceivers.length, 2); + assert_true(transceivers.includes(transceiver1)); + assert_true(transceivers.includes(transceiver2)); + + const senders = pc.getSenders(); + assert_equals(senders.length, 2); + assert_true(senders.includes(sender1)); + assert_true(senders.includes(sender2)); + + }, 'addTransceiver(track) multiple times should create multiple transceivers'); + + /* + TODO + 5.1. addTransceiver + Adding a transceiver will cause future calls to createOffer to add a media + description for the corresponding transceiver, as defined in [JSEP] + (section 5.2.2.). + + The sendEncodings argument can be used to specify the number of offered + simulcast encodings, and optionally their RIDs and encoding parameters. + Aside from rid , all read-only parameters in the RTCRtpEncodingParameters + dictionaries, such as ssrc , must be left unset, or an error will be thrown. + + 1. If the dictionary argument is present, and it has a streams member, let + streams be that list of MediaStream objects. + 2. If the dictionary argument is present, and it has a sendEncodings member, + let sendEncodings be that list of RTCRtpEncodingParameters objects. + 5. Verify that each rid value in sendEncodings is composed only of + case-sensitive alphanumeric characters (a-z, A-Z, 0-9) up to a + maximum of 16 characters. If one of the RIDs does not meet these + requirements, throw a TypeError. + 6. If any RTCRtpEncodingParameters dictionary in sendEncodings contains + a read-only parameter other than rid, throw an InvalidAccessError. + 7. If sendEncodings is set, then subsequent calls to createOffer will be + configured to send multiple RTP encodings as defined in [JSEP] + (section 5.2.2. and section 5.2.1.). When setRemoteDescription is called + with a corresponding remote description that is able to receive multiple + RTP encodings as defined in [JSEP] (section 3.7.), the RTCRtpSender may + send multiple RTP encodings and the parameters retrieved via the + transceiver's sender.getParameters() will reflect the encodings + negotiated. + 8. This specification does not define how to configure createOffer to + receive multiple RTP encodings. However when setRemoteDescription is + called with a corresponding remote description that is able to send + multiple RTP encodings as defined in [JSEP], the RTCRtpReceiver may + receive multiple RTP encodings and the parameters retrieved via the + transceiver's receiver.getParameters() will reflect the encodings + negotiated. + 5.3. RTCRtpReceiver Interface + Create an RTCRtpReceiver + 4. If an id string, id, was given as input to this algorithm, initialize + track.id to id. (Otherwise the value generated when track was created + will be used.) + + Non-testable + 5.2. RTCRtpSender Interface + create an RTCRtpSender + 3. Let sender have an [[associated MediaStreams]] internal slot, + representing a list of MediaStream objects that the MediaStreamTrack + object of this sender is associated with. + 4. Set sender's [[associated MediaStreams]] slot to streams. + 5. Let sender have a [[send encodings]] internal slot, representing a + list of RTCRtpEncodingParameters dictionaries. + 6. If sendEncodings is given as input to this algorithm, and is non-empty, + set the [[send encodings]] slot to sendEncodings. Otherwise, set it + to a list containing a single RTCRtpEncodingParameters with active + set to true. + + Tested in RTCPeerConnection-onnegotiationneeded.html + 5.1. addTransceiver + 11. Update the negotiation-needed flag for connection. + */ + </script>
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 855fc8d..599d048 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
@@ -194,6 +194,13 @@ PASS childWindow.statusbar.visible is false PASS childWindow.styleMedia.type is '' PASS childWindow.toolbar.visible is false +PASS childWindow.visualViewport.height is 0 +PASS childWindow.visualViewport.offsetLeft is 0 +PASS childWindow.visualViewport.offsetTop is 0 +PASS childWindow.visualViewport.pageLeft is 0 +PASS childWindow.visualViewport.pageTop is 0 +PASS childWindow.visualViewport.scale is 0 +PASS childWindow.visualViewport.width is 0 PASS successfullyParsed is true TEST COMPLETE
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 d674545..e866a2d 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
@@ -194,6 +194,13 @@ PASS childWindow.statusbar.visible is false PASS childWindow.styleMedia.type is '' PASS childWindow.toolbar.visible is false +PASS childWindow.visualViewport.height is 0 +PASS childWindow.visualViewport.offsetLeft is 0 +PASS childWindow.visualViewport.offsetTop is 0 +PASS childWindow.visualViewport.pageLeft is 0 +PASS childWindow.visualViewport.pageTop is 0 +PASS childWindow.visualViewport.scale is 0 +PASS childWindow.visualViewport.width is 0 PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/fast/overflow/overflow-with-local-background-attachment-expected.png similarity index 100% rename from third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png rename to third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/fast/overflow/overflow-with-local-background-attachment-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/css-clip-change-stacking-child-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/css-clip-change-stacking-child-expected.txt index 6a1a805..6f433408 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/css-clip-change-stacking-child-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/css-clip-change-stacking-child-expected.txt
@@ -8,8 +8,13 @@ "paintInvalidations": [ { "object": "LayoutBlockFlow DIV", + "rect": [8, 8, 300, 300], + "reason": "paint property change" + }, + { + "object": "LayoutBlockFlow DIV", "rect": [8, 8, 300, 200], - "reason": "subtree" + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt new file mode 100644 index 0000000..5fc88ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt
@@ -0,0 +1,24 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='before box'", + "rect": [8, 0, 240, 240], + "reason": "paint property change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-expected.txt new file mode 100644 index 0000000..ff44330 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-expected.txt
@@ -0,0 +1,24 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box before'", + "rect": [33, 25, 250, 250], + "reason": "paint property change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-xonly-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-xonly-expected.txt new file mode 100644 index 0000000..2a35d91b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-xonly-expected.txt
@@ -0,0 +1,24 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box before'", + "rect": [33, 50, 250, 200], + "reason": "paint property change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-yonly-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-yonly-expected.txt new file mode 100644 index 0000000..4d15d0b --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/filters/effect-reference-repaint-morphology-yonly-expected.txt
@@ -0,0 +1,24 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box before'", + "rect": [58, 25, 200, 250], + "reason": "paint property change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV class='box'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt index c49bfed..4d98c005 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/overflow-scroll-composited-non-stacking-child-expected.txt
@@ -18,8 +18,13 @@ }, { "object": "LayoutBlockFlow (positioned) DIV class='back'", + "rect": [93, 125, 180, 100], + "reason": "paint property change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='back'", "rect": [93, 75, 180, 100], - "reason": "subtree" + "reason": "paint property change" }, { "object": "VerticalScrollbar",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/reflection-repaint-test-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/reflection-repaint-test-expected.txt index 832b3bd..de037eb 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/reflection-repaint-test-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/reflection-repaint-test-expected.txt
@@ -9,17 +9,7 @@ { "object": "LayoutBlockFlow DIV id='target'", "rect": [22, 50, 226, 167], - "reason": "geometry" - }, - { - "object": "InlineTextBox 'PASS'", - "rect": [23, 51, 72, 110], - "reason": "appeared" - }, - { - "object": "InlineTextBox 'FAIL'", - "rect": [23, 51, 69, 109], - "reason": "disappeared" + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/repaint-during-scroll-with-zoom-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/repaint-during-scroll-with-zoom-expected.txt index 2841872..48f2d3f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/repaint-during-scroll-with-zoom-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/repaint-during-scroll-with-zoom-expected.txt
@@ -12,21 +12,16 @@ "reason": "subtree" }, { + "object": "LayoutView #document", + "rect": [3, 65, 235, 235], + "reason": "paint property change" + }, + { "object": "HorizontalScrollbar", "rect": [3, 300, 235, 15], "reason": "scroll control" }, { - "object": "LayoutView #document", - "rect": [3, 65, 225, 225], - "reason": "subtree" - }, - { - "object": "InlineTextBox 'scroll me'", - "rect": [3, 65, 55, 17], - "reason": "subtree" - }, - { "object": "VerticalScrollbar", "rect": [238, 65, 15, 235], "reason": "scroll control"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt index 0f6d9e5..0822fe5f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt
@@ -12,14 +12,14 @@ "reason": "subtree" }, { - "object": "InlineTextBox 'test test test'", - "rect": [10, 11, 59, 16], - "reason": "appeared" + "object": "LayoutBlockFlow DIV id='inner-editor'", + "rect": [10, 11, 60, 16], + "reason": "paint property change" }, { - "object": "InlineTextBox 'test test test'", + "object": "LayoutBlockFlow DIV id='inner-editor'", "rect": [10, 11, 59, 16], - "reason": "disappeared" + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt index e67738b..9839700d 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt
@@ -12,14 +12,9 @@ "reason": "subtree" }, { - "object": "InlineTextBox 'test test test'", + "object": "LayoutBlockFlow DIV id='inner-editor'", "rect": [10, 11, 60, 16], - "reason": "appeared" - }, - { - "object": "InlineTextBox 'test test test'", - "rect": [10, 11, 60, 16], - "reason": "disappeared" + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt index 5d20e08..fd8cb22 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/inner-svg-change-viewPort-relative-expected.txt
@@ -24,7 +24,7 @@ { "object": "LayoutSVGContainer use", "rect": [180, 120, 20, 20], - "reason": "chunk reordered" + "reason": "paint property change" }, { "object": "LayoutSVGRect rect", @@ -34,7 +34,7 @@ { "object": "LayoutSVGContainer use", "rect": [80, 120, 20, 20], - "reason": "chunk reordered" + "reason": "paint property change" }, { "object": "LayoutSVGRect rect",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size-expected.txt index b6ce25f..3bd67c4 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size-expected.txt
@@ -17,14 +17,14 @@ "reason": "geometry" }, { - "object": "LayoutSVGRect rect", + "object": "LayoutSVGRoot svg", "rect": [9, 9, 400, 400], - "reason": "geometry" + "reason": "paint property change" }, { - "object": "LayoutSVGEllipse circle", - "rect": [169, 169, 80, 80], - "reason": "geometry" + "object": "LayoutSVGRoot svg", + "rect": [9, 109, 200, 200], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-expected.txt index ac4e786..9af9b7b 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-expected.txt
@@ -12,9 +12,14 @@ "reason": "geometry" }, { - "object": "LayoutSVGRect rect id='targetRect'", + "object": "LayoutSVGRoot svg", "rect": [9, 73, 400, 400], - "reason": "geometry" + "reason": "paint property change" + }, + { + "object": "LayoutSVGRoot svg", + "rect": [9, 73, 100, 400], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt index d99dcae..b4b9bf8 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-content-with-resources-expected.txt
@@ -12,14 +12,14 @@ "reason": "geometry" }, { - "object": "LayoutSVGEllipse circle", + "object": "LayoutSVGRoot svg", "rect": [47, 111, 324, 324], - "reason": "SVG resource change" + "reason": "paint property change" }, { - "object": "LayoutSVGEllipse circle", - "rect": [8, 154, 170, 238], - "reason": "SVG resource change" + "object": "LayoutSVGRoot svg", + "rect": [8, 154, 102, 238], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-deep-shadow-tree-content-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-deep-shadow-tree-content-expected.txt index 2b2fd71d9..e78652a8 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-deep-shadow-tree-content-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-deep-shadow-tree-content-expected.txt
@@ -12,9 +12,14 @@ "reason": "geometry" }, { - "object": "LayoutSVGRect rect id='targetRect'", + "object": "LayoutSVGContainer g id='targetUse'", "rect": [209, 273, 200, 200], - "reason": "geometry" + "reason": "paint property change" + }, + { + "object": "LayoutSVGContainer g id='targetUse'", + "rect": [59, 273, 50, 200], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-inner-svg-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-inner-svg-expected.txt index 1d20b6a..7877a43 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-inner-svg-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-inner-svg-expected.txt
@@ -10,6 +10,16 @@ "object": "LayoutBlockFlow div id='contentBox'", "rect": [8, 52, 402, 402], "reason": "geometry" + }, + { + "object": "LayoutSVGViewportContainer svg", + "rect": [27, 69, 364, 366], + "reason": "paint property change" + }, + { + "object": "LayoutSVGViewportContainer svg", + "rect": [13, 207, 92, 92], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt index 5f143aa3..f8667fc 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-expected.txt
@@ -12,14 +12,24 @@ "reason": "geometry" }, { - "object": "LayoutSVGRect rect id='targetRect'", + "object": "LayoutSVGContainer use", "rect": [209, 273, 200, 200], - "reason": "geometry" + "reason": "paint property change" }, { "object": "LayoutSVGRect rect id='targetRect1'", "rect": [9, 73, 200, 200], - "reason": "geometry" + "reason": "paint property change" + }, + { + "object": "LayoutSVGContainer use", + "rect": [59, 273, 50, 200], + "reason": "paint property change" + }, + { + "object": "LayoutSVGRect rect id='targetRect1'", + "rect": [9, 73, 50, 200], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol-expected.txt index 2668abaa..48b9741a 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol-expected.txt
@@ -10,6 +10,16 @@ "object": "LayoutBlockFlow div id='contentBox'", "rect": [8, 72, 402, 402], "reason": "geometry" + }, + { + "object": "LayoutSVGViewportContainer svg id='targetSymbol'", + "rect": [9, 73, 400, 400], + "reason": "paint property change" + }, + { + "object": "LayoutSVGViewportContainer svg id='targetSymbol'", + "rect": [9, 223, 100, 100], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-on-symbol-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-on-symbol-expected.txt index 0fb6d08..518d5bf 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-on-symbol-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-on-symbol-expected.txt
@@ -10,6 +10,16 @@ "object": "LayoutBlockFlow div id='contentBox'", "rect": [8, 52, 402, 402], "reason": "geometry" + }, + { + "object": "LayoutSVGViewportContainer svg id='gamesBorder'", + "rect": [45, 87, 328, 330], + "reason": "paint property change" + }, + { + "object": "LayoutSVGViewportContainer svg id='gamesBorder'", + "rect": [18, 211, 82, 83], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-without-attributes-on-symbol-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-without-attributes-on-symbol-expected.txt index 0fb6d08..faa11dbc 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-without-attributes-on-symbol-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/svg/relative-sized-use-without-attributes-on-symbol-expected.txt
@@ -10,6 +10,16 @@ "object": "LayoutBlockFlow div id='contentBox'", "rect": [8, 52, 402, 402], "reason": "geometry" + }, + { + "object": "LayoutSVGViewportContainer svg id='gamesBorder'", + "rect": [27, 69, 364, 366], + "reason": "paint property change" + }, + { + "object": "LayoutSVGViewportContainer svg id='gamesBorder'", + "rect": [13, 207, 92, 92], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/transform-disable-layoutstate-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/transform-disable-layoutstate-expected.txt index 18f64154..0bd91205 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/transform-disable-layoutstate-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/transform-disable-layoutstate-expected.txt
@@ -7,14 +7,14 @@ "drawsContent": true, "paintInvalidations": [ { - "object": "LayoutBlockFlow DIV", - "rect": [58, 138, 500, 63], - "reason": "geometry" + "object": "LayoutBlockFlow DIV id='container'", + "rect": [58, 88, 500, 213], + "reason": "paint property change" }, { - "object": "LayoutBlockFlow DIV", - "rect": [58, 256, 500, 45], - "reason": "incremental" + "object": "LayoutBlockFlow DIV id='container'", + "rect": [58, 88, 500, 168], + "reason": "paint property change" } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt deleted file mode 100644 index 22b41aa7..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/paint/invalidation/selection/selection-in-composited-scrolling-container-expected.txt +++ /dev/null
@@ -1,57 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "paintInvalidations": [ - { - "object": "LayoutTextControl INPUT id='target'", - "rect": [7, 7, 66, 24], - "reason": "subtree" - }, - { - "object": "InlineTextBox 'test test test'", - "rect": [10, 11, 59, 16], - "reason": "subtree" - } - ] - } - ], - "objectPaintInvalidations": [ - { - "object": "LayoutBlockFlow HTML", - "reason": "selection" - }, - { - "object": "LayoutBlockFlow BODY", - "reason": "selection" - }, - { - "object": "LayoutTextControl INPUT id='target'", - "reason": "subtree" - }, - { - "object": "LayoutBlockFlow DIV id='inner-editor'", - "reason": "subtree" - }, - { - "object": "RootInlineBox", - "reason": "subtree" - }, - { - "object": "HorizontalScrollbar", - "reason": "scroll control" - }, - { - "object": "LayoutText #text", - "reason": "subtree" - }, - { - "object": "InlineTextBox 'test test test'", - "reason": "subtree" - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt deleted file mode 100644 index c8fbaa0..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/platform/linux/paint/invalidation/selection/selection-in-non-composited-scrolling-container-expected.txt +++ /dev/null
@@ -1,57 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "paintInvalidations": [ - { - "object": "LayoutTextControl INPUT id='target'", - "rect": [7, 7, 66, 24], - "reason": "subtree" - }, - { - "object": "InlineTextBox 'test test test'", - "rect": [10, 11, 60, 16], - "reason": "subtree" - } - ] - } - ], - "objectPaintInvalidations": [ - { - "object": "LayoutBlockFlow HTML", - "reason": "selection" - }, - { - "object": "LayoutBlockFlow BODY", - "reason": "selection" - }, - { - "object": "LayoutTextControl INPUT id='target'", - "reason": "subtree" - }, - { - "object": "LayoutBlockFlow DIV id='inner-editor'", - "reason": "subtree" - }, - { - "object": "RootInlineBox", - "reason": "subtree" - }, - { - "object": "HorizontalScrollbar", - "reason": "scroll control" - }, - { - "object": "LayoutText #text", - "reason": "subtree" - }, - { - "object": "InlineTextBox 'test test test'", - "reason": "subtree" - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/json-preview.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/json-preview.html index f47f6a0..9538c4d4d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/json-preview.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/json-preview.html
@@ -18,9 +18,9 @@ { var previewView = new Network.RequestPreviewView(request, null); previewView.wasShown(); - var previewer = await previewView._previewViewPromise; + var previewer = await previewView._contentViewPromise; InspectorTest.addResult("Its previewer is searchable: " + (previewer && previewer instanceof UI.SearchableView)); - InspectorTest.addResult("Its previewer is the JSON previewer: " + (previewer && previewer._searchProvider && previewer._searchProvider instanceof Network.JSONView)); + InspectorTest.addResult("Its previewer is the JSON previewer: " + (previewer && previewer._searchProvider && previewer._searchProvider instanceof SourceFrame.JSONView)); } function testType(contentType, callback)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-choose-preview-view.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-choose-preview-view.html index 746b5f25..c9c6cc84 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-choose-preview-view.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-choose-preview-view.html
@@ -31,8 +31,8 @@ var request = createNetworkRequest(contentType, content, statusCode); var previewView = new Network.RequestPreviewView(request, new Network.RequestResponseView(request)); previewView.wasShown(); - InspectorTest.addResult("Its previewer type: " + getViewName(await previewView._previewViewPromise)); - } + InspectorTest.addResult("Its previewer type: " + getViewName(await previewView._contentViewPromise)); + } InspectorTest.addResult("Simple JSON"); await testPreviewer("application/json", "[533,3223]", 200);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html index 55a5735b..6d933065 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html
@@ -39,9 +39,9 @@ InspectorTest.addSniffer(compontentView, "onTextEditorContentSet", previewViewHandled.bind(this, searches, callback, view)); return; } - } else if (compontentView instanceof Network.XMLView) { + } else if (compontentView instanceof SourceFrame.XMLView) { typeName = "XMLView"; - } else if(compontentView instanceof Network.JSONView) { + } else if(compontentView instanceof SourceFrame.JSONView) { typeName = "JSONView"; } else if(compontentView instanceof Network.RequestHTMLView) { typeName = "RequestHTMLView"; @@ -63,8 +63,8 @@ function trySearches(request, searches, callback) { - InspectorTest.addSniffer(Network.RequestPreviewView.prototype, "_showPreviewView", async function() { - previewViewHandled(searches, callback, await this._previewViewPromise); + InspectorTest.addSniffer(Network.RequestPreviewView.prototype, "showPreview", async function() { + previewViewHandled(searches, callback, await this._contentViewPromise); }); var networkPanel = UI.panels.network; networkPanel._showRequest(request);
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/resources/feature-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/resources/feature-worker.js new file mode 100644 index 0000000..1314a53 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/resources/feature-worker.js
@@ -0,0 +1,9 @@ +// A service worker for use with UseCounter tests. It uses a feature +// when asked via postMessage. +self.addEventListener('message', e => { + if (e.data == 'use-frameType') { + self.clients.matchAll().then(my_clients => { + my_clients[0].frameType; + }); + } + });
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html index a4f5784a..eb6592cb 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/usecounter.html
@@ -333,8 +333,8 @@ return wait_for_state(t, registration.installing, 'activated'); }) .then(() => { return openWindow(kScope); }) - .then(newWindow => { - win = newWindow; + .then(new_window => { + win = new_window; return observeUseCounter(win, kFetchEventIsReload); }) .then(() => { @@ -342,6 +342,34 @@ }); }, 'FetchEvent.isReload is counted'); +promise_test(t => { + const kServiceWorkerFrameType = 2033; // from WebFeature.h + const kUrl = 'resources/feature-worker.js'; + const kScope = 'resources/usecounter-window.html?frameType'; + let worker; + let win; + return service_worker_unregister_and_register(t, kUrl, kScope) + .then(registration => { + add_result_callback(() => { + if (win) { + win.close(); + } + registration.unregister(); + }); + worker = registration.installing; + return wait_for_state(t, worker, 'activated'); + }) + .then(() => { return openWindow(kScope); }) + .then(new_window => { + win = new_window; + worker.postMessage('use-frameType'); + return observeUseCounter(win, kServiceWorkerFrameType); + }) + .then(() => { + assert_true(isUseCounted(win, kServiceWorkerFrameType)); + }); + }, 'Client.frameType is counted'); + // TODO(nhiroki): Test a case where ServiceWorker controls SharedWorker that is // connected from multiple windows. In such a case, API use on ServiceWorker // should be propagated to all connecting windows via SharedWorker.
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x-expected.txt index ccf6b6fb..1d4cce5d 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x2 viewport='w=320' +Emulating device: 1200x1000x2 +Loading page with viewport=w=320 Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x.html deleted file mode 100644 index 24d4adf2..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-320-2x.html", 1200, 1000, 2, "w=320"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x.js new file mode 100644 index 0000000..4910b51 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-2x.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 2); + + var viewport = 'w=320'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-expected.txt index 421c395..03ba35c0 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x1 viewport='w=320' +Emulating device: 1200x1000x1 +Loading page with viewport=w=320 Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport-expected.txt index 2fc6d33b..7beb25ac 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 0x0x0 viewport='w=320' +Emulating device: 0x0x0 +Loading page with viewport=w=320 Device: window.screenX = 0px window.screenY = 0px @@ -21,4 +20,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport.html deleted file mode 100644 index 6669019..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-320-only-viewport.html", 0, 0, 0, "w=320"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport.js new file mode 100644 index 0000000..744cba5f --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320-only-viewport.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(0, 0, 0); + + var viewport = 'w=320'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(false)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320.html deleted file mode 100644 index ad273773..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320.html +++ /dev/null
@@ -1,34 +0,0 @@ -<html><head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-320.html", 1200, 1000, 1, "w=320"); -} -</script> - -</head><body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body></html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320.js new file mode 100644 index 0000000..9617db98 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-320.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 1); + + var viewport = 'w=320'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x-expected.txt index 0dcbdcf..b84aa8c1 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x2 viewport='w=980' +Emulating device: 1200x1000x2 +Loading page with viewport=w=980 Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x.html deleted file mode 100644 index 8bec85b..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-980-2x.html", 1200, 1000, 2, "w=980"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x.js new file mode 100644 index 0000000..d42b4f06 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-2x.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 2); + + var viewport = 'w=980'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-expected.txt index c4df266..bf60f7d 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x1 viewport='w=980' +Emulating device: 1200x1000x1 +Loading page with viewport=w=980 Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport-expected.txt index 22574203..f2017f0c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 0x0x0 viewport='w=980' +Emulating device: 0x0x0 +Loading page with viewport=w=980 Device: window.screenX = 0px window.screenY = 0px @@ -21,4 +20,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport.html deleted file mode 100644 index 653eb0a..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-980-only-viewport.html", 0, 0, 0, "w=980"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport.js new file mode 100644 index 0000000..3e3b6db --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980-only-viewport.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(0, 0, 0); + + var viewport = 'w=980'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(false)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980.html deleted file mode 100644 index 60f77965..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-980.html", 1200, 1000, 1, "w=980"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980.js new file mode 100644 index 0000000..5898ad9b --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-980.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 1); + + var viewport = 'w=980'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls-expected.txt index 132c38a..f30597c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls-expected.txt
@@ -1,9 +1,6 @@ Tests that form controls are rendered with correct theme. See crbug.com/591315. - -Radio -Checkbox -Page reloaded. -Emulating device: 800x600x1 viewport='none' +Emulating device: 800x600x1 +Loading page with viewport=none Device: window.screenX = 0px window.screenY = 0px @@ -42,4 +39,3 @@ measured radio: 13x13 measured checkbox: 13x13 -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls.html deleted file mode 100644 index cbd472e5..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls.html +++ /dev/null
@@ -1,41 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-controls.html", 800, 600, 1, "none"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that form controls are rendered with correct theme. See crbug.com/591315. -</p> -<form> -<input type="radio" class="device-emulation-measure">Radio<br> -<input type="checkbox" class="device-emulation-measure">Checkbox<br> -</form> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls.js new file mode 100644 index 0000000..13649f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-controls.js
@@ -0,0 +1,26 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that form controls are rendered with correct theme. See crbug.com/591315.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(800, 600, 1); + + var viewport = 'none'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.log(await session.evaluate(` + var input = document.createElement('input'); + input.type = 'radio'; + document.body.appendChild(input); + 'measured radio: ' + input.offsetWidth + 'x' + input.offsetHeight + `)); + testRunner.log(await session.evaluate(` + var input = document.createElement('input'); + input.type = 'checkbox'; + document.body.appendChild(input); + 'measured checkbox: ' + input.offsetWidth + 'x' + input.offsetHeight + `)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x-expected.txt index e20b0d38..7af4b24 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x2 viewport='w=dw' +Emulating device: 1200x1000x2 +Loading page with viewport=w=dw Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x.html deleted file mode 100644 index 73e321a..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-dw-2x.html", 1200, 1000, 2, "w=dw"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x.js new file mode 100644 index 0000000..1d9e915 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-2x.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 2); + + var viewport = 'w=dw'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-expected.txt index b839448..69b3f42 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x1 viewport='w=dw' +Emulating device: 1200x1000x1 +Loading page with viewport=w=dw Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw.html deleted file mode 100644 index eab4d6a..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-dw.html", 1200, 1000, 1, "w=dw"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw.js new file mode 100644 index 0000000..00300ef --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-dw.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 1); + + var viewport = 'w=dw'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale-expected.txt index dc11c4b..401808d2 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale-expected.txt
@@ -1,7 +1,11 @@ -Tests that turning on device emulation with a non-1 device pixel ratio sets the appropriate initial scale. Page scale is reflected by the innerWidth and innerHeight properties. Since the layout width is set to 980 (in the viewport meta tag), and the emulated viewport width is 490 px, the initial scale should be 490/980 = 0.5. i.e. innerWidth=980 innerHeight=640. -Page reloaded. -Emulating device: 490x320x3 viewport='w=980' + Tests that turning on device emulation with a non-1 device pixel ratio sets the + appropriate initial scale. Page scale is reflected by the innerWidth and + innerHeight properties. Since the layout width is set to 980 (in the viewport + meta tag), and the emulated viewport width is 490 px, the initial scale should + be 490/980 = 0.5. i.e. innerWidth=980 innerHeight=640. +Emulating device: 490x320x3 +Loading page with viewport=w=980 Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +42,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale.html deleted file mode 100644 index 4edb372..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale.html +++ /dev/null
@@ -1,42 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - // 980px viewport loaded into a 490x320 screen should load at 0.5 scale. - InspectorTest.testDeviceEmulation("device-emulation-initial-scale.html", 490, 320, 3, "w=980"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that turning on device emulation with a non-1 device pixel ratio sets the -appropriate initial scale. Page scale is reflected by the innerWidth and -innerHeight properties. Since the layout width is set to 980 (in the viewport -meta tag), and the emulated viewport width is 490 px, the initial scale should -be 490/980 = 0.5. i.e. innerWidth=980 innerHeight=640. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale.js new file mode 100644 index 0000000..f626513 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-initial-scale.js
@@ -0,0 +1,20 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank(` + Tests that turning on device emulation with a non-1 device pixel ratio sets the + appropriate initial scale. Page scale is reflected by the innerWidth and + innerHeight properties. Since the layout width is set to 980 (in the viewport + meta tag), and the emulated viewport width is 490 px, the initial scale should + be 490/980 = 0.5. i.e. innerWidth=980 innerHeight=640.`); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + // 980px viewport loaded into a 490x320 screen should load at 0.5 scale. + await deviceEmulator.emulate(490, 320, 3); + + var viewport = 'w=980'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets-expected.txt index 7ef3a45..f357336 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation with insets affects window.screenWidth, window.screenHeight, screen.width and screen.height. - -Page reloaded. -Emulating device: 1200x1000x1 viewport='none' +Emulating device: 1200x1000x1 +Loading page with viewport=none Device: window.screenX = 10px window.screenY = 20px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets.html deleted file mode 100644 index bf898fc..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-insets.html", 1200, 1000, 1, "none", {left: 10, top: 20, right: 30, bottom: 40}); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation with insets affects window.screenWidth, window.screenHeight, screen.width and screen.height. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets.js new file mode 100644 index 0000000..684386c --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-insets.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation with insets affects window.screenWidth, window.screenHeight, screen.width and screen.height.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 1, {left: 10, top: 20, right: 30, bottom: 40}); + + var viewport = 'none'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x-expected.txt index 1c0bfb3..dfd32a2 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x2 viewport='none' +Emulating device: 1200x1000x2 +Loading page with viewport=none Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x.html deleted file mode 100644 index e6bcdc3..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-none-2x.html", 1200, 1000, 2, "none"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x.js new file mode 100644 index 0000000..db49109 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-2x.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 2); + + var viewport = 'none'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-expected.txt index 92d7196f..06d447e 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none-expected.txt
@@ -1,7 +1,6 @@ Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. - -Page reloaded. -Emulating device: 1200x1000x1 viewport='none' +Emulating device: 1200x1000x1 +Loading page with viewport=none Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +37,3 @@ doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none.html deleted file mode 100644 index 04ff69f..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-none.html", 1200, 1000, 1, "none"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none.js new file mode 100644 index 0000000..b7dd26d --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-none.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(1200, 1000, 1); + + var viewport = 'none'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial-expected.txt index 1fb02015..10265b2 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial-expected.txt
@@ -1,6 +1,5 @@ Tests that overriding only a single parameter does not affect others. - Running test: collectMetrics Running test: noOverrides
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial.html deleted file mode 100644 index a041ec8..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial.html +++ /dev/null
@@ -1,138 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - -<style> -body { - margin: 0; - min-height: 1000px; -} -</style> - -<script> -function dumpMetrics() -{ - return JSON.stringify({ - width: window.innerWidth, - height: window.innerHeight, - screenWidth: window.screen.width, - screenHeight: window.screen.height, - screenX: window.screenX, - screenY: window.screenY, - deviceScaleFactor: window.devicePixelRatio - }); -} - -function test() -{ - function getPageMetrics(callback) - { - InspectorTest.evaluateInPage("dumpMetrics()", parse); - - function parse(json) - { - callback(JSON.parse(json)); - } - } - - var initialMetrics; - - function testPartialOverride(name, value, next) - { - var params = {width: 0, height: 0, deviceScaleFactor: 0, mobile: false, fitWindow: false}; - if (name === null) { - InspectorTest.sendCommandOrDie("Emulation.clearDeviceMetricsOverride", {}, getPageMetrics.bind(null, check)); - } else { - if (name) - params[name] = value; - InspectorTest.sendCommandOrDie("Emulation.setDeviceMetricsOverride", params, getPageMetrics.bind(null, check)); - } - - function check(metrics) - { - var fail = false; - for (var key in initialMetrics) { - var expected = key === name ? value : initialMetrics[key]; - if (metrics[key] !== expected) { - InspectorTest.log("[FAIL]: " + metrics[key] + " instead of " + expected + " for " + key); - fail = true; - } - } - if (!fail) - InspectorTest.log(name ? ("[PASS]: " + name + "=" + value) : "[PASS]"); - next(); - } - } - - InspectorTest.runTestSuite([ - function collectMetrics(next) - { - function collect(metrics) - { - initialMetrics = metrics; - next(); - } - getPageMetrics(collect); - }, - - function noOverrides(next) - { - testPartialOverride("", 0, next); - }, - - function width(next) - { - testPartialOverride("width", 300, next); - }, - - function height(next) - { - testPartialOverride("height", 400, next); - }, - - function deviceScaleFactor1(next) - { - testPartialOverride("deviceScaleFactor", 1, next); - }, - - function deviceScaleFactor2(next) - { - testPartialOverride("deviceScaleFactor", 2, next); - }, - - function clear(next) - { - testPartialOverride(null, null, next); - }, - - function anotherWidth(next) - { - testPartialOverride("width", 400, next); - }, - - function anotherHeight(next) - { - testPartialOverride("height", 300, next); - }, - - function deviceScaleFactor3(next) - { - testPartialOverride("deviceScaleFactor", 3, next); - }, - - function clear(next) - { - testPartialOverride(null, null, next); - } - ]); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that overriding only a single parameter does not affect others. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial.js new file mode 100644 index 0000000..8d3c637 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-partial.js
@@ -0,0 +1,95 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startHTML(` + <head> + <style> + body { + margin: 0; + min-height: 1000px; + } + </style> + </head> + `, 'Tests that overriding only a single parameter does not affect others.'); + + function dumpMetrics() { + return JSON.stringify({ + width: window.innerWidth, + height: window.innerHeight, + screenWidth: window.screen.width, + screenHeight: window.screen.height, + screenX: window.screenX, + screenY: window.screenY, + deviceScaleFactor: window.devicePixelRatio + }); + } + + var initialMetrics; + + async function testPartialOverride(name, value) { + var params = {width: 0, height: 0, deviceScaleFactor: 0, mobile: false, fitWindow: false}; + if (name === null) { + await dp.Emulation.clearDeviceMetricsOverride(); + } else { + if (name) + params[name] = value; + await dp.Emulation.setDeviceMetricsOverride(params); + } + + var metrics = JSON.parse(await session.evaluate(dumpMetrics)); + var fail = false; + for (var key in initialMetrics) { + var expected = key === name ? value : initialMetrics[key]; + if (metrics[key] !== expected) { + testRunner.log('[FAIL]: ' + metrics[key] + ' instead of ' + expected + ' for ' + key); + fail = true; + } + } + if (!fail) + testRunner.log(name ? ('[PASS]: ' + name + '=' + value) : '[PASS]'); + } + + await testRunner.runTestSuite([ + async function collectMetrics() { + initialMetrics = JSON.parse(await session.evaluate(dumpMetrics)); + }, + + async function noOverrides() { + await testPartialOverride('', 0); + }, + + async function width() { + await testPartialOverride('width', 300); + }, + + async function height() { + await testPartialOverride('height', 400); + }, + + async function deviceScaleFactor1() { + await testPartialOverride('deviceScaleFactor', 1); + }, + + async function deviceScaleFactor2() { + await testPartialOverride('deviceScaleFactor', 2); + }, + + async function clear() { + await testPartialOverride(null, null); + }, + + async function anotherWidth() { + await testPartialOverride('width', 400); + }, + + async function anotherHeight() { + await testPartialOverride('height', 300); + }, + + async function deviceScaleFactor3() { + await testPartialOverride('deviceScaleFactor', 3); + }, + + async function clear() { + await testPartialOverride(null, null); + } + ]); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore-expected.txt index 6c609244..66e8ce45 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore-expected.txt
@@ -1,7 +1,6 @@ Tests that disabling device emulation restores back to original values. - -Page reloaded. -Emulating device: 1200x1000x1 viewport='w=320' +Emulating device: 1200x1000x1 +Loading page with viewport=w=320 Device: window.screenX = 0px window.screenY = 0px @@ -37,6 +36,5 @@ doc.body.clientHeight = 266px doc.body.offsetHeight = 1000px doc.body.scrollHeight = 1000px - Original metrics restored correctly.
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore.html deleted file mode 100644 index 6cd01f0f..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore.html +++ /dev/null
@@ -1,63 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest._deviceEmulationPageUrl = "device-emulation-restore.html"; - InspectorTest._deviceEmulationResults = []; - var originalMetrics; - - InspectorTest.applyEmulationAndReload(false, 0, 0, 1, "none", null, undefined, InspectorTest.getPageMetrics.bind(InspectorTest, true, saveMetrics)); - - function saveMetrics(metrics) - { - originalMetrics = metrics.value; - InspectorTest.emulateAndGetMetrics(1200, 1000, 1, "w=320", null, undefined, restore); - } - - function restore() - { - function callback(metrics) - { - metrics = metrics.value; - if (metrics != originalMetrics) - InspectorTest._deviceEmulationResults.push("Original metrics not restored.\n==== Original ===\n" + originalMetrics + "\n==== Restored ====\n" + metrics); - else - InspectorTest._deviceEmulationResults.push("Original metrics restored correctly."); - InspectorTest.log(InspectorTest._deviceEmulationResults.join("\n")); - InspectorTest.completeTest(); - } - - InspectorTest.applyEmulationAndReload(false, 0, 0, 1, "none", null, undefined, InspectorTest.getPageMetrics.bind(InspectorTest, true, callback)); - } -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that disabling device emulation restores back to original values. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore.js new file mode 100644 index 0000000..5507921b --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-restore.js
@@ -0,0 +1,27 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that disabling device emulation restores back to original values.'); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + + var viewport = 'none'; + await session.navigate('../resources/device-emulation.html?' + viewport); + var originalMetrics = await session.evaluate(`dumpMetrics(true)`); + + await deviceEmulator.emulate(1200, 1000, 1); + viewport = 'w=320'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + + await deviceEmulator.clear(); + viewport = 'none'; + await session.navigate('../resources/device-emulation.html?' + viewport); + var metrics = await session.evaluate(`dumpMetrics(true)`); + if (metrics != originalMetrics) + testRunner.log('Original metrics not restored.\n==== Original ===\n' + originalMetrics + '\n==== Restored ====\n' + metrics); + else + testRunner.log('Original metrics restored correctly.'); + + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw-expected.txt index 795a58c..9df155a 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw-expected.txt
@@ -1,7 +1,9 @@ -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. Emulating small device on a page with viewport "width=device-width" set should work without reload for page without scrollbar. -Page reloaded. -Emulating device: 380x420x1 viewport='w=dw' + Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. + Emulating small device on a page with viewport "width=device-width" set should work without reload for page without scrollbar. + +Emulating device: 380x420x1 +Loading page with viewport=w=dw Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +40,3 @@ doc.body.offsetHeight = 420px doc.body.scrollHeight = 420px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw.html deleted file mode 100644 index 1aea636..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw.html +++ /dev/null
@@ -1,38 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport("w=dw"); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 100px; - overflow: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-small-dw.html", 380, 420, 1, "w=dw", undefined, false); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -Emulating small device on a page with viewport "width=device-width" set should work without reload for page without scrollbar. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw.js new file mode 100644 index 0000000..70d7270 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-dw.js
@@ -0,0 +1,18 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank(` + Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. + Emulating small device on a page with viewport "width=device-width" set should work without reload for page without scrollbar. + `); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(380, 420, 1); + + var viewport = 'w=dw'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + await session.evaluate(`document.body.classList.add('small')`); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-expected.txt index 98bb24a5..8540d74 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small-expected.txt
@@ -1,7 +1,9 @@ -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. Emulating small device on a page without viewport set should take UA viewport settings into account. -Page reloaded. -Emulating device: 380x420x1 viewport='none' + Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. + Emulating small device on a page without viewport set should take UA viewport settings into account. + +Emulating device: 380x420x1 +Loading page with viewport=none Device: window.screenX = 0px window.screenY = 0px @@ -38,4 +40,3 @@ doc.body.offsetHeight = 1083px doc.body.scrollHeight = 1083px -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small.html deleted file mode 100644 index 943eef8..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small.html +++ /dev/null
@@ -1,38 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="../resources/device-emulation-test.js"></script> - -<script> -// This test is based on http://jsbin.com/urowoh/latest. -setMetaViewport(); -</script> - -<style> -html { - overflow-x: hidden; -} - -body { - margin: 0; - min-height: 1000px; - overflow-x: hidden; -} -</style> - -<script> -function test() -{ - InspectorTest.testDeviceEmulation("device-emulation-small.html", 380, 420, 1, "none"); -} -</script> - -</head> -<body onload="runTest()"> -<p> -Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. -Emulating small device on a page without viewport set should take UA viewport settings into account. -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small.js new file mode 100644 index 0000000..a30d3211 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-emulation-small.js
@@ -0,0 +1,17 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank(` + Tests that device emulation affects media rules, viewport meta tag, body dimensions and window.screen. + Emulating small device on a page without viewport set should take UA viewport settings into account. + `); + + var DeviceEmulator = await testRunner.loadScript('../resources/device-emulator.js'); + var deviceEmulator = new DeviceEmulator(testRunner, session); + await deviceEmulator.emulate(380, 420, 1); + + var viewport = 'none'; + testRunner.log(`Loading page with viewport=${viewport}`); + await session.navigate('../resources/device-emulation.html?' + viewport); + + testRunner.log(await session.evaluate(`dumpMetrics(true)`)); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant-expected.txt index f43ec9b..40033b4 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant-expected.txt
@@ -1,6 +1,4 @@ Test that srcset does not use wrong image when override scalefactor and then disabled. - - Set deviceScaleFactor: 1 Reloading Page
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant.html b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant.html deleted file mode 100644 index c673b7eb..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant.html +++ /dev/null
@@ -1,87 +0,0 @@ -<html> -<head> -<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript"> - -function getCurrentSrc() -{ - return document.getElementById("image-test").currentSrc; -} - -function test() -{ - function setScaleFactor(value) - { - InspectorTest.log("Set deviceScaleFactor: " + value); - return InspectorTest.sendCommandPromise("Emulation.setDeviceMetricsOverride", { - deviceScaleFactor: value, - width: 1, - height: 1, - mobile: false, - fitWindow: false - }); - } - - function clearScaleFactor(value) - { - InspectorTest.log("Clear deviceScaleFactor"); - return InspectorTest.sendCommandPromise("Emulation.clearDeviceMetricsOverride", {}); - } - - function reloadPage() - { - InspectorTest.log("Reloading Page"); - return new Promise(success => InspectorTest.reloadProtocolTest(false, success)); - } - - function getSrcsetImage() - { - var runInPage = InspectorTest.evaluateInInspectedPage; - return new Promise(success => runInPage("getCurrentSrc()", result => success(result.result.result.value))); - } - - function dumpImageSrc() - { - return getSrcsetImage().then(src => { - var relativeSrc = src.substring(src.lastIndexOf("/resources/")); - InspectorTest.log("Used Image: " + relativeSrc); - }); - } - - var initialImage; - - // Test chain functions. - collectMetrics(); - - function collectMetrics() - { - getSrcsetImage().then(src => initialImage = src).then(setLowResScaleFactor); - } - - function setLowResScaleFactor() - { - setScaleFactor(1).then(reloadPage).then(dumpImageSrc).then(setHighResScaleFactor); - } - - function setHighResScaleFactor() - { - setScaleFactor(2).then(reloadPage).then(dumpImageSrc).then(clearOverride); - } - - function clearOverride() - { - clearScaleFactor().then(reloadPage).then(getSrcsetImage).then(value => { - var initImageEqCurrentImg = initialImage === value ? "Yes" : "No"; - InspectorTest.log("Current image src equal initial image: " + initImageEqCurrentImg); - InspectorTest.completeTest(); - }); - } -} - -</script> -</head> -<body onload="runTest()"> -<p>Test that srcset does not use wrong image when override scalefactor and then disabled.</p> -<img id="image-test" src="../resources/square.png" srcset="../resources/square.png 1x, ../resources/square200.png 2x" /> -</body> -</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant.js b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant.js new file mode 100644 index 0000000..206672e8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/emulation/device-scale-not-persistant.js
@@ -0,0 +1,52 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startURL('../resources/device-scale-not-persistant.html', + 'Test that srcset does not use wrong image when override scalefactor and then disabled.'); + + function getSrcsetImage() { + return session.evaluate(`document.getElementById('image-test').currentSrc`); + } + + async function setScaleFactor(value) { + testRunner.log('Set deviceScaleFactor: ' + value); + await dp.Emulation.setDeviceMetricsOverride({ + deviceScaleFactor: value, + width: 1, + height: 1, + mobile: false, + fitWindow: false + }); + } + + async function reloadPage() { + testRunner.log('Reloading Page'); + dp.Page.reload(); + await dp.Page.onceLoadEventFired(); + testRunner.log('\nPage reloaded.\n'); + } + + async function dumpImageSrc() { + var src = await getSrcsetImage(); + var relativeSrc = src.substring(src.lastIndexOf('/resources/')); + testRunner.log('Used Image: ' + relativeSrc); + } + + dp.Page.enable(); + var initialImage = await getSrcsetImage(); + + await setScaleFactor(1); + await reloadPage(); + await dumpImageSrc(); + + await setScaleFactor(2); + await reloadPage(); + await dumpImageSrc(); + + testRunner.log('Clear deviceScaleFactor'); + await dp.Emulation.clearDeviceMetricsOverride(); + await reloadPage(); + var value = await getSrcsetImage(); + var initImageEqCurrentImg = initialImage === value ? 'Yes' : 'No'; + testRunner.log('Current image src equal initial image: ' + initImageEqCurrentImg); + + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers-expected.txt index c4bdfe61..0aebf27 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers-expected.txt
@@ -1,4 +1,5 @@ + [ { "layerId": "string",
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers.html b/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers.html deleted file mode 100644 index 0131fc7..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers.html +++ /dev/null
@@ -1,156 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/layer-protocol-test.js"></script> -<script type="text/javascript"> - -function addCompositedLayer() -{ - var element = document.createElement("div"); - element.className = "composited"; - element.id = "last-element"; - document.body.appendChild(element); -}; - -function test() -{ - var documentNode; - var initialLayers; - var modifiedLayers; - - InspectorTest.enableLayerTreeAgent(gotInitialLayerTree); - - function gotInitialLayerTree(layers) - { - initialLayers = layers; - InspectorTest.setLayerTreeChangeCallback(gotModifiedLayerTree); - - InspectorTest.sendCommand("Runtime.evaluate", {"expression": "addCompositedLayer()"}); - }; - - function gotModifiedLayerTree(layers) - { - modifiedLayers = layers; - - var mutations = layerMutations(initialLayers, modifiedLayers); - var newLayer = mutations.additions[0]; - - InspectorTest.sendCommand("DOM.pushNodesByBackendIdsToFrontend", {"backendNodeIds": [newLayer.backendNodeId]}, InspectorTest.wrapCallback(gotNodeId)); - }; - - function gotNodeId(result) - { - InspectorTest.sendCommand("DOM.getAttributes", {"nodeId": result.nodeIds[0]}, InspectorTest.wrapCallback(gotNodeAttributes)); - } - - function gotNodeAttributes(result) - { - var attributes = attributesDictionaryFromArray(result.attributes); - if (attributes.id !== "last-element") - InspectorTest.log("FAIL: Did not obtain the expected element for the last inserted layer."); - - dumpLayers(initialLayers); - dumpLayers(modifiedLayers); - InspectorTest.log("DONE!"); - InspectorTest.completeTest(); - }; - - function layerMutations(oldLayers, newLayers) - { - function layerIdMap(layer) { - return layer.layerId; - } - - var oldLayerIds = oldLayers.map(layerIdMap); - var newLayerIds = newLayers.map(layerIdMap); - - return { - additions: newLayers.filter(function (layer) { - return (oldLayerIds.indexOf(layer.layerId) === -1); - }), - removals: oldLayers.filter(function (layer) { - return (newLayerIds.indexOf(layer.layerId) === -1); - }) - }; - }; - - function attributesDictionaryFromArray(attributes) - { - var dictionary = {} - for (var i = 0, count = attributes.length; i < count; i += 2) { - dictionary[attributes[i]] = attributes[i + 1]; - } - return dictionary; - }; - - function dumpLayers(layers) - { - // Keep "internal" layers out for better stability. - layers = layers.filter(function(layer) { return !!layer.backendNodeId; }); - function replacer(key, value) - { - - if (["layerId", "parentLayerId", "backendNodeId", "paintCount"].indexOf(key) >= 0) - return typeof(value); - - // some values differ based on port, but the ones we most - // care about will always be less or equal 100. - if ((key === "width" || key === "height") && value > 100) - return typeof(value); - - return value; - }; - - InspectorTest.log("\n" + JSON.stringify(layers, replacer, " ")); - }; -}; - -window.addEventListener("DOMContentLoaded", function () { - runTest(); -}, false); - -</script> -<style type="text/css"> - - div { - position: absolute; - top: 0; - left: 0; - } - - .regular { - width: 100px; - height: 100px; - background-color: black; - } - - .composited { - top: 25px; - left: 25px; - width: 50px; - height: 50px; - background-color: blue; - transform: translateZ(0); - } - - .offset { - left: 200px; - transform: translateZ(0); - } - -</style> -</head> -<body> - - <div class="regular"></div> - - <div class="composited"> - <div class="composited"></div> - </div> - - <div class="regular offset"> - <div class="composited"></div> - </div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers.js b/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers.js new file mode 100644 index 0000000..d5b92584 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layers/get-layers.js
@@ -0,0 +1,56 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startURL('../resources/get-layers.html', ''); + + function layerMutations(oldLayers, newLayers) { + var oldLayerIds = oldLayers.map(layer => layer.layerId); + var newLayerIds = newLayers.map(layer => layer.layerId); + return { + additions: newLayers.filter(layer => oldLayerIds.indexOf(layer.layerId) === -1), + removals: oldLayers.filter(layer => newLayerIds.indexOf(layer.layerId) === -1) + }; + } + + function attributesFromArray(attributes) { + var map = new Map(); + for (var i = 0, count = attributes.length; i < count; i += 2) + map.set(attributes[i], attributes[i + 1]); + return map; + } + + function dumpLayers(layers) { + function replacer(key, value) { + if (['layerId', 'parentLayerId', 'backendNodeId', 'paintCount'].indexOf(key) >= 0) + return typeof(value); + // some values differ based on port, but the ones we most + // care about will always be less or equal 100. + if ((key === 'width' || key === 'height') && value > 100) + return typeof(value); + return value; + } + + // Keep 'internal' layers out for better stability. + layers = layers.filter(layer => !!layer.backendNodeId); + testRunner.log('\n' + JSON.stringify(layers, replacer, ' ')); + } + + await dp.DOM.getDocument(); + dp.LayerTree.enable(); + var initialLayers = (await dp.LayerTree.onceLayerTreeDidChange()).params.layers; + + dp.Runtime.evaluate({expression: 'addCompositedLayer()'}); + var modifiedLayers = (await dp.LayerTree.onceLayerTreeDidChange()).params.layers; + + var mutations = layerMutations(initialLayers, modifiedLayers); + var newLayer = mutations.additions[0]; + + var nodeResponse = await dp.DOM.pushNodesByBackendIdsToFrontend({backendNodeIds: [newLayer.backendNodeId]}); + var attributesResponse = await dp.DOM.getAttributes({nodeId: nodeResponse.result.nodeIds[0]}); + var attributes = attributesFromArray(attributesResponse.result.attributes); + if (attributes.get('id') !== 'last-element') + testRunner.log('FAIL: Did not obtain the expected element for the last inserted layer.'); + + dumpLayers(initialLayers); + dumpLayers(modifiedLayers); + testRunner.log('DONE!'); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler-load-empty.html b/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler-load-empty.html deleted file mode 100644 index 4c7f0b7..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler-load-empty.html +++ /dev/null
@@ -1,29 +0,0 @@ -<html> -<head> -<script type="application/x-javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="application/x-javascript" src="../resources/layer-protocol-test.js"></script> -<script type="application/x-javascript"> - -function test() -{ - InspectorTest.sendCommand("LayerTree.loadSnapshot", { - "tiles": [{ - "x":351378, - "y":-15, - "picture": "c2tpYXBpY3QqAAAAiYICRsMkWkF3URZGz3Z9QgcAAAABZGFlcgAAAAB0Y2FmBAAAAAAAAABjZnB0AAAAAHlhcmEAAAAAIGZvZQ==" - }] - }, InspectorTest.wrapCallback(onLoad)); - - function onLoad(result) - { - InspectorTest.log("Loading empty snapshot: " + result.error); - InspectorTest.completeTest(); - } -} - -</script> -<body onload="runTest()"> - <div>Tests that Paint Profiler refuses to load a picture with empty dimensions</div> -</body> -</html> -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler-load-empty.js b/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler-load-empty.js new file mode 100644 index 0000000..04c7278d --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler-load-empty.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that Paint Profiler refuses to load a picture with empty dimensions'); + + var response = await dp.LayerTree.loadSnapshot({ + tiles: [{ + x: 351378, + y: -15, + picture: 'c2tpYXBpY3QqAAAAiYICRsMkWkF3URZGz3Z9QgcAAAABZGFlcgAAAAB0Y2FmBAAAAAAAAABjZnB0AAAAAHlhcmEAAAAAIGZvZQ==' + }] + }); + + testRunner.log('Loading empty snapshot: ' + response.error); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler.html b/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler.html deleted file mode 100644 index 06134e06..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler.html +++ /dev/null
@@ -1,66 +0,0 @@ -<html> -<head> -<style type="text/css"> -.composited { - position: absolute; - top: 25px; - left: 25px; - width: 50px; - height: 50px; - background-color: blue; - transform: translateZ(10px); -} -</style> -<script type="application/x-javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="application/x-javascript" src="../resources/layer-protocol-test.js"></script> -<script type="application/x-javascript"> - -function test() -{ - var documentNode; - var initialLayers; - var modifiedLayers; - - InspectorTest.enableLayerTreeAgent(gotLayerTree); - - function gotLayerTree(layers) - { - var matchingLayers = layers.filter(function(layer) { return !!(layer.backendNodeId && layer.transform); }); - InspectorTest.log("matchingLayers.length: " + matchingLayers.length); - var layerId = matchingLayers[0].layerId; - - InspectorTest.sendCommand("LayerTree.makeSnapshot", {"layerId": layerId}, InspectorTest.wrapCallback(gotSnapshot)); - } - var snapshotId; - function gotSnapshot(result) - { - snapshotId = result.snapshotId; - InspectorTest.sendCommand("LayerTree.profileSnapshot", {"snapshotId": snapshotId, "minRepeatCount":4, "minDuration": 0}, InspectorTest.wrapCallback(gotProfile)); - } - function gotProfile(result) - { - var timings = result.timings; - InspectorTest.log("Profile array length: " + result.timings.length); - for (var i = 0; i < result.timings.length; ++i) { - InspectorTest.log("Profile subarray " + i + " length: " + result.timings[i].length); - for (var j = 0; j < result.timings[i].length; ++j) - InspectorTest.log("Profile timing [" + i + "][" + j + "] is a number: " + (result.timings[i][j] >= 0)); - } - InspectorTest.sendCommand("LayerTree.replaySnapshot", {"snapshotId": snapshotId, "fromStep": 2, "toStep": result.timings[0].length - 2}, InspectorTest.wrapCallback(replayedSnapshot)); - } - function replayedSnapshot(result) - { - InspectorTest.log("LayerTree.replaySnapshot returned valid image: " + /^data:image\/png;base64,/.test(result.dataURL)); - InspectorTest.log("DONE!"); - InspectorTest.completeTest(); - } -} - -</script> -<body onload="runTest()"> - <div class="composited"> - Sanity test for DevTools Paint Profiler. - </div> -</body> -</html> -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler.js b/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler.js new file mode 100644 index 0000000..695b742 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layers/paint-profiler.js
@@ -0,0 +1,43 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startHTML(` + <head> + <style type='text/css'> + .composited { + position: absolute; + top: 25px; + left: 25px; + width: 50px; + height: 50px; + background-color: blue; + transform: translateZ(10px); + } + </style> + </head> + <body> + <div class='composited'> + Sanity test for DevTools Paint Profiler. + </div> + </body> + `, 'Sanity test for DevTools Paint Profiler.'); + + await dp.DOM.getDocument(); + dp.LayerTree.enable(); + var layers = (await dp.LayerTree.onceLayerTreeDidChange()).params.layers; + var matchingLayers = layers.filter(layer => !!(layer.backendNodeId && layer.transform)); + testRunner.log('matchingLayers.length: ' + matchingLayers.length); + + var layerId = matchingLayers[0].layerId; + var snapshotId = (await dp.LayerTree.makeSnapshot({layerId})).result.snapshotId; + var timings = (await dp.LayerTree.profileSnapshot({snapshotId, minRepeatCount: 4, minDuration: 0})).result.timings; + testRunner.log('Profile array length: ' + timings.length); + for (var i = 0; i < timings.length; ++i) { + testRunner.log('Profile subarray ' + i + ' length: ' + timings[i].length); + for (var j = 0; j < timings[i].length; ++j) + testRunner.log('Profile timing [' + i + '][' + j + '] is a number: ' + (timings[i][j] >= 0)); + } + + var image = (await dp.LayerTree.replaySnapshot({snapshotId, fromStep: 2, toStep: timings[0].length - 2})).result.dataURL; + testRunner.log('LayerTree.replaySnapshot returned valid image: ' + /^data:image\/png;base64,/.test(image)); + testRunner.log('DONE!'); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulation-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulation.html similarity index 68% rename from third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulation-test.js rename to third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulation.html index 3cbf32f..d36e0b8 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulation-test.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulation.html
@@ -1,3 +1,6 @@ +<html> +<head> +<script> function setMetaViewport(override) { var VIEWPORTS = { @@ -105,10 +108,6 @@ testJS("document.body.offsetHeight"); testJS("document.body.scrollHeight"); - var measured = document.querySelectorAll(".device-emulation-measure"); - for (var i = 0; i < measured.length; ++i) - writeResult("measured " + measured[i].getAttribute("type") + ": " + measured[i].offsetWidth + "x" + measured[i].offsetHeight); - return results.join("\n"); } @@ -186,74 +185,29 @@ { results.push(key + (val ? " = " + val : "")); } +</script> -var initialize_DeviceEmulationTest = function() { +<script> + // This test is based on http://jsbin.com/urowoh/latest. + setMetaViewport(); +</script> -InspectorTest.getPageMetrics = function(full, callback) -{ - InspectorTest.evaluateInPage("dumpMetrics(" + full + ")", callback); +<style> +html { + overflow-x: hidden; } -InspectorTest.applyEmulationAndReload = function(enabled, width, height, deviceScaleFactor, viewport, insets, noReload, callback) -{ - if (enabled) { - var params = {}; - params.width = width; - params.height = height; - params.deviceScaleFactor = deviceScaleFactor; - params.mobile = true; - params.fitWindow = false; - params.scale = 1; - params.screenWidth = width; - params.screenHeight = height; - params.positionX = 0; - params.positionY = 0; - if (insets) { - params.screenWidth += insets.left + insets.right; - params.positionX = insets.left; - params.screenHeight += insets.top + insets.bottom; - params.positionY = insets.top; - } - InspectorTest.sendCommand("Emulation.setDeviceMetricsOverride", params, emulateCallback); - } else { - InspectorTest.sendCommand("Emulation.clearDeviceMetricsOverride", {}, emulateCallback); - } +body { + margin: 0; + min-height: 1000px; + overflow-x: hidden; +} +body.small { + min-height: 100px; +} +</style> +</head> - function emulateCallback(result) - { - if (result.error) - InspectorTest._deviceEmulationResults.push("Error: " + result.error); - if (noReload) - callback(); - else - InspectorTest.navigate(InspectorTest._deviceEmulationPageUrl + "?" + viewport, callback); - } -}; - -InspectorTest.emulateAndGetMetrics = function(width, height, deviceScaleFactor, viewport, insets, noReload, callback) -{ - InspectorTest._deviceEmulationResults.push("Emulating device: " + width + "x" + height + "x" + deviceScaleFactor + " viewport='" + viewport + "'"); - var full = !!width && !!height && !!deviceScaleFactor; - InspectorTest.applyEmulationAndReload(true, width, height, deviceScaleFactor, viewport, insets, noReload, InspectorTest.getPageMetrics.bind(InspectorTest, full, printMetrics)); - - function printMetrics(metrics) - { - InspectorTest._deviceEmulationResults.push(metrics + "\n"); - callback(); - } -}; - -InspectorTest.testDeviceEmulation = function(pageUrl, width, height, deviceScaleFactor, viewport, insets, noReload) -{ - InspectorTest._deviceEmulationPageUrl = pageUrl; - InspectorTest._deviceEmulationResults = []; - InspectorTest.emulateAndGetMetrics(width, height, deviceScaleFactor, viewport, insets, noReload, callback); - - function callback() - { - InspectorTest.log(InspectorTest._deviceEmulationResults.join("\n")); - InspectorTest.completeTest(); - } -}; - -}; +<body> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulator.js b/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulator.js new file mode 100644 index 0000000..9040dc4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-emulator.js
@@ -0,0 +1,36 @@ +(class DeviceEmulator { + constructor(testRunner, session) { + this._testRunner = testRunner; + this._session = session; + } + + async emulate(width, height, deviceScaleFactor, insets) { + this._testRunner.log(`Emulating device: ${width}x${height}x${deviceScaleFactor}`); + var full = !!width && !!height && !!deviceScaleFactor; + var params = { + width, + height, + deviceScaleFactor, + mobile: true, + fitWindow: false, + scale: 1, + screenWidth: width, + screenHeight: height, + positionX: 0, + positionY: 0 + }; + if (insets) { + params.screenWidth += insets.left + insets.right; + params.positionX = insets.left; + params.screenHeight += insets.top + insets.bottom; + params.positionY = insets.top; + } + var response = await this._session.protocol.Emulation.setDeviceMetricsOverride(params); + if (response.error) + this._testRunner.log('Error: ' + response.error); + } + + async clear() { + await this._session.protocol.Emulation.clearDeviceMetricsOverride(); + } +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-scale-not-persistant.html b/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-scale-not-persistant.html new file mode 100644 index 0000000..3c0d597f --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/device-scale-not-persistant.html
@@ -0,0 +1,3 @@ +<body> +<img id='image-test' src='square.png'srcset='square.png 1x, square200.png 2x' /> +</body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/get-layers.html b/third_party/WebKit/LayoutTests/inspector-protocol/resources/get-layers.html new file mode 100644 index 0000000..5424867 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/get-layers.html
@@ -0,0 +1,52 @@ +<html> +<head> +<script> +function addCompositedLayer() { + var element = document.createElement("div"); + element.className = "composited"; + element.id = "last-element"; + document.body.appendChild(element); +} +</script> +<style type="text/css"> +div { + position: absolute; + top: 0; + left: 0; +} + +.regular { + width: 100px; + height: 100px; + background-color: black; +} + +.composited { + top: 25px; + left: 25px; + width: 50px; + height: 50px; + background-color: blue; + transform: translateZ(0); +} + +.offset { + left: 200px; + transform: translateZ(0); +} +</style> +</head> +<body> + +<div class="regular"></div> + +<div class="composited"> + <div class="composited"></div> +</div> + +<div class="regular offset"> + <div class="composited"></div> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js index 5530d82..ca43106 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js
@@ -199,20 +199,7 @@ this._testRunner.die(`Cannot navigate to ${url} with active session`, new Error()); var session = await this.createSession(); - session.protocol.Page.enable(); - session.protocol.Page.navigate({url: url}); - - var callback; - var promise = new Promise(f => callback = f); - session.protocol.Page.onFrameNavigated(message => { - if (!message.params.frame.parentId) - callback(); - }); - await Promise.all([ - promise, - session.protocol.Page.onceLoadEventFired() - ]); - + await session._navigate(url); await session.disconnect(); } @@ -279,6 +266,26 @@ } } + navigate(url) { + return this._navigate(this._testRunner.url(url)); + } + + async _navigate(url) { + this.protocol.Page.enable(); + this.protocol.Page.navigate({url: url}); + + var callback; + var promise = new Promise(f => callback = f); + this.protocol.Page.onFrameNavigated(message => { + if (!message.params.frame.parentId) + callback(); + }); + await Promise.all([ + promise, + this.protocol.Page.onceLoadEventFired() + ]); + } + _dispatchMessage(message) { if (this._testRunner._dumpInspectorProtocolMessages) this._testRunner.log(`backend => frontend: ${JSON.stringify(message)}`);
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/layer-protocol-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/resources/layer-protocol-test.js deleted file mode 100644 index 16454eae..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/resources/layer-protocol-test.js +++ /dev/null
@@ -1,48 +0,0 @@ -function initialize_layersTest() -{ - -var layers; -var layerTreeChangeCallback; - -InspectorTest.step = function(test) -{ - InspectorTest.sendCommand(test.command, test.parameters, function(messageObject) { - if (messageObject.hasOwnProperty("error")) { - InspectorTest.log("FAIL: " + messageObject.error.message + " (" + messageObject.error.code + ")"); - InspectorTest.completeTest(); - return; - } - if (test.callback) - test.callback(messageObject.result); - }); -}; - -function onLayerTreeChanged(message) -{ - layers = message.params.layers; - if (layerTreeChangeCallback) { - var callback = layerTreeChangeCallback; - layerTreeChangeCallback = null; - callback(layers); - } -} - -InspectorTest.setLayerTreeChangeCallback = function(callback) -{ - layerTreeChangeCallback = callback; -} - -InspectorTest.enableLayerTreeAgent = function(callback) -{ - if (layers) { - callback(layers); - return; - } - InspectorTest.eventHandler["LayerTree.layerTreeDidChange"] = onLayerTreeChanged; - InspectorTest.setLayerTreeChangeCallback(callback); - InspectorTest.sendCommand("DOM.getDocument", {}, function() { - InspectorTest.sendCommand("LayerTree.enable", {}, function() { }); - }); -} - -}
diff --git a/third_party/WebKit/LayoutTests/inspector/console/paintworklet-console-selector-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/paintworklet-console-selector-expected.txt new file mode 100644 index 0000000..0e08896 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/console/paintworklet-console-selector-expected.txt
@@ -0,0 +1,6 @@ +Tests console execution context selector for paintworklet. + +Console context selector: +* top + ____Paint Worklet +
diff --git a/third_party/WebKit/LayoutTests/inspector/console/paintworklet-console-selector.html b/third_party/WebKit/LayoutTests/inspector/console/paintworklet-console-selector.html new file mode 100644 index 0000000..67e75b85 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/console/paintworklet-console-selector.html
@@ -0,0 +1,39 @@ +<html> +<head> +<script src="../../http/tests/inspector/inspector-test.js"></script> +<script src="../../http/tests/inspector/console-test.js"></script> +<script src="../../http/tests/inspector/debugger-test.js"></script> + +<script id="code" type="text/worklet"> + registerPaint('foo', class { paint() { } }); +</script> +<script> +function setup() { + var blob = new Blob([code.textContent], {type: 'text/javascript'}); + return paintWorklet.addModule(URL.createObjectURL(blob)); +} + +async function test() +{ + await new Promise(f => InspectorTest.startDebuggerTest(f, true)); + await InspectorTest.evaluateInPageAsync('setup()'); + + var consoleView = Console.ConsoleView.instance(); + var selector = consoleView._consoleContextSelector; + InspectorTest.addResult('Console context selector:'); + for (var executionContext of selector._items) { + var selected = UI.context.flavor(SDK.ExecutionContext) === executionContext; + var text = '____'.repeat(selector._depthFor(executionContext)) + selector.titleFor(executionContext); + var disabled = !selector.isItemSelectable(executionContext); + InspectorTest.addResult(`${selected ? '*' : ' '} ${text} ${disabled ? '[disabled]' : ''}`); + } + + InspectorTest.completeDebuggerTest(); +} +</script> +</head> +<body onload="runTest()"> +<p> Tests console execution context selector for paintworklet. +</p> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/inspector/network/network-json-parser.html b/third_party/WebKit/LayoutTests/inspector/network/network-json-parser.html index ad5ef82..29b90dbe 100644 --- a/third_party/WebKit/LayoutTests/inspector/network/network-json-parser.html +++ b/third_party/WebKit/LayoutTests/inspector/network/network-json-parser.html
@@ -6,7 +6,7 @@ function test() { function check(jsonText) { - var resultData = Network.JSONView._extractJSON(jsonText); + var resultData = SourceFrame.JSONView._extractJSON(jsonText); if (!resultData) { failure(); return;
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js index b0e68d4..402c991 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js
@@ -42,7 +42,7 @@ var defaultMapping = { rawLocationToUILocation: function(rawLocation) { - return InspectorTest.uiSourceCodes[rawLocation.scriptId].uiLocation(rawLocation.lineNumber, 0); + return null; }, uiLocationToRawLocation: function(uiSourceCode, lineNumber) @@ -103,7 +103,9 @@ { var script = new SDK.Script(this, scriptId, url); this._scripts[scriptId] = script; - this._debuggerWorkspaceBinding._debuggerModelToData.get(this)._parsedScriptSource({data: script}); + var modelData = this._debuggerWorkspaceBinding._debuggerModelToData.get(this); + modelData._defaultMapping._parsedScriptSource({data: script}); + modelData._resourceMapping._parsedScriptSource({data: script}); } _scriptForURL(url) @@ -227,14 +229,6 @@ { target.debuggerModel._addScript(url, url); InspectorTest.addResult(" Adding script: " + url); - var uiSourceCodes = breakpointManager._workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Debugger); - for (var i = 0; i < uiSourceCodes.length; ++i) { - var uiSourceCode = uiSourceCodes[i]; - if (uiSourceCode.url() === url) { - InspectorTest.uiSourceCodes[url] = uiSourceCode; - return uiSourceCode; - } - } } InspectorTest.addUISourceCode = function(target, breakpointManager, url, doNotSetSourceMapping, doNotAddScript)
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt index 3156177..84177152 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -6246,6 +6246,16 @@ getter valid getter valueMissing method constructor +interface VisualViewport : EventTarget + attribute @@toStringTag + getter height + getter offsetLeft + getter offsetTop + getter pageLeft + getter pageTop + getter scale + getter width + method constructor interface WaveShaperNode : AudioNode attribute @@toStringTag getter curve @@ -8088,6 +8098,7 @@ getter statusbar getter styleMedia getter toolbar + getter visualViewport getter webkitStorageInfo method NodeFilter method alert @@ -8264,6 +8275,7 @@ setter status setter statusbar setter toolbar + setter visualViewport PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt index 0d020233..9135a2cd 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -6175,6 +6175,16 @@ getter valid getter valueMissing method constructor +interface VisualViewport : EventTarget + attribute @@toStringTag + getter height + getter offsetLeft + getter offsetTop + getter pageLeft + getter pageTop + getter scale + getter width + method constructor interface WaveShaperNode : AudioNode attribute @@toStringTag getter curve @@ -8017,6 +8027,7 @@ getter statusbar getter styleMedia getter toolbar + getter visualViewport getter webkitStorageInfo method NodeFilter method alert @@ -8193,6 +8204,7 @@ setter status setter statusbar setter toolbar + setter visualViewport PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp index cd72e76..841caa9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -367,8 +367,8 @@ if (!world) return nullptr; if (!world_name.IsEmpty()) { - DOMWrapperWorld::SetIsolatedWorldHumanReadableName(world->GetWorldId(), - world_name); + DOMWrapperWorld::SetNonMainWorldHumanReadableName(world->GetWorldId(), + world_name); } // Make sure the execution context exists. WindowProxy(*world);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.cpp b/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.cpp index 04a9fd7..fc98d1aa 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.cpp
@@ -715,26 +715,28 @@ } ExecutionContext* ToExecutionContext(v8::Local<v8::Context> context) { - if (context.IsEmpty()) - return 0; + DCHECK(!context.IsEmpty()); + RUNTIME_CALL_TIMER_SCOPE(context->GetIsolate(), RuntimeCallStats::CounterId::kToExecutionContext); - v8::Local<v8::Object> global = context->Global(); - v8::Local<v8::Object> window_wrapper = - V8Window::findInstanceInPrototypeChain(global, context->GetIsolate()); - if (!window_wrapper.IsEmpty()) - return V8Window::toImpl(window_wrapper)->GetExecutionContext(); - v8::Local<v8::Object> worker_wrapper = - V8WorkerGlobalScope::findInstanceInPrototypeChain(global, - context->GetIsolate()); - if (!worker_wrapper.IsEmpty()) - return V8WorkerGlobalScope::toImpl(worker_wrapper)->GetExecutionContext(); - v8::Local<v8::Object> worklet_wrapper = - V8WorkletGlobalScope::findInstanceInPrototypeChain(global, - context->GetIsolate()); - if (!worklet_wrapper.IsEmpty()) - return V8WorkletGlobalScope::toImpl(worklet_wrapper); - // FIXME: Is this line of code reachable? + + v8::Local<v8::Object> global_proxy = context->Global(); + // There are several contexts other than Window, WorkerGlobalScope or + // WorkletGlobalScope but entering into ToExecutionContext, namely GC context, + // DevTools' context (debug context), and maybe more. They all don't have + // any internal field. + if (global_proxy->InternalFieldCount() == 0) + return nullptr; + + const WrapperTypeInfo* wrapper_type_info = ToWrapperTypeInfo(global_proxy); + if (wrapper_type_info->Equals(&V8Window::wrapperTypeInfo)) + return V8Window::toImpl(global_proxy)->GetExecutionContext(); + if (wrapper_type_info->IsSubclass(&V8WorkerGlobalScope::wrapperTypeInfo)) + return V8WorkerGlobalScope::toImpl(global_proxy)->GetExecutionContext(); + if (wrapper_type_info->IsSubclass(&V8WorkletGlobalScope::wrapperTypeInfo)) + return V8WorkletGlobalScope::toImpl(global_proxy)->GetExecutionContext(); + + NOTREACHED(); return nullptr; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp index 3a57f92..8b0fcaa 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
@@ -135,7 +135,8 @@ script_state_->DisposePerContextData(); } -bool WorkerOrWorkletScriptController::InitializeContextIfNeeded() { +bool WorkerOrWorkletScriptController::InitializeContextIfNeeded( + const String& human_readable_name) { v8::HandleScope handle_scope(isolate_); if (IsContextInitialized()) @@ -229,6 +230,13 @@ debugger->ContextCreated(global_scope_->GetThread(), context); } + // Set the human readable name for the world if the call passes an actual + // |human_readable name|. + if (!human_readable_name.IsEmpty()) { + world_->SetNonMainWorldHumanReadableName(world_->GetWorldId(), + human_readable_name); + } + return true; } @@ -241,7 +249,7 @@ TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", InspectorEvaluateScriptEvent::Data(nullptr, file_name, script_start_position)); - if (!InitializeContextIfNeeded()) + if (!InitializeContextIfNeeded(String())) return ScriptValue(); ScriptState::Scope scope(script_state_.Get());
diff --git a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.h b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.h index 94d4adf..fbd45653 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.h +++ b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.h
@@ -71,7 +71,7 @@ // Used by WorkerThread. Returns true if the context is successfully // initialized or already initialized. - bool InitializeContextIfNeeded(); + bool InitializeContextIfNeeded(const String& human_readable_name); // Used by WorkerGlobalScope: void RethrowExceptionFromImportedScript(ErrorEvent*, ExceptionState&);
diff --git a/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py b/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py index 75200f3..be8030c 100644 --- a/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py +++ b/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py
@@ -106,10 +106,6 @@ optimize=optimize) self.lexer = lexer self.tokens = lexer.KnownTokens() - # Using SLR (instead of LALR) generates the table faster, - # but produces the same output. This is ok b/c Web IDL (and Blink IDL) - # is an SLR grammar (as is often the case for simple LL(1) grammars). - # # Optimized mode substantially decreases startup time (by disabling # error checking), and also allows use of Python's optimized mode. # See: Using Python's Optimized Mode @@ -120,7 +116,6 @@ # See: CHANGES, Version 3.2 # http://ply.googlecode.com/svn/trunk/CHANGES self.yaccobj = yacc.yacc(module=self, - method='SLR', debug=debug, optimize=optimize, write_tables=write_tables,
diff --git a/third_party/WebKit/Source/bindings/scripts/blink_idl_parser_test.py b/third_party/WebKit/Source/bindings/scripts/blink_idl_parser_test.py new file mode 100644 index 0000000..309b463 --- /dev/null +++ b/third_party/WebKit/Source/bindings/scripts/blink_idl_parser_test.py
@@ -0,0 +1,21 @@ +# 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. + +# pylint: disable=no-member,relative-import + +"""Unit tests for blink_idl_parser.py.""" + +import unittest + +from blink_idl_parser import BlinkIDLParser + + +class BlinkIDLParserTest(unittest.TestCase): + + def test_missing_semicolon_between_definitions(self): + # No semicolon after enum definition. + text = '''enum TestEnum { "value" } dictionary TestDictionary {};''' + parser = BlinkIDLParser() + parser.ParseText(filename='', data=text) + self.assertGreater(parser.GetErrors(), 0)
diff --git a/third_party/WebKit/Source/core/animation/BasicShapeInterpolationFunctions.cpp b/third_party/WebKit/Source/core/animation/BasicShapeInterpolationFunctions.cpp index 82ad4bf..b180812 100644 --- a/third_party/WebKit/Source/core/animation/BasicShapeInterpolationFunctions.cpp +++ b/third_party/WebKit/Source/core/animation/BasicShapeInterpolationFunctions.cpp
@@ -7,7 +7,6 @@ #include "core/animation/CSSPositionAxisListInterpolationType.h" #include "core/animation/LengthInterpolationFunctions.h" #include "core/css/CSSBasicShapeValues.h" -#include "core/css/resolver/StyleResolverState.h" #include "core/style/BasicShapes.h" #include <memory>
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h b/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h index e99959a0..9f19d5e 100644 --- a/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h +++ b/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h
@@ -12,6 +12,7 @@ #include "core/animation/css/CSSAnimatableValueFactory.h" #include "core/css/CSSKeyframesRule.h" #include "core/css/CSSPropertyEquality.h" +#include "core/style/ComputedStyle.h" #include "platform/wtf/Allocator.h" #include "platform/wtf/HashMap.h" #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimations.h b/third_party/WebKit/Source/core/animation/css/CSSAnimations.h index ecfd7ec5..2b23b5533 100644 --- a/third_party/WebKit/Source/core/animation/css/CSSAnimations.h +++ b/third_party/WebKit/Source/core/animation/css/CSSAnimations.h
@@ -37,7 +37,6 @@ #include "core/animation/css/CSSAnimationUpdate.h" #include "core/css/CSSKeyframesRule.h" #include "core/css/StylePropertySet.h" -#include "core/css/resolver/StyleResolverState.h" #include "core/dom/Document.h" #include "core/dom/Element.h" #include "platform/wtf/HashMap.h"
diff --git a/third_party/WebKit/Source/core/css/PageRuleCollector.cpp b/third_party/WebKit/Source/core/css/PageRuleCollector.cpp index 73dc085..96626a9 100644 --- a/third_party/WebKit/Source/core/css/PageRuleCollector.cpp +++ b/third_party/WebKit/Source/core/css/PageRuleCollector.cpp
@@ -30,10 +30,10 @@ #include "core/css/PageRuleCollector.h" +#include <algorithm> #include "core/css/StylePropertySet.h" #include "core/css/StyleRule.h" -#include "core/css/resolver/StyleResolverState.h" -#include <algorithm> +#include "core/style/ComputedStyle.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/css/PropertyRegistration.cpp b/third_party/WebKit/Source/core/css/PropertyRegistration.cpp index 3e4ad4c..c7338f9a 100644 --- a/third_party/WebKit/Source/core/css/PropertyRegistration.cpp +++ b/third_party/WebKit/Source/core/css/PropertyRegistration.cpp
@@ -71,8 +71,7 @@ return true; } - // TODO(timloh): Images and transform-function values can also contain - // lengths. + // TODO(timloh): Images values can also contain lengths. return true; }
diff --git a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp index cb38396..3056b95 100644 --- a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp +++ b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
@@ -125,7 +125,7 @@ ? FontLoadHistograms::kFromDiskCache : FontLoadHistograms::kFromNetwork); histograms_.RecordRemoteFont(font_.Get(), is_intervention_triggered_); - histograms_.FontLoaded(font_->IsCORSFailed(), + histograms_.FontLoaded(!font_->IsSameOriginOrCORSSuccessful(), font_->GetStatus() == ResourceStatus::kLoadError, is_intervention_triggered_); @@ -336,7 +336,8 @@ RecordLoadTimeHistogram(font, duration, is_intervention_triggered); enum { kCORSFail, kCORSSuccess, kCORSEnumMax }; - int cors_value = font->IsCORSFailed() ? kCORSFail : kCORSSuccess; + int cors_value = + font->IsSameOriginOrCORSSuccessful() ? kCORSSuccess : kCORSFail; DEFINE_STATIC_LOCAL(EnumerationHistogram, cors_histogram, ("WebFont.CORSSuccess", kCORSEnumMax)); cors_histogram.Count(cors_value);
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp index f9db435..1f1e3d09 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -1440,8 +1440,18 @@ static const CSSValue& ComputeRegisteredPropertyValue( const CSSToLengthConversionData& css_to_length_conversion_data, const CSSValue& value) { - // TODO(timloh): Images and transform-function values can also contain - // lengths. + // TODO(timloh): Images values can also contain lengths. + if (value.IsFunctionValue()) { + const CSSFunctionValue& function_value = ToCSSFunctionValue(value); + CSSFunctionValue* new_function = + CSSFunctionValue::Create(function_value.FunctionType()); + for (const CSSValue* inner_value : ToCSSValueList(value)) { + new_function->Append(ComputeRegisteredPropertyValue( + css_to_length_conversion_data, *inner_value)); + } + return *new_function; + } + if (value.IsValueList()) { CSSValueList* new_list = CSSValueList::CreateSpaceSeparated(); for (const CSSValue* inner_value : ToCSSValueList(value)) {
diff --git a/third_party/WebKit/Source/core/dom/ClassicScript.cpp b/third_party/WebKit/Source/core/dom/ClassicScript.cpp index 04ea42ce..2918a612 100644 --- a/third_party/WebKit/Source/core/dom/ClassicScript.cpp +++ b/third_party/WebKit/Source/core/dom/ClassicScript.cpp
@@ -106,8 +106,7 @@ } else { CHECK(GetScriptSourceCode().GetResource()); access_control_status = - GetScriptSourceCode().GetResource()->CalculateAccessControlStatus( - security_origin); + GetScriptSourceCode().GetResource()->CalculateAccessControlStatus(); } frame->GetScriptController().ExecuteScriptInMainWorld(GetScriptSourceCode(),
diff --git a/third_party/WebKit/Source/core/editing/WebSubstringUtil.mm b/third_party/WebKit/Source/core/editing/WebSubstringUtil.mm index e892011..7584a65 100644 --- a/third_party/WebKit/Source/core/editing/WebSubstringUtil.mm +++ b/third_party/WebKit/Source/core/editing/WebSubstringUtil.mm
@@ -40,6 +40,7 @@ #include "core/dom/Range.h" #include "core/editing/FrameSelection.h" #include "core/editing/PlainTextRange.h" +#include "core/editing/VisibleUnits.h" #include "core/editing/iterators/TextIterator.h" #include "core/frame/LocalFrame.h" #include "core/frame/LocalFrameView.h" @@ -138,9 +139,7 @@ WebPoint getBaselinePoint(LocalFrameView* frameView, const EphemeralRange& range, NSAttributedString* string) { - // TODO(yosin): We shold avoid to create |Range| object. See crbug.com/529985. - IntRect stringRect = - frameView->ContentsToViewport(CreateRange(range)->BoundingBox()); + IntRect stringRect = frameView->ContentsToViewport(ComputeTextRect(range)); IntPoint stringPoint = stringRect.MinXMaxYCorner(); // Adjust for the font's descender. AppKit wants the baseline point.
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp index fb1fcc9d..52d9ddb 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerControllerTest.cpp
@@ -35,6 +35,7 @@ #include "core/dom/Document.h" #include "core/dom/Range.h" #include "core/dom/Text.h" +#include "core/editing/EditingTestBase.h" #include "core/editing/EphemeralRange.h" #include "core/html/HTMLElement.h" #include "core/testing/DummyPageHolder.h" @@ -44,12 +45,8 @@ namespace blink { -class DocumentMarkerControllerTest : public ::testing::Test { +class DocumentMarkerControllerTest : public EditingTestBase { protected: - DocumentMarkerControllerTest() - : dummy_page_holder_(DummyPageHolder::Create(IntSize(800, 600))) {} - - Document& GetDocument() const { return dummy_page_holder_->GetDocument(); } DocumentMarkerController& MarkerController() const { return GetDocument().Markers(); } @@ -57,10 +54,6 @@ Text* CreateTextNode(const char*); void MarkNodeContents(Node*); void MarkNodeContentsTextMatch(Node*); - void SetBodyInnerHTML(const char*); - - private: - std::unique_ptr<DummyPageHolder> dummy_page_holder_; }; Text* DocumentMarkerControllerTest::CreateTextNode(const char* text_contents) { @@ -84,12 +77,8 @@ TextMatchMarker::MatchStatus::kActive); } -void DocumentMarkerControllerTest::SetBodyInnerHTML(const char* body_content) { - GetDocument().body()->setInnerHTML(String::FromUTF8(body_content)); -} - TEST_F(DocumentMarkerControllerTest, DidMoveToNewDocument) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); MarkNodeContents(parent); EXPECT_EQ(1u, MarkerController().Markers().size()); @@ -103,7 +92,7 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByNormalize) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); { Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); @@ -118,7 +107,7 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveChildren) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); MarkNodeContents(parent); EXPECT_EQ(1u, MarkerController().Markers().size()); @@ -129,7 +118,7 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedByRemoveMarked) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); { Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); @@ -143,7 +132,7 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveAncestor) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); { Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); @@ -157,7 +146,7 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveParent) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); { Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); @@ -171,7 +160,7 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByReplaceChild) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); { Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); @@ -185,13 +174,13 @@ } TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedBySetInnerHTML) { - SetBodyInnerHTML("<b><i>foo</i></b>"); + SetBodyContent("<b><i>foo</i></b>"); { Element* parent = ToElement(GetDocument().body()->firstChild()->firstChild()); MarkNodeContents(parent); EXPECT_EQ(1u, MarkerController().Markers().size()); - SetBodyInnerHTML(""); + SetBodyContent(""); } // No more reference to marked node. ThreadState::Current()->CollectAllGarbage(); @@ -199,7 +188,7 @@ } TEST_F(DocumentMarkerControllerTest, UpdateRenderedRects) { - SetBodyInnerHTML("<div style='margin: 100px'>foo</div>"); + SetBodyContent("<div style='margin: 100px'>foo</div>"); Element* div = ToElement(GetDocument().body()->firstChild()); MarkNodeContentsTextMatch(div); Vector<IntRect> rendered_rects = @@ -215,9 +204,8 @@ } TEST_F(DocumentMarkerControllerTest, CompositionMarkersNotMerged) { - SetBodyInnerHTML("<div style='margin: 100px'>foo</div>"); + SetBodyContent("<div style='margin: 100px'>foo</div>"); Node* text = GetDocument().body()->firstChild()->firstChild(); - GetDocument().UpdateStyleAndLayout(); MarkerController().AddCompositionMarker( EphemeralRange(Position(text, 0), Position(text, 1)), Color::kBlack, StyleableMarker::Thickness::kThin, Color::kBlack); @@ -229,8 +217,7 @@ } TEST_F(DocumentMarkerControllerTest, SetMarkerActiveTest) { - SetBodyInnerHTML("<b>foo</b>"); - GetDocument().UpdateStyleAndLayout(); + SetBodyContent("<b>foo</b>"); Element* b_element = ToElement(GetDocument().body()->firstChild()); EphemeralRange ephemeral_range = EphemeralRange::RangeOfContents(*b_element); Position start_b_element = @@ -248,8 +235,7 @@ } TEST_F(DocumentMarkerControllerTest, RemoveStartOfMarker) { - SetBodyInnerHTML("<b>abc</b>"); - GetDocument().UpdateStyleAndLayout(); + SetBodyContent("<b>abc</b>"); Node* b_element = GetDocument().body()->firstChild(); Node* text = b_element->firstChild(); @@ -268,8 +254,7 @@ } TEST_F(DocumentMarkerControllerTest, RemoveMiddleOfMarker) { - SetBodyInnerHTML("<b>abc</b>"); - GetDocument().UpdateStyleAndLayout(); + SetBodyContent("<b>abc</b>"); Node* b_element = GetDocument().body()->firstChild(); Node* text = b_element->firstChild(); @@ -288,8 +273,7 @@ } TEST_F(DocumentMarkerControllerTest, RemoveEndOfMarker) { - SetBodyInnerHTML("<b>abc</b>"); - GetDocument().UpdateStyleAndLayout(); + SetBodyContent("<b>abc</b>"); Node* b_element = GetDocument().body()->firstChild(); Node* text = b_element->firstChild(); @@ -308,8 +292,7 @@ } TEST_F(DocumentMarkerControllerTest, RemoveSpellingMarkersUnderWords) { - SetBodyInnerHTML("<div contenteditable>foo</div>"); - GetDocument().UpdateStyleAndLayout(); + SetBodyContent("<div contenteditable>foo</div>"); Element* div = GetDocument().QuerySelector("div"); Node* text = div->firstChild();
diff --git a/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.h b/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.h index a5508c3d..6948647 100644 --- a/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.h +++ b/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.h
@@ -39,6 +39,7 @@ #include "core/workers/SharedWorkerReportingProxy.h" #include "core/workers/WorkerClients.h" #include "core/workers/WorkerThread.h" +#include "platform/WebTaskRunner.h" #include "platform/wtf/RefPtr.h" #include "public/platform/Platform.h" #include "public/platform/WebAddressSpace.h" @@ -107,9 +108,11 @@ const WebString& method, const WebString& message) override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override { + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const WebURLRequest& request, + SingleThreadTaskRunner* task_runner) override { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return Platform::Current()->CreateURLLoader(); + return Platform::Current()->CreateURLLoader(request, task_runner); } // Callback methods for SharedWorkerReportingProxy.
diff --git a/third_party/WebKit/Source/core/exported/WebViewTest.cpp b/third_party/WebKit/Source/core/exported/WebViewTest.cpp index b78f2dae..cdb4c84 100644 --- a/third_party/WebKit/Source/core/exported/WebViewTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebViewTest.cpp
@@ -59,6 +59,7 @@ #include "core/layout/api/LayoutViewItem.h" #include "core/loader/DocumentLoader.h" #include "core/loader/FrameLoadRequest.h" +#include "core/page/ChromeClient.h" #include "core/page/Page.h" #include "core/page/PrintContext.h" #include "core/page/ScopedPageSuspender.h" @@ -80,6 +81,7 @@ #include "platform/wtf/PtrUtil.h" #include "public/platform/Platform.h" #include "public/platform/WebCoalescedInputEvent.h" +#include "public/platform/WebCursorInfo.h" #include "public/platform/WebDisplayMode.h" #include "public/platform/WebDragData.h" #include "public/platform/WebDragOperation.h" @@ -2576,6 +2578,66 @@ web_view->HandleInputEvent(WebCoalescedInputEvent(key_event)); } +class MiddleClickAutoscrollWebWidgetClient + : public FrameTestHelpers::TestWebWidgetClient { + public: + // WebWidgetClient methods + + void DidChangeCursor(const WebCursorInfo& cursor) override { + last_cursor_type_ = cursor.type; + } + + int GetLastCursorType() const { return last_cursor_type_; } + + private: + int last_cursor_type_ = 0; +}; + +TEST_P(WebViewTest, MiddleClickAutoscrollCursor) { + MiddleClickAutoscrollWebWidgetClient client; + RuntimeEnabledFeatures::SetMiddleClickAutoscrollEnabled(true); + RegisterMockedHttpURLLoad("content-width-1000.html"); + + WebViewBase* web_view = web_view_helper_.InitializeAndLoad( + base_url_ + "content-width-1000.html", nullptr, nullptr, &client); + web_view->Resize(WebSize(100, 100)); + web_view->UpdateAllLifecyclePhases(); + RunPendingTasks(); + + WebMouseEvent mouse_event(WebInputEvent::kMouseDown, + WebInputEvent::kNoModifiers, + WebInputEvent::kTimeStampForTesting); + mouse_event.button = WebMouseEvent::Button::kMiddle; + mouse_event.SetPositionInWidget(1, 1); + mouse_event.click_count = 1; + + // Start middle-click autoscroll. + web_view->HandleInputEvent(WebCoalescedInputEvent(mouse_event)); + mouse_event.SetType(WebInputEvent::kMouseUp); + web_view->HandleInputEvent(WebCoalescedInputEvent(mouse_event)); + + EXPECT_EQ(MiddlePanningCursor().GetType(), client.GetLastCursorType()); + + LocalFrame* local_frame = + ToWebLocalFrameBase(web_view->MainFrame())->GetFrame(); + + // Even if a plugin tries to change the cursor type, that should be ignored + // during middle-click autoscroll. + web_view->GetChromeClient().SetCursorForPlugin(WebCursorInfo(PointerCursor()), + local_frame); + EXPECT_EQ(MiddlePanningCursor().GetType(), client.GetLastCursorType()); + + // End middle-click autoscroll. + mouse_event.SetType(WebInputEvent::kMouseDown); + web_view->HandleInputEvent(WebCoalescedInputEvent(mouse_event)); + mouse_event.SetType(WebInputEvent::kMouseUp); + web_view->HandleInputEvent(WebCoalescedInputEvent(mouse_event)); + + web_view->GetChromeClient().SetCursorForPlugin(WebCursorInfo(IBeamCursor()), + local_frame); + EXPECT_EQ(IBeamCursor().GetType(), client.GetLastCursorType()); +} + static void ConfigueCompositingWebView(WebSettings* settings) { settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true);
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h index ce12db31..cfd52ced8 100644 --- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h +++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h
@@ -38,6 +38,7 @@ #include "core/exported/WebViewBase.h" #include "core/frame/Settings.h" #include "platform/RuntimeEnabledFeatures.h" +#include "platform/WebTaskRunner.h" #include "platform/scroll/ScrollbarTheme.h" #include "public/platform/Platform.h" #include "public/platform/WebCachePolicy.h" @@ -312,9 +313,11 @@ return nullptr; } - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override { + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const blink::WebURLRequest& request, + SingleThreadTaskRunner* task_runner) override { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return Platform::Current()->CreateURLLoader(); + return Platform::Current()->CreateURLLoader(request, task_runner); } private:
diff --git a/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp b/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp index baddbbcd..e5540aad 100644 --- a/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp +++ b/third_party/WebKit/Source/core/frame/HostsUsingFeatures.cpp
@@ -55,9 +55,10 @@ document->HostsUsingFeaturesValue().Count(feature); return; } - if (Page* page = document->GetPage()) + if (Page* page = document->GetPage()) { page->GetHostsUsingFeatures().CountName( - feature, script_state->World().IsolatedWorldHumanReadableName()); + feature, script_state->World().NonMainWorldHumanReadableName()); + } } void HostsUsingFeatures::Value::Count(Feature feature) {
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index c39f3a0..5bb29af 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -272,7 +272,7 @@ LocalDOMWindow::LocalDOMWindow(LocalFrame& frame) : DOMWindow(frame), - view_(DOMVisualViewport::Create(this)), + visualViewport_(DOMVisualViewport::Create(this)), unused_preloads_timer_( TaskRunnerHelper::Get(TaskType::kUnspecedTimer, &frame), this, @@ -1058,7 +1058,7 @@ return 0; if (!GetFrame()->GetPage()->GetSettings().GetInertVisualViewport()) - return view_->pageLeft(); + return visualViewport_->pageLeft(); LocalFrameView* view = GetFrame()->View(); if (!view) @@ -1076,7 +1076,7 @@ return 0; if (!GetFrame()->GetPage()->GetSettings().GetInertVisualViewport()) - return view_->pageTop(); + return visualViewport_->pageTop(); LocalFrameView* view = GetFrame()->View(); if (!view) @@ -1090,10 +1090,7 @@ } DOMVisualViewport* LocalDOMWindow::visualViewport() { - if (!GetFrame()) - return nullptr; - - return view_; + return visualViewport_; } const AtomicString& LocalDOMWindow::name() const { @@ -1667,7 +1664,7 @@ visitor->Trace(application_cache_); visitor->Trace(event_queue_); visitor->Trace(post_message_timers_); - visitor->Trace(view_); + visitor->Trace(visualViewport_); visitor->Trace(event_listener_observers_); DOMWindow::Trace(visitor); Supplementable<LocalDOMWindow>::Trace(visitor);
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h index b382141..ccd8b4c 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -347,7 +347,7 @@ void ClearDocument(); Member<Document> document_; - Member<DOMVisualViewport> view_; + Member<DOMVisualViewport> visualViewport_; TaskRunnerTimer<LocalDOMWindow> unused_preloads_timer_; bool should_print_when_finished_loading_;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp index c2975ee..605326f1 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -1076,8 +1076,10 @@ } } -std::unique_ptr<WebURLLoader> LocalFrame::CreateURLLoader() { - return Client()->CreateURLLoader(); +std::unique_ptr<WebURLLoader> LocalFrame::CreateURLLoader( + const ResourceRequest& request, + WebTaskRunner* task_runner) { + return Client()->CreateURLLoader(request, task_runner); } WebPluginContainerBase* LocalFrame::GetWebPluginContainerBase(
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.h b/third_party/WebKit/Source/core/frame/LocalFrame.h index 0070884..76a9adbf 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.h +++ b/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -78,10 +78,12 @@ template <typename Strategy> class PositionWithAffinityTemplate; class PluginData; +class ResourceRequest; class ScriptController; class SpellChecker; class WebFrameScheduler; class WebPluginContainerBase; +class WebTaskRunner; class WebURLLoader; extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<LocalFrame>; @@ -248,7 +250,8 @@ // the embedder decides that Client Lo-Fi should be used for this request. void MaybeAllowImagePlaceholder(FetchParameters&) const; - std::unique_ptr<WebURLLoader> CreateURLLoader(); + std::unique_ptr<WebURLLoader> CreateURLLoader(const ResourceRequest&, + WebTaskRunner*); bool IsInert() const { return is_inert_; }
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameClient.h b/third_party/WebKit/Source/core/frame/LocalFrameClient.h index 0ebbbbe..18d5119 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameClient.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
@@ -91,6 +91,7 @@ class WebRTCPeerConnectionHandler; class WebServiceWorkerProvider; class WebSpellCheckPanelHostClient; +class WebTaskRunner; class WebURLLoader; class CORE_EXPORT LocalFrameClient : public FrameClient { @@ -349,7 +350,8 @@ virtual TextCheckerClient& GetTextCheckerClient() const = 0; - virtual std::unique_ptr<WebURLLoader> CreateURLLoader() = 0; + virtual std::unique_ptr<WebURLLoader> CreateURLLoader(const ResourceRequest&, + WebTaskRunner*) = 0; virtual void AnnotatedRegionsChanged() = 0; };
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index 4ace0cb..39c76f3 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -1266,6 +1266,8 @@ if (!PerformLayout(in_subtree_layout)) { TRACE_EVENT_END0("devtools.timeline", "Layout"); + DCHECK(nested_layout_count_); + nested_layout_count_--; return; }
diff --git a/third_party/WebKit/Source/core/frame/SubresourceIntegrity.cpp b/third_party/WebKit/Source/core/frame/SubresourceIntegrity.cpp index 8686087..e871c454 100644 --- a/third_party/WebKit/Source/core/frame/SubresourceIntegrity.cpp +++ b/third_party/WebKit/Source/core/frame/SubresourceIntegrity.cpp
@@ -130,7 +130,7 @@ size_t size, const KURL& resource_url, const Resource& resource) { - if (!resource.IsEligibleForIntegrityCheck(document.GetSecurityOrigin())) { + if (!resource.IsSameOriginOrCORSSuccessful()) { UseCounter::Count(document, WebFeature::kSRIElementIntegrityAttributeButIneligible); LogErrorToConsole("Subresource Integrity: The resource '" +
diff --git a/third_party/WebKit/Source/core/frame/SubresourceIntegrityTest.cpp b/third_party/WebKit/Source/core/frame/SubresourceIntegrityTest.cpp index 38e7bb2..b609f07f 100644 --- a/third_party/WebKit/Source/core/frame/SubresourceIntegrityTest.cpp +++ b/third_party/WebKit/Source/core/frame/SubresourceIntegrityTest.cpp
@@ -11,11 +11,16 @@ #include "platform/loader/fetch/IntegrityMetadata.h" #include "platform/loader/fetch/RawResource.h" #include "platform/loader/fetch/Resource.h" +#include "platform/loader/fetch/ResourceFetcher.h" +#include "platform/loader/fetch/ResourceLoader.h" +#include "platform/loader/fetch/ResourceResponse.h" +#include "platform/loader/testing/MockFetchContext.h" #include "platform/weborigin/KURL.h" #include "platform/weborigin/SecurityOrigin.h" #include "platform/wtf/RefPtr.h" #include "platform/wtf/Vector.h" #include "platform/wtf/dtoa/utils.h" +#include "platform/wtf/text/StringBuilder.h" #include "platform/wtf/text/WTFString.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,6 +70,8 @@ virtual void SetUp() { document = Document::Create(); script_element = HTMLScriptElement::Create(*document, true); + context = + MockFetchContext::Create(MockFetchContext::kShouldLoadNewResource); } void ExpectAlgorithm(const String& text, HashAlgorithm expected_algorithm) { @@ -192,6 +199,7 @@ const TestCase test, Expectation expectation) { document->UpdateSecurityOrigin(SecurityOrigin::Create(test.origin)); + context->SetSecurityOrigin(SecurityOrigin::Create(test.origin)); script_element->setAttribute(HTMLNames::integrityAttr, integrity); EXPECT_EQ(expectation == kIntegritySuccess, @@ -205,17 +213,30 @@ Resource* CreateTestResource(const KURL& url, const KURL* allow_origin_url, ServiceWorkerMode service_worker_mode) { + ResourceFetcher* fetcher = + ResourceFetcher::Create(context, context->GetTaskRunner()); + Resource* resource = RawResource::CreateForTest(url, Resource::kRaw); + ResourceLoader* loader = ResourceLoader::Create(fetcher, resource); + + ResourceRequest request; + request.SetURL(url); + ResourceResponse response; - response.SetURL(url); response.SetHTTPStatusCode(200); + response.SetURL(url); if (allow_origin_url) { + request.SetFetchRequestMode(WebURLRequest::kFetchRequestModeCORS); + resource->MutableOptions().cors_handling_by_resource_fetcher = + kEnableCORSHandlingByResourceFetcher; response.SetHTTPHeaderField( "access-control-allow-origin", SecurityOrigin::Create(*allow_origin_url)->ToAtomicString()); response.SetHTTPHeaderField("access-control-allow-credentials", "true"); } + resource->SetResourceRequest(request); + if (service_worker_mode != kNoServiceWorker) { response.SetWasFetchedViaServiceWorker(true); @@ -228,9 +249,11 @@ } } - Resource* resource = - RawResource::CreateForTest(response.Url(), Resource::kRaw); - resource->SetResponse(response); + StringBuilder cors_error_msg; + CORSStatus cors_status = + loader->DetermineCORSStatus(response, cors_error_msg); + resource->SetCORSStatus(cors_status); + return resource; } @@ -238,6 +261,7 @@ KURL insec_url; Persistent<Document> document; + Persistent<MockFetchContext> context; Persistent<HTMLScriptElement> script_element; };
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl index c5bc0260..b251a243 100644 --- a/third_party/WebKit/Source/core/frame/Window.idl +++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -138,7 +138,7 @@ // Visual Viewport API // https://github.com/WICG/ViewportAPI - [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject] readonly attribute VisualViewport? visualViewport; + [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject] readonly attribute VisualViewport visualViewport; // client [Replaceable] readonly attribute long screenX;
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp index 87c47e75..acbe2a2 100644 --- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp +++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
@@ -150,9 +150,8 @@ aux_data_builder.Append(IdentifiersFactory::FrameId(frame)); aux_data_builder.Append("\"}"); String aux_data = aux_data_builder.ToString(); - String human_readable_name = world.IsIsolatedWorld() - ? world.IsolatedWorldHumanReadableName() - : String(); + String human_readable_name = + !world.IsMainWorld() ? world.NonMainWorldHumanReadableName() : String(); String origin_string = origin ? origin->ToRawString() : String(); v8_inspector::V8ContextInfo context_info( script_state->GetContext(), ContextGroupId(frame),
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn index bf1b7a3..96034692 100644 --- a/third_party/WebKit/Source/core/layout/BUILD.gn +++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -348,6 +348,7 @@ "ng/geometry/ng_physical_size.h", "ng/geometry/ng_static_position.cc", "ng/geometry/ng_static_position.h", + "ng/inline/empty_offset_mapping_builder.h", "ng/inline/ng_bidi_paragraph.cc", "ng/inline/ng_bidi_paragraph.h", "ng/inline/ng_inline_box_state.cc", @@ -373,6 +374,8 @@ "ng/inline/ng_line_breaker.h", "ng/inline/ng_line_height_metrics.cc", "ng/inline/ng_line_height_metrics.h", + "ng/inline/ng_offset_mapping_builder.cc", + "ng/inline/ng_offset_mapping_builder.h", "ng/inline/ng_physical_line_box_fragment.cc", "ng/inline/ng_physical_line_box_fragment.h", "ng/inline/ng_physical_text_fragment.h",
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp index a16e5d49..5bdb5e9 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -728,10 +728,8 @@ // A margin has three types: fixed, percentage, and auto (variable). // Auto and percentage margins become 0 when computing min/max width. // Fixed margins can be added in as is. - DCHECK(child.Style()); - DCHECK(Style()); - Length margin_left = child.Style()->MarginStartUsing(*Style()); - Length margin_right = child.Style()->MarginEndUsing(*Style()); + Length margin_left = child.StyleRef().MarginStartUsing(StyleRef()); + Length margin_right = child.StyleRef().MarginEndUsing(StyleRef()); LayoutUnit margin; if (margin_left.IsFixed()) margin += margin_left.Value();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index 43b4fb7..bcd7d16 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -638,9 +638,8 @@ // edge or any positive margin push it out. // If the child is being centred then the margin calculated to do that has // factored in any offset required to avoid floats, so use it if necessary. - DCHECK(Style()); - if (Style()->GetTextAlign() == ETextAlign::kWebkitCenter || - child.Style()->MarginStartUsing(*Style()).IsAuto()) + if (StyleRef().GetTextAlign() == ETextAlign::kWebkitCenter || + child.Style()->MarginStartUsing(StyleRef()).IsAuto()) new_position = std::max(new_position, position_to_avoid_floats + child_margin_start); else if (position_to_avoid_floats > initial_start_position)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 8a7030df..d20e35d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -3791,14 +3791,12 @@ const LayoutBlock* containing_block) { LayoutUnit margin_before; LayoutUnit margin_after; - DCHECK(Style()); DCHECK(containing_block); - DCHECK(containing_block->Style()); ComputeMarginsForDirection( kBlockDirection, containing_block, ContainingBlockLogicalWidthForContent(), LogicalHeight(), margin_before, - margin_after, Style()->MarginBeforeUsing(*containing_block->Style()), - Style()->MarginAfterUsing(*containing_block->Style())); + margin_after, StyleRef().MarginBeforeUsing(containing_block->StyleRef()), + StyleRef().MarginAfterUsing(containing_block->StyleRef())); // Note that in this 'positioning phase' of the layout we are using the // containing block's writing mode rather than our own when calculating // margins.
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp index 06f59cc..8436b88 100644 --- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -1636,10 +1636,8 @@ if (available_alignment_space <= 0) return; - DCHECK(child.Style()); - DCHECK(Style()); - Length margin_start = child.Style()->MarginStartUsing(*Style()); - Length margin_end = child.Style()->MarginEndUsing(*Style()); + Length margin_start = child.StyleRef().MarginStartUsing(StyleRef()); + Length margin_end = child.StyleRef().MarginEndUsing(StyleRef()); if (margin_start.IsAuto() && margin_end.IsAuto()) { child.SetMarginStart(available_alignment_space / 2, Style()); child.SetMarginEnd(available_alignment_space / 2, Style()); @@ -1662,10 +1660,8 @@ if (available_alignment_space <= 0) return; - DCHECK(child.Style()); - DCHECK(Style()); - Length margin_before = child.Style()->MarginBeforeUsing(*Style()); - Length margin_after = child.Style()->MarginAfterUsing(*Style()); + Length margin_before = child.StyleRef().MarginBeforeUsing(StyleRef()); + Length margin_after = child.StyleRef().MarginAfterUsing(StyleRef()); if (margin_before.IsAuto() && margin_after.IsAuto()) { child.SetMarginBefore(available_alignment_space / 2, Style()); child.SetMarginAfter(available_alignment_space / 2, Style());
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp index 7b5cd93..e053cf9 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -844,27 +844,23 @@ } LayoutUnit LayoutInline::MarginStart(const ComputedStyle* other_style) const { - DCHECK(Style()); - return ComputeMargin( - this, Style()->MarginStartUsing(other_style ? *other_style : *Style())); + return ComputeMargin(this, StyleRef().MarginStartUsing( + other_style ? *other_style : StyleRef())); } LayoutUnit LayoutInline::MarginEnd(const ComputedStyle* other_style) const { - DCHECK(Style()); return ComputeMargin( - this, Style()->MarginEndUsing(other_style ? *other_style : *Style())); + this, StyleRef().MarginEndUsing(other_style ? *other_style : StyleRef())); } LayoutUnit LayoutInline::MarginBefore(const ComputedStyle* other_style) const { - DCHECK(Style()); - return ComputeMargin( - this, Style()->MarginBeforeUsing(other_style ? *other_style : *Style())); + return ComputeMargin(this, StyleRef().MarginBeforeUsing( + other_style ? *other_style : StyleRef())); } LayoutUnit LayoutInline::MarginAfter(const ComputedStyle* other_style) const { - DCHECK(Style()); - return ComputeMargin( - this, Style()->MarginAfterUsing(other_style ? *other_style : *Style())); + return ComputeMargin(this, StyleRef().MarginAfterUsing( + other_style ? *other_style : StyleRef())); } LayoutUnit LayoutInline::MarginOver() const {
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h index e30873d1..9bfc60b 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -2810,36 +2810,31 @@ inline int AdjustForAbsoluteZoom(int value, LayoutObject* layout_object) { DCHECK(layout_object); - DCHECK(layout_object->Style()); - return AdjustForAbsoluteZoom(value, *layout_object->Style()); + return AdjustForAbsoluteZoom(value, layout_object->StyleRef()); } inline LayoutUnit AdjustLayoutUnitForAbsoluteZoom(LayoutUnit value, LayoutObject& layout_object) { - DCHECK(layout_object.Style()); - return AdjustLayoutUnitForAbsoluteZoom(value, *layout_object.Style()); + return AdjustLayoutUnitForAbsoluteZoom(value, layout_object.StyleRef()); } inline void AdjustFloatQuadForAbsoluteZoom(FloatQuad& quad, LayoutObject& layout_object) { - DCHECK(layout_object.Style()); - float zoom = layout_object.Style()->EffectiveZoom(); + float zoom = layout_object.StyleRef().EffectiveZoom(); if (zoom != 1) quad.Scale(1 / zoom, 1 / zoom); } inline void AdjustFloatRectForAbsoluteZoom(FloatRect& rect, LayoutObject& layout_object) { - DCHECK(layout_object.Style()); - float zoom = layout_object.Style()->EffectiveZoom(); + float zoom = layout_object.StyleRef().EffectiveZoom(); if (zoom != 1) rect.Scale(1 / zoom, 1 / zoom); } inline double AdjustScrollForAbsoluteZoom(double value, LayoutObject& layout_object) { - DCHECK(layout_object.Style()); - return AdjustScrollForAbsoluteZoom(value, *layout_object.Style()); + return AdjustScrollForAbsoluteZoom(value, layout_object.StyleRef()); } #define DEFINE_LAYOUT_OBJECT_TYPE_CASTS(thisType, predicate) \
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/empty_offset_mapping_builder.h b/third_party/WebKit/Source/core/layout/ng/inline/empty_offset_mapping_builder.h new file mode 100644 index 0000000..3a3f38a --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/inline/empty_offset_mapping_builder.h
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EmptyOffsetMappingBuilder_h +#define EmptyOffsetMappingBuilder_h + +#include "platform/wtf/Allocator.h" + +namespace blink { + +// A mock class providing all APIs of an offset mapping builder, but not doing +// anything. For templates functions/classes that can optionally create an +// offset mapping, this mock class is passed to create an instantiation that +// does not create any offset mapping. +class EmptyOffsetMappingBuilder { + STACK_ALLOCATED(); + + public: + EmptyOffsetMappingBuilder() = default; + void AppendIdentityMapping(unsigned) {} + void AppendCollapsedMapping(unsigned) {} + void CollapseTrailingSpace(unsigned) {} + + private: + DISALLOW_COPY_AND_ASSIGN(EmptyOffsetMappingBuilder); +}; + +} // namespace blink + +#endif // EmptyOffsetMappingBuilder_h
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc index 8533bd9..d0c256ef 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -6,16 +6,20 @@ #include "core/layout/LayoutObject.h" #include "core/layout/ng/inline/ng_inline_node.h" +#include "core/layout/ng/inline/ng_offset_mapping_builder.h" #include "core/style/ComputedStyle.h" namespace blink { -NGInlineItemsBuilder::~NGInlineItemsBuilder() { +template <typename OffsetMappingBuilder> +NGInlineItemsBuilderTemplate< + OffsetMappingBuilder>::~NGInlineItemsBuilderTemplate() { DCHECK_EQ(0u, exits_.size()); DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); } -String NGInlineItemsBuilder::ToString() { +template <typename OffsetMappingBuilder> +String NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ToString() { // Segment Break Transformation Rules[1] defines to keep trailing new lines, // but it will be removed in Phase II[2]. We prefer not to add trailing new // lines and collapsible spaces in Phase I. @@ -123,9 +127,11 @@ return c == kTabulationCharacter || c == kNewlineCharacter; } -void NGInlineItemsBuilder::Append(const String& string, - const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append( + const String& string, + const ComputedStyle* style, + LayoutObject* layout_object) { if (string.IsEmpty()) return; text_.ReserveCapacity(string.length()); @@ -140,12 +146,13 @@ layout_object); } -void NGInlineItemsBuilder::AppendWithWhiteSpaceCollapsing( - const String& string, - unsigned start, - unsigned end, - const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: + AppendWithWhiteSpaceCollapsing(const String& string, + unsigned start, + unsigned end, + const ComputedStyle* style, + LayoutObject* layout_object) { unsigned start_offset = text_.length(); for (unsigned i = start; i < end;) { UChar c = string[i]; @@ -156,8 +163,12 @@ return; } - if (last_collapsible_space_ == CollapsibleSpace::kNone) + if (last_collapsible_space_ == CollapsibleSpace::kNone) { text_.Append(kSpaceCharacter); + mapping_builder_.AppendIdentityMapping(1); + } else { + mapping_builder_.AppendCollapsedMapping(1); + } last_collapsible_space_ = CollapsibleSpace::kNewline; i++; continue; @@ -167,6 +178,9 @@ if (last_collapsible_space_ == CollapsibleSpace::kNone) { text_.Append(kSpaceCharacter); last_collapsible_space_ = CollapsibleSpace::kSpace; + mapping_builder_.AppendIdentityMapping(1); + } else { + mapping_builder_.AppendCollapsedMapping(1); } i++; continue; @@ -181,6 +195,7 @@ if (end_of_non_space == kNotFound) end_of_non_space = string.length(); text_.Append(string, i, end_of_non_space - i); + mapping_builder_.AppendIdentityMapping(end_of_non_space - i); i = end_of_non_space; last_collapsible_space_ = CollapsibleSpace::kNone; } @@ -193,10 +208,11 @@ // Even when without whitespace collapsing, control characters (newlines and // tabs) are in their own control items to make the line breaker easier. -void NGInlineItemsBuilder::AppendWithoutWhiteSpaceCollapsing( - const String& string, - const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: + AppendWithoutWhiteSpaceCollapsing(const String& string, + const ComputedStyle* style, + LayoutObject* layout_object) { for (unsigned start = 0; start < string.length();) { UChar c = string[start]; if (IsControlItemCharacter(c)) { @@ -210,6 +226,7 @@ end = string.length(); unsigned start_offset = text_.length(); text_.Append(string, start, end - start); + mapping_builder_.AppendIdentityMapping(end - start); AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, layout_object); start = end; @@ -218,10 +235,11 @@ last_collapsible_space_ = CollapsibleSpace::kNone; } -void NGInlineItemsBuilder::AppendWithPreservingNewlines( - const String& string, - const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: + AppendWithPreservingNewlines(const String& string, + const ComputedStyle* style, + LayoutObject* layout_object) { for (unsigned start = 0; start < string.length();) { if (string[start] == kNewlineCharacter) { AppendForcedBreak(style, layout_object); @@ -237,8 +255,10 @@ } } -void NGInlineItemsBuilder::AppendForcedBreak(const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendForcedBreak( + const ComputedStyle* style, + LayoutObject* layout_object) { // Remove collapsible spaces immediately before a preserved newline. RemoveTrailingCollapsibleSpaceIfExists(); @@ -248,39 +268,48 @@ last_collapsible_space_ = CollapsibleSpace::kSpace; } -void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, - UChar character, - const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append( + NGInlineItem::NGInlineItemType type, + UChar character, + const ComputedStyle* style, + LayoutObject* layout_object) { DCHECK_NE(character, kSpaceCharacter); DCHECK_NE(character, kZeroWidthSpaceCharacter); text_.Append(character); + mapping_builder_.AppendIdentityMapping(1); unsigned end_offset = text_.length(); AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object); last_collapsible_space_ = CollapsibleSpace::kNone; } -void NGInlineItemsBuilder::AppendOpaque(NGInlineItem::NGInlineItemType type, - UChar character) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( + NGInlineItem::NGInlineItemType type, + UChar character) { text_.Append(character); + mapping_builder_.AppendIdentityMapping(1); unsigned end_offset = text_.length(); AppendItem(items_, type, end_offset - 1, end_offset, nullptr, nullptr); } -void NGInlineItemsBuilder::AppendOpaque(NGInlineItem::NGInlineItemType type, - const ComputedStyle* style, - LayoutObject* layout_object) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( + NGInlineItem::NGInlineItemType type, + const ComputedStyle* style, + LayoutObject* layout_object) { unsigned end_offset = text_.length(); AppendItem(items_, type, end_offset, end_offset, style, layout_object); } // Removes the collapsible newline at the end of |text_| if exists and the // removal conditions met. -void NGInlineItemsBuilder::RemoveTrailingCollapsibleNewlineIfNeeded( - const String& after, - unsigned after_index, - const ComputedStyle* after_style) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: + RemoveTrailingCollapsibleNewlineIfNeeded(const String& after, + unsigned after_index, + const ComputedStyle* after_style) { DCHECK_EQ(last_collapsible_space_, CollapsibleSpace::kNewline); if (text_.IsEmpty() || text_[text_.length() - 1] != kSpaceCharacter) @@ -298,7 +327,9 @@ } // Removes the collapsible space at the end of |text_| if exists. -void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpaceIfExists() { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate< + OffsetMappingBuilder>::RemoveTrailingCollapsibleSpaceIfExists() { if (last_collapsible_space_ == CollapsibleSpace::kNone || text_.IsEmpty()) return; @@ -320,13 +351,16 @@ } // Removes the collapsible space at the specified index. -void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace(unsigned index) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate< + OffsetMappingBuilder>::RemoveTrailingCollapsibleSpace(unsigned index) { DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); DCHECK(!text_.IsEmpty()); DCHECK_EQ(text_[index], kSpaceCharacter); text_.erase(index); last_collapsible_space_ = CollapsibleSpace::kNone; + mapping_builder_.CollapseTrailingSpace(text_.length() - index); // Adjust items if the removed space is already included. for (unsigned i = items_->size(); i > 0;) { @@ -350,14 +384,18 @@ } } -void NGInlineItemsBuilder::AppendBidiControl(const ComputedStyle* style, - UChar ltr, - UChar rtl) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendBidiControl( + const ComputedStyle* style, + UChar ltr, + UChar rtl) { AppendOpaque(NGInlineItem::kBidiControl, IsLtr(style->Direction()) ? ltr : rtl); } -void NGInlineItemsBuilder::EnterBlock(const ComputedStyle* style) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::EnterBlock( + const ComputedStyle* style) { // Handle bidi-override on the block itself. switch (style->GetUnicodeBidi()) { case UnicodeBidi::kNormal: @@ -384,7 +422,9 @@ } } -void NGInlineItemsBuilder::EnterInline(LayoutObject* node) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::EnterInline( + LayoutObject* node) { // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-table const ComputedStyle* style = node->Style(); switch (style->GetUnicodeBidi()) { @@ -421,16 +461,22 @@ AppendOpaque(NGInlineItem::kOpenTag, style, node); } -void NGInlineItemsBuilder::Enter(LayoutObject* node, UChar character_to_exit) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Enter( + LayoutObject* node, + UChar character_to_exit) { exits_.push_back(OnExitNode{node, character_to_exit}); has_bidi_controls_ = true; } -void NGInlineItemsBuilder::ExitBlock() { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ExitBlock() { Exit(nullptr); } -void NGInlineItemsBuilder::ExitInline(LayoutObject* node) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ExitInline( + LayoutObject* node) { DCHECK(node); AppendOpaque(NGInlineItem::kCloseTag, node->Style(), node); @@ -438,11 +484,18 @@ Exit(node); } -void NGInlineItemsBuilder::Exit(LayoutObject* node) { +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Exit( + LayoutObject* node) { while (!exits_.IsEmpty() && exits_.back().node == node) { AppendOpaque(NGInlineItem::kBidiControl, exits_.back().character); exits_.pop_back(); } } +template class CORE_TEMPLATE_EXPORT + NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; +template class CORE_TEMPLATE_EXPORT + NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>; + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h index 24dc8d1..6215798 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h
@@ -6,7 +6,9 @@ #define NGInlineItemsBuilder_h #include "core/CoreExport.h" +#include "core/layout/ng/inline/empty_offset_mapping_builder.h" #include "core/layout/ng/inline/ng_inline_node.h" +#include "core/layout/ng/inline/ng_offset_mapping_builder.h" #include "platform/wtf/Allocator.h" #include "platform/wtf/Vector.h" #include "platform/wtf/text/StringBuilder.h" @@ -27,12 +29,20 @@ // By calling EnterInline/ExitInline, it inserts bidirectional control // characters as defined in: // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-table -class CORE_EXPORT NGInlineItemsBuilder { +// +// NGInlineItemsBuilder may optionally take an NGOffsetMappingBuilder template +// parameter to construct the white-space collapsed offset mapping, which maps +// offsets in the concatenation of all appended strings and characters to +// offsets in |text_|. +// See https://goo.gl/CJbxky for more details about offset mapping. +template <typename OffsetMappingBuilder> +class CORE_TEMPLATE_CLASS_EXPORT NGInlineItemsBuilderTemplate { STACK_ALLOCATED(); public: - explicit NGInlineItemsBuilder(Vector<NGInlineItem>* items) : items_(items) {} - ~NGInlineItemsBuilder(); + explicit NGInlineItemsBuilderTemplate(Vector<NGInlineItem>* items) + : items_(items) {} + ~NGInlineItemsBuilderTemplate(); String ToString(); @@ -82,9 +92,12 @@ void EnterInline(LayoutObject*); void ExitInline(LayoutObject*); + OffsetMappingBuilder& GetOffsetMappingBuilder() { return mapping_builder_; } + private: Vector<NGInlineItem>* items_; StringBuilder text_; + OffsetMappingBuilder mapping_builder_; typedef struct OnExitNode { LayoutObject* node; @@ -122,6 +135,16 @@ void Exit(LayoutObject*); }; +extern template class CORE_EXTERN_TEMPLATE_EXPORT + NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; +extern template class CORE_EXTERN_TEMPLATE_EXPORT + NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>; + +using NGInlineItemsBuilder = + NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; +using NGInlineItemsBuilderForOffsetMapping = + NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>; + } // namespace blink #endif // NGInlineItemsBuilder_h
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc index 5bd4a54..8d99660 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -6,6 +6,7 @@ #include "core/layout/LayoutInline.h" #include "core/layout/ng/inline/ng_inline_node.h" +#include "core/layout/ng/inline/ng_offset_mapping_builder.h" #include "core/style/ComputedStyle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,6 +20,28 @@ return style; } +static String GetCollapsed(const NGOffsetMappingBuilder& builder) { + Vector<unsigned> mapping = builder.DumpOffsetMappingForTesting(); + + Vector<unsigned> collapsed_indexes; + for (unsigned i = 0; i + 1 < mapping.size(); ++i) { + if (mapping[i] == mapping[i + 1]) + collapsed_indexes.push_back(i); + } + + StringBuilder result; + result.Append('{'); + bool first = true; + for (unsigned index : collapsed_indexes) { + if (!first) + result.Append(", "); + result.AppendNumber(index); + first = false; + } + result.Append('}'); + return result.ToString(); +} + class NGInlineItemsBuilderTest : public ::testing::Test { protected: void SetUp() override { style_ = ComputedStyle::Create(); } @@ -29,10 +52,11 @@ const String& TestAppend(const String inputs[], int size) { items_.clear(); - NGInlineItemsBuilder builder(&items_); + NGInlineItemsBuilderForOffsetMapping builder(&items_); for (int i = 0; i < size; i++) builder.Append(inputs[i], style_.Get()); text_ = builder.ToString(); + collapsed_ = GetCollapsed(builder.GetOffsetMappingBuilder()); ValidateItems(); return text_; } @@ -67,161 +91,225 @@ Vector<NGInlineItem> items_; String text_; + String collapsed_; RefPtr<ComputedStyle> style_; }; -#define TestWhitespaceValue(expected, input, whitespace) \ - SetWhiteSpace(whitespace); \ - EXPECT_EQ(expected, TestAppend(input)) << "white-space: " #whitespace; +#define TestWhitespaceValue(expected_text, expected_collapsed, input, \ + whitespace) \ + SetWhiteSpace(whitespace); \ + EXPECT_EQ(expected_text, TestAppend(input)) << "white-space: " #whitespace; \ + EXPECT_EQ(expected_collapsed, collapsed_); TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) { String input("text text text text"); String collapsed("text text text text"); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); - TestWhitespaceValue(input, input, EWhiteSpace::kPre); - TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); + String collapsed_indexes("{10, 16, 17}"); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kNormal); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kNowrap); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kWebkitNowrap); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kPreLine); + TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPre); + TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPreWrap); } TEST_F(NGInlineItemsBuilderTest, CollapseTabs) { - String input("text\ttext\t text \t text"); + String input("text text text text"); String collapsed("text text text text"); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); - TestWhitespaceValue(input, input, EWhiteSpace::kPre); - TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); + String collapsed_indexes("{10, 16, 17}"); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kNormal); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kNowrap); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kWebkitNowrap); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kPreLine); + TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPre); + TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPreWrap); } TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) { String input("text\ntext \n text\n\ntext"); String collapsed("text text text text"); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); - TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); - TestWhitespaceValue("text\ntext\ntext\n\ntext", input, EWhiteSpace::kPreLine); - TestWhitespaceValue(input, input, EWhiteSpace::kPre); - TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); + String collapsed_indexes("{10, 11, 17}"); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kNormal); + TestWhitespaceValue(collapsed, collapsed_indexes, input, + EWhiteSpace::kNowrap); + TestWhitespaceValue("text\ntext\ntext\n\ntext", "{9, 11}", input, + EWhiteSpace::kPreLine); + TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPre); + TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPreWrap); } TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { EXPECT_EQ("text text", TestAppend("text\ntext")); + EXPECT_EQ("{}", collapsed_); EXPECT_EQ("text text", TestAppend("text\n\ntext")); + EXPECT_EQ("{5}", collapsed_); EXPECT_EQ("text text", TestAppend("text \n\n text")); + EXPECT_EQ("{5, 6, 7}", collapsed_); EXPECT_EQ("text text", TestAppend("text \n \n text")); + EXPECT_EQ("{5, 6, 7, 8}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) { EXPECT_EQ("text text", TestAppend("text ", " text")) << "Spaces are collapsed even when across elements."; + EXPECT_EQ("{5}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) { EXPECT_EQ("text", TestAppend(" text")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("text", TestAppend(" ", "text")); + EXPECT_EQ("{0}", collapsed_); EXPECT_EQ("text", TestAppend(" ", " text")); + EXPECT_EQ("{0, 1}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) { EXPECT_EQ("text", TestAppend("text ")); + EXPECT_EQ("{4, 5}", collapsed_); EXPECT_EQ("text", TestAppend("text", " ")); + EXPECT_EQ("{4}", collapsed_); EXPECT_EQ("text", TestAppend("text ", " ")); + EXPECT_EQ("{4, 5}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) { EXPECT_EQ("", TestAppend(" ")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("", TestAppend(" ", " ")); + EXPECT_EQ("{0, 1, 2, 3}", collapsed_); EXPECT_EQ("", TestAppend(" ", "\n")); + EXPECT_EQ("{0, 1, 2}", collapsed_); EXPECT_EQ("", TestAppend("\n", " ")); + EXPECT_EQ("{0, 1, 2}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) { EXPECT_EQ("text", TestAppend("\ntext")); + EXPECT_EQ("{0}", collapsed_); EXPECT_EQ("text", TestAppend("\n\ntext")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("text", TestAppend("\n", "text")); + EXPECT_EQ("{0}", collapsed_); EXPECT_EQ("text", TestAppend("\n\n", "text")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("text", TestAppend(" \n", "text")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("text", TestAppend("\n", " text")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("text", TestAppend("\n\n", " text")); + EXPECT_EQ("{0, 1, 2}", collapsed_); EXPECT_EQ("text", TestAppend(" \n", " text")); + EXPECT_EQ("{0, 1, 2}", collapsed_); EXPECT_EQ("text", TestAppend("\n", "\ntext")); + EXPECT_EQ("{0, 1}", collapsed_); EXPECT_EQ("text", TestAppend("\n\n", "\ntext")); + EXPECT_EQ("{0, 1, 2}", collapsed_); EXPECT_EQ("text", TestAppend(" \n", "\ntext")); + EXPECT_EQ("{0, 1, 2}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) { EXPECT_EQ("text", TestAppend("text\n")); + EXPECT_EQ("{4}", collapsed_); EXPECT_EQ("text", TestAppend("text", "\n")); + EXPECT_EQ("{4}", collapsed_); EXPECT_EQ("text", TestAppend("text\n", "\n")); + EXPECT_EQ("{4, 5}", collapsed_); EXPECT_EQ("text", TestAppend("text\n", " ")); + EXPECT_EQ("{4, 5}", collapsed_); EXPECT_EQ("text", TestAppend("text ", "\n")); + EXPECT_EQ("{4, 5}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { EXPECT_EQ("text text", TestAppend("text ", "\ntext")); + EXPECT_EQ("{5}", collapsed_); EXPECT_EQ("text text", TestAppend("text", " ", "\ntext")); + EXPECT_EQ("{5}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { SetWhiteSpace(EWhiteSpace::kPreLine); EXPECT_EQ("text\ntext", TestAppend("text \n text")) << "Spaces before and after newline are removed."; + EXPECT_EQ("{4, 5, 7, 8}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) { - NGInlineItemsBuilder builder(&items_); + NGInlineItemsBuilderForOffsetMapping builder(&items_); RefPtr<ComputedStyle> pre_wrap(CreateWhitespaceStyle(EWhiteSpace::kPreWrap)); builder.Append("text ", pre_wrap.Get()); builder.Append(" text", style_.Get()); EXPECT_EQ("text text", builder.ToString()) << "The whitespace in constructions like '<span style=\"white-space: " "pre-wrap\">text <span><span> text</span>' does not collapse."; + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) { EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext")) << "Newline is removed if the character before is ZWS."; + EXPECT_EQ("{5}", collapsed_); EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext")) << "Newline is removed if the character after is ZWS."; + EXPECT_EQ("{4}", collapsed_); EXPECT_EQ(String(u"text\u200B\u200Btext"), TestAppend(u"text\u200B\n\u200Btext")) << "Newline is removed if the character before/after is ZWS."; + EXPECT_EQ("{5}", collapsed_); EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n", u"\u200Btext")) << "Newline is removed if the character after across elements is ZWS."; + EXPECT_EQ("{4}", collapsed_); EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B", u"\ntext")) << "Newline is removed if the character before is ZWS even across " "elements."; + EXPECT_EQ("{5}", collapsed_); EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text \n", u"\u200Btext")) << "Collapsible space before newline does not affect the result."; + EXPECT_EQ("{4, 5}", collapsed_); EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\n", u" text")) << "Collapsible space after newline is removed even when the " "newline was removed."; + EXPECT_EQ("{5, 6}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) { EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00")) << "Newline is removed when both sides are Wide."; + EXPECT_EQ("{1}", collapsed_); EXPECT_EQ(String(u"\u4E00 A"), TestAppend(u"\u4E00\nA")) << "Newline is not removed when after is Narrow."; + EXPECT_EQ("{}", collapsed_); EXPECT_EQ(String(u"A \u4E00"), TestAppend(u"A\n\u4E00")) << "Newline is not removed when before is Narrow."; + EXPECT_EQ("{}", collapsed_); EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n", u"\u4E00")) << "Newline at the end of elements is removed when both sides are Wide."; + EXPECT_EQ("{1}", collapsed_); EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00", u"\n\u4E00")) << "Newline at the beginning of elements is removed " "when both sides are Wide."; + EXPECT_EQ("{1}", collapsed_); } TEST_F(NGInlineItemsBuilderTest, OpaqueToSpaceCollapsing) { - NGInlineItemsBuilder builder(&items_); + NGInlineItemsBuilderForOffsetMapping builder(&items_); builder.Append("Hello ", style_.Get()); builder.AppendOpaque(NGInlineItem::kBidiControl, kFirstStrongIsolateCharacter); @@ -230,18 +318,20 @@ kFirstStrongIsolateCharacter); builder.Append(" World", style_.Get()); EXPECT_EQ(String(u"Hello \u2068\u2068World"), builder.ToString()); + EXPECT_EQ("{7, 9}", GetCollapsed(builder.GetOffsetMappingBuilder())); } TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) { - NGInlineItemsBuilder builder(&items_); + NGInlineItemsBuilderForOffsetMapping builder(&items_); builder.Append("Hello ", style_.Get()); builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); builder.Append(" World", style_.Get()); EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString()); + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) { - NGInlineItemsBuilder builder(&items_); + NGInlineItemsBuilderForOffsetMapping builder(&items_); builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); builder.Append("\n", style_.Get()); builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); @@ -250,16 +340,19 @@ EXPECT_EQ(nullptr, items_[0].Style()); EXPECT_EQ(style_.Get(), items_[1].Style()); EXPECT_EQ(nullptr, items_[2].Style()); + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { EXPECT_EQ("", TestAppend("")); + EXPECT_EQ("{}", collapsed_); EXPECT_EQ(0u, items_.size()); } TEST_F(NGInlineItemsBuilderTest, NewLines) { SetWhiteSpace(EWhiteSpace::kPre); EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n")); + EXPECT_EQ("{}", collapsed_); EXPECT_EQ(6u, items_.size()); EXPECT_EQ(NGInlineItem::kText, items_[0].Type()); EXPECT_EQ(NGInlineItem::kControl, items_[1].Type()); @@ -271,17 +364,18 @@ TEST_F(NGInlineItemsBuilderTest, Empty) { Vector<NGInlineItem> items; - NGInlineItemsBuilder builder(&items); + NGInlineItemsBuilderForOffsetMapping builder(&items); RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); builder.EnterBlock(block_style.Get()); builder.ExitBlock(); EXPECT_EQ("", builder.ToString()); + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { Vector<NGInlineItem> items; - NGInlineItemsBuilder builder(&items); + NGInlineItemsBuilderForOffsetMapping builder(&items); RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); block_style->SetDirection(TextDirection::kRtl); @@ -295,6 +389,7 @@ u"Hello" u"\u202C"), builder.ToString()); + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } static std::unique_ptr<LayoutInline> CreateLayoutInline( @@ -308,7 +403,7 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolate) { Vector<NGInlineItem> items; - NGInlineItemsBuilder builder(&items); + NGInlineItemsBuilderForOffsetMapping builder(&items); builder.Append("Hello ", style_.Get()); std::unique_ptr<LayoutInline> isolate_rtl( CreateLayoutInline([](ComputedStyle* style) { @@ -328,11 +423,12 @@ u"\u2069" u" World"), builder.ToString()); + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) { Vector<NGInlineItem> items; - NGInlineItemsBuilder builder(&items); + NGInlineItemsBuilderForOffsetMapping builder(&items); builder.Append("Hello ", style_.Get()); std::unique_ptr<LayoutInline> isolate_override_rtl( CreateLayoutInline([](ComputedStyle* style) { @@ -352,6 +448,7 @@ u"\u202C\u2069" u" World"), builder.ToString()); + EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder())); } } // namespace
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc index ec2e95d..fe38e80 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -39,7 +39,7 @@ // Perform 1st Layout. LayoutNGBlockFlow* block_flow = ToLayoutNGBlockFlow(GetLayoutObjectByElementId("container")); - NGInlineNode inline_node(block_flow, block_flow->FirstChild()); + NGInlineNode inline_node(block_flow); RefPtr<NGConstraintSpace> constraint_space = NGConstraintSpaceBuilder(NGWritingMode::kHorizontalTopBottom) .SetAvailableSize({LayoutUnit(50), LayoutUnit(20)}) @@ -96,7 +96,7 @@ )HTML"); LayoutNGBlockFlow* block_flow = ToLayoutNGBlockFlow(GetLayoutObjectByElementId("container")); - NGInlineNode inline_node(block_flow, block_flow->FirstChild()); + NGInlineNode inline_node(block_flow); RefPtr<NGConstraintSpace> space = NGConstraintSpace::CreateFromLayoutObject(*block_flow); RefPtr<NGLayoutResult> layout_result = inline_node.Layout(space.Get());
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc index d508b03..6bb6121 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
@@ -165,15 +165,12 @@ } // namespace -NGInlineNode::NGInlineNode(LayoutNGBlockFlow* block, LayoutObject* start_inline) +NGInlineNode::NGInlineNode(LayoutNGBlockFlow* block) : NGLayoutInputNode(block) { - DCHECK(start_inline); DCHECK(block); block->SetLayoutNGInline(true); - if (!block->HasNGInlineNodeData()) { + if (!block->HasNGInlineNodeData()) block->ResetNGInlineNodeData(); - } - MutableData().start_inline_ = start_inline; } NGInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) { @@ -181,9 +178,7 @@ } void NGInlineNode::InvalidatePrepareLayout() { - LayoutObject* start_inline = Data().start_inline_; ToLayoutNGBlockFlow(GetLayoutBlockFlow())->ResetNGInlineNodeData(); - MutableData().start_inline_ = start_inline; MutableData().text_content_ = String(); MutableData().items_.clear(); } @@ -191,7 +186,7 @@ void NGInlineNode::PrepareLayout() { // Scan list of siblings collecting all in-flow non-atomic inlines. A single // NGInlineNode represent a collection of adjacent non-atomic inlines. - CollectInlines(Data().start_inline_, GetLayoutBlockFlow()); + CollectInlines(GetLayoutBlockFlow()); SegmentText(); ShapeText(); } @@ -200,12 +195,12 @@ // NGInlineNode object. Collects LayoutText items, merging them up into the // parent LayoutInline where possible, and joining all text content in a single // string to allow bidi resolution and shaping of the entire block. -void NGInlineNode::CollectInlines(LayoutObject* start, LayoutBlockFlow* block) { +void NGInlineNode::CollectInlines(LayoutBlockFlow* block) { DCHECK(Data().text_content_.IsNull()); DCHECK(Data().items_.IsEmpty()); NGInlineItemsBuilder builder(&MutableData().items_); builder.EnterBlock(block->Style()); - LayoutObject* next_sibling = CollectInlines(start, block, &builder); + LayoutObject* next_sibling = CollectInlines(block, &builder); builder.ExitBlock(); MutableData().text_content_ = builder.ToString(); @@ -216,10 +211,9 @@ !(Data().text_content_.Is8Bit() && !builder.HasBidiControls()); } -LayoutObject* NGInlineNode::CollectInlines(LayoutObject* start, - LayoutBlockFlow* block, +LayoutObject* NGInlineNode::CollectInlines(LayoutBlockFlow* block, NGInlineItemsBuilder* builder) { - LayoutObject* node = start; + LayoutObject* node = block->FirstChild(); while (node) { if (node->IsText()) { builder->SetIsSVGText(node->IsSVGInlineText());
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h index f203a73a..5de226fc 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h
@@ -15,6 +15,10 @@ namespace blink { +template <typename OffsetMappingBuilder> +class NGInlineItemsBuilderTemplate; + +class EmptyOffsetMappingBuilder; class LayoutBlockFlow; class LayoutNGBlockFlow; class LayoutObject; @@ -22,14 +26,15 @@ class NGConstraintSpace; class NGInlineItem; class NGInlineItemRange; -class NGInlineItemsBuilder; +using NGInlineItemsBuilder = + NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; class NGLayoutResult; // Represents an anonymous block box to be laid out, that contains consecutive // inline nodes and their descendants. class CORE_EXPORT NGInlineNode : public NGLayoutInputNode { public: - NGInlineNode(LayoutNGBlockFlow*, LayoutObject*); + NGInlineNode(LayoutNGBlockFlow*); LayoutBlockFlow* GetLayoutBlockFlow() const { return ToLayoutBlockFlow(box_); @@ -75,10 +80,8 @@ void PrepareLayout(); bool IsPrepareLayoutFinished() const { return !Text().IsNull(); } - void CollectInlines(LayoutObject* start, LayoutBlockFlow*); - LayoutObject* CollectInlines(LayoutObject* start, - LayoutBlockFlow*, - NGInlineItemsBuilder*); + void CollectInlines(LayoutBlockFlow*); + LayoutObject* CollectInlines(LayoutBlockFlow*, NGInlineItemsBuilder*); void SegmentText(); void ShapeText();
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_data.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_data.h index 2550071b..0f91e423 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_data.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_data.h
@@ -35,9 +35,6 @@ // Calling NGInlineNode::NextSibling will trigger this. LayoutBox* next_sibling_; - // start_inline_ must always be reset within the constructor of NGInlineNode. - LayoutObject* start_inline_; - unsigned is_bidi_enabled_ : 1; unsigned base_direction_ : 1; // TextDirection };
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc index a67410b..8c1649e 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
@@ -89,8 +89,7 @@ NGInlineNodeForTest CreateInlineNode() { if (!layout_block_flow_) SetupHtml("t", "<div id=t style='font:10px'>test</div>"); - NGInlineNodeForTest node(layout_block_flow_, - layout_block_flow_->FirstChild()); + NGInlineNodeForTest node(layout_block_flow_); node.InvalidatePrepareLayout(); return node; } @@ -138,7 +137,7 @@ TEST_F(NGInlineNodeTest, CollectInlinesText) { SetupHtml("t", "<div id=t>Hello <span>inline</span> world.</div>"); NGInlineNodeForTest node = CreateInlineNode(); - node.CollectInlines(layout_object_, layout_block_flow_); + node.CollectInlines(layout_block_flow_); Vector<NGInlineItem>& items = node.Items(); TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 6u); TEST_ITEM_TYPE_OFFSET(items[1], kOpenTag, 6u, 6u); @@ -151,7 +150,7 @@ TEST_F(NGInlineNodeTest, CollectInlinesBR) { SetupHtml("t", u"<div id=t>Hello<br>World</div>"); NGInlineNodeForTest node = CreateInlineNode(); - node.CollectInlines(layout_object_, layout_block_flow_); + node.CollectInlines(layout_block_flow_); EXPECT_EQ("Hello\nWorld", node.Text()); Vector<NGInlineItem>& items = node.Items(); TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 5u); @@ -163,7 +162,7 @@ TEST_F(NGInlineNodeTest, CollectInlinesRtlText) { SetupHtml("t", u"<div id=t dir=rtl>\u05E2 <span>\u05E2</span> \u05E2</div>"); NGInlineNodeForTest node = CreateInlineNode(); - node.CollectInlines(layout_object_, layout_block_flow_); + node.CollectInlines(layout_block_flow_); EXPECT_TRUE(node.IsBidiEnabled()); node.SegmentText(); EXPECT_TRUE(node.IsBidiEnabled()); @@ -179,7 +178,7 @@ TEST_F(NGInlineNodeTest, CollectInlinesMixedText) { SetupHtml("t", u"<div id=t>Hello, \u05E2 <span>\u05E2</span></div>"); NGInlineNodeForTest node = CreateInlineNode(); - node.CollectInlines(layout_object_, layout_block_flow_); + node.CollectInlines(layout_block_flow_); EXPECT_TRUE(node.IsBidiEnabled()); node.SegmentText(); EXPECT_TRUE(node.IsBidiEnabled()); @@ -195,7 +194,7 @@ TEST_F(NGInlineNodeTest, CollectInlinesMixedTextEndWithON) { SetupHtml("t", u"<div id=t>Hello, \u05E2 <span>\u05E2!</span></div>"); NGInlineNodeForTest node = CreateInlineNode(); - node.CollectInlines(layout_object_, layout_block_flow_); + node.CollectInlines(layout_block_flow_); EXPECT_TRUE(node.IsBidiEnabled()); node.SegmentText(); EXPECT_TRUE(node.IsBidiEnabled());
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc index 4761ba3f..02cd2fb 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -20,7 +20,7 @@ LayoutNGBlockFlow* block_flow = ToLayoutNGBlockFlow(GetLayoutObjectByElementId("container")); - return NGInlineNode(block_flow, block_flow->FirstChild()); + return NGInlineNode(block_flow); } // Break lines using the specified available width.
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_builder.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_builder.cc new file mode 100644 index 0000000..4d42e54c --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_builder.cc
@@ -0,0 +1,50 @@ +// 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 "core/layout/ng/inline/ng_offset_mapping_builder.h" + +#include "platform/wtf/text/StringBuilder.h" + +namespace blink { + +NGOffsetMappingBuilder::NGOffsetMappingBuilder() { + mapping_.push_back(0); +} + +void NGOffsetMappingBuilder::AppendIdentityMapping(unsigned length) { + DCHECK_GT(length, 0u); + DCHECK(!mapping_.IsEmpty()); + for (unsigned i = 0; i < length; ++i) { + unsigned next = mapping_.back() + 1; + mapping_.push_back(next); + } +} + +void NGOffsetMappingBuilder::AppendCollapsedMapping(unsigned length) { + DCHECK_GT(length, 0u); + DCHECK(!mapping_.IsEmpty()); + const unsigned back = mapping_.back(); + for (unsigned i = 0; i < length; ++i) + mapping_.push_back(back); +} + +void NGOffsetMappingBuilder::CollapseTrailingSpace(unsigned skip_length) { + DCHECK(!mapping_.IsEmpty()); + + // Find the |skipped_count + 1|-st last uncollapsed character. By collapsing + // it, all mapping values beyond this position are decremented by 1. + unsigned skipped_count = 0; + for (unsigned i = mapping_.size() - 1; skipped_count <= skip_length; --i) { + DCHECK_GT(i, 0u); + if (mapping_[i] != mapping_[i - 1]) + ++skipped_count; + --mapping_[i]; + } +} + +Vector<unsigned> NGOffsetMappingBuilder::DumpOffsetMappingForTesting() const { + return mapping_; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_builder.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_builder.h new file mode 100644 index 0000000..03158f9 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_builder.h
@@ -0,0 +1,84 @@ +// 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 NGOffsetMappingBuilder_h +#define NGOffsetMappingBuilder_h + +#include "core/CoreExport.h" +#include "platform/wtf/Allocator.h" +#include "platform/wtf/Vector.h" +#include "platform/wtf/text/WTFString.h" + +namespace blink { + +// This is the helper class for constructing the DOM-to-TextContent offset +// mapping. It holds an offset mapping, and provides APIs to modify the mapping +// step by step until the construction is finished. +// Design doc: https://goo.gl/CJbxky +// TODO(xiaochengh): Change the mock implemetation to a real one. +class CORE_EXPORT NGOffsetMappingBuilder { + STACK_ALLOCATED(); + + public: + NGOffsetMappingBuilder(); + + // TODO(xiaochengh): Add the following API when we implement the construction + // of the concatenated offset mapping. + // Associate the offset mapping with a simple annotation with the given node + // as its value. + // void Annotate(const Node&); + + // Append an identity offset mapping of the specified length with null + // annotation to the builder. + void AppendIdentityMapping(unsigned length); + + // Append a collapsed offset mapping from the specified length with null + // annotation to the builder. + void AppendCollapsedMapping(unsigned length); + + // TODO(xiaochengh): Add the following API when we start to fix offset mapping + // for text-transform. + // Append an expanded offset mapping to the specified length with null + // annotation to the builder. + // void AppendExpandedMapping(unsigned length); + + // This function should only be called by NGInlineItemsBuilder during + // whitespace collapsing, and in the case that the target string of the + // currently held mapping: + // (i) has at least |skip_length + 1| characters, + // (ii) has the last |skip_length| characters being non-text extra + // characters, and + // (iii) has the |skip_length + 1|-st last character being a space. + // This function changes the space into collapsed. + void CollapseTrailingSpace(unsigned index); + + // TODO(xiaochengh): Add the following API when we implement the construction + // of the concatenated offset mapping. + // Concatenate the offset mapping held by another builder to this builder. + // void Concatenate(const OffsetMappingBuilder&); + + // TODO(xiaochengh): Add the following APIs when we implement the construction + // of the DOM-to-TextContent offset mapping. + + // Composite the offset mapping held by another builder to this builder. + // void Composite(const OffsetMappingBuilder&); + + // Finalize and return the offset mapping. + // OffsetMappingResult Build(); + + // Exposed for testing only. + Vector<unsigned> DumpOffsetMappingForTesting() const; + + private: + // A mock implementation of the offset mapping builder that stores the mapping + // value of every offset in the plain way. This is simple but inefficient, and + // will be replaced by a real efficient implementation. + Vector<unsigned> mapping_; + + DISALLOW_COPY_AND_ASSIGN(NGOffsetMappingBuilder); +}; + +} // namespace blink + +#endif // OffsetMappingBuilder_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc index 645a908..98575440 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -198,17 +198,8 @@ NGLayoutInputNode NGBlockNode::NextSibling() const { LayoutObject* next_sibling = box_->NextSibling(); if (next_sibling) { - if (next_sibling->IsInline()) { - // As long as we traverse LayoutObject tree, this should not happen. - // See ShouldHandleByInlineContext() for more context. - // Also this leads to incorrect layout because we create two - // NGLayoutInputNode for one LayoutBlockFlow. - NOTREACHED(); - LayoutNGBlockFlow* block_flow = ToLayoutNGBlockFlow(GetLayoutObject()); - return NGInlineNode(block_flow, next_sibling); - } else { - return NGBlockNode(ToLayoutBox(next_sibling)); - } + DCHECK(!next_sibling->IsInline()); + return NGBlockNode(ToLayoutBox(next_sibling)); } return nullptr; } @@ -218,7 +209,7 @@ if (child) { if (box_->ChildrenInline()) { LayoutNGBlockFlow* block_flow = ToLayoutNGBlockFlow(GetLayoutObject()); - return NGInlineNode(block_flow, child); + return NGInlineNode(block_flow); } else { return NGBlockNode(ToLayoutBox(child)); }
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index c8d4c14..1fd1425e0 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -42,6 +42,7 @@ #include "core/page/Page.h" #include "platform/DragImage.h" #include "platform/WebFrameScheduler.h" +#include "platform/exported/WrappedResourceRequest.h" #include "platform/geometry/FloatPoint.h" #include "platform/geometry/FloatRect.h" #include "platform/geometry/IntRect.h" @@ -367,9 +368,13 @@ WebApplicationCacheHostClient*) override; TextCheckerClient& GetTextCheckerClient() const override; - std::unique_ptr<WebURLLoader> CreateURLLoader() override { + std::unique_ptr<WebURLLoader> CreateURLLoader( + const ResourceRequest& request, + WebTaskRunner* task_runner) override { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return Platform::Current()->CreateURLLoader(); + WrappedResourceRequest wrapped(request); + return Platform::Current()->CreateURLLoader( + wrapped, task_runner->ToSingleThreadTaskRunner()); } void AnnotatedRegionsChanged() override {}
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index ed52786..a56696f 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -1083,9 +1083,7 @@ const ResourceRequest& request) { DCHECK(!IsDetached()); - auto loader = GetFrame()->CreateURLLoader(); RefPtr<WebTaskRunner> task_runner; - if (request.GetKeepalive()) { // The loader should be able to work after the frame destruction, so we // cannot use the task runner associated with the frame. @@ -1094,8 +1092,7 @@ } else { task_runner = GetTaskRunner(); } - loader->SetLoadingTaskRunner(task_runner.Get()); - return loader; + return GetFrame()->CreateURLLoader(request, task_runner.Get()); } FetchContext* FrameFetchContext::Detach() {
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index e60229e6..b9b284a 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -1457,7 +1457,8 @@ provisional_document_loader_->SetItemForHistoryNavigation(history_item); } - frame_->FrameScheduler()->DidStartProvisionalLoad(); + DCHECK(!frame_load_request.GetResourceRequest().IsSameDocumentNavigation()); + frame_->FrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame()); // TODO(ananta): // We should get rid of the dependency on the DocumentLoader in consumers of
diff --git a/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp b/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp index 2faf3de..0e08b428 100644 --- a/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp
@@ -209,10 +209,10 @@ } std::unique_ptr<WebURLLoader> WorkerFetchContext::CreateURLLoader( - const ResourceRequest&) { - auto loader = web_context_->CreateURLLoader(); - loader->SetLoadingTaskRunner(loading_task_runner_.Get()); - return loader; + const ResourceRequest& request) { + WrappedResourceRequest wrapped(request); + return web_context_->CreateURLLoader( + wrapped, loading_task_runner_->ToSingleThreadTaskRunner()); } bool WorkerFetchContext::IsControlledByServiceWorker() const {
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp index be9efa8..5c314e92 100644 --- a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp
@@ -206,8 +206,7 @@ String source_text = GetResource()->SourceText(); AccessControlStatus access_control_status = - GetResource()->CalculateAccessControlStatus( - modulator_->GetSecurityOrigin()); + GetResource()->CalculateAccessControlStatus(); // Step 9. Let module script be the result of creating a module script given // source text, module map settings object, response's url, cryptographic
diff --git a/third_party/WebKit/Source/core/loader/resource/FontResource.h b/third_party/WebKit/Source/core/loader/resource/FontResource.h index 6c5d0d3..e959490 100644 --- a/third_party/WebKit/Source/core/loader/resource/FontResource.h +++ b/third_party/WebKit/Source/core/loader/resource/FontResource.h
@@ -55,8 +55,6 @@ void AllClientsAndObserversRemoved() override; void StartLoadLimitTimers(); - void SetCORSFailed() override { cors_failed_ = true; } - bool IsCORSFailed() const { return cors_failed_; } String OtsParsingMessage() const { return ots_parsing_message_; } PassRefPtr<FontCustomPlatformData> GetCustomFontData();
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp index 472011e..f698bae 100644 --- a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
@@ -181,7 +181,8 @@ FetchParameters::kAllowPlaceholder && placeholder_option_ != PlaceholderOption::kDoNotReloadPlaceholder) return false; - return true; + + return Resource::CanReuse(params); } bool ImageResource::CanUseCacheValidator() const { @@ -599,15 +600,16 @@ SecurityOrigin* security_origin, ImageResourceInfo::DoesCurrentFrameHaveSingleSecurityOrigin does_current_frame_has_single_security_origin) const { - if (GetResponse().WasFetchedViaServiceWorker()) { - return GetResponse().ServiceWorkerResponseType() != - kWebServiceWorkerResponseTypeOpaque; - } + if (GetCORSStatus() == CORSStatus::kServiceWorkerOpaque) + return false; + if (does_current_frame_has_single_security_origin != ImageResourceInfo::kHasSingleSecurityOrigin) return false; - if (PassesAccessControlCheck(security_origin)) + + if (IsSameOriginOrCORSSuccessful()) return true; + return !security_origin->TaintsCanvas(GetResponse().Url()); }
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResource.h b/third_party/WebKit/Source/core/loader/resource/ImageResource.h index bc687fc..94e6f23 100644 --- a/third_party/WebKit/Source/core/loader/resource/ImageResource.h +++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.h
@@ -94,8 +94,6 @@ // For compatibility, images keep loading even if there are HTTP errors. bool ShouldIgnoreHTTPStatusCodeErrors() const override { return true; } - bool IsImage() const override { return true; } - // MultipartImageResourceParser::Client void OnePartInMultipartReceived(const ResourceResponse&) final; void MultipartDataReceived(const char*, size_t) final;
diff --git a/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp b/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp index c212c14..4fb56ae 100644 --- a/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp
@@ -107,18 +107,11 @@ response.HttpContentType()); } -AccessControlStatus ScriptResource::CalculateAccessControlStatus( - const SecurityOrigin* security_origin) const { - if (GetResponse().WasFetchedViaServiceWorker()) { - if (GetResponse().ServiceWorkerResponseType() == - kWebServiceWorkerResponseTypeOpaque) { - return kOpaqueResource; - } +AccessControlStatus ScriptResource::CalculateAccessControlStatus() const { + if (GetCORSStatus() == CORSStatus::kServiceWorkerOpaque) + return kOpaqueResource; - return kSharableCrossOrigin; - } - - if (PassesAccessControlCheck(security_origin)) + if (IsSameOriginOrCORSSuccessful()) return kSharableCrossOrigin; return kNotSharableCrossOrigin;
diff --git a/third_party/WebKit/Source/core/loader/resource/ScriptResource.h b/third_party/WebKit/Source/core/loader/resource/ScriptResource.h index 1c7ff8f..9f6c1cd5 100644 --- a/third_party/WebKit/Source/core/loader/resource/ScriptResource.h +++ b/third_party/WebKit/Source/core/loader/resource/ScriptResource.h
@@ -84,7 +84,7 @@ static bool MimeTypeAllowedByNosniff(const ResourceResponse&); - AccessControlStatus CalculateAccessControlStatus(const SecurityOrigin*) const; + AccessControlStatus CalculateAccessControlStatus() const; private: class ScriptResourceFactory : public ResourceFactory {
diff --git a/third_party/WebKit/Source/core/page/AutoscrollController.cpp b/third_party/WebKit/Source/core/page/AutoscrollController.cpp index 1829f5d..0a17c9a5 100644 --- a/third_party/WebKit/Source/core/page/AutoscrollController.cpp +++ b/third_party/WebKit/Source/core/page/AutoscrollController.cpp
@@ -238,7 +238,9 @@ last_velocity_ = velocity; if (middle_click_mode_ == kMiddleClickInitial) middle_click_mode_ = kMiddleClickHolding; + page_->GetChromeClient().SetCursorOverridden(false); view->SetCursor(MiddleClickAutoscrollCursor(velocity)); + page_->GetChromeClient().SetCursorOverridden(true); page_->GetChromeClient().AutoscrollFling(velocity, frame); } } @@ -265,6 +267,7 @@ page_->GetChromeClient().AutoscrollEnd(frame); autoscroll_type_ = kNoAutoscroll; + page_->GetChromeClient().SetCursorOverridden(false); frame->LocalFrameRoot().GetEventHandler().ScheduleCursorUpdate(); } @@ -289,8 +292,10 @@ UseCounter::Count(frame, WebFeature::kMiddleClickAutoscrollStart); last_velocity_ = FloatSize(); + if (LocalFrameView* view = frame->View()) view->SetCursor(MiddleClickAutoscrollCursor(last_velocity_)); + page_->GetChromeClient().SetCursorOverridden(true); page_->GetChromeClient().AutoscrollStart( position.ScaledBy(1 / frame->DevicePixelRatio()), frame); }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index 676b168..7db17267 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -163,8 +163,11 @@ // Currently, some properties are stored in ComputedStyle and some in // ComputedStyleBase. Eventually, the storage of all properties (except SVG // ones) will be in ComputedStyleBase. -class CORE_EXPORT ComputedStyle : public ComputedStyleBase, - public RefCounted<ComputedStyle> { +// +// Since this class is huge, do not mark all of it CORE_EXPORT. Instead, +// export only the methods you need below. +class ComputedStyle : public ComputedStyleBase, + public RefCounted<ComputedStyle> { // Needed to allow access to private/protected getters of fields to allow diff // generation friend class ComputedStyleBase; @@ -209,14 +212,14 @@ static RefPtr<ComputedStyle> CreateInitialStyle(); // TODO(shend): Remove this. Initial style should not be mutable. - static ComputedStyle& MutableInitialStyle(); + CORE_EXPORT static ComputedStyle& MutableInitialStyle(); public: - static RefPtr<ComputedStyle> Create(); + CORE_EXPORT static RefPtr<ComputedStyle> Create(); static RefPtr<ComputedStyle> CreateAnonymousStyleWithDisplay( const ComputedStyle& parent_style, EDisplay); - static RefPtr<ComputedStyle> Clone(const ComputedStyle&); + CORE_EXPORT static RefPtr<ComputedStyle> Clone(const ComputedStyle&); static const ComputedStyle& InitialStyle() { return MutableInitialStyle(); } static void InvalidateInitialStyle(); @@ -994,7 +997,7 @@ // line-height static Length InitialLineHeight() { return Length(-100.0, kPercent); } Length LineHeight() const; - void SetLineHeight(const Length& specified_line_height); + CORE_EXPORT void SetLineHeight(const Length& specified_line_height); // List style properties. // list-style-image @@ -1057,16 +1060,16 @@ } // Font properties. - const Font& GetFont() const; - void SetFont(const Font&); - const FontDescription& GetFontDescription() const; - bool SetFontDescription(const FontDescription&); + CORE_EXPORT const Font& GetFont() const; + CORE_EXPORT void SetFont(const Font&); + CORE_EXPORT const FontDescription& GetFontDescription() const; + CORE_EXPORT bool SetFontDescription(const FontDescription&); bool HasIdenticalAscentDescentAndLineGap(const ComputedStyle& other) const; // font-size int FontSize() const; - float SpecifiedFontSize() const; - float ComputedFontSize() const; + CORE_EXPORT float SpecifiedFontSize() const; + CORE_EXPORT float ComputedFontSize() const; LayoutUnit ComputedFontSizeAsFixed() const; // font-size-adjust @@ -1074,7 +1077,7 @@ bool HasFontSizeAdjust() const; // font-weight - FontWeight GetFontWeight() const; + CORE_EXPORT FontWeight GetFontWeight() const; // font-stretch FontStretch GetFontStretch() const; @@ -1200,7 +1203,7 @@ // Comparison operators // TODO(shend): Replace callers of operator== wth a named method instead, e.g. // inheritedEquals(). - bool operator==(const ComputedStyle& other) const; + CORE_EXPORT bool operator==(const ComputedStyle& other) const; bool operator!=(const ComputedStyle& other) const { return !(*this == other); } @@ -1297,7 +1300,7 @@ float TextAutosizingMultiplier() const { return TextAutosizingMultiplierInternal(); } - void SetTextAutosizingMultiplier(float); + CORE_EXPORT void SetTextAutosizingMultiplier(float); // Column utility functions. void ClearMultiCol(); @@ -1940,8 +1943,8 @@ bool HasOutline() const { return OutlineWidth() > 0 && OutlineStyle() > EBorderStyle::kHidden; } - int OutlineOutsetExtent() const; - float GetOutlineStrokeWidthForFocusRing() const; + CORE_EXPORT int OutlineOutsetExtent() const; + CORE_EXPORT float GetOutlineStrokeWidthForFocusRing() const; bool HasOutlineWithCurrentColor() const { return HasOutline() && OutlineColor().IsCurrentColor(); } @@ -2207,7 +2210,8 @@ // they don't determine the stacking of the elements underneath them. (Note: // There are also other elements treated as stacking context during painting, // but not managed in stacks. See ObjectPainter::PaintAllPhasesAtomically().) - void UpdateIsStackingContext(bool is_document_element, bool is_in_top_layer); + CORE_EXPORT void UpdateIsStackingContext(bool is_document_element, + bool is_in_top_layer); bool IsStacked() const { return IsStackingContext() || GetPosition() != EPosition::kStatic; } @@ -2339,7 +2343,7 @@ // Color utility functions. // TODO(sashab): Rename this to just getColor(), and add a comment explaining // how it works. - Color VisitedDependentColor(int color_property) const; + CORE_EXPORT Color VisitedDependentColor(int color_property) const; // -webkit-appearance utility functions. bool HasAppearance() const { return Appearance() != kNoControlPart; } @@ -2589,8 +2593,8 @@ const StyleImage&, const ComputedStyle& other) const; bool DiffNeedsVisualRectUpdate(const ComputedStyle& other) const; - void UpdatePropertySpecificDifferences(const ComputedStyle& other, - StyleDifference&) const; + CORE_EXPORT void UpdatePropertySpecificDifferences(const ComputedStyle& other, + StyleDifference&) const; static bool ShadowListHasCurrentColor(const ShadowList*);
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp index cdb2965..3840a32 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -40,6 +40,7 @@ #include "core/dom/ShadowRoot.h" #include "core/events/Event.h" #include "core/frame/Settings.h" +#include "core/frame/UseCounter.h" #include "core/frame/csp/ContentSecurityPolicy.h" #include "core/html/HTMLElement.h" #include "core/inspector/ConsoleMessage.h"
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp index 394e31a..c57e067 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -490,7 +490,8 @@ // TODO(nhiroki): Handle a case where the script controller fails to // initialize the context. - if (GlobalScope()->ScriptController()->InitializeContextIfNeeded()) { + if (GlobalScope()->ScriptController()->InitializeContextIfNeeded( + String())) { worker_reporting_proxy_.DidInitializeWorkerContext(); v8::HandleScope handle_scope(GetIsolate()); Platform::Current()->WorkerContextCreated(
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp index e750066..9771aae 100644 --- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp +++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -369,7 +369,7 @@ }); size = binary_response_builder_->size(); blob_data->SetContentType( - FinalResponseMIMETypeWithFallback().DeprecatedLower()); + FinalResponseMIMETypeWithFallback().LowerASCII()); binary_response_builder_.Clear(); } response_blob_ = @@ -1448,7 +1448,7 @@ } bool XMLHttpRequest::ResponseIsHTML() const { - return DeprecatedEqualIgnoringCase(FinalResponseMIMEType(), "text/html"); + return EqualIgnoringASCIICase(FinalResponseMIMEType(), "text/html"); } int XMLHttpRequest::status() const { @@ -1584,8 +1584,7 @@ // FIXME: finalResponseMIMETypeWithFallback() defaults to // text/xml which may be incorrect. Replace it with // finalResponseMIMEType() after compatibility investigation. - blob_data->SetContentType( - FinalResponseMIMETypeWithFallback().DeprecatedLower()); + blob_data->SetContentType(FinalResponseMIMETypeWithFallback().LowerASCII()); } return BlobDataHandle::Create(std::move(blob_data), length_downloaded_to_file_);
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index 95a770ac..377f7fa2 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -10,11 +10,13 @@ "front_end/accessibility/AccessibilityModel.js", "front_end/accessibility/accessibilityNode.css", "front_end/accessibility/AccessibilityNodeView.js", + "front_end/accessibility/accessibilityProperties.css", "front_end/accessibility/AccessibilitySidebarView.js", "front_end/accessibility/AccessibilityStrings.js", "front_end/accessibility/ARIAAttributesView.js", "front_end/accessibility/ARIAConfig.js", "front_end/accessibility/ARIAMetadata.js", + "front_end/accessibility/axBreadcrumbs.css", "front_end/accessibility/AXBreadcrumbsPane.js", "front_end/accessibility/module.json", "front_end/animation/AnimationGroupPreviewUI.js", @@ -329,7 +331,6 @@ "front_end/network/EventSourceMessagesView.js", "front_end/network/FilterSuggestionBuilder.js", "front_end/network/HARWriter.js", - "front_end/network/JSONView.js", "front_end/network/module.json", "front_end/network/networkConfigView.css", "front_end/network/NetworkConfigView.js", @@ -356,12 +357,8 @@ "front_end/network/RequestPreviewView.js", "front_end/network/RequestResponseView.js", "front_end/network/RequestTimingView.js", - "front_end/network/RequestView.js", "front_end/network/ResourceWebSocketFrameView.js", "front_end/network/webSocketFrameView.css", - "front_end/network/xmlTree.css", - "front_end/network/xmlView.css", - "front_end/network/XMLView.js", "front_end/network_log/HAREntry.js", "front_end/network_log/module.json", "front_end/network_log/NetworkLog.js", @@ -548,14 +545,19 @@ "front_end/source_frame/fontView.css", "front_end/source_frame/FontView.js", "front_end/source_frame/imageView.css", + "front_end/source_frame/JSONView.js", "front_end/source_frame/ImageView.js", "front_end/source_frame/messagesPopover.css", "front_end/source_frame/module.json", + "front_end/source_frame/PreviewFactory.js", "front_end/source_frame/ResourceSourceFrame.js", "front_end/source_frame/SourceCodeDiff.js", "front_end/source_frame/SourceFrame.js", "front_end/source_frame/SourcesTextEditor.js", "front_end/source_frame/UISourceCodeFrame.js", + "front_end/source_frame/xmlTree.css", + "front_end/source_frame/xmlView.css", + "front_end/source_frame/XMLView.js", "front_end/sources/AddSourceMapURLDialog.js", "front_end/sources/AdvancedSearchView.js", "front_end/sources/callStackSidebarPane.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js index 0f1d0ec4..417b495aa 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js
@@ -25,6 +25,8 @@ this._rootElement.addEventListener('mousemove', this._onMouseMove.bind(this), false); this._rootElement.addEventListener('mouseleave', this._onMouseLeave.bind(this), false); this._rootElement.addEventListener('click', this._onClick.bind(this), false); + + this.registerRequiredCSS('accessibility/axBreadcrumbs.css'); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js index 6d691b0a..1cac76ee 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js
@@ -17,6 +17,7 @@ this._ignoredReasonsTree = this.createTreeOutline(); this.element.classList.add('accessibility-computed'); + this.registerRequiredCSS('accessibility/accessibilityNode.css'); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js index b3c30ae..59ca564 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -153,7 +153,7 @@ super(name); this._axNode = null; - this.registerRequiredCSS('accessibility/accessibilityNode.css'); + this.registerRequiredCSS('accessibility/accessibilityProperties.css'); } /** @@ -195,9 +195,11 @@ createTreeOutline() { var treeOutline = new UI.TreeOutlineInShadow(); treeOutline.registerRequiredCSS('accessibility/accessibilityNode.css'); + treeOutline.registerRequiredCSS('accessibility/accessibilityProperties.css'); treeOutline.registerRequiredCSS('object_ui/objectValue.css'); treeOutline.element.classList.add('hidden'); + treeOutline.hideOverflow(); this.element.appendChild(treeOutline.element); return treeOutline; }
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css index 3e24358..1fcbfde0 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css
@@ -1,5 +1,5 @@ /* - * Copyright 2015 The Chromium Authors. All rights reserved. + * 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. */ @@ -12,47 +12,11 @@ overflow-x: hidden; } -.ax-computed-text { - background-image: url(Images/speech.png); - background-repeat: no-repeat; - background-position: 0px center; - background-size: 12px; - padding-left: 17px; -} - -.ax-computed-text div { - display: inline-block; - padding: 2px; - width: 100%; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - width: 100%; -} - div.ax-text-alternatives { margin-bottom: 3px; border-bottom: 1px solid #BFBFBF; } -.ax-name { - color: rgb(153, 69, 0); - flex-shrink: 0; -} - -.ax-readable-name { - flex-shrink: 0; - padding-left: 2px; -} - -.ax-readable-string { - font-style: italic; -} - -span.ax-internal-role { - font-style: italic; -} - .ax-ignored-info { padding: 6px; } @@ -65,12 +29,31 @@ text-decoration: line-through; } +span.ax-value-undefined { + font-style: italic; +} + +.ax-value-source-unused { + opacity: 0.7; +} + +.ax-value-source-superseded, +.ax-value-source-invalid { + text-decoration: line-through; +} + +.sidebar-pane-stack .sidebar-pane { + padding-left: 4px; +} + .tree-outline label[is=dt-icon-label] { position: relative; left: -11px; } .tree-outline li { + display: block; + overflow-x: hidden; padding-left: 1px; align-items: baseline; } @@ -84,162 +67,12 @@ left: -2px; } -.ax-breadcrumbs-ignored-node { - font-style: italic; - opacity: 0.7; -} - -.ax-breadcrumbs { - padding-top: 1px; - margin: 0; - position: relative; -} - -.ax-breadcrumbs .ax-node { - white-space: nowrap; - position: relative; - min-height: 16px; - align-items: baseline; - padding-left: 4px; - padding-right: 4px; - overflow-x: hidden; -} - -.ax-breadcrumbs .ax-node::before { - -webkit-mask-image: url(Images/chevrons.png); - -webkit-mask-position: 0 0; - -webkit-mask-size: 30px 10px; - -webkit-mask-repeat: no-repeat; - background-color: rgb(48, 57, 66); - content: " "; - color: transparent; - text-shadow: none; - margin-right: -2px; - height: 12px; - width: 14px; - position: absolute; -} - -@media (-webkit-min-device-pixel-ratio: 1.1) { - .ax-breadcrumbs .ax-node::before { - -webkit-mask-image: url(Images/chevrons_2x.png); - } -} /* media */ - -.ax-breadcrumbs .ax-node:not(.parent):not(.children-unloaded)::before { - background-color: transparent; -} - -.ax-breadcrumbs .ax-node.parent::before { - -webkit-mask-position: -20px 1px; -} - -.ax-breadcrumbs .ax-node.children-unloaded::before { - -webkit-mask-position: 0px 1px; - width: 13px; -} - -.ax-breadcrumbs .ax-node.no-dom-node { - opacity: 0.5; -} - -.ax-breadcrumbs .ax-node.children-unloaded::before { - opacity: 0.4; -} - -span.ax-value-undefined { - font-style: italic; -} - -.ax-value-source-unused { - opacity: 0.5; -} - -.ax-value-source-superseded, -.ax-value-source-invalid { - text-decoration: line-through; -} - .tree-outline label[is=dt-icon-label] + .ax-name { margin-left: -11px; } -.ax-value-string { - color: rgb(200, 0, 0); -} - -.sidebar-pane-stack .sidebar-pane { - padding-left: 4px; -} - -button.expand-siblings { - border-radius: 1px; - background-color: #f3f3f3; - border: 1px solid #ddd; - margin-left: 5px; - margin-bottom: 1px; -} - -li.siblings-expanded button.expand-siblings { - display: none; -} - -.ax-breadcrumbs .ax-node { - text-overflow: ellipsis; - white-space: nowrap; - position: relative; - align-items: center; - min-height: 16px; - margin-top: 1px; - padding-top: 1px; -} - -.ax-breadcrumbs .ax-node.preselected:not(.inspected) .selection, -.ax-breadcrumbs .ax-node.hovered:not(.inspected) .selection { - display: block; - left: 2px; - right: 2px; - background-color: rgba(56, 121, 217, 0.1); - border-radius: 5px; -} - -.ax-breadcrumbs .ax-node.preselected:not(.inspected):focus .selection { - border: 1px solid rgba(56, 121, 217, 0.4); -} - -.ax-breadcrumbs .ax-node .selection { - display: none; - z-index: -1; -} - -.ax-breadcrumbs .ax-node.inspected .selection { - display: block; - background-color: #ddd; -} - -.ax-breadcrumbs .ax-node.inspected:focus .selection { - background-color: rgb(56, 121, 217); -} - -.ax-breadcrumbs .ax-node.parent.inspected:focus::before { - background-color: white; -} - -.ax-breadcrumbs .ax-node.inspected:focus { - color: white; -} - -.ax-breadcrumbs .ax-node.inspected:focus * { - color: inherit; -} - -.ax-breadcrumbs .ax-node span { +.tree-outline li span { flex-shrink: 0; text-overflow: ellipsis; white-space: nowrap; } - -.ax-breadcrumbs .ax-node .wrapper { - padding-left: 12px; - overflow-x: hidden; -}
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityProperties.css b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityProperties.css new file mode 100644 index 0000000..c193898 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityProperties.css
@@ -0,0 +1,27 @@ +/* + * 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. + */ + +.ax-name { + color: rgb(153, 69, 0); + flex-shrink: 0; +} + +.ax-readable-name { + flex-shrink: 0; + padding-left: 2px; +} + +.ax-readable-string { + font-style: italic; +} + +.ax-value-string { + color: rgb(200, 0, 0); +} + +span.ax-internal-role { + font-style: italic; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/axBreadcrumbs.css b/third_party/WebKit/Source/devtools/front_end/accessibility/axBreadcrumbs.css new file mode 100644 index 0000000..35a67fb --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/axBreadcrumbs.css
@@ -0,0 +1,121 @@ +/* + * 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. + */ + +.ax-breadcrumbs-ignored-node { + font-style: italic; + opacity: 0.7; +} + +.ax-breadcrumbs { + padding-top: 1px; + margin: 0; + position: relative; +} + +.ax-breadcrumbs .ax-node { + align-items: center; + margin-top: 1px; + min-height: 16px; + overflow-x: hidden; + padding-left: 4px; + padding-right: 4px; + padding-top: 1px; + position: relative; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ax-breadcrumbs .ax-node span { + flex-shrink: 0; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ax-breadcrumbs .ax-node .wrapper { + padding-left: 12px; + overflow-x: hidden; +} + +.ax-breadcrumbs .ax-node::before { + -webkit-mask-image: url(Images/chevrons.png); + -webkit-mask-position: 0 0; + -webkit-mask-size: 30px 10px; + -webkit-mask-repeat: no-repeat; + background-color: rgb(48, 57, 66); + content: " "; + color: transparent; + text-shadow: none; + margin-right: -2px; + height: 12px; + width: 14px; + position: absolute; +} + +@media (-webkit-min-device-pixel-ratio: 1.1) { + .ax-breadcrumbs .ax-node::before { + -webkit-mask-image: url(Images/chevrons_2x.png); + } +} /* media */ + +.ax-breadcrumbs .ax-node:not(.parent):not(.children-unloaded)::before { + background-color: transparent; +} + +.ax-breadcrumbs .ax-node.parent::before { + -webkit-mask-position: -20px 1px; +} + +.ax-breadcrumbs .ax-node.children-unloaded::before { + -webkit-mask-position: 0px 1px; + width: 13px; +} + +.ax-breadcrumbs .ax-node.no-dom-node { + opacity: 0.7; +} + +.ax-breadcrumbs .ax-node.children-unloaded::before { + opacity: 0.4; +} + +.ax-breadcrumbs .ax-node.preselected:not(.inspected) .selection, +.ax-breadcrumbs .ax-node.hovered:not(.inspected) .selection { + display: block; + left: 2px; + right: 2px; + background-color: rgba(56, 121, 217, 0.1); + border-radius: 5px; +} + +.ax-breadcrumbs .ax-node.preselected:not(.inspected):focus .selection { + border: 1px solid rgba(56, 121, 217, 0.4); +} + +.ax-breadcrumbs .ax-node .selection { + display: none; + z-index: -1; +} + +.ax-breadcrumbs .ax-node.inspected .selection { + display: block; + background-color: #ddd; +} + +.ax-breadcrumbs .ax-node.inspected:focus .selection { + background-color: rgb(56, 121, 217); +} + +.ax-breadcrumbs .ax-node.parent.inspected:focus::before { + background-color: white; +} + +.ax-breadcrumbs .ax-node.inspected:focus { + color: white; +} + +.ax-breadcrumbs .ax-node.inspected:focus * { + color: inherit; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/module.json b/third_party/WebKit/Source/devtools/front_end/accessibility/module.json index 8107bb8..9ec17112 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/module.json +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/module.json
@@ -26,6 +26,8 @@ "ARIAConfig.js" ], "resources": [ - "accessibilityNode.css" + "accessibilityNode.css", + "accessibilityProperties.css", + "axBreadcrumbs.css" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js index 7f6501b..adce9082 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -259,13 +259,6 @@ this._locations = new Multimap(); debuggerModel.setBeforePausedCallback(this._beforePaused.bind(this)); - this._eventListeners = [ - debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this), - debuggerModel.addEventListener( - SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this), - debuggerModel.addEventListener( - SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this._discardedScriptSource, this) - ]; } /** @@ -336,26 +329,8 @@ return !!this._compilerMapping.mapsToSourceCode(debuggerPausedDetails.callFrames[0].location()); } - /** - * @param {!Common.Event} event - */ - _parsedScriptSource(event) { - var script = /** @type {!SDK.Script} */ (event.data); - this._defaultMapping.addScript(script); - this._resourceMapping.addScript(script); - } - - /** - * @param {!Common.Event} event - */ - _discardedScriptSource(event) { - var script = /** @type {!SDK.Script} */ (event.data); - this._defaultMapping.removeScript(script); - } - _dispose() { this._debuggerModel.setBeforePausedCallback(null); - Common.EventTarget.removeEventListeners(this._eventListeners); this._compilerMapping.dispose(); this._resourceMapping.dispose(); this._defaultMapping.dispose();
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js index 9fbb5dc..a3a32c3b 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js
@@ -40,11 +40,17 @@ constructor(debuggerModel, workspace, debuggerWorkspaceBinding) { this._debuggerModel = debuggerModel; this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; - var projectId = Bindings.DefaultScriptMapping.projectIdForTarget(debuggerModel.target()); this._project = new Bindings.ContentProviderBasedProject( - workspace, projectId, Workspace.projectTypes.Debugger, '', true /* isServiceProject */); - this._eventListeners = - [debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this)]; + workspace, 'debugger:' + debuggerModel.target().id(), Workspace.projectTypes.Debugger, '', + true /* isServiceProject */); + this._eventListeners = [ + debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this), + debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this), + debuggerModel.addEventListener( + SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this), + debuggerModel.addEventListener( + SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this._discardedScriptSource, this) + ]; } /** @@ -56,14 +62,6 @@ } /** - * @param {!SDK.Target} target - * @return {string} - */ - static projectIdForTarget(target) { - return 'debugger:' + target.id(); - } - - /** * @override * @param {!SDK.DebuggerModel.Location} rawLocation * @return {?Workspace.UILocation} @@ -99,9 +97,10 @@ } /** - * @param {!SDK.Script} script + * @param {!Common.Event} event */ - addScript(script) { + _parsedScriptSource(event) { + var script = /** @type {!SDK.Script} */ (event.data); var name = Common.ParsedURL.extractName(script.sourceURL); var url = 'debugger:///VM' + script.scriptId + (name ? ' ' + name : ''); @@ -113,9 +112,10 @@ } /** - * @param {!SDK.Script} script + * @param {!Common.Event} event */ - removeScript(script) { + _discardedScriptSource(event) { + var script = /** @type {!SDK.Script} */ (event.data); var uiSourceCode = script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol]; if (!uiSourceCode) return; @@ -136,4 +136,4 @@ }; Bindings.DefaultScriptMapping._scriptSymbol = Symbol('symbol'); -Bindings.DefaultScriptMapping._uiSourceCodeSymbol = Symbol('uiSourceCodeSymbol'); \ No newline at end of file +Bindings.DefaultScriptMapping._uiSourceCodeSymbol = Symbol('uiSourceCodeSymbol');
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js index 4997760..48e86cc5 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -49,6 +49,9 @@ this._eventListeners = [ debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this), + debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this), + debuggerModel.addEventListener( + SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this), workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this), workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this) ]; @@ -99,9 +102,10 @@ } /** - * @param {!SDK.Script} script + * @param {!Common.Event} event */ - addScript(script) { + _parsedScriptSource(event) { + var script = /** @type {!SDK.Script} */ (event.data); if (script.isAnonymousScript()) return;
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js index c3d5cd3..d3d4064 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js
@@ -31,15 +31,15 @@ /** * @unrestricted */ -Network.RequestHTMLView = class extends Network.RequestView { +Network.RequestHTMLView = class extends UI.VBox { /** - * @param {!SDK.NetworkRequest} request * @param {string} dataURL */ - constructor(request, dataURL) { - super(request); + constructor(dataURL) { + super(); + this._dataURL = dataURL; - this.element.classList.add('html'); + this.element.classList.add('html', 'request-view'); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js index 6ccb311d..9348b837 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js
@@ -28,81 +28,37 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -Network.RequestPreviewView = class extends Network.RequestView { +Network.RequestPreviewView = class extends Network.RequestResponseView { /** * @param {!SDK.NetworkRequest} request */ constructor(request) { super(request); - /** @type {?Promise<!UI.Widget>} */ - this._previewViewPromise = null; - } - - /** - * @return {!UI.EmptyWidget} - */ - _createEmptyWidget() { - return this._createMessageView(Common.UIString('This request has no preview available.')); - } - - /** - * @param {string} message - * @return {!UI.EmptyWidget} - */ - _createMessageView(message) { - return new UI.EmptyWidget(message); - } - - /** - * @param {string} content - * @param {string} mimeType - * @return {?UI.SearchableView} - */ - _xmlView(content, mimeType) { - var parsedXML = Network.XMLView.parseXML(content, mimeType); - return parsedXML ? Network.XMLView.createSearchableView(parsedXML) : null; - } - - /** - * @param {string} content - * @return {!Promise<?UI.SearchableView>} - */ - async _jsonView(content) { - // We support non-strict JSON parsing by parsing an AST tree which is why we offload it to a worker. - var parsedJSON = await Network.JSONView.parseJSON(content); - if (!parsedJSON || typeof parsedJSON.data !== 'object') - return null; - return Network.JSONView.createSearchableView(/** @type {!Network.ParsedJSON} */ (parsedJSON)); } /** * @override + * @protected + * @return {!Promise<?UI.Widget>} */ - wasShown() { - this._showPreviewView(); - } - - async _showPreviewView() { - if (!this._previewViewPromise) - this._previewViewPromise = this._createPreviewView(); - var previewView = await this._previewViewPromise; - if (this.element.contains(previewView.element)) - return; - - previewView.show(this.element); - - if (previewView instanceof UI.SimpleView) { - var toolbar = new UI.Toolbar('network-item-preview-toolbar', this.element); - for (var item of previewView.syncToolbarItems()) - toolbar.appendToolbarItem(item); - } + async showPreview() { + var view = await super.showPreview(); + if (!(view instanceof UI.SimpleView)) + return view; + var toolbar = new UI.Toolbar('network-item-preview-toolbar', this.element); + for (var item of view.syncToolbarItems()) + toolbar.appendToolbarItem(item); + return view; } /** - * @param {!SDK.NetworkRequest.ContentData} contentData - * @return {?Network.RequestHTMLView} + * @return {!Promise<?UI.Widget>} */ - _htmlErrorPreview(contentData) { + async _htmlErrorPreview() { + var contentData = await this.request.contentData(); + if (contentData.error) + return new UI.EmptyWidget(Common.UIString('Failed to load response data')); + // We can assume the status code has been set already because fetching contentData should wait for request to be // finished. if (!this.request.hasErrorStatusCode() && this.request.resourceType() !== Common.resourceTypes.XHR) @@ -114,45 +70,26 @@ var dataURL = Common.ContentProvider.contentAsDataURL( contentData.content, this.request.mimeType, contentData.encoded, contentData.encoded ? 'utf-8' : null); - if (dataURL === null) - return null; - - return new Network.RequestHTMLView(this.request, dataURL); + return dataURL ? new Network.RequestHTMLView(dataURL) : null; } /** + * @override * @return {!Promise<!UI.Widget>} */ - async _createPreviewView() { - var contentData = await this.request.contentData(); - if (contentData.error) - return this._createMessageView(Common.UIString('Failed to load response data')); - - var content = contentData.content || ''; - if (contentData.encoded) - content = window.atob(content); - if (!content) - return this._createEmptyWidget(); - - var xmlView = this._xmlView(content, this.request.mimeType); - if (xmlView) - return xmlView; - - var jsonView = await this._jsonView(content); - if (jsonView) - return jsonView; - - var htmlErrorPreview = this._htmlErrorPreview(contentData); + async createPreview() { + var htmlErrorPreview = await this._htmlErrorPreview(); if (htmlErrorPreview) return htmlErrorPreview; + // Try provider before the source view - so JSON and XML are not shown in generic editor + var provided = await SourceFrame.PreviewFactory.createPreview(this.request, this.request.mimeType); + if (provided) + return provided; + var sourceView = await Network.RequestResponseView.sourceViewForRequest(this.request); if (sourceView) return sourceView; - - if (this.request.resourceType() === Common.resourceTypes.Other) - return this._createEmptyWidget(); - - return Network.RequestView.nonSourceViewForRequest(this.request); + return new UI.EmptyWidget(Common.UIString('Preview not available')); } };
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js index 2c2eeb5..1320e2e 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js
@@ -28,18 +28,37 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -Network.RequestResponseView = class extends Network.RequestView { +Network.RequestResponseView = class extends UI.VBox { /** * @param {!SDK.NetworkRequest} request */ constructor(request) { - super(request); + super(); + this.element.classList.add('request-view'); + /** @protected */ + this.request = request; /** @type {?Promise<!UI.Widget>} */ - this._responseView = null; + this._contentViewPromise = null; } /** * @param {!SDK.NetworkRequest} request + * @param {!SDK.NetworkRequest.ContentData} contentData + * @return {boolean} + */ + static _hasTextContent(request, contentData) { + if (request.resourceType().isTextType()) + return true; + if (contentData.error) + return false; + if (request.resourceType() === Common.resourceTypes.Other) + return !!contentData.content && !contentData.encoded; + return false; + } + + /** + * @protected + * @param {!SDK.NetworkRequest} request * @return {!Promise<?UI.SearchableView>} */ static async sourceViewForRequest(request) { @@ -48,12 +67,12 @@ return sourceView; var contentData = await request.contentData(); - if (!Network.RequestView.hasTextContent(request, contentData)) { + if (!Network.RequestResponseView._hasTextContent(request, contentData)) { request[Network.RequestResponseView._sourceViewSymbol] = null; return null; } - var contentProvider = new Network.RequestResponseView.ContentProvider(request); + var contentProvider = new Network.DecodingContentProvider(request); var highlighterType = request.resourceType().canonicalMimeType() || request.mimeType; sourceView = SourceFrame.ResourceSourceFrame.createSearchableView(contentProvider, highlighterType); request[Network.RequestResponseView._sourceViewSymbol] = sourceView; @@ -61,38 +80,39 @@ } /** - * @param {string} message - * @return {!UI.EmptyWidget} + * @override + * @final */ - _createMessageView(message) { - return new UI.EmptyWidget(message); + wasShown() { + this.showPreview(); } /** - * @override + * @protected + * @return {!Promise<?UI.Widget>} */ - wasShown() { - this._showResponseView(); - } - - async _showResponseView() { - if (!this._responseView) - this._responseView = this._createResponseView(); - var responseView = await this._responseView; + async showPreview() { + if (!this._contentViewPromise) + this._contentViewPromise = this.createPreview(); + var responseView = await this._contentViewPromise; if (this.element.contains(responseView.element)) - return; + return null; responseView.show(this.element); + return responseView; } - async _createResponseView() { + /** + * @return {!Promise<!UI.Widget>} + */ + async createPreview() { var contentData = await this.request.contentData(); var sourceView = await Network.RequestResponseView.sourceViewForRequest(this.request); if ((!contentData.content || !sourceView) && !contentData.error) - return this._createMessageView(Common.UIString('This request has no response data available.')); + return new UI.EmptyWidget(Common.UIString('This request has no response data available.')); if (contentData.content && sourceView) return sourceView; - return this._createMessageView(Common.UIString('Failed to load response data')); + return new UI.EmptyWidget(Common.UIString('Failed to load response data')); } }; @@ -101,7 +121,7 @@ /** * @implements {Common.ContentProvider} */ -Network.RequestResponseView.ContentProvider = class { +Network.DecodingContentProvider = class { /** * @param {!SDK.NetworkRequest} request */
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestView.js deleted file mode 100644 index bc5f9237..0000000 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestView.js +++ /dev/null
@@ -1,69 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -Network.RequestView = class extends UI.VBox { - /** - * @param {!SDK.NetworkRequest} request - */ - constructor(request) { - super(); - - this.element.classList.add('request-view'); - this.request = request; - } - - /** - * @param {!SDK.NetworkRequest} request - * @param {!SDK.NetworkRequest.ContentData} contentData - * @return {boolean} - */ - static hasTextContent(request, contentData) { - if (request.resourceType().isTextType()) - return true; - if (request.resourceType() === Common.resourceTypes.Other || contentData.error) - return !!contentData.content && !contentData.encoded; - return false; - } - - /** - * @param {!SDK.NetworkRequest} request - * @return {!UI.Widget} - */ - static nonSourceViewForRequest(request) { - switch (request.resourceType()) { - case Common.resourceTypes.Image: - return new SourceFrame.ImageView(request.mimeType, request); - case Common.resourceTypes.Font: - return new SourceFrame.FontView(request.mimeType, request); - default: - return new Network.RequestView(request); - } - } -};
diff --git a/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js b/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js index f2d959ac..4c12160 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js
@@ -165,34 +165,18 @@ /** * @param {!Common.Event} event */ - _onFrameSelected(event) { + async _onFrameSelected(event) { var selectedNode = /** @type {!Network.ResourceWebSocketFrameNode} */ (event.data); this._currentSelectedNode = selectedNode; var contentProvider = selectedNode.contentProvider(); - contentProvider.requestContent().then(contentHandler.bind(this)); - - /** - * @param {(string|null)} content - * @this {Network.ResourceWebSocketFrameView} - */ - function contentHandler(content) { - if (this._currentSelectedNode !== selectedNode) - return; - Network.JSONView.parseJSON(content).then(handleJSONData.bind(this)); - } - - /** - * @param {?Network.ParsedJSON} parsedJSON - * @this {Network.ResourceWebSocketFrameView} - */ - function handleJSONData(parsedJSON) { - if (this._currentSelectedNode !== selectedNode) - return; - if (parsedJSON) - this._splitWidget.setSidebarWidget(Network.JSONView.createSearchableView(parsedJSON)); - else - this._splitWidget.setSidebarWidget(new SourceFrame.ResourceSourceFrame(contentProvider)); - } + var content = await contentProvider.requestContent(); + var parsedJSON = await SourceFrame.JSONView.parseJSON(content); + if (this._currentSelectedNode !== selectedNode) + return; + if (parsedJSON) + this._splitWidget.setSidebarWidget(SourceFrame.JSONView.createSearchableView(parsedJSON)); + else + this._splitWidget.setSidebarWidget(new SourceFrame.ResourceSourceFrame(contentProvider)); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/network/module.json b/third_party/WebKit/Source/devtools/front_end/network/module.json index 7f19972..8ea43af 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/module.json +++ b/third_party/WebKit/Source/devtools/front_end/network/module.json
@@ -119,20 +119,16 @@ "perf_ui", "cookie_table", "data_grid", - "object_ui", "network_log", "product_registry", "mobile_throttling", - "network_priorities", - "formatter" + "network_priorities" ], "scripts": [ "BlockedURLsPane.js", "EventSourceMessagesView.js", "FilterSuggestionBuilder.js", "HARWriter.js", - "JSONView.js", - "RequestView.js", "NetworkConfigView.js", "NetworkDataGridNode.js", "NetworkItemView.js", @@ -146,12 +142,11 @@ "RequestCookiesView.js", "RequestHeadersView.js", "RequestHTMLView.js", - "RequestPreviewView.js", "RequestResponseView.js", + "RequestPreviewView.js", "RequestTimingView.js", "ResourceWebSocketFrameView.js", - "NetworkPanel.js", - "XMLView.js" + "NetworkPanel.js" ], "resources": [ "blockedURLsPane.css", @@ -165,8 +160,6 @@ "requestCookiesView.css", "requestHeadersTree.css", "requestHeadersView.css", - "webSocketFrameView.css", - "xmlTree.css", - "xmlView.css" + "webSocketFrameView.css" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/JSONView.js b/third_party/WebKit/Source/devtools/front_end/source_frame/JSONView.js similarity index 91% rename from third_party/WebKit/Source/devtools/front_end/network/JSONView.js rename to third_party/WebKit/Source/devtools/front_end/source_frame/JSONView.js index 10f7bbb..9549ae27 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/JSONView.js +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/JSONView.js
@@ -31,9 +31,9 @@ * @implements {UI.Searchable} * @unrestricted */ -Network.JSONView = class extends UI.VBox { +SourceFrame.JSONView = class extends UI.VBox { /** - * @param {!Network.ParsedJSON} parsedJSON + * @param {!SourceFrame.ParsedJSON} parsedJSON */ constructor(parsedJSON) { super(); @@ -53,11 +53,11 @@ } /** - * @param {!Network.ParsedJSON} parsedJSON + * @param {!SourceFrame.ParsedJSON} parsedJSON * @return {!UI.SearchableView} */ static createSearchableView(parsedJSON) { - var jsonView = new Network.JSONView(parsedJSON); + var jsonView = new SourceFrame.JSONView(parsedJSON); var searchableView = new UI.SearchableView(jsonView); searchableView.setPlaceholder(Common.UIString('Find')); jsonView._searchableView = searchableView; @@ -68,19 +68,19 @@ /** * @param {?string} text - * @return {!Promise<?Network.ParsedJSON>} + * @return {!Promise<?SourceFrame.ParsedJSON>} */ static parseJSON(text) { var returnObj = null; if (text) - returnObj = Network.JSONView._extractJSON(/** @type {string} */ (text)); + returnObj = SourceFrame.JSONView._extractJSON(/** @type {string} */ (text)); if (!returnObj) - return Promise.resolve(/** @type {?Network.ParsedJSON} */ (null)); + return Promise.resolve(/** @type {?SourceFrame.ParsedJSON} */ (null)); return Formatter.formatterWorkerPool().parseJSONRelaxed(returnObj.data).then(handleReturnedJSON); /** * @param {*} data - * @return {?Network.ParsedJSON} + * @return {?SourceFrame.ParsedJSON} */ function handleReturnedJSON(data) { if (!data) @@ -92,14 +92,14 @@ /** * @param {string} text - * @return {?Network.ParsedJSON} + * @return {?SourceFrame.ParsedJSON} */ static _extractJSON(text) { // Do not treat HTML as JSON. if (text.startsWith('<')) return null; - var inner = Network.JSONView._findBrackets(text, '{', '}'); - var inner2 = Network.JSONView._findBrackets(text, '[', ']'); + var inner = SourceFrame.JSONView._findBrackets(text, '{', '}'); + var inner2 = SourceFrame.JSONView._findBrackets(text, '[', ']'); inner = inner2.length > inner.length ? inner2 : inner; // Return on blank payloads or on payloads significantly smaller than original text. @@ -114,7 +114,7 @@ if (suffix.trim().length && !(suffix.trim().startsWith(')') && prefix.trim().endsWith('('))) return null; - return new Network.ParsedJSON(text, prefix, suffix); + return new SourceFrame.ParsedJSON(text, prefix, suffix); } /** @@ -285,7 +285,7 @@ /** * @unrestricted */ -Network.ParsedJSON = class { +SourceFrame.ParsedJSON = class { /** * @param {*} data * @param {string} prefix
diff --git a/third_party/WebKit/Source/devtools/front_end/source_frame/PreviewFactory.js b/third_party/WebKit/Source/devtools/front_end/source_frame/PreviewFactory.js new file mode 100644 index 0000000..4d0c648 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/PreviewFactory.js
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +SourceFrame.PreviewFactory = class { + /** + * @param {!Common.ContentProvider} provider + * @param {string} mimeType + * @returns {!Promise<?UI.Widget>} + */ + static async createPreview(provider, mimeType) { + var content = await provider.requestContent(); + if (!content) + return new UI.EmptyWidget(Common.UIString('Nothing to preview')); + + var parsedXML = SourceFrame.XMLView.parseXML(content, mimeType); + if (parsedXML) + return SourceFrame.XMLView.createSearchableView(parsedXML); + + // We support non-strict JSON parsing by parsing an AST tree which is why we offload it to a worker. + var parsedJSON = await SourceFrame.JSONView.parseJSON(content); + if (parsedJSON && typeof parsedJSON.data === 'object') + return SourceFrame.JSONView.createSearchableView(/** @type {!SourceFrame.ParsedJSON} */ (parsedJSON)); + + var resourceType = provider.contentType() || Common.resourceTypes.Other; + + if (resourceType.isTextType()) + return SourceFrame.ResourceSourceFrame.createSearchableView(provider, mimeType); + + switch (resourceType) { + case Common.resourceTypes.Image: + return new SourceFrame.ImageView(mimeType, provider); + case Common.resourceTypes.Font: + return new SourceFrame.FontView(mimeType, provider); + } + return null; + } +};
diff --git a/third_party/WebKit/Source/devtools/front_end/network/XMLView.js b/third_party/WebKit/Source/devtools/front_end/source_frame/XMLView.js similarity index 92% rename from third_party/WebKit/Source/devtools/front_end/network/XMLView.js rename to third_party/WebKit/Source/devtools/front_end/source_frame/XMLView.js index 9c208a98..df95a41 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/XMLView.js +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/XMLView.js
@@ -5,16 +5,16 @@ * @implements {UI.Searchable} * @unrestricted */ -Network.XMLView = class extends UI.Widget { +SourceFrame.XMLView = class extends UI.Widget { /** * @param {!Document} parsedXML */ constructor(parsedXML) { super(true); - this.registerRequiredCSS('network/xmlView.css'); + this.registerRequiredCSS('source_frame/xmlView.css'); this.contentElement.classList.add('shadow-xml-view', 'source-code'); this._treeOutline = new UI.TreeOutlineInShadow(); - this._treeOutline.registerRequiredCSS('network/xmlTree.css'); + this._treeOutline.registerRequiredCSS('source_frame/xmlTree.css'); this.contentElement.appendChild(this._treeOutline.element); /** @type {?UI.SearchableView} */ @@ -26,7 +26,7 @@ /** @type {?UI.SearchableView.SearchConfig} */ this._searchConfig; - Network.XMLView.Node.populate(this._treeOutline, parsedXML, this); + SourceFrame.XMLView.Node.populate(this._treeOutline, parsedXML, this); } /** @@ -34,7 +34,7 @@ * @return {!UI.SearchableView} */ static createSearchableView(parsedXML) { - var xmlView = new Network.XMLView(parsedXML); + var xmlView = new SourceFrame.XMLView(parsedXML); var searchableView = new UI.SearchableView(xmlView); searchableView.setPlaceholder(Common.UIString('Find')); xmlView._searchableView = searchableView; @@ -116,7 +116,7 @@ var regex = this._searchConfig.toSearchRegex(true); for (var element = this._treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) { - if (!(element instanceof Network.XMLView.Node)) + if (!(element instanceof SourceFrame.XMLView.Node)) continue; var hasMatch = element.setSearchRegex(regex); if (hasMatch) @@ -142,7 +142,7 @@ _innerSearchCanceled() { for (var element = this._treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) { - if (!(element instanceof Network.XMLView.Node)) + if (!(element instanceof SourceFrame.XMLView.Node)) continue; element.revertHighlightChanges(); } @@ -213,11 +213,11 @@ /** * @unrestricted */ -Network.XMLView.Node = class extends UI.TreeElement { +SourceFrame.XMLView.Node = class extends UI.TreeElement { /** * @param {!Node} node * @param {boolean} closeTag - * @param {!Network.XMLView} xmlView + * @param {!SourceFrame.XMLView} xmlView */ constructor(node, closeTag, xmlView) { super('', !closeTag && !!node.childElementCount); @@ -233,7 +233,7 @@ /** * @param {!UI.TreeOutline|!UI.TreeElement} root * @param {!Node} xmlNode - * @param {!Network.XMLView} xmlView + * @param {!SourceFrame.XMLView} xmlView */ static populate(root, xmlNode, xmlView) { var node = xmlNode.firstChild; @@ -247,7 +247,7 @@ // ignore ATTRIBUTE, ENTITY_REFERENCE, ENTITY, DOCUMENT, DOCUMENT_TYPE, DOCUMENT_FRAGMENT, NOTATION if ((nodeType !== 1) && (nodeType !== 3) && (nodeType !== 4) && (nodeType !== 7) && (nodeType !== 8)) continue; - root.appendChild(new Network.XMLView.Node(currentNode, false, xmlView)); + root.appendChild(new SourceFrame.XMLView.Node(currentNode, false, xmlView)); } } @@ -369,7 +369,7 @@ * @override */ onpopulate() { - Network.XMLView.Node.populate(this, this._node, this._xmlView); - this.appendChild(new Network.XMLView.Node(this._node, true, this._xmlView)); + SourceFrame.XMLView.Node.populate(this, this._node, this._xmlView); + this.appendChild(new SourceFrame.XMLView.Node(this._node, true, this._xmlView)); } };
diff --git a/third_party/WebKit/Source/devtools/front_end/source_frame/module.json b/third_party/WebKit/Source/devtools/front_end/source_frame/module.json index 4b34a1f..4419087 100644 --- a/third_party/WebKit/Source/devtools/front_end/source_frame/module.json +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/module.json
@@ -36,6 +36,8 @@ "ui", "platform", "persistence", + "formatter", + "object_ui", "workspace_diff" ], "scripts": [ @@ -45,11 +47,16 @@ "SourceFrame.js", "ResourceSourceFrame.js", "UISourceCodeFrame.js", + "JSONView.js", + "XMLView.js", + "PreviewFactory.js", "SourceCodeDiff.js" ], "resources": [ "fontView.css", "imageView.css", - "messagesPopover.css" + "messagesPopover.css", + "xmlTree.css", + "xmlView.css" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/xmlTree.css b/third_party/WebKit/Source/devtools/front_end/source_frame/xmlTree.css similarity index 100% rename from third_party/WebKit/Source/devtools/front_end/network/xmlTree.css rename to third_party/WebKit/Source/devtools/front_end/source_frame/xmlTree.css
diff --git a/third_party/WebKit/Source/devtools/front_end/network/xmlView.css b/third_party/WebKit/Source/devtools/front_end/source_frame/xmlView.css similarity index 100% rename from third_party/WebKit/Source/devtools/front_end/network/xmlView.css rename to third_party/WebKit/Source/devtools/front_end/source_frame/xmlView.css
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/textButton.css b/third_party/WebKit/Source/devtools/front_end/ui/textButton.css index 5d7f099..0cb514c 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/textButton.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/textButton.css
@@ -15,6 +15,7 @@ color: #333; background-color: #fff; flex: none; + white-space: nowrap; } :host(:not(:disabled):focus),
diff --git a/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainerTest.cpp b/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainerTest.cpp index 814c5bd..91a7b9e 100644 --- a/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainerTest.cpp +++ b/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainerTest.cpp
@@ -44,9 +44,10 @@ TEST(CredentialsContainerTest, TestGetWithDocumentDestroyed) { CredentialsContainer* credential_container = CredentialsContainer::Create(); std::unique_ptr<WebCredentialManagerClient::RequestCallbacks> get_callback; + + V8TestingScope scope; { // Set up. - V8TestingScope scope; scope.GetDocument().SetSecurityOrigin( SecurityOrigin::CreateFromString("https://example.test")); testing::StrictMock<MockCredentialManagerClient> mock_client;
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp index 0a1a14b..f4df9b75 100644 --- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp +++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp
@@ -29,7 +29,10 @@ new PaintWorkletGlobalScope(frame, url, user_agent, std::move(security_origin), isolate, pending_generator_registry); - paint_worklet_global_scope->ScriptController()->InitializeContextIfNeeded(); + // TODO(xidachen): When we implement two PaintWorkletGlobalScope, we should + // change the last parameter. + paint_worklet_global_scope->ScriptController()->InitializeContextIfNeeded( + "Paint Worklet"); MainThreadDebugger::Instance()->ContextCreated( paint_worklet_global_scope->ScriptController()->GetScriptState(), paint_worklet_global_scope->GetFrame(),
diff --git a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.h b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.h index e526ac9..1b33a0dd 100644 --- a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.h +++ b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.h
@@ -34,6 +34,7 @@ #include <memory> #include "core/workers/WorkerClients.h" #include "modules/ModulesExport.h" +#include "platform/WebTaskRunner.h" #include "platform/heap/Handle.h" #include "public/platform/Platform.h" #include "public/platform/WebContentSecurityPolicy.h" @@ -79,9 +80,11 @@ void AddMessageToConsole(const WebConsoleMessage&) override; void PostMessageToPageInspector(int session_id, const WTF::String&); - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override { + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const WebURLRequest& request, + SingleThreadTaskRunner* task_runner) override { // TODO(yhirano): Stop using Platform::CreateURLLoader() here. - return Platform::Current()->CreateURLLoader(); + return Platform::Current()->CreateURLLoader(request, task_runner); } private:
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBAny.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBAny.cpp index 1793fb2..26be2129 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBAny.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBAny.cpp
@@ -30,6 +30,7 @@ #include "modules/indexeddb/IDBDatabase.h" #include "modules/indexeddb/IDBIndex.h" #include "modules/indexeddb/IDBObjectStore.h" +#include "platform/wtf/RefPtr.h" namespace blink { @@ -124,7 +125,7 @@ IDBAny::IDBAny(const Vector<RefPtr<IDBValue>>& values) : type_(kIDBValueArrayType), idb_values_(values) {} -IDBAny::IDBAny(PassRefPtr<IDBValue> value) +IDBAny::IDBAny(RefPtr<IDBValue> value) : type_(kIDBValueType), idb_value_(std::move(value)) {} IDBAny::IDBAny(IDBKey* key) : type_(kKeyType), idb_key_(key) {}
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBAny.h b/third_party/WebKit/Source/modules/indexeddb/IDBAny.h index 16c7bee4..58d6eb2 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBAny.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBAny.h
@@ -32,6 +32,7 @@ #include "modules/indexeddb/IDBValue.h" #include "platform/bindings/ScriptWrappable.h" #include "platform/wtf/Forward.h" +#include "platform/wtf/RefPtr.h" #include "platform/wtf/text/WTFString.h" namespace blink { @@ -63,7 +64,7 @@ return new IDBAny(dom_string_list); } static IDBAny* Create(int64_t value) { return new IDBAny(value); } - static IDBAny* Create(PassRefPtr<IDBValue> value) { + static IDBAny* Create(RefPtr<IDBValue> value) { return new IDBAny(std::move(value)); } static IDBAny* Create(const Vector<RefPtr<IDBValue>>& values) { @@ -110,7 +111,7 @@ explicit IDBAny(IDBObjectStore*); explicit IDBAny(IDBKey*); explicit IDBAny(const Vector<RefPtr<IDBValue>>&); - explicit IDBAny(PassRefPtr<IDBValue>); + explicit IDBAny(RefPtr<IDBValue>); explicit IDBAny(int64_t); const Type type_;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp index cdc551f7..ee4c30a 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp
@@ -138,7 +138,8 @@ void IDBCursor::advance(unsigned count, ExceptionState& exception_state) { IDB_TRACE("IDBCursor::advanceRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBCursor::advance", this); + IDBRequest::AsyncTraceState metrics("IDBCursor::advance", this, + ++next_tracing_id_); if (!count) { exception_state.ThrowTypeError( "A count argument with value 0 (zero) was supplied, must be greater " @@ -171,7 +172,8 @@ const ScriptValue& key_value, ExceptionState& exception_state) { IDB_TRACE("IDBCursor::continueRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBCursor::continue", this); + IDBRequest::AsyncTraceState metrics("IDBCursor::continue", this, + ++next_tracing_id_); if (!transaction_->IsActive()) { exception_state.ThrowDOMException(kTransactionInactiveError, @@ -208,7 +210,8 @@ const ScriptValue& primary_key_value, ExceptionState& exception_state) { IDB_TRACE("IDBCursor::continuePrimaryKeyRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBCursor::continuePrimaryKey", this); + IDBRequest::AsyncTraceState metrics("IDBCursor::continuePrimaryKey", this, + ++next_tracing_id_); if (!transaction_->IsActive()) { exception_state.ThrowDOMException(kTransactionInactiveError, @@ -313,7 +316,8 @@ IDBRequest* IDBCursor::deleteFunction(ScriptState* script_state, ExceptionState& exception_state) { IDB_TRACE("IDBCursor::deleteRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBCursor::delete", this); + IDBRequest::AsyncTraceState metrics("IDBCursor::delete", this, + ++next_tracing_id_); if (!transaction_->IsActive()) { exception_state.ThrowDOMException(kTransactionInactiveError, transaction_->InactiveErrorMessage()); @@ -409,7 +413,7 @@ void IDBCursor::SetValueReady(IDBKey* key, IDBKey* primary_key, - PassRefPtr<IDBValue> value) { + RefPtr<IDBValue> value) { key_ = key; key_dirty_ = true;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.h b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.h index 8483405..ce2ccca 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.h
@@ -33,7 +33,6 @@ #include "modules/indexeddb/IndexedDB.h" #include "platform/bindings/ScriptWrappable.h" #include "platform/wtf/Compiler.h" -#include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefPtr.h" #include "public/platform/modules/indexeddb/WebIDBCursor.h" #include "public/platform/modules/indexeddb/WebIDBTypes.h" @@ -94,7 +93,7 @@ void PostSuccessHandlerCallback(); bool IsDeleted() const; void Close(); - void SetValueReady(IDBKey*, IDBKey* primary_key, PassRefPtr<IDBValue>); + void SetValueReady(IDBKey*, IDBKey* primary_key, RefPtr<IDBValue>); IDBKey* IdbPrimaryKey() const { return primary_key_; } virtual bool IsKeyCursor() const { return true; } virtual bool IsCursorWithValue() const { return false; } @@ -121,6 +120,7 @@ Member<IDBKey> key_; Member<IDBKey> primary_key_; RefPtr<IDBValue> value_; + int64_t next_tracing_id_ = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h index 54ab405..d4515ce 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.h
@@ -26,6 +26,8 @@ #ifndef IDBDatabase_h #define IDBDatabase_h +#include <memory> + #include "bindings/modules/v8/StringOrStringSequence.h" #include "core/dom/ContextLifecycleObserver.h" #include "core/dom/DOMStringList.h" @@ -42,12 +44,9 @@ #include "platform/bindings/ActiveScriptWrappable.h" #include "platform/bindings/ScriptState.h" #include "platform/heap/Handle.h" -#include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefPtr.h" #include "public/platform/modules/indexeddb/WebIDBDatabase.h" -#include <memory> - namespace blink { class DOMException;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h b/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h index 40b84a64..a7c2029 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabaseCallbacks.h
@@ -28,7 +28,6 @@ #include "modules/ModulesExport.h" #include "platform/heap/Handle.h" -#include "platform/wtf/PassRefPtr.h" #include "public/platform/WebVector.h" #include <unordered_map>
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBFactory.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBFactory.cpp index 8af2527d..7cbb1a6 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBFactory.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBFactory.cpp
@@ -66,7 +66,8 @@ IDBRequest* IDBFactory::GetDatabaseNames(ScriptState* script_state, ExceptionState& exception_state) { IDB_TRACE("IDBFactory::getDatabaseNamesRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBFactory::getDatabaseNames", this); + IDBRequest::AsyncTraceState metrics("IDBFactory::getDatabaseNames", this, + ++next_tracing_id_); IDBRequest* request = IDBRequest::Create(script_state, IDBAny::CreateNull(), nullptr, std::move(metrics)); // TODO(jsbell): Used only by inspector; remove unneeded checks/exceptions? @@ -99,7 +100,6 @@ const String& name, unsigned long long version, ExceptionState& exception_state) { - IDB_TRACE("IDBFactory::open"); if (!version) { exception_state.ThrowTypeError("The version provided must not be 0."); return nullptr; @@ -111,6 +111,9 @@ const String& name, int64_t version, ExceptionState& exception_state) { + IDB_TRACE1("IDBFactory::open", "name", name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBFactory::open", this, + ++next_tracing_id_); IDBDatabase::RecordApiCallsHistogram(kIDBOpenCall); DCHECK(version >= 1 || version == IDBDatabaseMetadata::kNoVersion); if (!IsContextValid(ExecutionContext::From(script_state))) @@ -125,8 +128,9 @@ IDBDatabaseCallbacks* database_callbacks = IDBDatabaseCallbacks::Create(); int64_t transaction_id = IDBDatabase::NextTransactionId(); - IDBOpenDBRequest* request = IDBOpenDBRequest::Create( - script_state, database_callbacks, transaction_id, version); + IDBOpenDBRequest* request = + IDBOpenDBRequest::Create(script_state, database_callbacks, transaction_id, + version, std::move(metrics)); if (!IndexedDBClient::From(ExecutionContext::From(script_state)) ->AllowIndexedDB(ExecutionContext::From(script_state), name)) { @@ -146,7 +150,6 @@ IDBOpenDBRequest* IDBFactory::open(ScriptState* script_state, const String& name, ExceptionState& exception_state) { - IDB_TRACE("IDBFactory::open"); return OpenInternal(script_state, name, IDBDatabaseMetadata::kNoVersion, exception_state); } @@ -172,7 +175,9 @@ const String& name, ExceptionState& exception_state, bool force_close) { - IDB_TRACE("IDBFactory::deleteDatabase"); + IDB_TRACE1("IDBFactory::deleteDatabase", "name", name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBFactory::deleteDatabase", this, + ++next_tracing_id_); IDBDatabase::RecordApiCallsHistogram(kIDBDeleteDatabaseCall); if (!IsContextValid(ExecutionContext::From(script_state))) return nullptr; @@ -185,7 +190,8 @@ } IDBOpenDBRequest* request = IDBOpenDBRequest::Create( - script_state, nullptr, 0, IDBDatabaseMetadata::kDefaultVersion); + script_state, nullptr, 0, IDBDatabaseMetadata::kDefaultVersion, + std::move(metrics)); if (!IndexedDBClient::From(ExecutionContext::From(script_state)) ->AllowIndexedDB(ExecutionContext::From(script_state), name)) {
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBFactory.h b/third_party/WebKit/Source/modules/indexeddb/IDBFactory.h index 48d2e50..f77f103 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBFactory.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBFactory.h
@@ -78,6 +78,7 @@ const String& name, ExceptionState&, bool); + int64_t next_tracing_id_ = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBIndex.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBIndex.cpp index 39b2f9ab..527148a 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBIndex.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBIndex.cpp
@@ -115,8 +115,10 @@ const ScriptValue& range, const String& direction_string, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::openCursorRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBIndex::openCursor", this); + IDB_TRACE1("IDBIndex::openCursorRequestSetup", "index_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::openCursor", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException(kInvalidStateError, IDBDatabase::kIndexDeletedErrorMessage); @@ -160,8 +162,10 @@ IDBRequest* IDBIndex::count(ScriptState* script_state, const ScriptValue& range, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::countRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBIndex::count", this); + IDB_TRACE1("IDBIndex::countRequestSetup", "index_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::count", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException(kInvalidStateError, IDBDatabase::kIndexDeletedErrorMessage); @@ -196,8 +200,10 @@ const ScriptValue& range, const String& direction_string, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::openKeyCursorRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBIndex::openKeyCursor", this); + IDB_TRACE1("IDBIndex::openKeyCursorRequestSetup", "index_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::openKeyCursor", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException(kInvalidStateError, IDBDatabase::kIndexDeletedErrorMessage); @@ -233,8 +239,11 @@ IDBRequest* IDBIndex::get(ScriptState* script_state, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::getRequestSetup"); - return GetInternal(script_state, key, exception_state, false); + IDB_TRACE1("IDBIndex::getRequestSetup", "index_name", metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::get", this, + ++next_tracing_id_); + return GetInternal(script_state, key, exception_state, false, + std::move(metrics)); } IDBRequest* IDBIndex::getAll(ScriptState* script_state, @@ -248,8 +257,12 @@ const ScriptValue& range, unsigned long max_count, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::getAllRequestSetup"); - return GetAllInternal(script_state, range, max_count, exception_state, false); + IDB_TRACE1("IDBIndex::getAllRequestSetup", "index_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::getAll", this, + ++next_tracing_id_); + return GetAllInternal(script_state, range, max_count, exception_state, false, + std::move(metrics)); } IDBRequest* IDBIndex::getAllKeys(ScriptState* script_state, @@ -263,24 +276,30 @@ const ScriptValue& range, uint32_t max_count, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::getAllKeysRequestSetup"); + IDB_TRACE1("IDBIndex::getAllKeysRequestSetup", "index_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::getAllKeys", this, + ++next_tracing_id_); return GetAllInternal(script_state, range, max_count, exception_state, - /*key_only=*/true); + /*key_only=*/true, std::move(metrics)); } IDBRequest* IDBIndex::getKey(ScriptState* script_state, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBIndex::getKeyRequestSetup"); - return GetInternal(script_state, key, exception_state, true); + IDB_TRACE1("IDBIndex::getKeyRequestSetup", "index_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBIndex::getKey", this, + ++next_tracing_id_); + return GetInternal(script_state, key, exception_state, true, + std::move(metrics)); } IDBRequest* IDBIndex::GetInternal(ScriptState* script_state, const ScriptValue& key, ExceptionState& exception_state, - bool key_only) { - IDBRequest::AsyncTraceState metrics( - key_only ? "IDBIndex::getKey" : "IDBIndex::get", this); + bool key_only, + IDBRequest::AsyncTraceState metrics) { if (IsDeleted()) { exception_state.ThrowDOMException(kInvalidStateError, IDBDatabase::kIndexDeletedErrorMessage); @@ -319,9 +338,8 @@ const ScriptValue& range, unsigned long max_count, ExceptionState& exception_state, - bool key_only) { - IDBRequest::AsyncTraceState metrics( - key_only ? "IDBIndex::getAllKeys" : "IDBIndex::getAll", this); + bool key_only, + IDBRequest::AsyncTraceState metrics) { if (!max_count) max_count = std::numeric_limits<uint32_t>::max();
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBIndex.h b/third_party/WebKit/Source/modules/indexeddb/IDBIndex.h index 1338bcc..acc3ba1 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBIndex.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBIndex.h
@@ -127,17 +127,20 @@ IDBRequest* GetInternal(ScriptState*, const ScriptValue& key, ExceptionState&, - bool key_only); + bool key_only, + IDBRequest::AsyncTraceState metrics); IDBRequest* GetAllInternal(ScriptState*, const ScriptValue& range, unsigned long max_count, ExceptionState&, - bool key_only); + bool key_only, + IDBRequest::AsyncTraceState metrics); RefPtr<IDBIndexMetadata> metadata_; Member<IDBObjectStore> object_store_; Member<IDBTransaction> transaction_; bool deleted_ = false; + int64_t next_tracing_id_ = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBKey.h b/third_party/WebKit/Source/modules/indexeddb/IDBKey.h index f1cf4c9..2a6b5fb5 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBKey.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBKey.h
@@ -30,6 +30,7 @@ #include "platform/SharedBuffer.h" #include "platform/heap/Handle.h" #include "platform/wtf/Forward.h" +#include "platform/wtf/RefPtr.h" #include "platform/wtf/Vector.h" #include "platform/wtf/text/WTFString.h" @@ -114,7 +115,7 @@ IDBKey() : type_(kInvalidType) {} IDBKey(Type type, double number) : type_(type), number_(number) {} explicit IDBKey(const String& value) : type_(kStringType), string_(value) {} - explicit IDBKey(PassRefPtr<SharedBuffer> value) + explicit IDBKey(RefPtr<SharedBuffer> value) : type_(kBinaryType), binary_(std::move(value)) {} explicit IDBKey(const KeyArray& key_array) : type_(kArrayType), array_(key_array) {}
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp index 7b5031a..1e89bd3 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
@@ -119,7 +119,8 @@ } DOMStringList* IDBObjectStore::indexNames() const { - IDB_TRACE("IDBObjectStore::indexNames"); + IDB_TRACE1("IDBObjectStore::indexNames", "store_name", + metadata_->name.Utf8()); DOMStringList* index_names = DOMStringList::Create(); for (const auto& it : Metadata().indexes) index_names->Append(it.value->name); @@ -130,8 +131,10 @@ IDBRequest* IDBObjectStore::get(ScriptState* script_state, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::getRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::get", this); + IDB_TRACE1("IDBObjectStore::getRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::get", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -169,8 +172,10 @@ IDBRequest* IDBObjectStore::getKey(ScriptState* script_state, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::getKeyRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::getKey", this); + IDB_TRACE1("IDBObjectStore::getKeyRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::getKey", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -216,8 +221,10 @@ const ScriptValue& key_range, unsigned long max_count, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::getAllRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::getAll", this); + IDB_TRACE1("IDBObjectStore::getAllRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::getAll", this, + ++next_tracing_id_); if (!max_count) max_count = std::numeric_limits<uint32_t>::max(); @@ -261,8 +268,10 @@ const ScriptValue& key_range, unsigned long max_count, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::getAllKeysRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::getAllKeys", this); + IDB_TRACE1("IDBObjectStore::getAllKeysRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::getAllKeys", this, + ++next_tracing_id_); if (!max_count) max_count = std::numeric_limits<uint32_t>::max(); @@ -333,7 +342,8 @@ const ScriptValue& value, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::addRequestSetup"); + IDB_TRACE1("IDBObjectStore::addRequestSetup", "store_name", + metadata_->name.Utf8()); return put(script_state, kWebIDBPutModeAddOnly, IDBAny::Create(this), value, key, exception_state); } @@ -342,7 +352,8 @@ const ScriptValue& value, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::putRequestSetup"); + IDB_TRACE1("IDBObjectStore::putRequestSetup", "store_name", + metadata_->name.Utf8()); return put(script_state, kWebIDBPutModeAddOrUpdate, IDBAny::Create(this), value, key, exception_state); } @@ -380,7 +391,7 @@ tracing_name = "IDBCursor::update"; break; } - IDBRequest::AsyncTraceState metrics(tracing_name, this); + IDBRequest::AsyncTraceState metrics(tracing_name, this, ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -538,8 +549,10 @@ IDBRequest* IDBObjectStore::deleteFunction(ScriptState* script_state, const ScriptValue& key, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::deleteRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::delete", this); + IDB_TRACE1("IDBObjectStore::deleteRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::delete", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -582,7 +595,8 @@ IDBRequest* IDBObjectStore::clear(ScriptState* script_state, ExceptionState& exception_state) { IDB_TRACE("IDBObjectStore::clearRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::clear", this); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::clear", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -678,8 +692,7 @@ Vector<int64_t> index_ids; index_ids.push_back(IndexMetadata().id); if (cursor && !cursor->IsDeleted()) { - cursor->Continue(nullptr, nullptr, - IDBRequest::AsyncTraceState("IDBCursor::continue", this), + cursor->Continue(nullptr, nullptr, IDBRequest::AsyncTraceState(), ASSERT_NO_EXCEPTION); IDBKey* primary_key = cursor->IdbPrimaryKey(); @@ -717,8 +730,10 @@ const IDBKeyPath& key_path, const IDBIndexParameters& options, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::createIndexRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::createIndex", this); + IDB_TRACE1("IDBObjectStore::createIndexRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::createIndex", this, + ++next_tracing_id_); if (!transaction_->IsVersionChange()) { exception_state.ThrowDOMException( kInvalidStateError, @@ -790,7 +805,7 @@ IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::index"); + IDB_TRACE1("IDBObjectStore::index", "store_name", metadata_->name.Utf8()); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -824,7 +839,8 @@ void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::deleteIndex"); + IDB_TRACE1("IDBObjectStore::deleteIndex", "store_name", + metadata_->name.Utf8()); if (!transaction_->IsVersionChange()) { exception_state.ThrowDOMException( kInvalidStateError, @@ -868,8 +884,10 @@ const ScriptValue& range, const String& direction_string, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::openCursorRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::openCursor", this); + IDB_TRACE1("IDBObjectStore::openCursorRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::openCursor", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -918,8 +936,10 @@ const ScriptValue& range, const String& direction_string, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::openKeyCursorRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::openKeyCursor", this); + IDB_TRACE1("IDBObjectStore::openKeyCursorRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::openKeyCursor", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); @@ -959,8 +979,10 @@ IDBRequest* IDBObjectStore::count(ScriptState* script_state, const ScriptValue& range, ExceptionState& exception_state) { - IDB_TRACE("IDBObjectStore::countRequestSetup"); - IDBRequest::AsyncTraceState metrics("IDBObjectStore::count", this); + IDB_TRACE1("IDBObjectStore::countRequestSetup", "store_name", + metadata_->name.Utf8()); + IDBRequest::AsyncTraceState metrics("IDBObjectStore::count", this, + ++next_tracing_id_); if (IsDeleted()) { exception_state.ThrowDOMException( kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage);
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h index bf1abbc..99320e4 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h
@@ -219,6 +219,8 @@ // after a transaction is finished, and can be cleared. IDBIndexMap index_map_; + int64_t next_tracing_id_ = 0; + #if DCHECK_IS_ON() bool clear_index_cache_called_ = false; #endif // DCHECK_IS_ON()
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObservation.h b/third_party/WebKit/Source/modules/indexeddb/IDBObservation.h index a1867150..7b09cc23 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObservation.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObservation.h
@@ -8,7 +8,7 @@ #include "bindings/core/v8/ScriptValue.h" #include "platform/bindings/ScriptWrappable.h" #include "platform/heap/Handle.h" -#include "platform/wtf/PassRefPtr.h" +#include "platform/wtf/RefPtr.h" #include "public/platform/modules/indexeddb/WebIDBTypes.h" namespace blink {
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp index b4f6cbbb..6f4cbeb 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp
@@ -39,12 +39,14 @@ namespace blink { -IDBOpenDBRequest* IDBOpenDBRequest::Create(ScriptState* script_state, - IDBDatabaseCallbacks* callbacks, - int64_t transaction_id, - int64_t version) { - IDBOpenDBRequest* request = - new IDBOpenDBRequest(script_state, callbacks, transaction_id, version); +IDBOpenDBRequest* IDBOpenDBRequest::Create( + ScriptState* script_state, + IDBDatabaseCallbacks* callbacks, + int64_t transaction_id, + int64_t version, + IDBRequest::AsyncTraceState metrics) { + IDBOpenDBRequest* request = new IDBOpenDBRequest( + script_state, callbacks, transaction_id, version, std::move(metrics)); request->SuspendIfNeeded(); return request; } @@ -52,11 +54,12 @@ IDBOpenDBRequest::IDBOpenDBRequest(ScriptState* script_state, IDBDatabaseCallbacks* callbacks, int64_t transaction_id, - int64_t version) + int64_t version, + IDBRequest::AsyncTraceState metrics) : IDBRequest(script_state, IDBAny::CreateNull(), nullptr, - IDBRequest::AsyncTraceState()), + std::move(metrics)), database_callbacks_(callbacks), transaction_id_(transaction_id), version_(version) { @@ -99,8 +102,10 @@ WebIDBDataLoss data_loss, String data_loss_message) { IDB_TRACE("IDBOpenDBRequest::onUpgradeNeeded()"); - if (!ShouldEnqueueEvent()) + if (!ShouldEnqueueEvent()) { + metrics_.RecordAndReset(); return; + } DCHECK(database_callbacks_); @@ -131,8 +136,10 @@ void IDBOpenDBRequest::EnqueueResponse(std::unique_ptr<WebIDBDatabase> backend, const IDBDatabaseMetadata& metadata) { IDB_TRACE("IDBOpenDBRequest::onSuccess()"); - if (!ShouldEnqueueEvent()) + if (!ShouldEnqueueEvent()) { + metrics_.RecordAndReset(); return; + } IDBDatabase* idb_database = nullptr; if (ResultAsAny()) { @@ -151,12 +158,15 @@ } idb_database->SetMetadata(metadata); EnqueueEvent(Event::Create(EventTypeNames::success)); + metrics_.RecordAndReset(); } void IDBOpenDBRequest::EnqueueResponse(int64_t old_version) { IDB_TRACE("IDBOpenDBRequest::onSuccess()"); - if (!ShouldEnqueueEvent()) + if (!ShouldEnqueueEvent()) { + metrics_.RecordAndReset(); return; + } if (old_version == IDBDatabaseMetadata::kNoVersion) { // This database hasn't had an integer version before. old_version = IDBDatabaseMetadata::kDefaultVersion; @@ -164,6 +174,7 @@ SetResult(IDBAny::CreateUndefined()); EnqueueEvent(IDBVersionChangeEvent::Create( EventTypeNames::success, old_version, Nullable<unsigned long long>())); + metrics_.RecordAndReset(); } bool IDBOpenDBRequest::ShouldEnqueueEvent() const {
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.h b/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.h index 8346400..3de4c79 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.h
@@ -42,7 +42,8 @@ static IDBOpenDBRequest* Create(ScriptState*, IDBDatabaseCallbacks*, int64_t transaction_id, - int64_t version); + int64_t version, + IDBRequest::AsyncTraceState metrics); ~IDBOpenDBRequest() override; DECLARE_VIRTUAL_TRACE(); @@ -76,7 +77,8 @@ IDBOpenDBRequest(ScriptState*, IDBDatabaseCallbacks*, int64_t transaction_id, - int64_t version); + int64_t version, + IDBRequest::AsyncTraceState metrics); Member<IDBDatabaseCallbacks> database_callbacks_; const int64_t transaction_id_;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp index f34d20f4..349a2fc 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp
@@ -58,10 +58,12 @@ namespace blink { -IDBRequest::AsyncTraceState::AsyncTraceState(const char* tracing_name, void* id) - : tracing_name_(tracing_name), id_(id) { +IDBRequest::AsyncTraceState::AsyncTraceState(const char* tracing_name, + void* id, + size_t sub_id) + : tracing_name_(tracing_name), id_(static_cast<char*>(id) + sub_id) { if (tracing_name_) - TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id); + TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id_); } void IDBRequest::AsyncTraceState::RecordAndReset() { @@ -96,8 +98,8 @@ : SuspendableObject(ExecutionContext::From(script_state)), transaction_(transaction), isolate_(script_state->GetIsolate()), - source_(source), - metrics_(std::move(metrics)) {} + metrics_(std::move(metrics)), + source_(source) {} IDBRequest::~IDBRequest() { DCHECK((ready_state_ == DONE && !metrics_.is_valid()) || @@ -411,7 +413,8 @@ IDBKey* key, IDBKey* primary_key, RefPtr<IDBValue>&& value) { - IDB_TRACE("IDBRequest::EnqueueResponse(IDBCursor)"); + IDB_TRACE1("IDBRequest::EnqueueResponse(IDBCursor)", "size", + value ? value->DataSize() : 0); if (!ShouldEnqueueEvent()) { metrics_.RecordAndReset(); return; @@ -450,8 +453,18 @@ metrics_.RecordAndReset(); } +namespace { +size_t SizeOfValues(const Vector<RefPtr<IDBValue>>& values) { + size_t size = 0; + for (const auto& value : values) + size += value->DataSize(); + return size; +} +} // namespace + void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { - IDB_TRACE("IDBRequest::EnqueueResponse([IDBValue])"); + IDB_TRACE1("IDBRequest::EnqueueResponse([IDBValue])", "size", + SizeOfValues(values)); if (!ShouldEnqueueEvent()) { metrics_.RecordAndReset(); return; @@ -475,7 +488,8 @@ #endif // DCHECK_IS_ON() void IDBRequest::EnqueueResponse(RefPtr<IDBValue>&& value) { - IDB_TRACE("IDBRequest::EnqueueResponse(IDBValue)"); + IDB_TRACE1("IDBRequest::EnqueueResponse(IDBValue)", "size", + value ? value->DataSize() : 0); if (!ShouldEnqueueEvent()) { metrics_.RecordAndReset(); return;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h index 5c7483f..9b2faeb0 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.h
@@ -73,7 +73,7 @@ class AsyncTraceState { public: AsyncTraceState() {} - AsyncTraceState(const char* tracing_name, void*); + AsyncTraceState(const char* tracing_name, void*, size_t sub_id); ~AsyncTraceState(); AsyncTraceState(AsyncTraceState&& other) { this->tracing_name_ = other.tracing_name_; @@ -92,7 +92,7 @@ private: const char* tracing_name_ = nullptr; - void* id_; + const void* id_; DISALLOW_COPY_AND_ASSIGN(AsyncTraceState); }; @@ -282,6 +282,8 @@ // registered against it. v8::Isolate* isolate_; + AsyncTraceState metrics_; + private: // Calls EnqueueResponse(). friend class IDBRequestQueueItem; @@ -310,8 +312,6 @@ Member<IDBAny> result_; Member<DOMException> error_; - AsyncTraceState metrics_; - bool has_pending_activity_ = true; HeapVector<Member<Event>> enqueued_events_;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.h b/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.h index d447dcb..d57013f09 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.h
@@ -5,14 +5,13 @@ #ifndef IDBRequestLoader_h #define IDBRequestLoader_h +#include <memory> + #include "core/fileapi/FileReaderLoaderClient.h" #include "platform/wtf/Allocator.h" -#include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefPtr.h" #include "platform/wtf/Vector.h" -#include <memory> - namespace blink { class FileReaderLoader;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp index ade7e98..345e82e 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp
@@ -4,12 +4,15 @@ #include "modules/indexeddb/IDBRequestQueueItem.h" +#include <memory> + #include "core/dom/DOMException.h" #include "modules/indexeddb/IDBKey.h" #include "modules/indexeddb/IDBRequest.h" #include "modules/indexeddb/IDBRequestLoader.h" #include "modules/indexeddb/IDBValue.h" #include "platform/wtf/PtrUtil.h" +#include "platform/wtf/RefPtr.h" #include "public/platform/modules/indexeddb/WebIDBCursor.h" namespace blink { @@ -70,7 +73,7 @@ IDBRequestQueueItem::IDBRequestQueueItem( IDBRequest* request, - PassRefPtr<IDBValue> value, + RefPtr<IDBValue> value, bool attach_loader, std::unique_ptr<WTF::Closure> on_result_load_complete) : request_(request), @@ -106,7 +109,7 @@ IDBRequest* request, IDBKey* key, IDBKey* primary_key, - PassRefPtr<IDBValue> value, + RefPtr<IDBValue> value, bool attach_loader, std::unique_ptr<WTF::Closure> on_result_load_complete) : request_(request), @@ -128,7 +131,7 @@ std::unique_ptr<WebIDBCursor> cursor, IDBKey* key, IDBKey* primary_key, - PassRefPtr<IDBValue> value, + RefPtr<IDBValue> value, bool attach_loader, std::unique_ptr<WTF::Closure> on_result_load_complete) : request_(request),
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h index e239461..d39077e0 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h
@@ -5,14 +5,13 @@ #ifndef IDBRequestQueueItem_h #define IDBRequestQueueItem_h +#include <memory> + #include "platform/heap/Handle.h" #include "platform/wtf/Allocator.h" -#include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefPtr.h" #include "platform/wtf/Vector.h" -#include <memory> - namespace blink { class DOMException; @@ -59,7 +58,7 @@ IDBKey*, std::unique_ptr<WTF::Closure> on_result_load_complete); IDBRequestQueueItem(IDBRequest*, - PassRefPtr<IDBValue>, + RefPtr<IDBValue>, bool attach_loader, std::unique_ptr<WTF::Closure> on_load_complete); IDBRequestQueueItem(IDBRequest*, @@ -69,14 +68,14 @@ IDBRequestQueueItem(IDBRequest*, IDBKey*, IDBKey* primary_key, - PassRefPtr<IDBValue>, + RefPtr<IDBValue>, bool attach_loader, std::unique_ptr<WTF::Closure> on_result_load_complete); IDBRequestQueueItem(IDBRequest*, std::unique_ptr<WebIDBCursor>, IDBKey*, IDBKey* primary_key, - PassRefPtr<IDBValue>, + RefPtr<IDBValue>, bool attach_loader, std::unique_ptr<WTF::Closure> on_result_load_complete); ~IDBRequestQueueItem();
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestTest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequestTest.cpp index 1d6f188..de54d55 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestTest.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestTest.cpp
@@ -46,7 +46,7 @@ #include "modules/indexeddb/MockWebIDBDatabase.h" #include "platform/SharedBuffer.h" #include "platform/bindings/ScriptState.h" -#include "platform/wtf/PassRefPtr.h" +#include "platform/wtf/RefPtr.h" #include "platform/wtf/Vector.h" #include "platform/wtf/dtoa/utils.h" #include "public/platform/Platform.h" @@ -123,7 +123,7 @@ IDBKeyPath key_path(String("primaryKey")); RefPtr<IDBValue> idb_value = IDBValue::Create( - wrapped_marker_buffer, std::move(blob_data_handles), + std::move(wrapped_marker_buffer), std::move(blob_data_handles), WTF::MakeUnique<Vector<WebBlobInfo>>(blob_infos), key, key_path); DCHECK_EQ(create_wrapped_value, @@ -279,7 +279,8 @@ std::unique_ptr<MockWebIDBDatabase> backend = MockWebIDBDatabase::Create(); EXPECT_CALL(*backend, Close()).Times(1); IDBOpenDBRequest* request = IDBOpenDBRequest::Create( - scope.GetScriptState(), callbacks, kTransactionId, kVersion); + scope.GetScriptState(), callbacks, kTransactionId, kVersion, + IDBRequest::AsyncTraceState()); EXPECT_EQ(request->readyState(), "pending"); std::unique_ptr<WebIDBCallbacks> callbacks = request->CreateWebCallbacks(); @@ -292,7 +293,8 @@ std::unique_ptr<MockWebIDBDatabase> backend = MockWebIDBDatabase::Create(); EXPECT_CALL(*backend, Close()).Times(1); IDBOpenDBRequest* request = IDBOpenDBRequest::Create( - scope.GetScriptState(), callbacks, kTransactionId, kVersion); + scope.GetScriptState(), callbacks, kTransactionId, kVersion, + IDBRequest::AsyncTraceState()); EXPECT_EQ(request->readyState(), "pending"); std::unique_ptr<WebIDBCallbacks> callbacks = request->CreateWebCallbacks();
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTracing.h b/third_party/WebKit/Source/modules/indexeddb/IDBTracing.h index 9348f8d..1138066 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBTracing.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBTracing.h
@@ -31,5 +31,6 @@ #include "platform/instrumentation/tracing/TraceEvent.h" #define IDB_TRACE(a) TRACE_EVENT0("IndexedDB", (a)); +#define IDB_TRACE1(a, b, b_val) TRACE_EVENT1("IndexedDB", (a), (b), (b_val)); #endif // IDBTracing_h
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransactionTest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBTransactionTest.cpp index 2dcf0d32..c5780aa 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBTransactionTest.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransactionTest.cpp
@@ -141,7 +141,7 @@ IDBKeyPath key_path(String("primaryKey")); RefPtr<IDBValue> idb_value = IDBValue::Create( - wrapped_marker_buffer, std::move(blob_data_handles), + std::move(wrapped_marker_buffer), std::move(blob_data_handles), WTF::MakeUnique<Vector<WebBlobInfo>>(blob_infos), key, key_path); DCHECK_EQ(create_wrapped_value,
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp index f4eb6d04..ff18d95 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp
@@ -7,6 +7,7 @@ #include "bindings/core/v8/serialization/SerializedScriptValue.h" #include "platform/blob/BlobData.h" #include "platform/wtf/PtrUtil.h" +#include "platform/wtf/RefPtr.h" #include "public/platform/WebBlobInfo.h" #include "public/platform/modules/indexeddb/WebIDBValue.h" #include "v8/include/v8.h" @@ -76,23 +77,23 @@ isolate_->AdjustAmountOfExternalAllocatedMemory(-external_allocated_size_); } -PassRefPtr<IDBValue> IDBValue::Create() { +RefPtr<IDBValue> IDBValue::Create() { return AdoptRef(new IDBValue()); } -PassRefPtr<IDBValue> IDBValue::Create(const WebIDBValue& value, - v8::Isolate* isolate) { +RefPtr<IDBValue> IDBValue::Create(const WebIDBValue& value, + v8::Isolate* isolate) { return AdoptRef(new IDBValue(value, isolate)); } -PassRefPtr<IDBValue> IDBValue::Create(const IDBValue* value, - IDBKey* primary_key, - const IDBKeyPath& key_path) { +RefPtr<IDBValue> IDBValue::Create(const IDBValue* value, + IDBKey* primary_key, + const IDBKeyPath& key_path) { return AdoptRef(new IDBValue(value, primary_key, key_path)); } -PassRefPtr<IDBValue> IDBValue::Create( - PassRefPtr<SharedBuffer> unwrapped_data, +RefPtr<IDBValue> IDBValue::Create( + RefPtr<SharedBuffer> unwrapped_data, std::unique_ptr<Vector<RefPtr<BlobDataHandle>>> blob_data, std::unique_ptr<Vector<WebBlobInfo>> blob_info, const IDBKey* primary_key,
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBValue.h b/third_party/WebKit/Source/modules/indexeddb/IDBValue.h index 8c7d2b3..56b1f9d 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBValue.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBValue.h
@@ -10,7 +10,6 @@ #include "modules/indexeddb/IDBKey.h" #include "modules/indexeddb/IDBKeyPath.h" #include "platform/SharedBuffer.h" -#include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefPtr.h" #include "public/platform/WebVector.h" @@ -23,14 +22,12 @@ class MODULES_EXPORT IDBValue final : public RefCounted<IDBValue> { public: - static PassRefPtr<IDBValue> Create(); - static PassRefPtr<IDBValue> Create(const WebIDBValue&, v8::Isolate*); - static PassRefPtr<IDBValue> Create(const IDBValue*, - IDBKey*, - const IDBKeyPath&); + static RefPtr<IDBValue> Create(); + static RefPtr<IDBValue> Create(const WebIDBValue&, v8::Isolate*); + static RefPtr<IDBValue> Create(const IDBValue*, IDBKey*, const IDBKeyPath&); // Used by IDBValueUnwrapper and its tests. - static PassRefPtr<IDBValue> Create( - PassRefPtr<SharedBuffer> unwrapped_data, + static RefPtr<IDBValue> Create( + RefPtr<SharedBuffer> unwrapped_data, std::unique_ptr<Vector<RefPtr<BlobDataHandle>>>, std::unique_ptr<Vector<WebBlobInfo>>, const IDBKey*, @@ -38,6 +35,8 @@ ~IDBValue(); + size_t DataSize() const { return data_ ? data_->size() : 0; } + bool IsNull() const; Vector<String> GetUUIDs() const; RefPtr<SerializedScriptValue> CreateSerializedValue() const;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.h b/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.h index 2554a3f..42ece4e 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.h
@@ -32,8 +32,6 @@ #include "modules/indexeddb/IDBAny.h" #include "modules/indexeddb/IDBRequest.h" #include "modules/indexeddb/IDBVersionChangeEventInit.h" -#include "platform/wtf/PassRefPtr.h" -#include "platform/wtf/RefPtr.h" #include "platform/wtf/text/WTFString.h" #include "public/platform/modules/indexeddb/WebIDBTypes.h"
diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.h b/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.h index b32f5e2..71854cf 100644 --- a/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.h +++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.h
@@ -30,8 +30,7 @@ #define WebIDBCallbacksImpl_h #include <memory> -#include "platform/wtf/PassRefPtr.h" -#include "platform/wtf/RefPtr.h" + #include "public/platform/modules/indexeddb/WebIDBCallbacks.h" namespace blink {
diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h index 2c07d191..9c10e37 100644 --- a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h +++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.h
@@ -27,8 +27,6 @@ #define WebIDBDatabaseCallbacksImpl_h #include "modules/indexeddb/IDBDatabaseCallbacks.h" -#include "platform/wtf/PassRefPtr.h" -#include "platform/wtf/RefPtr.h" #include "public/platform/WebString.h" #include "public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h" #include "public/platform/modules/indexeddb/WebIDBDatabaseError.h"
diff --git a/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp b/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp index e492df5..2f62169 100644 --- a/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp +++ b/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp
@@ -605,20 +605,26 @@ DEFINE_STATIC_LOCAL(const AtomicString, network, ("network")); DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode")); - if (error == network) { - EndOfStreamInternal(WebMediaSource::kEndOfStreamStatusNetworkError, - exception_state); - } else if (error == decode) { - EndOfStreamInternal(WebMediaSource::kEndOfStreamStatusDecodeError, - exception_state); - } else { - NOTREACHED(); // IDL enforcement should prevent this case. - } + // https://www.w3.org/TR/media-source/#dom-mediasource-endofstream + // 1. If the readyState attribute is not in the "open" state then throw an + // InvalidStateError exception and abort these steps. + // 2. If the updating attribute equals true on any SourceBuffer in + // sourceBuffers, then throw an InvalidStateError exception and abort these + // steps. + if (ThrowExceptionIfClosedOrUpdating(IsOpen(), IsUpdating(), exception_state)) + return; + + // 3. Run the end of stream algorithm with the error parameter set to error. + if (error == network) + EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusNetworkError); + else if (error == decode) + EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusDecodeError); + else // "" is allowed internally but not by IDL bindings. + EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusNoError); } void MediaSource::endOfStream(ExceptionState& exception_state) { - EndOfStreamInternal(WebMediaSource::kEndOfStreamStatusNoError, - exception_state); + endOfStream("", exception_state); } void MediaSource::setLiveSeekableRange(double start, @@ -670,29 +676,6 @@ live_seekable_range_ = TimeRanges::Create(); } -void MediaSource::EndOfStreamInternal( - const WebMediaSource::EndOfStreamStatus eos_status, - ExceptionState& exception_state) { - // 2.2 - // http://www.w3.org/TR/media-source/#widl-MediaSource-endOfStream-void-EndOfStreamError-error - // 1. If the readyState attribute is not in the "open" state then throw an - // InvalidStateError exception and abort these steps. - // 2. If the updating attribute equals true on any SourceBuffer in - // sourceBuffers, then throw an InvalidStateError exception and abort these - // steps. - if (ThrowExceptionIfClosedOrUpdating(IsOpen(), IsUpdating(), exception_state)) - return; - - // 3. Run the end of stream algorithm with the error parameter set to error. - // 1. Change the readyState attribute value to "ended". - // 2. Queue a task to fire a simple event named sourceended at the - // MediaSource. - SetReadyState(EndedKeyword()); - - // 3. Do various steps based on |eosStatus|. - web_media_source_->MarkEndOfStream(eos_status); -} - bool MediaSource::IsOpen() const { return readyState() == OpenKeyword(); } @@ -731,6 +714,18 @@ return attached_element_.Get(); } +void MediaSource::EndOfStreamAlgorithm( + const WebMediaSource::EndOfStreamStatus eos_status) { + // https://www.w3.org/TR/media-source/#end-of-stream-algorithm + // 1. Change the readyState attribute value to "ended". + // 2. Queue a task to fire a simple event named sourceended at the + // MediaSource. + SetReadyState(EndedKeyword()); + + // 3. Do various steps based on |eos_status|. + web_media_source_->MarkEndOfStream(eos_status); +} + bool MediaSource::IsClosed() const { return readyState() == ClosedKeyword(); }
diff --git a/third_party/WebKit/Source/modules/mediasource/MediaSource.h b/third_party/WebKit/Source/modules/mediasource/MediaSource.h index 4115c62..3f1a99d 100644 --- a/third_party/WebKit/Source/modules/mediasource/MediaSource.h +++ b/third_party/WebKit/Source/modules/mediasource/MediaSource.h
@@ -119,6 +119,7 @@ bool IsOpen() const; void SetSourceBufferActive(SourceBuffer*, bool); HTMLMediaElement* MediaElement() const; + void EndOfStreamAlgorithm(const WebMediaSource::EndOfStreamStatus); // Used by MediaSourceRegistry. void AddedToRegistry(); @@ -138,8 +139,6 @@ const String& codecs, ExceptionState&); void ScheduleEvent(const AtomicString& event_name); - void EndOfStreamInternal(const WebMediaSource::EndOfStreamStatus, - ExceptionState&); // Implements the duration change algorithm. // http://w3c.github.io/media-source/#duration-change-algorithm
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp index f3fad64..6af62fd 100644 --- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp +++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
@@ -1310,7 +1310,7 @@ // 5. If decode error is true, then run the end of stream algorithm with the // error parameter set to "decode". - source_->endOfStream("decode", ASSERT_NO_EXCEPTION); + source_->EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusDecodeError); } DEFINE_TRACE(SourceBuffer) {
diff --git a/third_party/WebKit/Source/modules/serviceworkers/Client.idl b/third_party/WebKit/Source/modules/serviceworkers/Client.idl index c94b780..b5eef12 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/Client.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/Client.idl
@@ -13,5 +13,5 @@ [PostMessage, RaisesException, CallWith=ScriptState] void postMessage(SerializedScriptValue message, optional sequence<Transferable> transfer); // FIXME: frameType is non-standard, see https://crbug.com/697110 - readonly attribute ContextFrameType frameType; + [CallWith=ScriptState] readonly attribute ContextFrameType frameType; };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp index 88c5946..8c8333a 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp
@@ -6,6 +6,7 @@ #include "bindings/core/v8/ToV8ForCore.h" #include "core/dom/ExecutionContext.h" +#include "core/frame/UseCounter.h" #include "core/timing/WorkerGlobalScopePerformance.h" #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" #include "modules/fetch/Request.h"
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.cpp index 6cf1051..1983914 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.cpp
@@ -10,9 +10,11 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/serialization/SerializedScriptValue.h" #include "core/dom/ExecutionContext.h" +#include "core/frame/UseCounter.h" #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h" #include "platform/bindings/ScriptState.h" #include "platform/wtf/RefPtr.h" +#include "public/platform/WebFeature.h" #include "public/platform/WebString.h" namespace blink { @@ -67,7 +69,9 @@ return String(); } -String ServiceWorkerClient::frameType() const { +String ServiceWorkerClient::frameType(ScriptState* script_state) const { + UseCounter::Count(ExecutionContext::From(script_state), + WebFeature::kServiceWorkerClientFrameType); switch (frame_type_) { case WebURLRequest::kFrameTypeAuxiliary: return "auxiliary";
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.h index 764aa2b15..0320751 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.h +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClient.h
@@ -37,7 +37,7 @@ // Client.idl String url() const { return url_; } String type() const; - String frameType() const; + String frameType(ScriptState*) const; String id() const { return uuid_; } void postMessage(ScriptState*, PassRefPtr<SerializedScriptValue> message,
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 1e871fb..00273c0 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -340,7 +340,6 @@ "WebThreadSupportingGC.cpp", "WebThreadSupportingGC.h", "WebTouchEvent.cpp", - "WebURLLoader.cpp", "WindowsKeyboardCodes.h", "animation/AnimationTranslationUtil.cpp", "animation/AnimationTranslationUtil.h", @@ -516,6 +515,8 @@ "bindings/WrapperCreationSecurityCheck.h", "bindings/WrapperTypeInfo.cpp", "bindings/WrapperTypeInfo.h", + "blob/BlobBytesProvider.cpp", + "blob/BlobBytesProvider.h", "blob/BlobData.cpp", "blob/BlobData.h", "blob/BlobRegistry.cpp", @@ -1096,6 +1097,7 @@ "graphics/paint/PaintController.cpp", "graphics/paint/PaintController.h", "graphics/paint/PaintFlags.h", + "graphics/paint/PaintPropertyNode.cpp", "graphics/paint/PaintPropertyNode.h", "graphics/paint/PaintRecord.h", "graphics/paint/PaintRecordBuilder.cpp", @@ -1819,6 +1821,7 @@ "animation/TimingFunctionTest.cpp", "audio/PushPullFIFOTest.cpp", "bindings/RuntimeCallStatsTest.cpp", + "blob/BlobBytesProviderTest.cpp", "blob/BlobDataTest.cpp", "exported/FilePathConversionTest.cpp", "exported/WebStringTest.cpp", @@ -1882,6 +1885,7 @@ "graphics/paint/PaintChunkTest.cpp", "graphics/paint/PaintChunkerTest.cpp", "graphics/paint/PaintControllerTest.cpp", + "graphics/paint/PaintPropertyNodeTest.cpp", "graphics/paint/PropertyTreeStateTest.cpp", "image-decoders/FastSharedBufferReaderTest.cpp", "image-decoders/ImageDecoderTest.cpp",
diff --git a/third_party/WebKit/Source/platform/Length.cpp b/third_party/WebKit/Source/platform/Length.cpp index 8a945e5a..be1ca46 100644 --- a/third_party/WebKit/Source/platform/Length.cpp +++ b/third_party/WebKit/Source/platform/Length.cpp
@@ -103,6 +103,19 @@ CalculationValue::Create(PixelsAndPercent(pixels, percent), range)); } +Length Length::BlendSameTypes(const Length& from, + double progress, + ValueRange range) const { + LengthType result_type = GetType(); + if (IsZero()) + result_type = from.GetType(); + + float blended_value = blink::Blend(from.Value(), Value(), progress); + if (range == kValueRangeNonNegative) + blended_value = clampTo<float>(blended_value, 0); + return Length(blended_value, result_type); +} + PixelsAndPercent Length::GetPixelsAndPercent() const { switch (GetType()) { case kFixed:
diff --git a/third_party/WebKit/Source/platform/Length.h b/third_party/WebKit/Source/platform/Length.h index 23b760e..9c4722f 100644 --- a/third_party/WebKit/Source/platform/Length.h +++ b/third_party/WebKit/Source/platform/Length.h
@@ -23,15 +23,9 @@ #ifndef Length_h #define Length_h -#include <cstring> +#include "platform/LayoutUnit.h" #include "platform/PlatformExport.h" -#include "platform/animation/AnimationUtilities.h" #include "platform/wtf/Allocator.h" -#include "platform/wtf/Assertions.h" -#include "platform/wtf/Forward.h" -#include "platform/wtf/HashMap.h" -#include "platform/wtf/MathExtras.h" -#include "platform/wtf/Vector.h" namespace blink { @@ -270,14 +264,7 @@ if (from.IsZero() && IsZero()) return *this; - LengthType result_type = GetType(); - if (IsZero()) - result_type = from.GetType(); - - float blended_value = blink::Blend(from.Value(), Value(), progress); - if (range == kValueRangeNonNegative) - blended_value = clampTo<float>(blended_value, 0); - return Length(blended_value, result_type); + return BlendSameTypes(from, progress, range); } float GetFloatValue() const { @@ -298,6 +285,8 @@ Length BlendMixedTypes(const Length& from, double progress, ValueRange) const; + Length BlendSameTypes(const Length& from, double progress, ValueRange) const; + int CalculationHandle() const { DCHECK(IsCalculated()); return GetIntValue();
diff --git a/third_party/WebKit/Source/platform/LengthFunctions.cpp b/third_party/WebKit/Source/platform/LengthFunctions.cpp index 54b1a42..93bd3fbb 100644 --- a/third_party/WebKit/Source/platform/LengthFunctions.cpp +++ b/third_party/WebKit/Source/platform/LengthFunctions.cpp
@@ -26,6 +26,8 @@ #include "platform/LayoutUnit.h" #include "platform/LengthPoint.h" #include "platform/LengthSize.h" +#include "platform/geometry/FloatPoint.h" +#include "platform/geometry/FloatSize.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index 25195dc0..0d45cc3 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -1045,7 +1045,7 @@ }, { name: "VisualViewportAPI", - status: "experimental", + status: "stable", }, { name: "WakeLock",
diff --git a/third_party/WebKit/Source/platform/WebFrameScheduler.h b/third_party/WebKit/Source/platform/WebFrameScheduler.h index 42ffbda9..19648f8 100644 --- a/third_party/WebKit/Source/platform/WebFrameScheduler.h +++ b/third_party/WebKit/Source/platform/WebFrameScheduler.h
@@ -132,7 +132,7 @@ // Tells the scheduler that a provisional load has started, virtual time may // be paused. Must be called from the main thread. - virtual void DidStartProvisionalLoad() {} + virtual void DidStartProvisionalLoad(bool is_main_frame) {} // Tells the scheduler that a provisional load has failed, virtual time may be // unpaused. Must be called from the main thread.
diff --git a/third_party/WebKit/Source/platform/WebURLLoader.cpp b/third_party/WebKit/Source/platform/WebURLLoader.cpp deleted file mode 100644 index 0fbff17..0000000 --- a/third_party/WebKit/Source/platform/WebURLLoader.cpp +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "public/platform/WebURLLoader.h" - -#include "platform/WebTaskRunner.h" - -namespace blink { - -void WebURLLoader::SetLoadingTaskRunner(WebTaskRunner* task_runner) { - SetLoadingTaskRunner(task_runner->ToSingleThreadTaskRunner()); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.cpp b/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.cpp index 5f1fa38..ef4500a 100644 --- a/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.cpp +++ b/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.cpp
@@ -56,6 +56,10 @@ return DOMWrapperWorld::kMainWorldId < world_id && world_id < DOMWrapperWorld::kIsolatedWorldIdLimit; } + +static bool IsMainWorldId(int world_id) { + return world_id == DOMWrapperWorld::kMainWorldId; +} #endif PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::Create(v8::Isolate* isolate, @@ -196,16 +200,16 @@ return map; } -String DOMWrapperWorld::IsolatedWorldHumanReadableName() { - DCHECK(this->IsIsolatedWorld()); +String DOMWrapperWorld::NonMainWorldHumanReadableName() { + DCHECK(!this->IsMainWorld()); return IsolatedWorldHumanReadableNames().at(GetWorldId()); } -void DOMWrapperWorld::SetIsolatedWorldHumanReadableName( +void DOMWrapperWorld::SetNonMainWorldHumanReadableName( int world_id, const String& human_readable_name) { #if DCHECK_IS_ON() - DCHECK(IsIsolatedWorldId(world_id)); + DCHECK(!IsMainWorldId(world_id)); #endif IsolatedWorldHumanReadableNames().Set(world_id, human_readable_name); }
diff --git a/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.h b/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.h index 3fd0038..77646d13 100644 --- a/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.h +++ b/third_party/WebKit/Source/platform/bindings/DOMWrapperWorld.h
@@ -105,8 +105,8 @@ static DOMWrapperWorld& MainWorld(); - static void SetIsolatedWorldHumanReadableName(int world_id, const String&); - String IsolatedWorldHumanReadableName(); + static void SetNonMainWorldHumanReadableName(int world_id, const String&); + String NonMainWorldHumanReadableName(); // Associates an isolated world (see above for description) with a security // origin. XMLHttpRequest instances used in that world will be considered
diff --git a/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp b/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp new file mode 100644 index 0000000..03e7066d --- /dev/null +++ b/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp
@@ -0,0 +1,184 @@ +// 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 "platform/blob/BlobBytesProvider.h" + +#include "base/numerics/safe_conversions.h" +#include "platform/wtf/Functional.h" +#include "public/platform/Platform.h" + +namespace blink { + +namespace { + +// Helper class that streams all the bytes from a vector of RawData RefPtrs to +// a mojo data pipe. Instances will delete themselves when all data has been +// written, or when the data pipe is disconnected. +class BlobBytesStreamer { + public: + BlobBytesStreamer(Vector<RefPtr<RawData>> data, + mojo::ScopedDataPipeProducerHandle pipe) + : data_(std::move(data)), + pipe_(std::move(pipe)), + watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) { + watcher_.Watch(pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + ConvertToBaseCallback(WTF::Bind( + &BlobBytesStreamer::OnWritable, WTF::Unretained(this)))); + } + + void OnWritable(MojoResult result) { + if (result == MOJO_RESULT_CANCELLED || + result == MOJO_RESULT_FAILED_PRECONDITION) { + delete this; + return; + } + DCHECK_EQ(result, MOJO_RESULT_OK); + + while (true) { + uint32_t num_bytes = base::saturated_cast<uint32_t>( + data_[current_item_]->length() - current_item_offset_); + MojoResult write_result = mojo::WriteDataRaw( + pipe_.get(), data_[current_item_]->data() + current_item_offset_, + &num_bytes, MOJO_WRITE_DATA_FLAG_NONE); + if (write_result == MOJO_RESULT_OK) { + current_item_offset_ += num_bytes; + if (current_item_offset_ >= data_[current_item_]->length()) { + data_[current_item_] = nullptr; + current_item_++; + current_item_offset_ = 0; + if (current_item_ >= data_.size()) { + // All items were sent completely. + delete this; + return; + } + } + } else if (write_result == MOJO_RESULT_SHOULD_WAIT) { + break; + } else { + // TOOD(mek): Something went wrong, log this error somewhere. + delete this; + return; + } + } + } + + private: + // The index of the item currently being written. + size_t current_item_ = 0; + // The offset into the current item of the first byte not yet written to the + // data pipe. + size_t current_item_offset_ = 0; + // The data being written. + Vector<RefPtr<RawData>> data_; + + mojo::ScopedDataPipeProducerHandle pipe_; + mojo::SimpleWatcher watcher_; +}; + +} // namespace + +BlobBytesProvider::BlobBytesProvider(RefPtr<RawData> data) { + // TODO(mek): This is probably not enough to keep the renderer alive while + // data is being transferred. The IPC based blob code additionally calls + // ChildProcess::current()->AddRefProcess/ReleaseProcess. + Platform::Current()->SuddenTerminationChanged(false); + data_.push_back(std::move(data)); +} + +BlobBytesProvider::~BlobBytesProvider() { + Platform::Current()->SuddenTerminationChanged(true); +} + +void BlobBytesProvider::AppendData(RefPtr<RawData> data) { + data_.push_back(std::move(data)); +} + +void BlobBytesProvider::RequestAsReply(RequestAsReplyCallback callback) { + // TODO(mek): Once better metrics are created we could experiment with ways + // to reduce the number of copies of data that are made here. + Vector<uint8_t> result; + for (const auto& d : data_) + result.Append(d->data(), d->length()); + std::move(callback).Run(result); +} + +void BlobBytesProvider::RequestAsStream( + mojo::ScopedDataPipeProducerHandle pipe) { + // BlobBytesStreamer will self delete when done. + new BlobBytesStreamer(std::move(data_), std::move(pipe)); +} + +void BlobBytesProvider::RequestAsFile(uint64_t source_offset, + uint64_t source_size, + base::File file, + uint64_t file_offset, + RequestAsFileCallback callback) { + // TODO(mek): Make sure this code runs on a thread that is allowed to do + // file IO. + if (!file.IsValid()) { + std::move(callback).Run(WTF::nullopt); + return; + } + + int64_t seek_distance = + file.Seek(base::File::FROM_BEGIN, SafeCast<int64_t>(file_offset)); + bool seek_failed = seek_distance < 0; + if (seek_failed) { + // TODO(mek): Log histogram Storage.Blob.RendererFileSeekFailed. + std::move(callback).Run(WTF::nullopt); + return; + } + + // TODO(mek): Could have a more efficient way to find beginning. + + // Offset of the current data chunk in the overall stream provided by this + // provider. + uint64_t offset = 0; + for (const RefPtr<RawData>& data : data_) { + // Skip any chunks that are entirely before the data we need to write. + if (offset + data->length() <= source_offset) { + offset += data->length(); + continue; + } + + // We're done if the beginning of the current chunk is past the end of the + // data to write. + if (offset >= source_offset + source_size) + break; + + // Offset within this chunk where writing needs to start from. + uint64_t data_offset = offset > source_offset ? 0 : source_offset - offset; + uint64_t data_size = + std::min(data->length() - data_offset, + source_offset + source_size - offset - data_offset); + size_t written = 0; + while (written < data_size) { + int writing_size = base::saturated_cast<int>(data_size - written); + int actual_written = file.WriteAtCurrentPos( + data->data() + data_offset + written, writing_size); + bool write_failed = actual_written < 0; + if (write_failed) { + // TODO(mek): Log histogram Storage.Blob.RendererFileWriteFailed + std::move(callback).Run(WTF::nullopt); + return; + } + written += actual_written; + } + + offset += data->length(); + } + + if (!file.Flush()) { + std::move(callback).Run(WTF::nullopt); + return; + } + base::File::Info info; + if (!file.GetInfo(&info)) { + std::move(callback).Run(WTF::nullopt); + return; + } + std::move(callback).Run(info.last_modified); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/blob/BlobBytesProvider.h b/third_party/WebKit/Source/platform/blob/BlobBytesProvider.h new file mode 100644 index 0000000..fd4d1d3 --- /dev/null +++ b/third_party/WebKit/Source/platform/blob/BlobBytesProvider.h
@@ -0,0 +1,43 @@ +// 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 BlobBytesProvider_h +#define BlobBytesProvider_h + +#include "platform/blob/BlobData.h" +#include "storage/public/interfaces/blobs.mojom-blink.h" + +namespace blink { + +// Implementation of the BytesProvider mojo interface, used to transport bytes +// making up a blob to the browser process, at the request of the blob service. +// +// Typical usage of this class creates and calls AppendData on one thread, and +// then transfers ownership of the class to a different thread where it will be +// bound to a mojo pipe, such that the various Request* methods are called on a +// thread that is allowed to do File IO. +class PLATFORM_EXPORT BlobBytesProvider + : public storage::mojom::blink::BytesProvider { + public: + explicit BlobBytesProvider(RefPtr<RawData>); + ~BlobBytesProvider() override; + + void AppendData(RefPtr<RawData>); + + // BytesProvider implementation: + void RequestAsReply(RequestAsReplyCallback) override; + void RequestAsStream(mojo::ScopedDataPipeProducerHandle) override; + void RequestAsFile(uint64_t source_offset, + uint64_t source_size, + base::File, + uint64_t file_offset, + RequestAsFileCallback) override; + + private: + Vector<RefPtr<RawData>> data_; +}; + +} // namespace blink + +#endif // BlobBytesProvider_h
diff --git a/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp b/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp new file mode 100644 index 0000000..1a5a7b0 --- /dev/null +++ b/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp
@@ -0,0 +1,318 @@ +// 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 "platform/blob/BlobBytesProvider.h" + +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/test/scoped_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { +namespace { + +class BlobBytesProviderTest : public testing::Test { + public: + void SetUp() override { + test_bytes1_.resize(128); + for (size_t i = 0; i < test_bytes1_.size(); ++i) + test_bytes1_[i] = i % 191; + test_data1_ = RawData::Create(); + test_data1_->MutableData()->AppendVector(test_bytes1_); + test_bytes2_.resize(64); + for (size_t i = 0; i < test_bytes2_.size(); ++i) + test_bytes2_[i] = i; + test_data2_ = RawData::Create(); + test_data2_->MutableData()->AppendVector(test_bytes2_); + test_bytes3_.resize(32); + for (size_t i = 0; i < test_bytes3_.size(); ++i) + test_bytes3_[i] = (i + 10) % 137; + test_data3_ = RawData::Create(); + test_data3_->MutableData()->AppendVector(test_bytes3_); + + combined_bytes_.AppendVector(test_bytes1_); + combined_bytes_.AppendVector(test_bytes2_); + combined_bytes_.AppendVector(test_bytes3_); + } + + protected: + base::test::ScopedTaskEnvironment scoped_task_environment_; + + RefPtr<RawData> test_data1_; + Vector<uint8_t> test_bytes1_; + RefPtr<RawData> test_data2_; + Vector<uint8_t> test_bytes2_; + RefPtr<RawData> test_data3_; + Vector<uint8_t> test_bytes3_; + Vector<uint8_t> combined_bytes_; +}; + +TEST_F(BlobBytesProviderTest, RequestAsReply) { + auto provider = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + Vector<uint8_t> received_bytes; + provider->RequestAsReply( + base::Bind([](Vector<uint8_t>* bytes_out, + const Vector<uint8_t>& bytes) { *bytes_out = bytes; }, + &received_bytes)); + EXPECT_EQ(test_bytes1_, received_bytes); + + received_bytes.clear(); + provider = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + provider->AppendData(test_data2_); + provider->AppendData(test_data3_); + provider->RequestAsReply( + base::Bind([](Vector<uint8_t>* bytes_out, + const Vector<uint8_t>& bytes) { *bytes_out = bytes; }, + &received_bytes)); + EXPECT_EQ(combined_bytes_, received_bytes); +} + +struct FileTestData { + uint64_t offset; + uint64_t size; +}; + +void PrintTo(const FileTestData& test, std::ostream* os) { + *os << "offset: " << test.offset << ", size: " << test.size; +} + +class RequestAsFile : public BlobBytesProviderTest, + public testing::WithParamInterface<FileTestData> { + public: + void SetUp() override { + BlobBytesProviderTest::SetUp(); + test_provider_ = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + test_provider_->AppendData(test_data2_); + test_provider_->AppendData(test_data3_); + + sliced_data_.AppendRange( + combined_bytes_.begin() + GetParam().offset, + combined_bytes_.begin() + GetParam().offset + GetParam().size); + } + + base::File DoRequestAsFile(uint64_t source_offset, + uint64_t source_length, + uint64_t file_offset) { + base::FilePath path; + base::CreateTemporaryFile(&path); + WTF::Optional<WTF::Time> received_modified; + test_provider_->RequestAsFile( + source_offset, source_length, + base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), + file_offset, + base::Bind( + [](WTF::Optional<WTF::Time>* received_modified, + WTF::Optional<WTF::Time> modified) { + *received_modified = modified; + }, + &received_modified)); + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_DELETE_ON_CLOSE); + base::File::Info info; + EXPECT_TRUE(file.GetInfo(&info)); + EXPECT_EQ(info.last_modified, received_modified); + return file; + } + + protected: + std::unique_ptr<BlobBytesProvider> test_provider_; + Vector<uint8_t> sliced_data_; +}; + +TEST_P(RequestAsFile, AtStartOfEmptyFile) { + FileTestData test = GetParam(); + base::File file = DoRequestAsFile(test.offset, test.size, 0); + + base::File::Info info; + EXPECT_TRUE(file.GetInfo(&info)); + EXPECT_EQ(static_cast<int64_t>(test.size), info.size); + + Vector<uint8_t> read_data(test.size); + EXPECT_EQ(static_cast<int>(test.size), + file.Read(0, reinterpret_cast<char*>(read_data.data()), test.size)); + EXPECT_EQ(sliced_data_, read_data); +} + +TEST_P(RequestAsFile, OffsetInEmptyFile) { + FileTestData test = GetParam(); + int file_offset = 32; + sliced_data_.InsertVector(0, Vector<uint8_t>(file_offset)); + + base::File file = DoRequestAsFile(test.offset, test.size, file_offset); + + base::File::Info info; + EXPECT_TRUE(file.GetInfo(&info)); + if (test.size == 0) { + EXPECT_EQ(0, info.size); + } else { + EXPECT_EQ(static_cast<int64_t>(test.size) + 32, info.size); + + Vector<uint8_t> read_data(sliced_data_.size()); + EXPECT_EQ(static_cast<int>(sliced_data_.size()), + file.Read(0, reinterpret_cast<char*>(read_data.data()), + sliced_data_.size())); + EXPECT_EQ(sliced_data_, read_data); + } +} + +TEST_P(RequestAsFile, OffsetInNonEmptyFile) { + FileTestData test = GetParam(); + int file_offset = 23; + + Vector<uint8_t> expected_data(1024, 42); + + base::FilePath path; + base::CreateTemporaryFile(&path); + { + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE); + EXPECT_EQ(static_cast<int>(expected_data.size()), + file.WriteAtCurrentPos( + reinterpret_cast<const char*>(expected_data.data()), + expected_data.size())); + } + + std::copy(sliced_data_.begin(), sliced_data_.end(), + expected_data.begin() + file_offset); + + test_provider_->RequestAsFile( + test.offset, test.size, + base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), + file_offset, base::Bind([](WTF::Optional<WTF::Time> last_modified) { + EXPECT_TRUE(last_modified); + })); + + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_DELETE_ON_CLOSE); + base::File::Info info; + EXPECT_TRUE(file.GetInfo(&info)); + EXPECT_EQ(static_cast<int64_t>(expected_data.size()), info.size); + + Vector<uint8_t> read_data(expected_data.size()); + EXPECT_EQ(static_cast<int>(expected_data.size()), + file.Read(0, reinterpret_cast<char*>(read_data.data()), + expected_data.size())); + EXPECT_EQ(expected_data, read_data); +} + +const FileTestData file_tests[] = { + {0, 128 + 64 + 32}, // The full amount of data. + {0, 128 + 64}, // First two chunks. + {10, 13}, // Just a subset of the first chunk. + {10, 128}, // Parts of both the first and second chunk. + {128, 64}, // The entire second chunk. + {0, 0}, // Zero bytes from the beginning. + {130, 10}, // Just a subset of the second chunk. + {140, 0}, // Zero bytes from the middle of the second chunk. + {10, 128 + 64}, // Parts of all three chunks. +}; + +INSTANTIATE_TEST_CASE_P(BlobBytesProviderTest, + RequestAsFile, + testing::ValuesIn(file_tests)); + +TEST_F(BlobBytesProviderTest, RequestAsFile_MultipleChunks) { + auto provider = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + provider->AppendData(test_data2_); + provider->AppendData(test_data3_); + + base::FilePath path; + base::CreateTemporaryFile(&path); + + Vector<uint8_t> expected_data; + for (size_t i = 0; i < combined_bytes_.size(); i += 16) { + provider->RequestAsFile( + i, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), + combined_bytes_.size() - i - 16, + base::Bind([](WTF::Optional<WTF::Time> last_modified) { + EXPECT_TRUE(last_modified); + })); + expected_data.insert(0, combined_bytes_.data() + i, 16); + } + + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_DELETE_ON_CLOSE); + base::File::Info info; + EXPECT_TRUE(file.GetInfo(&info)); + EXPECT_EQ(static_cast<int64_t>(combined_bytes_.size()), info.size); + + Vector<uint8_t> read_data(expected_data.size()); + EXPECT_EQ(static_cast<int>(expected_data.size()), + file.Read(0, reinterpret_cast<char*>(read_data.data()), + expected_data.size())); + EXPECT_EQ(expected_data, read_data); +} + +TEST_F(BlobBytesProviderTest, RequestAsFile_InvaldFile) { + auto provider = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + + provider->RequestAsFile( + 0, 16, base::File(), 0, + base::Bind([](WTF::Optional<WTF::Time> last_modified) { + EXPECT_FALSE(last_modified); + })); +} + +TEST_F(BlobBytesProviderTest, RequestAsFile_UnwritableFile) { + auto provider = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + + base::FilePath path; + base::CreateTemporaryFile(&path); + provider->RequestAsFile( + 0, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ), 0, + base::Bind([](WTF::Optional<WTF::Time> last_modified) { + EXPECT_FALSE(last_modified); + })); + + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_DELETE_ON_CLOSE); + base::File::Info info; + EXPECT_TRUE(file.GetInfo(&info)); + EXPECT_EQ(0, info.size); +} + +TEST_F(BlobBytesProviderTest, RequestAsStream) { + auto provider = WTF::MakeUnique<BlobBytesProvider>(test_data1_); + provider->AppendData(test_data2_); + provider->AppendData(test_data3_); + + mojo::DataPipe pipe(7); + provider->RequestAsStream(std::move(pipe.producer_handle)); + + Vector<uint8_t> received_data; + base::RunLoop loop; + mojo::SimpleWatcher watcher(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC); + watcher.Watch( + pipe.consumer_handle.get(), MOJO_HANDLE_SIGNAL_READABLE, + base::Bind( + [](mojo::DataPipeConsumerHandle pipe, base::Closure quit_closure, + Vector<uint8_t>* bytes_out, MojoResult result) { + if (result == MOJO_RESULT_CANCELLED || + result == MOJO_RESULT_FAILED_PRECONDITION) { + quit_closure.Run(); + return; + } + + uint32_t num_bytes = 0; + MojoResult query_result = mojo::ReadDataRaw( + pipe, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_QUERY); + if (query_result == MOJO_RESULT_SHOULD_WAIT) + return; + EXPECT_EQ(MOJO_RESULT_OK, query_result); + + Vector<uint8_t> bytes(num_bytes); + EXPECT_EQ(MOJO_RESULT_OK, + mojo::ReadDataRaw(pipe, bytes.data(), &num_bytes, + MOJO_READ_DATA_FLAG_ALL_OR_NONE)); + bytes_out->AppendVector(bytes); + }, + pipe.consumer_handle.get(), loop.QuitClosure(), &received_data)); + loop.Run(); + + EXPECT_EQ(combined_bytes_, received_data); +} + +} // namespace + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/blob/BlobData.cpp b/third_party/WebKit/Source/platform/blob/BlobData.cpp index 190479b..422c3a8 100644 --- a/third_party/WebKit/Source/platform/blob/BlobData.cpp +++ b/third_party/WebKit/Source/platform/blob/BlobData.cpp
@@ -31,8 +31,10 @@ #include "platform/blob/BlobData.h" #include <memory> +#include "mojo/public/cpp/bindings/strong_binding.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/UUID.h" +#include "platform/blob/BlobBytesProvider.h" #include "platform/blob/BlobRegistry.h" #include "platform/text/LineEnding.h" #include "platform/wtf/PassRefPtr.h" @@ -285,6 +287,7 @@ size_t current_memory_population = 0; Vector<DataElementPtr> elements; const DataElementPtr null_element = nullptr; + BlobBytesProvider* last_bytes_provider = nullptr; // TODO(mek): When the mojo code path is the default BlobData should // directly create mojom::DataElements rather than BlobDataItems, @@ -312,6 +315,7 @@ bool last_element_is_bytes = last_element && last_element->is_bytes(); if (last_element_is_bytes) { // Append bytes to previous element. + DCHECK(last_bytes_provider); const auto& bytes_element = last_element->get_bytes(); bytes_element->length += item.data->length(); if (should_embed_bytes && bytes_element->embedded_data) { @@ -322,11 +326,17 @@ current_memory_population -= bytes_element->embedded_data->size(); bytes_element->embedded_data = WTF::nullopt; } - // TODO(mek): Append data to previous element's BytesProvider. + last_bytes_provider->AppendData(item.data); } else { BytesProviderPtr bytes_provider; - // TODO(mek): Bind bytes provider to something. - MakeRequest(&bytes_provider); + // TODO(mek): BytesProvider should be bound on a thread that doesn't + // run javascript to prevent deadlock if javascript starts trying to + // synchronously read the blob before all data has been transported + // to the browser process. + last_bytes_provider = static_cast<BlobBytesProvider*>( + MakeStrongBinding(WTF::MakeUnique<BlobBytesProvider>(item.data), + MakeRequest(&bytes_provider)) + ->impl()); DataElementBytesPtr bytes_element = DataElementBytes::New( item.data->length(), WTF::nullopt, std::move(bytes_provider)); if (should_embed_bytes) {
diff --git a/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp b/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp index 834c8b34..e88a65d 100644 --- a/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp +++ b/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp
@@ -148,6 +148,7 @@ struct ExpectedElement { DataElementPtr element; String blob_uuid; + Vector<uint8_t> large_data; static ExpectedElement EmbeddedBytes(Vector<uint8_t> embedded_data) { uint64_t size = embedded_data.size(); @@ -155,9 +156,11 @@ DataElementBytes::New(size, std::move(embedded_data), nullptr))}; } - static ExpectedElement LargeBytes(uint64_t size) { - return ExpectedElement{DataElement::NewBytes( - DataElementBytes::New(size, WTF::nullopt, nullptr))}; + static ExpectedElement LargeBytes(Vector<uint8_t> data) { + uint64_t size = data.size(); + return ExpectedElement{DataElement::NewBytes(DataElementBytes::New( + size, WTF::nullopt, nullptr)), + String(), std::move(data)}; } static ExpectedElement File(const String& path, @@ -252,6 +255,21 @@ EXPECT_EQ(expected->get_bytes()->length, actual->get_bytes()->length); EXPECT_EQ(expected->get_bytes()->embedded_data, actual->get_bytes()->embedded_data); + + base::RunLoop loop; + Vector<uint8_t> received_bytes; + actual->get_bytes()->data->RequestAsReply(base::Bind( + [](base::Closure quit_closure, Vector<uint8_t>* bytes_out, + const Vector<uint8_t>& bytes) { + *bytes_out = bytes; + quit_closure.Run(); + }, + loop.QuitClosure(), &received_bytes)); + loop.Run(); + if (expected->get_bytes()->embedded_data) + EXPECT_EQ(expected->get_bytes()->embedded_data, received_bytes); + else + EXPECT_EQ(expected_elements[i].large_data, received_bytes); } else if (expected->is_file()) { ASSERT_TRUE(actual->is_file()); EXPECT_EQ(expected->get_file()->path, actual->get_file()->path); @@ -377,8 +395,7 @@ data->AppendBytes(large_test_data_.data(), large_test_data_.size()); Vector<ExpectedElement> expected_elements; - expected_elements.push_back( - ExpectedElement::LargeBytes(large_test_data_.size())); + expected_elements.push_back(ExpectedElement::LargeBytes(large_test_data_)); TestCreateBlob(std::move(data), std::move(expected_elements)); } @@ -405,9 +422,12 @@ data->AppendBytes(small_test_data_.data(), small_test_data_.size()); EXPECT_EQ(2u, data->Items().size()); + Vector<uint8_t> expected_data = large_test_data_; + expected_data.AppendVector(small_test_data_); + Vector<ExpectedElement> expected_elements; - expected_elements.push_back(ExpectedElement::LargeBytes( - large_test_data_.size() + small_test_data_.size())); + expected_elements.push_back( + ExpectedElement::LargeBytes(std::move(expected_data))); TestCreateBlob(std::move(data), std::move(expected_elements)); } @@ -418,9 +438,12 @@ data->AppendBytes(large_test_data_.data(), large_test_data_.size()); EXPECT_EQ(2u, data->Items().size()); + Vector<uint8_t> expected_data = small_test_data_; + expected_data.AppendVector(large_test_data_); + Vector<ExpectedElement> expected_elements; - expected_elements.push_back(ExpectedElement::LargeBytes( - large_test_data_.size() + small_test_data_.size())); + expected_elements.push_back( + ExpectedElement::LargeBytes(std::move(expected_data))); TestCreateBlob(std::move(data), std::move(expected_elements)); } @@ -490,8 +513,7 @@ expected_elements.push_back( ExpectedElement::EmbeddedBytes(std::move(expected_data))); expected_elements.push_back(ExpectedElement::Blob(test_blob_uuid_, 0, 10)); - expected_elements.push_back( - ExpectedElement::LargeBytes(large_test_data_.size())); + expected_elements.push_back(ExpectedElement::LargeBytes(large_test_data_)); TestCreateBlob(std::move(data), std::move(expected_elements)); } @@ -503,8 +525,7 @@ data->AppendBytes(small_test_data_.data(), small_test_data_.size()); Vector<ExpectedElement> expected_elements; - expected_elements.push_back( - ExpectedElement::LargeBytes(large_test_data_.size())); + expected_elements.push_back(ExpectedElement::LargeBytes(large_test_data_)); expected_elements.push_back(ExpectedElement::Blob(test_blob_uuid_, 0, 10)); expected_elements.push_back(ExpectedElement::EmbeddedBytes(small_test_data_)); @@ -513,16 +534,17 @@ TEST_F(BlobDataHandleTest, CreateFromManyMergedBytes) { std::unique_ptr<BlobData> data = BlobData::Create(); - uint64_t merged_size = 0; - while (merged_size <= DataElementBytes::kMaximumEmbeddedDataSize) { + Vector<uint8_t> merged_data; + while (merged_data.size() <= DataElementBytes::kMaximumEmbeddedDataSize) { data->AppendBytes(medium_test_data_.data(), medium_test_data_.size()); - merged_size += medium_test_data_.size(); + merged_data.AppendVector(medium_test_data_); } data->AppendBlob(test_blob_, 0, 10); data->AppendBytes(medium_test_data_.data(), medium_test_data_.size()); Vector<ExpectedElement> expected_elements; - expected_elements.push_back(ExpectedElement::LargeBytes(merged_size)); + expected_elements.push_back( + ExpectedElement::LargeBytes(std::move(merged_data))); expected_elements.push_back(ExpectedElement::Blob(test_blob_uuid_, 0, 10)); expected_elements.push_back( ExpectedElement::EmbeddedBytes(medium_test_data_));
diff --git a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp index 974804a..df5055f 100644 --- a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp +++ b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.cpp
@@ -56,6 +56,8 @@ return "chunk reordered"; case PaintInvalidationReason::kFullLayer: return "full layer"; + case PaintInvalidationReason::kPaintProperty: + return "paint property change"; case PaintInvalidationReason::kForTesting: return "for testing"; case PaintInvalidationReason::kDelayedFull:
diff --git a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h index 38108c5..d3a3ddae 100644 --- a/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h +++ b/third_party/WebKit/Source/platform/graphics/PaintInvalidationReason.h
@@ -35,6 +35,7 @@ kChunkUncacheable, kChunkReordered, kFullLayer, + kPaintProperty, kForTesting, // kDelayedFull means that kFull is needed in order to fully paint the // content, but that painting of the object can be delayed until a future
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp index e398b5c..d6b9b47 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp
@@ -84,11 +84,10 @@ IntRect ContentLayerClientImpl::MapRasterInvalidationRectFromChunkToLayer( const FloatRect& r, - const PaintChunk& chunk, - const PropertyTreeState& layer_state) const { + const PaintChunk& chunk) const { FloatClipRect rect(r); GeometryMapper::LocalToAncestorVisualRect( - chunk.properties.property_tree_state, layer_state, rect); + chunk.properties.property_tree_state, layer_state_, rect); if (rect.Rect().IsEmpty()) return IntRect(); @@ -129,8 +128,7 @@ // larger than O(n). void ContentLayerClientImpl::GenerateRasterInvalidations( const Vector<const PaintChunk*>& new_chunks, - const Vector<PaintChunkInfo>& new_chunks_info, - const PropertyTreeState& layer_state) { + const Vector<PaintChunkInfo>& new_chunks_info) { Vector<bool> old_chunks_matched; old_chunks_matched.resize(paint_chunks_info_.size()); size_t old_index = 0; @@ -153,20 +151,24 @@ } old_chunks_matched[matched] = true; - if (matched == old_index) { - // TODO(wangxianzhu): Also fully invalidate for paint property changes. + + bool properties_changed = + new_chunk.properties != paint_chunks_info_[matched].properties || + new_chunk.properties.property_tree_state.Changed(layer_state_); + if (!properties_changed && matched == old_index) { // Add the raster invalidations found by PaintController within the chunk. - AddDisplayItemRasterInvalidations(new_chunk, layer_state); + AddDisplayItemRasterInvalidations(new_chunk); } else { - // Invalidate both old and new bounds of the chunk if the chunk is - // reordered and may expose area that was previously covered by it. + // Invalidate both old and new bounds of the chunk if the chunk's paint + // properties changed, or is moved backward and may expose area that was + // previously covered by it. const auto& old_chunks_info = paint_chunks_info_[matched]; - InvalidateRasterForOldChunk(old_chunks_info, - PaintInvalidationReason::kChunkReordered); - if (old_chunks_info.bounds_in_layer != new_chunk_info.bounds_in_layer) { - InvalidateRasterForNewChunk(new_chunk_info, - PaintInvalidationReason::kChunkReordered); - } + PaintInvalidationReason reason = + properties_changed ? PaintInvalidationReason::kPaintProperty + : PaintInvalidationReason::kChunkReordered; + InvalidateRasterForOldChunk(old_chunks_info, reason); + if (old_chunks_info.bounds_in_layer != new_chunk_info.bounds_in_layer) + InvalidateRasterForNewChunk(new_chunk_info, reason); // Ignore the display item raster invalidations because we have fully // invalidated the chunk. } @@ -189,15 +191,14 @@ } void ContentLayerClientImpl::AddDisplayItemRasterInvalidations( - const PaintChunk& chunk, - const PropertyTreeState& layer_state) { + const PaintChunk& chunk) { DCHECK(chunk.raster_invalidation_tracking.IsEmpty() || chunk.raster_invalidation_rects.size() == chunk.raster_invalidation_tracking.size()); for (size_t i = 0; i < chunk.raster_invalidation_rects.size(); ++i) { auto rect = MapRasterInvalidationRectFromChunkToLayer( - chunk.raster_invalidation_rects[i], chunk, layer_state); + chunk.raster_invalidation_rects[i], chunk); if (rect.IsEmpty()) continue; cc_picture_layer_->SetNeedsDisplayRect(rect); @@ -275,6 +276,8 @@ bool layer_bounds_was_empty = layer_bounds_.IsEmpty(); bool layer_origin_changed = layer_bounds_.origin() != layer_bounds.origin(); + bool layer_state_changed = layer_state_ != layer_state; + layer_state_ = layer_state; layer_bounds_ = layer_bounds; cc_picture_layer_->SetBounds(layer_bounds.size()); cc_picture_layer_->SetIsDrawable(true); @@ -282,10 +285,9 @@ Vector<PaintChunkInfo> new_chunks_info; new_chunks_info.ReserveCapacity(paint_chunks.size()); for (const auto* chunk : paint_chunks) { - new_chunks_info.push_back( - PaintChunkInfo(MapRasterInvalidationRectFromChunkToLayer( - chunk->bounds, *chunk, layer_state), - *chunk)); + new_chunks_info.push_back(PaintChunkInfo( + MapRasterInvalidationRectFromChunkToLayer(chunk->bounds, *chunk), + *chunk)); if (raster_invalidation_tracking_info_) { raster_invalidation_tracking_info_->new_client_debug_names.insert( &chunk->id.client, chunk->id.client.DebugName()); @@ -293,10 +295,10 @@ } if (!layer_bounds_was_empty && !layer_bounds_.IsEmpty()) { - if (layer_origin_changed) + if (layer_origin_changed || layer_state_changed) InvalidateRasterForWholeLayer(); else - GenerateRasterInvalidations(paint_chunks, new_chunks_info, layer_state); + GenerateRasterInvalidations(paint_chunks, new_chunks_info); } Optional<RasterUnderInvalidationCheckingParams> params; @@ -317,14 +319,6 @@ raster_invalidation_tracking_info_->new_client_debug_names); } - for (const auto* chunk : paint_chunks) { - // TODO(wangxianzhu): This will be unnecessary if we don't call - // PaintArtifactCompositor::Update() when paint artifact is unchanged. - chunk->client_is_just_created = false; - chunk->raster_invalidation_rects.clear(); - chunk->raster_invalidation_tracking.clear(); - } - return cc_picture_layer_; }
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h index ffd3e12..9e53067 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h
@@ -26,7 +26,8 @@ public: ContentLayerClientImpl() - : cc_picture_layer_(cc::PictureLayer::Create(this)) {} + : cc_picture_layer_(cc::PictureLayer::Create(this)), + layer_state_(nullptr, nullptr, nullptr) {} ~ContentLayerClientImpl() override {} // cc::ContentLayerClient @@ -67,7 +68,8 @@ PaintChunkInfo(const IntRect& bounds, const PaintChunk& chunk) : bounds_in_layer(bounds), id(chunk.id), - is_cacheable(chunk.is_cacheable) {} + is_cacheable(chunk.is_cacheable), + properties(chunk.properties) {} bool Matches(const PaintChunk& new_chunk) const { return is_cacheable && new_chunk.Matches(id); @@ -76,20 +78,17 @@ IntRect bounds_in_layer; PaintChunk::Id id; bool is_cacheable; + PaintChunkProperties properties; }; - IntRect MapRasterInvalidationRectFromChunkToLayer( - const FloatRect&, - const PaintChunk&, - const PropertyTreeState&) const; + IntRect MapRasterInvalidationRectFromChunkToLayer(const FloatRect&, + const PaintChunk&) const; void GenerateRasterInvalidations( const Vector<const PaintChunk*>& new_chunks, - const Vector<PaintChunkInfo>& new_chunks_info, - const PropertyTreeState&); + const Vector<PaintChunkInfo>& new_chunks_info); size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk, size_t old_index); - void AddDisplayItemRasterInvalidations(const PaintChunk&, - const PropertyTreeState&); + void AddDisplayItemRasterInvalidations(const PaintChunk&); void InvalidateRasterForNewChunk(const PaintChunkInfo&, PaintInvalidationReason); void InvalidateRasterForOldChunk(const PaintChunkInfo&, @@ -99,6 +98,7 @@ scoped_refptr<cc::PictureLayer> cc_picture_layer_; scoped_refptr<cc::DisplayItemList> cc_display_item_list_; gfx::Rect layer_bounds_; + PropertyTreeState layer_state_; Vector<PaintChunkInfo> paint_chunks_info_; Vector<std::unique_ptr<JSONArray>> paint_chunk_debug_data_;
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp index 016d8e6..04df6a0 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImplTest.cpp
@@ -240,8 +240,70 @@ } TEST_F(ContentLayerClientImplTest, RasterInvalidationPaintPropertyChange) { - // TODO(wangxianzhu): Add this test when implmenting raster invalidation on - // paint property change. + ContentLayerClientImpl c; + CHUNKS(chunks, Chunk(0), Chunk(1), Chunk(2)); + FloatRoundedRect clip_rect(-100000, -100000, 200000, 200000); + RefPtr<ClipPaintPropertyNode> clip0 = ClipPaintPropertyNode::Create( + ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), + clip_rect); + RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::Create( + clip0, TransformPaintPropertyNode::Root(), clip_rect); + + PropertyTreeState layer_state(TransformPaintPropertyNode::Root(), clip0.Get(), + EffectPaintPropertyNode::Root()); + chunks_array[0].properties = PaintChunkProperties(layer_state); + chunks_array[1].properties = PaintChunkProperties(layer_state); + chunks_array[2].properties = PaintChunkProperties( + PropertyTreeState(TransformPaintPropertyNode::Root(), clip2.Get(), + EffectPaintPropertyNode::Root())); + + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, chunks, + layer_state, false); + EXPECT_TRUE(TrackedRasterInvalidations(c).IsEmpty()); + + // Change both clip0 and clip2. + CHUNKS(new_chunks, Chunk(0), Chunk(1), Chunk(2)); + FloatRoundedRect new_clip_rect(-200000, -200000, 400000, 400000); + clip0->Update(clip0->Parent(), clip0->LocalTransformSpace(), new_clip_rect); + clip2->Update(clip2->Parent(), clip2->LocalTransformSpace(), new_clip_rect); + new_chunks_array[0].properties = chunks[0]->properties; + new_chunks_array[1].properties = chunks[1]->properties; + new_chunks_array[2].properties = chunks[2]->properties; + + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks, + layer_state, false); + const auto& invalidations = TrackedRasterInvalidations(c); + ASSERT_EQ(1u, invalidations.size()); + // Property change in the layer state should not trigger raster invalidation. + // |clip2| change should trigger raster invalidation. + ExpectChunkInvalidation(invalidations, 0, *new_chunks[2], + PaintInvalidationReason::kPaintProperty); + c.SetTracksRasterInvalidations(false); + clip2->ClearChangedToRoot(); + + // Change chunk1's properties to use a different property tree state. + CHUNKS(new_chunks1, Chunk(0), Chunk(1), Chunk(2)); + new_chunks1_array[0].properties = chunks[0]->properties; + new_chunks1_array[1].properties = chunks[2]->properties; + new_chunks1_array[2].properties = chunks[2]->properties; + + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks1, + layer_state, false); + const auto& invalidations1 = TrackedRasterInvalidations(c); + ASSERT_EQ(1u, invalidations1.size()); + ExpectChunkInvalidation(invalidations1, 0, *new_chunks1[1], + PaintInvalidationReason::kPaintProperty); + c.SetTracksRasterInvalidations(false); + + // Change of layer state invalidates the whole layer. + c.SetTracksRasterInvalidations(true); + c.UpdateCcPictureLayer(PaintArtifact(), kDefaultLayerBounds, new_chunks1, + DefaultPropertyTreeState(), false); + const auto& invalidations2 = TrackedRasterInvalidations(c); + ASSERT_EQ(1u, invalidations2.size()); + EXPECT_EQ(PaintInvalidationReason::kFullLayer, invalidations2[0].reason); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index 4f78184..034040c 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -514,6 +514,15 @@ host->property_trees()->ResetCachedData(); g_s_property_tree_sequence_number++; + + for (const auto& chunk : paint_artifact.PaintChunks()) { + chunk.properties.property_tree_state.ClearChangedToRoot(); + // TODO(wangxianzhu): This will be unnecessary if we don't call + // PaintArtifactCompositor::Update() when paint artifact is unchanged. + chunk.client_is_just_created = false; + chunk.raster_invalidation_rects.clear(); + chunk.raster_invalidation_tracking.clear(); + } } #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp index 5ef8abd..ac9a747b 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
@@ -336,11 +336,9 @@ int PropertyTreeManager::SwitchToEffectNode( const EffectPaintPropertyNode& next_effect) { - const EffectPaintPropertyNode* ancestor = - GeometryMapper::LowestCommonAncestor(CurrentEffectNode(), &next_effect); - DCHECK(ancestor) << "Malformed effect tree. All nodes must be descendant of " - "EffectPaintPropertyNode::root()."; - while (CurrentEffectNode() != ancestor) + const auto& ancestor = + LowestCommonAncestor(*CurrentEffectNode(), next_effect); + while (CurrentEffectNode() != &ancestor) effect_stack_.pop_back(); // Now the current effect is the lowest common ancestor of previous effect
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h index afbb61d..12f3e1e 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h
@@ -51,6 +51,7 @@ clip_rect == clip_rect_) return parent_changed; + SetChanged(); local_transform_space_ = std::move(local_transform_space); clip_rect_ = clip_rect; return true;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h index de68bcb..d3c4001 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h
@@ -69,6 +69,7 @@ paint_offset == paint_offset_) return parent_changed; + SetChanged(); local_transform_space_ = std::move(local_transform_space); output_clip_ = std::move(output_clip); color_filter_ = color_filter;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp index 0d93b3a..1df57ef 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
@@ -320,61 +320,4 @@ GeometryMapperClipCache::ClearCache(); } -namespace { - -template <typename NodeType> -unsigned NodeDepth(const NodeType* node) { - unsigned depth = 0; - while (node) { - depth++; - node = node->Parent(); - } - return depth; -} - -} // namespace - -template <typename NodeType> -const NodeType* GeometryMapper::LowestCommonAncestor(const NodeType* a, - const NodeType* b) { - // Measure both depths. - unsigned depth_a = NodeDepth(a); - unsigned depth_b = NodeDepth(b); - - // Make it so depthA >= depthB. - if (depth_a < depth_b) { - std::swap(a, b); - std::swap(depth_a, depth_b); - } - - // Make it so depthA == depthB. - while (depth_a > depth_b) { - a = a->Parent(); - depth_a--; - } - - // Walk up until we find the ancestor. - while (a != b) { - a = a->Parent(); - b = b->Parent(); - } - return a; -} - -// Explicitly instantiate the template for all supported types. This allows -// placing the template implementation in this .cpp file. See -// http://stackoverflow.com/a/488989 for more. -template PLATFORM_EXPORT const EffectPaintPropertyNode* -GeometryMapper::LowestCommonAncestor(const EffectPaintPropertyNode*, - const EffectPaintPropertyNode*); -template PLATFORM_EXPORT const TransformPaintPropertyNode* -GeometryMapper::LowestCommonAncestor(const TransformPaintPropertyNode*, - const TransformPaintPropertyNode*); -template PLATFORM_EXPORT const ClipPaintPropertyNode* -GeometryMapper::LowestCommonAncestor(const ClipPaintPropertyNode*, - const ClipPaintPropertyNode*); -template PLATFORM_EXPORT const ScrollPaintPropertyNode* -GeometryMapper::LowestCommonAncestor(const ScrollPaintPropertyNode*, - const ScrollPaintPropertyNode*); - } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h index 200ca82b..794202f 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h
@@ -91,11 +91,6 @@ const PropertyTreeState& ancestor_state, FloatClipRect& mapping_rect); - // Returns the lowest common ancestor in the paint property tree. - template <typename NodeType> - static PLATFORM_EXPORT const NodeType* LowestCommonAncestor(const NodeType*, - const NodeType*); - static void ClearCache(); private:
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp index d809cb7..2e7278b 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -34,12 +34,6 @@ return descendant_clip->GetClipCache().GetCachedClip(clip_and_transform); } - const TransformPaintPropertyNode* LowestCommonAncestor( - const TransformPaintPropertyNode* a, - const TransformPaintPropertyNode* b) { - return GeometryMapper::LowestCommonAncestor(a, b); - } - void LocalToAncestorVisualRectInternal( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, @@ -683,42 +677,6 @@ EXPECT_RECT_EQ(FloatRect(20, -40, 40, 30), float_clip_rect.Rect()); } -TEST_P(GeometryMapperTest, LowestCommonAncestor) { - TransformationMatrix matrix; - RefPtr<TransformPaintPropertyNode> child1 = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - matrix, FloatPoint3D()); - RefPtr<TransformPaintPropertyNode> child2 = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - matrix, FloatPoint3D()); - - RefPtr<TransformPaintPropertyNode> child_of_child1 = - TransformPaintPropertyNode::Create(child1, matrix, FloatPoint3D()); - RefPtr<TransformPaintPropertyNode> child_of_child2 = - TransformPaintPropertyNode::Create(child2, matrix, FloatPoint3D()); - - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child_of_child1.Get(), child_of_child2.Get())); - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child_of_child1.Get(), child2.Get())); - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child_of_child1.Get(), - TransformPaintPropertyNode::Root())); - EXPECT_EQ(child1, LowestCommonAncestor(child_of_child1.Get(), child1.Get())); - - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child_of_child2.Get(), child_of_child1.Get())); - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child_of_child2.Get(), child1.Get())); - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child_of_child2.Get(), - TransformPaintPropertyNode::Root())); - EXPECT_EQ(child2, LowestCommonAncestor(child_of_child2.Get(), child2.Get())); - - EXPECT_EQ(TransformPaintPropertyNode::Root(), - LowestCommonAncestor(child1.Get(), child2.Get())); -} - TEST_P(GeometryMapperTest, FilterWithClipsAndTransforms) { RefPtr<TransformPaintPropertyNode> transform_above_effect = TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(),
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp new file mode 100644 index 0000000..dc278f1 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp
@@ -0,0 +1,83 @@ +// 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 "PaintPropertyNode.h" + +#include "ClipPaintPropertyNode.h" +#include "EffectPaintPropertyNode.h" +#include "ScrollPaintPropertyNode.h" +#include "TransformPaintPropertyNode.h" + +namespace blink { + +namespace { + +template <typename NodeType> +unsigned NodeDepth(const NodeType& node) { + unsigned depth = 0; + for (const NodeType* n = &node; n; n = n->Parent()) + depth++; + return depth; +} + +template <typename NodeType> +const NodeType& LowestCommonAncestorTemplate(const NodeType& a, + const NodeType& b) { + // Measure both depths. + unsigned depth_a = NodeDepth(a); + unsigned depth_b = NodeDepth(b); + + const auto* a_ptr = &a; + const auto* b_ptr = &b; + + // Make it so depthA >= depthB. + if (depth_a < depth_b) { + std::swap(a_ptr, b_ptr); + std::swap(depth_a, depth_b); + } + + // Make it so depthA == depthB. + while (depth_a > depth_b) { + a_ptr = a_ptr->Parent(); + depth_a--; + } + + // Walk up until we find the ancestor. + while (a_ptr != b_ptr) { + a_ptr = a_ptr->Parent(); + b_ptr = b_ptr->Parent(); + } + + DCHECK(a_ptr) << "Malformed property tree. All nodes must be descendant of " + "the same root."; + return *a_ptr; +} + +} // namespace + +const TransformPaintPropertyNode& LowestCommonAncestor( + const TransformPaintPropertyNode& a, + const TransformPaintPropertyNode& b) { + return LowestCommonAncestorTemplate(a, b); +} + +const ClipPaintPropertyNode& LowestCommonAncestor( + const ClipPaintPropertyNode& a, + const ClipPaintPropertyNode& b) { + return LowestCommonAncestorTemplate(a, b); +} + +const EffectPaintPropertyNode& LowestCommonAncestor( + const EffectPaintPropertyNode& a, + const EffectPaintPropertyNode& b) { + return LowestCommonAncestorTemplate(a, b); +} + +const ScrollPaintPropertyNode& LowestCommonAncestor( + const ScrollPaintPropertyNode& a, + const ScrollPaintPropertyNode& b) { + return LowestCommonAncestorTemplate(a, b); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h index daf0137..544a12aa 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h
@@ -5,12 +5,32 @@ #ifndef PaintPropertyNode_h #define PaintPropertyNode_h +#include "platform/PlatformExport.h" #include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefCounted.h" #include "platform/wtf/RefPtr.h" namespace blink { +class ClipPaintPropertyNode; +class EffectPaintPropertyNode; +class ScrollPaintPropertyNode; +class TransformPaintPropertyNode; + +// Returns the lowest common ancestor in the paint property tree. +PLATFORM_EXPORT const ClipPaintPropertyNode& LowestCommonAncestor( + const ClipPaintPropertyNode&, + const ClipPaintPropertyNode&); +PLATFORM_EXPORT const EffectPaintPropertyNode& LowestCommonAncestor( + const EffectPaintPropertyNode&, + const EffectPaintPropertyNode&); +PLATFORM_EXPORT const ScrollPaintPropertyNode& LowestCommonAncestor( + const ScrollPaintPropertyNode&, + const ScrollPaintPropertyNode&); +PLATFORM_EXPORT const TransformPaintPropertyNode& LowestCommonAncestor( + const TransformPaintPropertyNode&, + const TransformPaintPropertyNode&); + template <typename NodeType> class PaintPropertyNode : public RefCounted<NodeType> { public: @@ -18,9 +38,38 @@ const NodeType* Parent() const { return parent_.Get(); } bool IsRoot() const { return !parent_; } + // TODO(wangxianzhu): Changed() and ClearChangedToRoot() are inefficient + // due to the tree walks. Optimize this if this affects overall performance. + + // Returns true if any node (excluding the lowest common ancestor of + // |relative_to_node| and |this|) is marked changed along the shortest path + // from |this| to |relative_to_node|. + bool Changed(const NodeType& relative_to_node) const { + if (this == &relative_to_node) + return false; + + bool changed = false; + for (const auto* n = this; n; n = n->Parent()) { + if (n == &relative_to_node) + return changed; + if (n->changed_) + changed = true; + } + + // We reach here if |relative_to_node| is not an ancestor of |this|. + const auto& lca = LowestCommonAncestor(static_cast<const NodeType&>(*this), + relative_to_node); + return Changed(lca) || relative_to_node.Changed(lca); + } + + void ClearChangedToRoot() const { + for (auto* n = this; n; n = n->Parent()) + n->changed_ = false; + } + protected: PaintPropertyNode(PassRefPtr<const NodeType> parent) - : parent_(std::move(parent)) {} + : parent_(std::move(parent)), changed_(false) {} bool Update(PassRefPtr<const NodeType> parent) { DCHECK(!IsRoot()); @@ -28,12 +77,16 @@ if (parent == parent_) return false; + SetChanged(); parent_ = std::move(parent); return true; } + void SetChanged() { changed_ = true; } + private: RefPtr<const NodeType> parent_; + mutable bool changed_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNodeTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNodeTest.cpp new file mode 100644 index 0000000..9ced6ef --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNodeTest.cpp
@@ -0,0 +1,134 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by node BSD-style license that can be +// found in the LICENSE file. + +#include "platform/graphics/paint/PaintPropertyNode.h" + +#include "platform/geometry/FloatRoundedRect.h" +#include "platform/graphics/paint/ClipPaintPropertyNode.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class PaintPropertyNodeTest : public ::testing::Test { + protected: + void SetUp() override { + root = ClipPaintPropertyNode::Root(); + node = ClipPaintPropertyNode::Create(root, nullptr, FloatRoundedRect()); + child1 = ClipPaintPropertyNode::Create(node, nullptr, FloatRoundedRect()); + child2 = ClipPaintPropertyNode::Create(node, nullptr, FloatRoundedRect()); + grandchild1 = + ClipPaintPropertyNode::Create(child1, nullptr, FloatRoundedRect()); + grandchild2 = + ClipPaintPropertyNode::Create(child2, nullptr, FloatRoundedRect()); + + // root + // | + // node + // / \ + // child1 child2 + // | | + // grandchild1 grandchild2 + } + + void ResetAllChanged() { + grandchild1->ClearChangedToRoot(); + grandchild2->ClearChangedToRoot(); + } + + void ExpectInitialState() { + EXPECT_FALSE(root->Changed(*root)); + EXPECT_FALSE(node->Changed(*root)); + EXPECT_FALSE(child1->Changed(*root)); + EXPECT_FALSE(child2->Changed(*root)); + EXPECT_FALSE(grandchild1->Changed(*root)); + EXPECT_FALSE(grandchild2->Changed(*root)); + } + + RefPtr<ClipPaintPropertyNode> root; + RefPtr<ClipPaintPropertyNode> node; + RefPtr<ClipPaintPropertyNode> child1; + RefPtr<ClipPaintPropertyNode> child2; + RefPtr<ClipPaintPropertyNode> grandchild1; + RefPtr<ClipPaintPropertyNode> grandchild2; +}; + +TEST_F(PaintPropertyNodeTest, LowestCommonAncestor) { + EXPECT_EQ(node, &LowestCommonAncestor(*node, *node)); + EXPECT_EQ(root, &LowestCommonAncestor(*root, *root)); + + EXPECT_EQ(node, &LowestCommonAncestor(*grandchild1, *grandchild2)); + EXPECT_EQ(node, &LowestCommonAncestor(*grandchild1, *child2)); + EXPECT_EQ(root, &LowestCommonAncestor(*grandchild1, *root)); + EXPECT_EQ(child1, &LowestCommonAncestor(*grandchild1, *child1)); + + EXPECT_EQ(node, &LowestCommonAncestor(*grandchild2, *grandchild1)); + EXPECT_EQ(node, &LowestCommonAncestor(*grandchild2, *child1)); + EXPECT_EQ(root, &LowestCommonAncestor(*grandchild2, *root)); + EXPECT_EQ(child2, &LowestCommonAncestor(*grandchild2, *child2)); + + EXPECT_EQ(node, &LowestCommonAncestor(*child1, *child2)); + EXPECT_EQ(node, &LowestCommonAncestor(*child2, *child1)); +} + +TEST_F(PaintPropertyNodeTest, InitialStateAndReset) { + ExpectInitialState(); + ResetAllChanged(); + ExpectInitialState(); +} + +TEST_F(PaintPropertyNodeTest, ChangeNode) { + node->Update(root, nullptr, FloatRoundedRect(1, 2, 3, 4)); + EXPECT_TRUE(node->Changed(*root)); + EXPECT_FALSE(node->Changed(*node)); + EXPECT_TRUE(child1->Changed(*root)); + EXPECT_FALSE(child1->Changed(*node)); + EXPECT_TRUE(grandchild1->Changed(*root)); + EXPECT_FALSE(grandchild1->Changed(*node)); + + EXPECT_FALSE(grandchild1->Changed(*child2)); + EXPECT_FALSE(grandchild1->Changed(*grandchild2)); + + ResetAllChanged(); + ExpectInitialState(); +} + +TEST_F(PaintPropertyNodeTest, ChangeOneChild) { + child1->Update(node, nullptr, FloatRoundedRect(1, 2, 3, 4)); + EXPECT_FALSE(node->Changed(*root)); + EXPECT_FALSE(node->Changed(*node)); + EXPECT_TRUE(child1->Changed(*root)); + EXPECT_TRUE(child1->Changed(*node)); + EXPECT_TRUE(grandchild1->Changed(*node)); + EXPECT_FALSE(grandchild1->Changed(*child1)); + EXPECT_FALSE(child2->Changed(*node)); + EXPECT_FALSE(grandchild2->Changed(*node)); + + EXPECT_TRUE(child2->Changed(*child1)); + EXPECT_TRUE(child1->Changed(*child2)); + EXPECT_TRUE(child2->Changed(*grandchild1)); + EXPECT_TRUE(child1->Changed(*grandchild2)); + EXPECT_TRUE(grandchild1->Changed(*child2)); + EXPECT_TRUE(grandchild1->Changed(*grandchild2)); + EXPECT_TRUE(grandchild2->Changed(*child1)); + EXPECT_TRUE(grandchild2->Changed(*grandchild1)); + + ResetAllChanged(); + ExpectInitialState(); +} + +TEST_F(PaintPropertyNodeTest, Reparent) { + child1->Update(child2, nullptr, FloatRoundedRect(1, 2, 3, 4)); + EXPECT_FALSE(node->Changed(*root)); + EXPECT_TRUE(child1->Changed(*node)); + EXPECT_TRUE(child1->Changed(*child2)); + EXPECT_FALSE(child2->Changed(*node)); + EXPECT_TRUE(grandchild1->Changed(*node)); + EXPECT_FALSE(grandchild1->Changed(*child1)); + EXPECT_TRUE(grandchild1->Changed(*child2)); + + ResetAllChanged(); + ExpectInitialState(); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeState.h b/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeState.h index 01ee2d9f..674e8ec 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeState.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeState.h
@@ -15,9 +15,7 @@ namespace blink { // A complete set of paint properties including those that are inherited from -// other objects. RefPtrs are used to guard against use-after-free bugs and -// DCHECKs ensure PropertyTreeState never retains the last reference to a -// property tree node. +// other objects. RefPtrs are used to guard against use-after-free bugs. class PLATFORM_EXPORT PropertyTreeState { USING_FAST_MALLOC(PropertyTreeState); @@ -25,16 +23,11 @@ PropertyTreeState(const TransformPaintPropertyNode* transform, const ClipPaintPropertyNode* clip, const EffectPaintPropertyNode* effect) - : transform_(transform), clip_(clip), effect_(effect) { - DCHECK(!transform_ || !transform_->HasOneRef()); - DCHECK(!clip_ || !clip_->HasOneRef()); - DCHECK(!effect_ || !effect_->HasOneRef()); - } + : transform_(transform), clip_(clip), effect_(effect) {} bool HasDirectCompositingReasons() const; const TransformPaintPropertyNode* Transform() const { - DCHECK(!transform_ || !transform_->HasOneRef()); return transform_.Get(); } void SetTransform(RefPtr<const TransformPaintPropertyNode> node) { @@ -42,7 +35,6 @@ } const ClipPaintPropertyNode* Clip() const { - DCHECK(!clip_ || !clip_->HasOneRef()); return clip_.Get(); } void SetClip(RefPtr<const ClipPaintPropertyNode> node) { @@ -50,7 +42,6 @@ } const EffectPaintPropertyNode* Effect() const { - DCHECK(!effect_ || !effect_->HasOneRef()); return effect_.Get(); } void SetEffect(RefPtr<const EffectPaintPropertyNode> node) { @@ -109,6 +100,19 @@ // DCHECK(iterator.next()->innermostNode() == None); InnermostNode GetInnermostNode() const; + // See PaintPropertyNode::Changed(). + bool Changed(const PropertyTreeState& relative_to_state) const { + return Transform()->Changed(*relative_to_state.Transform()) || + Clip()->Changed(*relative_to_state.Clip()) || + Effect()->Changed(*relative_to_state.Effect()); + } + + void ClearChangedToRoot() const { + Transform()->ClearChangedToRoot(); + Clip()->ClearChangedToRoot(); + Effect()->ClearChangedToRoot(); + } + #if DCHECK_IS_ON() // Dumps the tree from this state up to the root as a string. String ToTreeString() const;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h index b7f54b2..71f872e 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h
@@ -66,6 +66,7 @@ scroll_client == scroll_client_) return parent_changed; + SetChanged(); clip_ = clip; bounds_ = bounds; user_scrollable_horizontal_ = user_scrollable_horizontal;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h index 3ef5f37..a88fd62d 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h
@@ -92,6 +92,7 @@ compositor_element_id == compositor_element_id_) return parent_changed; + SetChanged(); matrix_ = matrix; origin_ = origin; flattens_inherited_transform_ = flattens_inherited_transform;
diff --git a/third_party/WebKit/Source/platform/loader/BUILD.gn b/third_party/WebKit/Source/platform/loader/BUILD.gn index 46aa3fa2..f9be0b0 100644 --- a/third_party/WebKit/Source/platform/loader/BUILD.gn +++ b/third_party/WebKit/Source/platform/loader/BUILD.gn
@@ -125,6 +125,7 @@ "fetch/RawResourceTest.cpp", "fetch/ResourceFetcherTest.cpp", "fetch/ResourceLoaderOptionsTest.cpp", + "fetch/ResourceLoaderTest.cpp", "fetch/ResourceRequestTest.cpp", "fetch/ResourceTest.cpp", ]
diff --git a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp index f8b5533..0917b5a 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
@@ -311,7 +311,7 @@ return false; } - return true; + return Resource::CanReuse(new_fetch_parameters); } RawResourceClientStateChecker::RawResourceClientStateChecker()
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp index f193cff..1a32242 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
@@ -423,33 +423,6 @@ return GetResponse().HttpContentType(); } -bool Resource::PassesAccessControlCheck( - const SecurityOrigin* security_origin) const { - CrossOriginAccessControl::AccessStatus status = - CrossOriginAccessControl::CheckAccess( - GetResponse(), LastResourceRequest().GetFetchCredentialsMode(), - security_origin); - - return status == CrossOriginAccessControl::kAccessAllowed; -} - -bool Resource::IsEligibleForIntegrityCheck( - SecurityOrigin* security_origin) const { - // Service workers do separate CORS checks. We need to check for opaque - // responses even if the response would otherwise be same origin. - if (GetResponse().WasFetchedViaServiceWorker()) { - return GetResponse().ServiceWorkerResponseType() != - kWebServiceWorkerResponseTypeOpaque; - } - - // Same origin, no CORS checks needed: - if (security_origin->CanRequest(GetResourceRequest().Url())) - return true; - - // Perform standard CORS check: - return PassesAccessControlCheck(security_origin); -} - void Resource::SetIntegrityDisposition( ResourceIntegrityDisposition disposition) { DCHECK_NE(disposition, ResourceIntegrityDisposition::kNotChecked); @@ -851,6 +824,77 @@ DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled); } +bool Resource::CanReuse(const FetchParameters& params) const { + const ResourceRequest& new_request = params.GetResourceRequest(); + const ResourceLoaderOptions& new_options = params.Options(); + + // Certain requests (e.g., XHRs) might have manually set headers that require + // revalidation. In theory, this should be a Revalidate case. In practice, the + // MemoryCache revalidation path assumes a whole bunch of things about how + // revalidation works that manual headers violate, so punt to Reload instead. + // + // Similarly, a request with manually added revalidation headers can lead to a + // 304 response for a request that wasn't flagged as a revalidation attempt. + // Normally, successful revalidation will maintain the original response's + // status code, but for a manual revalidation the response code remains 304. + // In this case, the Resource likely has insufficient context to provide a + // useful cache hit or revalidation. See http://crbug.com/643659 + if (new_request.IsConditional() || response_.HttpStatusCode() == 304) + return false; + + // Answers the question "can a separate request with different options be + // re-used" (e.g. preload request). The safe (but possibly slow) answer is + // always false. + // + // Data buffering policy differences are believed to be safe for re-use. + // + // TODO: Check content_security_policy_option. + // + // initiator_info is purely informational and should be benign for re-use. + // + // request_initiator_context is benign (indicates document vs. worker). + + if (new_options.synchronous_policy != options_.synchronous_policy) + return false; + + if (resource_request_.GetKeepalive() || new_request.GetKeepalive()) { + return false; + } + + // securityOrigin has more complicated checks which callers are responsible + // for. + + // TODO(yhirano): Clean up this condition. This is generated to keep the old + // behavior across refactoring. + // + // TODO(tyoshino): Consider returning false when the credentials mode + // differs. + + bool new_is_with_fetcher_cors_suppressed = + new_options.cors_handling_by_resource_fetcher == + kDisableCORSHandlingByResourceFetcher; + bool existing_was_with_fetcher_cors_suppressed = + options_.cors_handling_by_resource_fetcher == + kDisableCORSHandlingByResourceFetcher; + + bool new_is_with_cors_mode = + new_request.GetFetchRequestMode() == WebURLRequest::kFetchRequestModeCORS; + bool existing_was_with_cors_mode = resource_request_.GetFetchRequestMode() == + WebURLRequest::kFetchRequestModeCORS; + + if (new_is_with_fetcher_cors_suppressed) { + if (existing_was_with_fetcher_cors_suppressed) + return true; + + return !existing_was_with_cors_mode; + } + + if (existing_was_with_fetcher_cors_suppressed) + return !new_is_with_cors_mode; + + return new_is_with_cors_mode == existing_was_with_cors_mode; +} + void Resource::Prune() { DestroyDecodedDataIfPossible(); }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.h b/third_party/WebKit/Source/platform/loader/fetch/Resource.h index 4df41221..cc906cd 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.h +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.h
@@ -47,6 +47,7 @@ #include "platform/wtf/text/AtomicString.h" #include "platform/wtf/text/TextEncoding.h" #include "platform/wtf/text/WTFString.h" +#include "public/platform/CORSStatus.h" #include "public/platform/WebDataConsumerHandle.h" namespace blink { @@ -110,7 +111,6 @@ virtual WTF::TextEncoding Encoding() const { return WTF::TextEncoding(); } virtual void AppendData(const char*, size_t); virtual void FinishAsError(const ResourceError&); - virtual void SetCORSFailed() {} void SetNeedsSynchronousCacheHit(bool needs_synchronous_cache_hit) { needs_synchronous_cache_hit_ = needs_synchronous_cache_hit; @@ -202,7 +202,6 @@ void SetLoader(ResourceLoader*); ResourceLoader* Loader() const { return loader_.Get(); } - virtual bool IsImage() const { return false; } bool ShouldBlockLoadEvent() const; bool IsLoadEventBlockingResourceType() const; @@ -211,8 +210,6 @@ virtual void Finish(double finish_time); void Finish() { Finish(0.0); } - bool PassesAccessControlCheck(const SecurityOrigin*) const; - virtual RefPtr<const SharedBuffer> ResourceBuffer() const { return data_; } void SetResourceBuffer(RefPtr<SharedBuffer>); @@ -270,8 +267,6 @@ bool HasCacheControlNoStoreHeader() const; bool MustReloadDueToVaryHeader(const ResourceRequest& new_request) const; - bool IsEligibleForIntegrityCheck(SecurityOrigin*) const; - void SetIntegrityMetadata(const IntegrityMetadataSet& metadata) { integrity_metadata_ = metadata; } @@ -287,6 +282,14 @@ bool IsAlive() const { return is_alive_; } + CORSStatus GetCORSStatus() const { return cors_status_; } + + bool IsSameOriginOrCORSSuccessful() const { + return cors_status_ == CORSStatus::kSameOrigin || + cors_status_ == CORSStatus::kSuccessful || + cors_status_ == CORSStatus::kServiceWorkerSuccessful; + } + void SetCacheIdentifier(const String& cache_identifier) { cache_identifier_ = cache_identifier; } @@ -308,7 +311,7 @@ response_.SetDecodedBodyLength(value); } - virtual bool CanReuse(const FetchParameters&) const { return true; } + virtual bool CanReuse(const FetchParameters&) const; // If cache-aware loading is activated, this callback is called when the first // disk-cache-only request failed due to cache miss. After this callback, @@ -420,6 +423,10 @@ virtual void SetEncoding(const String&) {} private: + // To allow access to SetCORSStatus + friend class ResourceLoader; + friend class SubresourceIntegrityTest; + class CachedMetadataHandlerImpl; class ServiceWorkerResponseCachedMetadataHandler; @@ -432,12 +439,17 @@ String ReasonNotDeletable() const; + void SetCORSStatus(const CORSStatus cors_status) { + cors_status_ = cors_status; + } + // MemoryCoordinatorClient overrides: void OnPurgeMemory() override; PreloadResult preload_result_; Type type_; ResourceStatus status_; + CORSStatus cors_status_; Member<CachedMetadataHandlerImpl> cache_handler_; RefPtr<SecurityOrigin> fetcher_security_origin_;
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp index 3af6858..d689dd24 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -311,7 +311,8 @@ // preload. if (resource->GetType() == Resource::kFont && !params.IsLinkPreload()) return false; - if (resource->IsImage() && ShouldDeferImageLoad(resource->Url())) + if (resource->GetType() == Resource::kImage && + ShouldDeferImageLoad(resource->Url())) return false; return policy != kUse || resource->StillNeedsLoad(); } @@ -952,6 +953,7 @@ Resource* existing_resource, bool is_static_data) const { const ResourceRequest& request = params.GetResourceRequest(); + // Do not load from cache if images are not enabled. There are two general // cases: // @@ -966,7 +968,7 @@ // but not m_autoLoadImages, in order to allow for this differing behavior. // // TODO(japhet): Can we get rid of one of these settings? - if (existing_resource->IsImage() && + if (existing_resource->GetType() == Resource::kImage && !Context().AllowImage(images_enabled_, existing_resource->Url())) { return false; } @@ -986,84 +988,10 @@ return false; } - if (!is_static_data && !existing_resource->CanReuse(params)) - return false; - - // Certain requests (e.g., XHRs) might have manually set headers that require - // revalidation. In theory, this should be a Revalidate case. In practice, the - // MemoryCache revalidation path assumes a whole bunch of things about how - // revalidation works that manual headers violate, so punt to Reload instead. - // - // Similarly, a request with manually added revalidation headers can lead to a - // 304 response for a request that wasn't flagged as a revalidation attempt. - // Normally, successful revalidation will maintain the original response's - // status code, but for a manual revalidation the response code remains 304. - // In this case, the Resource likely has insufficient context to provide a - // useful cache hit or revalidation. See http://crbug.com/643659 - if (!is_static_data && - (request.IsConditional() || - existing_resource->GetResponse().HttpStatusCode() == 304)) { - return false; - } - if (is_static_data) return true; - // Answers the question "can a separate request with different options be - // re-used" (e.g. preload request). The safe (but possibly slow) answer is - // always false. - // - // Data buffering policy differences are believed to be safe for re-use. - // - // TODO: Check content_security_policy_option. - // - // initiator_info is purely informational and should be benign for re-use. - // - // request_initiator_context is benign (indicates document vs. worker). - - if (params.Options().synchronous_policy != - existing_resource->Options().synchronous_policy) - return false; - - if (existing_resource->GetResourceRequest().GetKeepalive() || - params.GetResourceRequest().GetKeepalive()) { - return false; - } - - // securityOrigin has more complicated checks which callers are responsible - // for. - - // TODO(yhirano): Clean up this condition. This is generated to keep the old - // behavior across refactoring. - // - // TODO(tyoshino): Consider returning false when the credentials mode - // differs. - - bool new_is_with_fetcher_cors_suppressed = - params.Options().cors_handling_by_resource_fetcher == - kDisableCORSHandlingByResourceFetcher; - bool existing_was_with_fetcher_cors_suppressed = - existing_resource->Options().cors_handling_by_resource_fetcher == - kDisableCORSHandlingByResourceFetcher; - - bool new_is_with_cors_mode = - params.GetResourceRequest().GetFetchRequestMode() == - WebURLRequest::kFetchRequestModeCORS; - bool existing_was_with_cors_mode = - existing_resource->GetResourceRequest().GetFetchRequestMode() == - WebURLRequest::kFetchRequestModeCORS; - - if (new_is_with_fetcher_cors_suppressed) { - if (existing_was_with_fetcher_cors_suppressed) - return true; - - return !existing_was_with_cors_mode; - } - - if (existing_was_with_fetcher_cors_suppressed) - return !new_is_with_cors_mode; - - return new_is_with_cors_mode == existing_was_with_cors_mode; + return existing_resource->CanReuse(params); } ResourceFetcher::RevalidationPolicy @@ -1556,7 +1484,8 @@ "ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities"); for (const auto& document_resource : document_resources_) { Resource* resource = document_resource.value.Get(); - if (!resource || !resource->IsImage() || !resource->IsLoading()) + if (!resource || resource->GetType() != Resource::kImage || + !resource->IsLoading()) continue; ResourcePriority resource_priority = resource->PriorityFromObservers();
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp index 43b2095..854cfd3 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
@@ -201,7 +201,7 @@ source_origin, new_request, redirect_response, resource_->GetResourceRequest().GetFetchCredentialsMode(), resource_->MutableOptions(), error_message)) { - resource_->SetCORSFailed(); + resource_->SetCORSStatus(CORSStatus::kFailed); Context().AddConsoleMessage(error_message); CancelForRedirectAccessCheckError(new_request.Url(), ResourceRequestBlockedReason::kOther); @@ -282,7 +282,8 @@ ResourceRequestBlockedReason ResourceLoader::CanAccessResponse( Resource* resource, - const ResourceResponse& response) const { + const ResourceResponse& response, + const String& cors_error_message) const { // Redirects can change the response URL different from one of request. bool unused_preload = resource->IsUnusedPreload(); ResourceRequestBlockedReason blocked_reason = Context().CanRequest( @@ -295,46 +296,84 @@ if (blocked_reason != ResourceRequestBlockedReason::kNone) return blocked_reason; - SecurityOrigin* source_origin = resource->Options().security_origin.Get(); + if (resource->IsSameOriginOrCORSSuccessful()) + return ResourceRequestBlockedReason::kNone; + + if (!resource_->IsUnusedPreload()) + Context().AddConsoleMessage(cors_error_message); + + return ResourceRequestBlockedReason::kOther; +} + +CORSStatus ResourceLoader::DetermineCORSStatus(const ResourceResponse& response, + StringBuilder& error_msg) const { + // Service workers handle CORS separately. + if (response.WasFetchedViaServiceWorker()) { + switch (response.ServiceWorkerResponseType()) { + case kWebServiceWorkerResponseTypeBasic: + case kWebServiceWorkerResponseTypeCORS: + case kWebServiceWorkerResponseTypeDefault: + case kWebServiceWorkerResponseTypeError: + return CORSStatus::kServiceWorkerSuccessful; + case kWebServiceWorkerResponseTypeOpaque: + case kWebServiceWorkerResponseTypeOpaqueRedirect: + return CORSStatus::kServiceWorkerOpaque; + break; + default: + NOTREACHED(); + } + } + + if (resource_->GetType() == Resource::Type::kMainResource) + return CORSStatus::kNotApplicable; + + SecurityOrigin* source_origin = resource_->Options().security_origin.Get(); + if (!source_origin) source_origin = Context().GetSecurityOrigin(); + DCHECK(source_origin); + if (source_origin->CanRequestNoSuborigin(response.Url())) - return ResourceRequestBlockedReason::kNone; + return CORSStatus::kSameOrigin; + + if (resource_->Options().cors_handling_by_resource_fetcher != + kEnableCORSHandlingByResourceFetcher || + resource_->GetResourceRequest().GetFetchRequestMode() != + WebURLRequest::kFetchRequestModeCORS) + return CORSStatus::kNotApplicable; // Use the original response instead of the 304 response for a successful - // revaldiation. + // revalidation. const ResourceResponse& response_for_access_control = - (resource->IsCacheValidator() && response.HttpStatusCode() == 304) - ? resource->GetResponse() + (resource_->IsCacheValidator() && response.HttpStatusCode() == 304) + ? resource_->GetResponse() : response; CrossOriginAccessControl::AccessStatus cors_status = CrossOriginAccessControl::CheckAccess( response_for_access_control, - resource->GetResourceRequest().GetFetchCredentialsMode(), + resource_->LastResourceRequest().GetFetchCredentialsMode(), source_origin); - if (cors_status != CrossOriginAccessControl::kAccessAllowed) { - resource->SetCORSFailed(); - if (!unused_preload) { - String resource_type = Resource::ResourceTypeToString( - resource->GetType(), resource->Options().initiator_info.name); - StringBuilder builder; - builder.Append("Access to "); - builder.Append(resource_type); - builder.Append(" at '"); - builder.Append(response.Url().GetString()); - builder.Append("' from origin '"); - builder.Append(source_origin->ToString()); - builder.Append("' has been blocked by CORS policy: "); - CrossOriginAccessControl::AccessControlErrorString( - builder, cors_status, response_for_access_control, source_origin, - resource->LastResourceRequest().GetRequestContext()); - Context().AddConsoleMessage(builder.ToString()); - } - return ResourceRequestBlockedReason::kOther; - } - return ResourceRequestBlockedReason::kNone; + + if (cors_status == CrossOriginAccessControl::AccessStatus::kAccessAllowed) + return CORSStatus::kSuccessful; + + String resource_type = Resource::ResourceTypeToString( + resource_->GetType(), resource_->Options().initiator_info.name); + error_msg.Append("Access to "); + error_msg.Append(resource_type); + error_msg.Append(" at '"); + error_msg.Append(response.Url().GetString()); + error_msg.Append("' from origin '"); + error_msg.Append(source_origin->ToString()); + error_msg.Append("' has been blocked by CORS policy: "); + + CrossOriginAccessControl::AccessControlErrorString( + error_msg, cors_status, response_for_access_control, source_origin, + resource_->LastResourceRequest().GetRequestContext()); + + return CORSStatus::kFailed; } void ResourceLoader::DidReceiveResponse( @@ -344,6 +383,11 @@ const ResourceResponse& response = web_url_response.ToResourceResponse(); + // Later, CORS results should already be in the response we get from the + // browser at this point. + StringBuilder cors_error_msg; + resource_->SetCORSStatus(DetermineCORSStatus(response, cors_error_msg)); + if (response.WasFetchedViaServiceWorker()) { if (resource_->Options().cors_handling_by_resource_fetcher == kEnableCORSHandlingByResourceFetcher && @@ -390,7 +434,7 @@ resource_->GetResourceRequest().GetFetchRequestMode() == WebURLRequest::kFetchRequestModeCORS) { ResourceRequestBlockedReason blocked_reason = - CanAccessResponse(resource_, response); + CanAccessResponse(resource_, response, cors_error_msg.ToString()); if (blocked_reason != ResourceRequestBlockedReason::kNone) { HandleError(ResourceError::CancelledDueToAccessCheckError( response.Url(), blocked_reason));
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h index d887df5..9657e306 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h
@@ -30,9 +30,12 @@ #define ResourceLoader_h #include <memory> +#include "base/gtest_prod_util.h" #include "platform/PlatformExport.h" #include "platform/heap/Handle.h" #include "platform/heap/SelfKeepAlive.h" +#include "platform/loader/fetch/CrossOriginAccessControl.h" +#include "platform/loader/fetch/Resource.h" #include "platform/loader/fetch/ResourceLoaderOptions.h" #include "platform/loader/fetch/ResourceRequest.h" #include "platform/wtf/Forward.h" @@ -42,7 +45,6 @@ namespace blink { class FetchContext; -class Resource; class ResourceError; class ResourceFetcher; @@ -115,6 +117,10 @@ void DidFinishLoadingFirstPartInMultipart(); private: + FRIEND_TEST_ALL_PREFIXES(ResourceLoaderTest, DetermineCORSStatus); + + friend class SubresourceIntegrityTest; + // Assumes ResourceFetcher and Resource are non-null. ResourceLoader(ResourceFetcher*, Resource*); @@ -125,7 +131,10 @@ FetchContext& Context() const; ResourceRequestBlockedReason CanAccessResponse(Resource*, - const ResourceResponse&) const; + const ResourceResponse&, + const String&) const; + + CORSStatus DetermineCORSStatus(const ResourceResponse&, StringBuilder&) const; void CancelForRedirectAccessCheckError(const KURL&, ResourceRequestBlockedReason);
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoaderTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoaderTest.cpp new file mode 100644 index 0000000..44cfa2f --- /dev/null +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoaderTest.cpp
@@ -0,0 +1,153 @@ +// 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 "platform/loader/fetch/RawResource.h" +#include "platform/loader/fetch/ResourceFetcher.h" +#include "platform/loader/fetch/ResourceLoader.h" +#include "platform/loader/fetch/ResourceResponse.h" +#include "platform/loader/testing/MockFetchContext.h" +#include "platform/testing/TestingPlatformSupport.h" +#include "platform/wtf/text/StringBuilder.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class ResourceLoaderTest : public ::testing::Test { + DISALLOW_COPY_AND_ASSIGN(ResourceLoaderTest); + + public: + ResourceLoaderTest() + : foo_url_(kParsedURLString, "https://foo.test"), + bar_url_(kParsedURLString, "https://bar.test") {}; + + void SetUp() { + context_ = + MockFetchContext::Create(MockFetchContext::kShouldLoadNewResource); + } + + protected: + enum ServiceWorkerMode { kNoSW, kSWOpaque, kSWClear }; + + struct TestCase { + const KURL& origin; + const KURL& target; + const KURL* allow_origin_url; + const ServiceWorkerMode service_worker; + const Resource::Type resource_type; + const CORSStatus expectation; + }; + + Persistent<MockFetchContext> context_; + + ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> + platform_; + + const KURL foo_url_; + const KURL bar_url_; +}; + +TEST_F(ResourceLoaderTest, DetermineCORSStatus) { + TestCase cases[] = { + // No CORS status for main resources: + {foo_url_, foo_url_, nullptr, kNoSW, Resource::Type::kMainResource, + CORSStatus::kNotApplicable}, + + // Same origin: + {foo_url_, foo_url_, nullptr, kNoSW, Resource::Type::kRaw, + CORSStatus::kSameOrigin}, + + // Cross origin CORS successful: + {foo_url_, bar_url_, &foo_url_, kNoSW, Resource::Type::kRaw, + CORSStatus::kSuccessful}, + + // Cross origin not in CORS mode: + {foo_url_, bar_url_, nullptr, kNoSW, Resource::Type::kRaw, + CORSStatus::kNotApplicable}, + + // Cross origin CORS failed: + {foo_url_, bar_url_, &bar_url_, kNoSW, Resource::Type::kRaw, + CORSStatus::kFailed}, + + // CORS handled by service worker + {foo_url_, foo_url_, nullptr, kSWClear, Resource::Type::kRaw, + CORSStatus::kServiceWorkerSuccessful}, + {foo_url_, foo_url_, &foo_url_, kSWClear, Resource::Type::kRaw, + CORSStatus::kServiceWorkerSuccessful}, + {foo_url_, bar_url_, nullptr, kSWClear, Resource::Type::kRaw, + CORSStatus::kServiceWorkerSuccessful}, + {foo_url_, bar_url_, &foo_url_, kSWClear, Resource::Type::kRaw, + CORSStatus::kServiceWorkerSuccessful}, + + // Opaque response by service worker + {foo_url_, foo_url_, nullptr, kSWOpaque, Resource::Type::kRaw, + CORSStatus::kServiceWorkerOpaque}, + {foo_url_, bar_url_, nullptr, kSWOpaque, Resource::Type::kRaw, + CORSStatus::kServiceWorkerOpaque}, + {foo_url_, bar_url_, &foo_url_, kSWOpaque, Resource::Type::kRaw, + CORSStatus::kServiceWorkerOpaque}, + }; + + for (const auto& test : cases) { + SCOPED_TRACE( + ::testing::Message() + << "Origin: " << test.origin.GetString() + << ", target: " << test.target.GetString() + << ", CORS access-control-allow-origin header: " + << (test.allow_origin_url ? test.allow_origin_url->GetString() : "-") + << ", service worker: " + << (test.service_worker == kNoSW + ? "no" + : (test.service_worker == kSWClear ? "clear response" + : "opaque response")) + << ", expected CORSStatus == " + << static_cast<unsigned>(test.expectation)); + + context_->SetSecurityOrigin(SecurityOrigin::Create(test.origin)); + ResourceFetcher* fetcher = + ResourceFetcher::Create(context_, context_->GetTaskRunner().Get()); + + Resource* resource = + RawResource::CreateForTest(test.target, test.resource_type); + ResourceLoader* loader = ResourceLoader::Create(fetcher, resource); + + ResourceRequest request; + request.SetURL(test.target); + + ResourceResponse response; + response.SetHTTPStatusCode(200); + response.SetURL(test.target); + + if (test.allow_origin_url) { + request.SetFetchRequestMode(WebURLRequest::kFetchRequestModeCORS); + resource->MutableOptions().cors_handling_by_resource_fetcher = + kEnableCORSHandlingByResourceFetcher; + response.SetHTTPHeaderField( + "access-control-allow-origin", + SecurityOrigin::Create(*test.allow_origin_url)->ToAtomicString()); + response.SetHTTPHeaderField("access-control-allow-credentials", "true"); + } + + resource->SetResourceRequest(request); + + if (test.service_worker != kNoSW) { + response.SetWasFetchedViaServiceWorker(true); + + if (test.service_worker == kSWOpaque) { + response.SetServiceWorkerResponseType( + WebServiceWorkerResponseType::kWebServiceWorkerResponseTypeOpaque); + } else { + response.SetServiceWorkerResponseType( + WebServiceWorkerResponseType::kWebServiceWorkerResponseTypeDefault); + } + } + + StringBuilder cors_error_msg; + CORSStatus cors_status = + loader->DetermineCORSStatus(response, cors_error_msg); + + EXPECT_EQ(cors_status, test.expectation); + } +} +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.cpp b/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.cpp index f3013640..c91aab3fc 100644 --- a/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.cpp +++ b/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.cpp
@@ -45,7 +45,9 @@ return url_loader_mock_factory_.get(); } -std::unique_ptr<WebURLLoader> FetchTestingPlatformSupport::CreateURLLoader() { +std::unique_ptr<WebURLLoader> FetchTestingPlatformSupport::CreateURLLoader( + const blink::WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { return url_loader_mock_factory_->CreateURLLoader(nullptr); }
diff --git a/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.h b/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.h index 16e6e5b..8160fcb2 100644 --- a/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.h +++ b/third_party/WebKit/Source/platform/loader/testing/FetchTestingPlatformSupport.h
@@ -24,7 +24,9 @@ // Platform: WebURLError CancelledError(const WebURL&) const override; WebURLLoaderMockFactory* GetURLLoaderMockFactory() override; - std::unique_ptr<WebURLLoader> CreateURLLoader() override; + std::unique_ptr<WebURLLoader> CreateURLLoader( + const blink::WebURLRequest&, + base::SingleThreadTaskRunner*) override; private: class FetchTestingWebURLLoaderMockFactory;
diff --git a/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h b/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h index 7c0a01f..7b6b6d69 100644 --- a/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h +++ b/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h
@@ -5,6 +5,7 @@ #ifndef MockFetchContext_h #define MockFetchContext_h +#include "platform/exported/WrappedResourceRequest.h" #include "platform/loader/fetch/FetchContext.h" #include "platform/loader/fetch/FetchParameters.h" #include "platform/loader/fetch/ResourceTimingInfo.h" @@ -42,6 +43,14 @@ void SetLoadComplete(bool complete) { complete_ = complete; } long long GetTransferSize() const { return transfer_size_; } + SecurityOrigin* GetSecurityOrigin() const override { + return security_origin_.Get(); + } + + void SetSecurityOrigin(RefPtr<SecurityOrigin> security_origin) { + security_origin_ = security_origin; + } + // FetchContext: bool AllowImage(bool images_enabled, const KURL&) const override { return true; @@ -75,10 +84,10 @@ } std::unique_ptr<WebURLLoader> CreateURLLoader( - const ResourceRequest&) override { - auto loader = Platform::Current()->CreateURLLoader(); - loader->SetLoadingTaskRunner(runner_.Get()); - return loader; + const ResourceRequest& request) override { + WrappedResourceRequest wrapped(request); + return Platform::Current()->CreateURLLoader( + wrapped, runner_->ToSingleThreadTaskRunner()); } RefPtr<WebTaskRunner> GetTaskRunner() { return runner_; } @@ -88,11 +97,13 @@ : load_policy_(load_policy), runner_(task_runner ? std::move(task_runner) : AdoptRef(new scheduler::FakeWebTaskRunner)), + security_origin_(SecurityOrigin::CreateUnique()), complete_(false), transfer_size_(-1) {} enum LoadPolicy load_policy_; RefPtr<WebTaskRunner> runner_; + RefPtr<SecurityOrigin> security_origin_; bool complete_; long long transfer_size_; };
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc index c8049df..d409fcf 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -29,10 +29,10 @@ lateness); } -void RecordImmediateTaskQueueingDuration(tracked_objects::Duration duration) { +void RecordImmediateTaskQueueingDuration(base::TimeDelta duration) { UMA_HISTOGRAM_TIMES( "RendererScheduler.TaskQueueManager.ImmediateTaskQueueingDuration", - base::TimeDelta::FromMilliseconds(duration.InMilliseconds())); + duration); } double MonotonicTimeInSeconds(base::TimeTicks time_ticks) { @@ -564,7 +564,7 @@ RecordDelayedTaskLateness(delegate_->NowTicks() - pending_task.delayed_run_time); } else if (!pending_task.time_posted.is_null()) { - RecordImmediateTaskQueueingDuration(tracked_objects::TrackedTime::Now() - + RecordImmediateTaskQueueingDuration(base::TimeTicks::Now() - pending_task.time_posted); } }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc index 37ec1fb..693971e2 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -850,6 +850,10 @@ } } +base::TimeDelta RendererSchedulerImpl::MostRecentExpectedQueueingTime() { + return GetMainThreadOnly().most_recent_expected_queueing_time; +} + bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { helper_.CheckOnValidThread(); if (helper_.IsShutdown()) @@ -1713,6 +1717,15 @@ ResetForNavigationLocked(); } +void RendererSchedulerImpl::DidStartProvisionalLoad(bool is_main_frame) { + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + "RendererSchedulerImpl::DidStartProvisionalLoad"); + if (is_main_frame) { + base::AutoLock lock(any_thread_lock_); + ResetForNavigationLocked(); + } +} + void RendererSchedulerImpl::DidCommitProvisionalLoad( bool is_web_history_inert_commit, bool is_reload, @@ -1909,6 +1922,7 @@ void RendererSchedulerImpl::DidProcessTask(TaskQueue* task_queue, double start_time, double end_time) { + DCHECK_LE(start_time, end_time); // TODO(scheduler-dev): Remove conversions when Blink starts using // base::TimeTicks instead of doubles for time. base::TimeTicks start_time_ticks = @@ -2029,6 +2043,8 @@ void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( base::TimeDelta queueing_time, base::TimeTicks window_start_time) { + GetMainThreadOnly().most_recent_expected_queueing_time = queueing_time; + if (GetMainThreadOnly().has_navigated) { if (GetMainThreadOnly().max_queueing_time < queueing_time) { if (!GetMainThreadOnly().max_queueing_time_metric) {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h index 8336f29a..741118c 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
@@ -101,6 +101,7 @@ InputEventState event_state) override; void DidHandleInputEventOnMainThread(const WebInputEvent& web_input_event, WebInputEventResult result) override; + base::TimeDelta MostRecentExpectedQueueingTime() override; void DidAnimateForInputOnCompositorThread() override; void SetRendererHidden(bool hidden) override; void SetRendererBackgrounded(bool backgrounded) override; @@ -194,6 +195,10 @@ // state. void OnAudioStateChanged(); + // Tells the scheduler that a provisional load has committed. Must be called + // from the main thread. + void DidStartProvisionalLoad(bool is_main_frame); + // Tells the scheduler that a provisional load has committed. The scheduler // may reset the task cost estimators and the UserModel. Must be called from // the main thread. @@ -483,6 +488,7 @@ base::TimeTicks estimated_next_frame_begin; base::TimeTicks current_task_start_time; base::TimeTicks uma_last_queueing_time_report_window_start_time; + base::TimeDelta most_recent_expected_queueing_time; base::TimeDelta compositor_frame_interval; base::TimeDelta longest_jank_free_task_duration; base::Optional<base::TimeTicks> last_audio_state_change;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index 29f57db..15094cd 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -233,8 +233,9 @@ parent_web_view_scheduler_->WillNavigateBackForwardSoon(this); } -void WebFrameSchedulerImpl::DidStartProvisionalLoad() { +void WebFrameSchedulerImpl::DidStartProvisionalLoad(bool is_main_frame) { parent_web_view_scheduler_->DidBeginProvisionalLoad(this); + renderer_scheduler_->DidStartProvisionalLoad(is_main_frame); } void WebFrameSchedulerImpl::DidFailProvisionalLoad() {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h index 6f4b58d6..287a3797 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h
@@ -53,7 +53,7 @@ RefPtr<WebTaskRunner> UnthrottledButBlockableTaskRunner() override; WebViewScheduler* GetWebViewScheduler() override; void WillNavigateBackForwardSoon() override; - void DidStartProvisionalLoad() override; + void DidStartProvisionalLoad(bool is_main_frame) override; void DidFailProvisionalLoad() override; void DidCommitProvisionalLoad(bool is_web_history_inert_commit, bool is_reload,
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc index 6b0e10c..eee3adf 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc
@@ -66,6 +66,10 @@ const blink::WebInputEvent& web_input_event, WebInputEventResult result) {} +base::TimeDelta FakeRendererScheduler::MostRecentExpectedQueueingTime() { + return base::TimeDelta(); +} + void FakeRendererScheduler::DidAnimateForInputOnCompositorThread() {} bool FakeRendererScheduler::IsHighPriorityWorkAnticipated() {
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp index f217785..d8991f6 100644 --- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp +++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
@@ -190,8 +190,11 @@ return old_platform_ ? old_platform_->GetURLLoaderMockFactory() : nullptr; } -std::unique_ptr<WebURLLoader> TestingPlatformSupport::CreateURLLoader() { - return old_platform_ ? old_platform_->CreateURLLoader() : nullptr; +std::unique_ptr<WebURLLoader> TestingPlatformSupport::CreateURLLoader( + const WebURLRequest& request, + base::SingleThreadTaskRunner* runner) { + return old_platform_ ? old_platform_->CreateURLLoader(request, runner) + : nullptr; } WebData TestingPlatformSupport::GetDataResource(const char* name) {
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h index 9dcfbf25..c9e1709 100644 --- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h +++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
@@ -112,7 +112,9 @@ WebFileUtilities* GetFileUtilities() override; WebIDBFactory* IdbFactory() override; WebURLLoaderMockFactory* GetURLLoaderMockFactory() override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override; + std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const WebURLRequest&, + base::SingleThreadTaskRunner*) override; WebData GetDataResource(const char* name) override; WebURLError CancelledError(const WebURL&) const override; InterfaceProvider* GetInterfaceProvider() override;
diff --git a/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc b/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc index 82451bde..f71f6ea 100644 --- a/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc +++ b/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc
@@ -159,13 +159,6 @@ NOTIMPLEMENTED(); } -void WebURLLoaderMock::SetLoadingTaskRunner( - base::SingleThreadTaskRunner* runner) { - // In principle this is NOTIMPLEMENTED(), but if we put that here it floods - // the console during webkit unit tests, so we leave the function empty. - DCHECK(runner); -} - WeakPtr<WebURLLoaderMock> WebURLLoaderMock::GetWeakPtr() { return weak_factory_.CreateWeakPtr(); }
diff --git a/third_party/WebKit/Source/platform/testing/weburl_loader_mock.h b/third_party/WebKit/Source/platform/testing/weburl_loader_mock.h index 58d64b06..00ee9bc 100644 --- a/third_party/WebKit/Source/platform/testing/weburl_loader_mock.h +++ b/third_party/WebKit/Source/platform/testing/weburl_loader_mock.h
@@ -54,7 +54,6 @@ WebURLLoaderClient* client) override; void Cancel() override; void SetDefersLoading(bool defer) override; - void SetLoadingTaskRunner(base::SingleThreadTaskRunner*) override; bool is_deferred() { return is_deferred_; } bool is_cancelled() { return !client_; }
diff --git a/third_party/WebKit/Source/platform/transforms/TranslateTransformOperation.cpp b/third_party/WebKit/Source/platform/transforms/TranslateTransformOperation.cpp index a354450..205267f 100644 --- a/third_party/WebKit/Source/platform/transforms/TranslateTransformOperation.cpp +++ b/third_party/WebKit/Source/platform/transforms/TranslateTransformOperation.cpp
@@ -21,6 +21,8 @@ #include "platform/transforms/TranslateTransformOperation.h" +#include "platform/animation/AnimationUtilities.h" + namespace blink { PassRefPtr<TransformOperation> TranslateTransformOperation::Blend(
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp index 704b954f..7c68e8d 100644 --- a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp +++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
@@ -1059,8 +1059,12 @@ return web_frame_->GetTextCheckerClient(); } -std::unique_ptr<blink::WebURLLoader> LocalFrameClientImpl::CreateURLLoader() { - return web_frame_->CreateURLLoader(); +std::unique_ptr<blink::WebURLLoader> LocalFrameClientImpl::CreateURLLoader( + const ResourceRequest& request, + WebTaskRunner* task_runner) { + WrappedResourceRequest wrapped(request); + return web_frame_->CreateURLLoader(wrapped, + task_runner->ToSingleThreadTaskRunner()); } service_manager::InterfaceProvider*
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.h b/third_party/WebKit/Source/web/LocalFrameClientImpl.h index f96edc5..a5512647 100644 --- a/third_party/WebKit/Source/web/LocalFrameClientImpl.h +++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
@@ -233,7 +233,8 @@ TextCheckerClient& GetTextCheckerClient() const override; - std::unique_ptr<WebURLLoader> CreateURLLoader() override; + std::unique_ptr<WebURLLoader> CreateURLLoader(const ResourceRequest&, + WebTaskRunner*) override; service_manager::InterfaceProvider* GetInterfaceProvider() override;
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index c98bf229..4fa7a05 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -681,8 +681,8 @@ int world_id, const WebString& human_readable_name) { DCHECK(GetFrame()); - DOMWrapperWorld::SetIsolatedWorldHumanReadableName(world_id, - human_readable_name); + DOMWrapperWorld::SetNonMainWorldHumanReadableName(world_id, + human_readable_name); } void WebLocalFrameImpl::AddMessageToConsole(const WebConsoleMessage& message) { @@ -2350,8 +2350,10 @@ return frame_widget_; } -std::unique_ptr<WebURLLoader> WebLocalFrameImpl::CreateURLLoader() { - return client_->CreateURLLoader(); +std::unique_ptr<WebURLLoader> WebLocalFrameImpl::CreateURLLoader( + const WebURLRequest& request, + base::SingleThreadTaskRunner* task_runner) { + return client_->CreateURLLoader(request, task_runner); } void WebLocalFrameImpl::CopyImageAt(const WebPoint& pos_in_viewport) {
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index e9a15f7..6ba0c6b 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -444,7 +444,9 @@ void SetContextMenuNode(Node* node) override { context_menu_node_ = node; } void ClearContextMenuNode() override { context_menu_node_.Clear(); } - std::unique_ptr<WebURLLoader> CreateURLLoader() override; + std::unique_ptr<WebURLLoader> CreateURLLoader( + const WebURLRequest&, + base::SingleThreadTaskRunner*) override; DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py index 09fcd92..82a7f5e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py
@@ -163,10 +163,7 @@ def _read_configuration_from_gn(fs, options): """Returns the configuration to used based on args.gn, if possible.""" - - # TODO(qyearsley): Default to 'out' everywhere. build_directory = getattr(options, 'build_directory', 'out') - target = options.target finder = PathFinder(fs) path = fs.join(finder.chromium_base(), build_directory, target, 'args.gn')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py index b040c7a..726a8bc 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py
@@ -45,8 +45,6 @@ FALLBACK_PATHS = {} FALLBACK_PATHS['trusty'] = ['linux'] + win.WinPort.latest_platform_fallback_path() - DEFAULT_BUILD_DIRECTORIES = ('out',) - BUILD_REQUIREMENTS_URL = 'https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md' XVFB_START_TIMEOUT = 5.0 # Wait up to 5 seconds for Xvfb to start.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index 4ebf2fc..b0e1d9a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -14,7 +14,7 @@ import argparse import logging -from webkitpy.common.net.git_cl import GitCL +from webkitpy.common.net.git_cl import GitCL, TryJobStatus from webkitpy.common.net.buildbot import current_build_link from webkitpy.common.path_finder import PathFinder from webkitpy.layout_tests.models.test_expectations import TestExpectations, TestExpectationParser @@ -327,6 +327,7 @@ poll_delay_seconds=POLL_DELAY_SECONDS, timeout_seconds=TIMEOUT_SECONDS) if not try_results: + _log.error('No initial try job results, aborting.') self.git_cl.run(['set-close']) return False @@ -337,22 +338,26 @@ self._upload_patchset(message) # Trigger CQ and wait for CQ try jobs to finish. - self.git_cl.run(['set-commit', '--gerrit']) + self.git_cl.run(['try']) try_results = self.git_cl.wait_for_try_jobs( - poll_delay_seconds=POLL_DELAY_SECONDS, timeout_seconds=TIMEOUT_SECONDS) + poll_delay_seconds=POLL_DELAY_SECONDS, + timeout_seconds=TIMEOUT_SECONDS) - _log.info('Try results: %s', try_results) - - # If the CQ passed, then the issue will be closed already. - status = self.git_cl.run(['status', '--field', 'status']).strip() - _log.info('CL status: "%s"', status) - if status not in ('lgtm', 'closed'): - _log.error('CQ appears to have failed; aborting.') + if not try_results: self.git_cl.run(['set-close']) + _log.error('No CQ try job results, aborting.') return False - _log.info('Update completed.') - return True + if try_results and all(s == TryJobStatus('COMPLETED', 'SUCCESS') for _, s in try_results.iteritems()): + _log.info('CQ appears to have passed; trying to commit.') + self.git_cl.run(['cl', 'upload', '--send-mail']) # Turn off WIP mode. + self.git_cl.run(['set-commit']) + _log.info('Update completed.') + return True + + self.git_cl.run(['set-close']) + _log.error('CQ appears to have failed; aborting.') + return False def _upload_cl(self): _log.info('Uploading change list.')
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index e1c8d71..3607e8b5 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -107,6 +107,7 @@ source_set("blink_headers") { sources = [ "platform/BlameContext.h", + "platform/CORSStatus.h", "platform/FilePathConversion.h", "platform/InterfaceProvider.h", "platform/InterfaceRegistry.h",
diff --git a/third_party/WebKit/public/platform/CORSStatus.h b/third_party/WebKit/public/platform/CORSStatus.h new file mode 100644 index 0000000..609b87c --- /dev/null +++ b/third_party/WebKit/public/platform/CORSStatus.h
@@ -0,0 +1,27 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CORSStatus_h +#define CORSStatus_h + +namespace blink { + +enum class CORSStatus { + kUnknown, // Status not determined - not supposed to be seen by users. + kNotApplicable, // E.g. for main resources or if not in fetch mode CORS. + + // Response not handled by service worker: + kSameOrigin, // Request was same origin. + kSuccessful, // Request was cross origin and CORS checks passed. + kFailed, // Request was cross origin and CORS checks failed. + + // Response handled by service worker: + kServiceWorkerSuccessful, // ResponseType other than opaque (including + // error). + kServiceWorkerOpaque, // ResponseType was opaque. +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h index cc072e9b..4d390c1 100644 --- a/third_party/WebKit/public/platform/Platform.h +++ b/third_party/WebKit/public/platform/Platform.h
@@ -64,6 +64,10 @@ #include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/message_pipe.h" +namespace base { +class SingleThreadTaskRunner; +} + namespace device { class Gamepads; } @@ -335,7 +339,11 @@ // Network ------------------------------------------------------------- // Returns a new WebURLLoader instance. - virtual std::unique_ptr<WebURLLoader> CreateURLLoader() { return nullptr; } + virtual std::unique_ptr<WebURLLoader> CreateURLLoader( + const WebURLRequest&, + base::SingleThreadTaskRunner*) { + return nullptr; + } // Returns a WebDataConsumerHandle for given a mojo data pipe endpoint. virtual std::unique_ptr<WebDataConsumerHandle> CreateDataConsumerHandle(
diff --git a/third_party/WebKit/public/platform/WebFeature.h b/third_party/WebKit/public/platform/WebFeature.h index d0543d47..3da0b66 100644 --- a/third_party/WebKit/public/platform/WebFeature.h +++ b/third_party/WebKit/public/platform/WebFeature.h
@@ -1565,6 +1565,7 @@ kMIDIOutputSend = 2030, kMIDIMessageEvent = 2031, kFetchEventIsReload = 2032, + kServiceWorkerClientFrameType = 2033, // 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/platform/WebURLLoader.h b/third_party/WebKit/public/platform/WebURLLoader.h index 132e90ca..2578467b 100644 --- a/third_party/WebKit/public/platform/WebURLLoader.h +++ b/third_party/WebKit/public/platform/WebURLLoader.h
@@ -35,14 +35,9 @@ #include "WebURLRequest.h" #include <stdint.h> -namespace base { -class SingleThreadTaskRunner; -} // namespace base - namespace blink { class WebData; -class WebTaskRunner; class WebURLLoaderClient; class WebURLResponse; struct WebURLError; @@ -83,12 +78,6 @@ int intra_priority_value) { DidChangePriority(new_priority); } - - // Sets the task runner for which any loading tasks should be posted on. - // Use WebTaskRunner version when it's called from core or module directory, - // since we don't directly expose base to them. - BLINK_PLATFORM_EXPORT void SetLoadingTaskRunner(WebTaskRunner*); - virtual void SetLoadingTaskRunner(base::SingleThreadTaskRunner*) = 0; }; } // namespace blink
diff --git a/third_party/WebKit/public/platform/WebWorkerFetchContext.h b/third_party/WebKit/public/platform/WebWorkerFetchContext.h index 504d1313..6d6a665 100644 --- a/third_party/WebKit/public/platform/WebWorkerFetchContext.h +++ b/third_party/WebKit/public/platform/WebWorkerFetchContext.h
@@ -29,7 +29,9 @@ // Returns a new WebURLLoader instance which is associated with the worker // thread. - virtual std::unique_ptr<WebURLLoader> CreateURLLoader() = 0; + virtual std::unique_ptr<WebURLLoader> CreateURLLoader( + const WebURLRequest&, + base::SingleThreadTaskRunner*) = 0; // Called when a request is about to be sent out to modify the request to // handle the request correctly in the loading stack later. (Example: service
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h b/third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h index 20d6ec35..ac8761c2 100644 --- a/third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h +++ b/third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h
@@ -5,15 +5,18 @@ #ifndef WebNavigationPreloadState_h #define WebNavigationPreloadState_h +#include "public/platform/WebString.h" + namespace blink { struct WebNavigationPreloadState { WebNavigationPreloadState(bool enabled, const WebString& header_value) : enabled(enabled), header_value(header_value) {} - bool enabled; - WebString header_value; + const bool enabled; + const WebString header_value; }; -} + +} // namespace blink #endif // WebNavigationPreloadState_h
diff --git a/third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h b/third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h index 17fadc04..0e9e78b4 100644 --- a/third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h +++ b/third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h
@@ -109,6 +109,10 @@ const WebInputEvent& web_input_event, WebInputEventResult result) = 0; + // Returns the most recently reported expected queueing time, computed over + // the past 1 second window. + virtual base::TimeDelta MostRecentExpectedQueueingTime() = 0; + // Tells the scheduler that the system is displaying an input animation (e.g. // a fling). Called by the compositor (impl) thread. virtual void DidAnimateForInputOnCompositorThread() = 0;
diff --git a/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h b/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h index aa89af4..db66f2c 100644 --- a/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h +++ b/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h
@@ -36,6 +36,7 @@ InputEventState event_state) override; void DidHandleInputEventOnMainThread(const WebInputEvent& web_input_event, WebInputEventResult result) override; + base::TimeDelta MostRecentExpectedQueueingTime() override; void DidAnimateForInputOnCompositorThread() override; void SetRendererHidden(bool hidden) override; void SetRendererBackgrounded(bool backgrounded) override;
diff --git a/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h b/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h index 14ba4dbe..06fa9a78 100644 --- a/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h +++ b/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h
@@ -41,6 +41,7 @@ void(const WebInputEvent&, InputEventState)); MOCK_METHOD2(DidHandleInputEventOnMainThread, void(const WebInputEvent&, WebInputEventResult)); + MOCK_METHOD0(MostRecentExpectedQueueingTime, base::TimeDelta()); MOCK_METHOD0(DidAnimateForInputOnCompositorThread, void()); MOCK_METHOD1(SetRendererHidden, void(bool)); MOCK_METHOD1(SetRendererBackgrounded, void(bool));
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h index 80ee19c..c16217eb 100644 --- a/third_party/WebKit/public/web/WebFrameClient.h +++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -79,6 +79,10 @@ class InterfaceProvider; } +namespace base { +class SingleThreadTaskRunner; +} + namespace blink { enum class WebTreeScopeType; @@ -815,7 +819,9 @@ // Loading -------------------------------------------------------------- - virtual std::unique_ptr<blink::WebURLLoader> CreateURLLoader() { + virtual std::unique_ptr<blink::WebURLLoader> CreateURLLoader( + const WebURLRequest&, + base::SingleThreadTaskRunner*) { NOTREACHED(); return nullptr; }
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h index 813d1110..ad5e729 100644 --- a/third_party/WebKit/public/web/WebLocalFrame.h +++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -699,7 +699,9 @@ // Creates and returns a loader. This function can be called only when this // frame is attached to a document. - virtual std::unique_ptr<WebURLLoader> CreateURLLoader() = 0; + virtual std::unique_ptr<WebURLLoader> CreateURLLoader( + const WebURLRequest&, + base::SingleThreadTaskRunner*) = 0; // Reload the current document. // Note: reload() and reloadWithOverrideURL() will be deprecated.
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h index 3509832..689ba8f 100644 --- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h +++ b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h
@@ -54,10 +54,12 @@ class WebServiceWorkerResponse; class WebString; -// This interface is implemented by the client. It is supposed to be created -// on the main thread and then passed on to the worker thread by a newly -// created WorkerGlobalScope. Unless otherwise noted, all methods of this class -// are called on the worker thread. +// WebServiceWorkerContextClient is a "client" of a service worker execution +// context. This interface is implemented by the embedder and allows the +// embedder to communicate with the service worker execution context. It is +// supposed to be created on the main thread and then passed on to the worker +// thread by a newly created WorkerGlobalScope. Unless otherwise noted, all +// methods of this class are called on the worker thread. class WebServiceWorkerContextClient { public: virtual ~WebServiceWorkerContextClient() {}
diff --git a/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1 b/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1 index c07eb32..1eb1d25 100644 --- a/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1 +++ b/third_party/binutils/Linux_ia32/binutils.tar.bz2.sha1
@@ -1 +1 @@ -0ba2f98a7d104eabe3a21ad30a3045526d241602 \ No newline at end of file +caada1ceaa6800a4a28a849adcecc74e4db7e1c3 \ No newline at end of file
diff --git a/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1 b/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1 index 7ad0a65..b4dc4a9c 100644 --- a/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1 +++ b/third_party/binutils/Linux_x64/binutils.tar.bz2.sha1
@@ -1 +1 @@ -5e71702981e5f3b45632f2f209eb3a85d65ca764 \ No newline at end of file +0cb5726d9701f8be6a81b199899de1de552922f2 \ No newline at end of file
diff --git a/third_party/binutils/README.chromium b/third_party/binutils/README.chromium index 85714a9b..b9eeb7d7 100644 --- a/third_party/binutils/README.chromium +++ b/third_party/binutils/README.chromium
@@ -13,8 +13,7 @@ Ubuntu Trusty. The script creates chroots for 32bit and 64bit Ubuntu Precise and then builds -binutils inside the roots. It also builds tcmalloc and links binutils with it -to improve the speed of LTO. +binutils inside the roots. Version 2.26 was released on Mon, 25 Jan 2016
diff --git a/third_party/binutils/build-all.sh b/third_party/binutils/build-all.sh index 1e3d4eb..ee64a45 100755 --- a/third_party/binutils/build-all.sh +++ b/third_party/binutils/build-all.sh
@@ -35,10 +35,6 @@ exit 1 fi -if [ ! -d gperftools ]; then - git clone --branch gperftools-2.4 https://github.com/gperftools/gperftools -fi - # Extract the source rm -rf binutils-$VERSION tar jxf binutils-$VERSION.tar.bz2 @@ -72,10 +68,9 @@ echo "" echo "Building chroot for $ARCH" echo "=============================" - GPERFTOOLS_DEPS=autoconf,automake,libtool sudo debootstrap \ --arch=$ARCH \ - --include=build-essential,flex,bison,$GPERFTOOLS_DEPS \ + --include=build-essential,flex,bison \ precise precise-chroot-$ARCH echo "=============================" fi @@ -91,7 +86,6 @@ sudo mkdir -p "$BUILDDIR" sudo cp -a binutils-$VERSION "$BUILDDIR" sudo cp -a build-one.sh "$BUILDDIR" - sudo cp -a gperftools "$BUILDDIR" # Do the build PREFIX= @@ -122,10 +116,6 @@ # Copy them out of the chroot cp -a "$BUILDDIR/output/$ARCHNAME" "$OUTPUTDIR" - # Copy plugin header out of the chroot - mkdir "$OUTPUTDIR/$ARCHNAME/include" - cp "$BUILDDIR/binutils-$VERSION/include/plugin-api.h" "$OUTPUTDIR/$ARCHNAME/include/" - # Clean up chroot sudo rm -rf "$BUILDDIR" done
diff --git a/third_party/binutils/build-one.sh b/third_party/binutils/build-one.sh index ccb58be3..9eb81e8 100755 --- a/third_party/binutils/build-one.sh +++ b/third_party/binutils/build-one.sh
@@ -15,42 +15,6 @@ fi cd "$1" - -# First, we need to build libtcmalloc_minimal - -cd ../gperftools/ -./autogen.sh -./configure \ - --disable-cpu-profiler \ - --disable-heap-checker \ - --disable-heap-profiler \ - --disable-static \ - --enable-minimal - -echo -echo "= gperftools src/config.h ==========================================" -cat src/config.h -echo "====================================================================" -echo - -make -j8 - -cd "$1" - -# Ask the dynamic loader to load libstdc++ from the LLVM build directory if -# available. That copy of libstdc++ is required by the gold plugin in the same -# directory. Do the same for libtcmalloc_minimal, that is stored in ../lib. -# The dynamic loader expects the relative path to start with $ORIGIN, -# but because of escaping issues -# (https://sourceware.org/ml/binutils/2009-05/msg00252.html) -# we embed a dummy path with $ replaced with z and fix it up later. - -readonly LIBSTDCPP_RPATH="zORIGIN/../../../../llvm-build/Release+Asserts/lib" -readonly LIBTCMALLOC_RPATH="zORIGIN/../lib" -export LDFLAGS="-Wl,-rpath,$LIBSTDCPP_RPATH:$LIBTCMALLOC_RPATH \ - -L$(pwd)/../gperftools/.libs/" -export LIBS='-ltcmalloc_minimal' - ./configure \ --enable-deterministic-archives \ --enable-gold=default \ @@ -66,21 +30,3 @@ echo "====================================================================" echo make install - -# Copy libtcmalloc_minimal library and symlinks to the install lib dir. -cp -a ../gperftools/.libs/libtcmalloc_minimal.so* /build/output/*/lib/ - -# Save the list of binaries. The sed -i command will leave .orig files behind. -# We don't want them to appear in the for loop below. -bins="$(echo /build/output/*/bin/*)" - -# Fix up zORIGIN -> $ORIGIN. -sed -i.orig 's,zORIGIN,$ORIGIN,g' $bins - -# Verify that we changed only two bytes per executable. -for bin in $bins; do - test "`cmp -l $bin.orig $bin | wc -l`" = 2 || \ - (echo "$bin: verification failed" && exit 1) -done - -rm /build/output/*/bin/*.orig
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn index 359eb51..2b871032 100644 --- a/third_party/harfbuzz-ng/BUILD.gn +++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -165,7 +165,7 @@ "HAVE_OT", "HAVE_ICU", "HAVE_ICU_BUILTIN", - "HB_NO_MT", + "HAVE_INTEL_ATOMIC_PRIMITIVES", ] configs -= [ "//build/config/compiler:chromium_code" ] @@ -229,7 +229,7 @@ "HAVE_OT", "HAVE_ICU", "HAVE_ICU_BUILTIN", - "HB_NO_MT", + "HAVE_INTEL_ATOMIC_PRIMITIVES", ] deps = [
diff --git a/third_party/khronos/EGL/eglext.h b/third_party/khronos/EGL/eglext.h index c59a9b3..d07a7b7 100644 --- a/third_party/khronos/EGL/eglext.h +++ b/third_party/khronos/EGL/eglext.h
@@ -1198,16 +1198,21 @@ #define EGL_NATIVE_SURFACE_TIZEN 0x32A1 #endif /* EGL_TIZEN_image_native_surface */ +/* Chromium-specific Added support for EGL_EXT_image_flush_external extension */ #ifndef EGL_EXT_image_flush_external #define EGL_EXT_image_flush_external 1 -#define EGL_IMAGE_EXTERNAL_FLUSH_EXT 0x32A2 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLIMAGEFLUSHEXTERNALEXTPROC) (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLIMAGEINVALIDATEEXTERNALEXTPROC) (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglImageFlushExternalEXT (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglImageInvalidateExternalEXT (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY +eglImageFlushExternalEXT(EGLDisplay dpy, + EGLImageKHR image, + const EGLint* attrib_list); +#else +typedef EGLBoolean(EGLAPIENTRYP PFNGLEGLIMAGEFLUSHEXTERNALEXT)( + EGLDisplay dpy, + EGLImageKHR image, + const EGLint* attrib_list); #endif -#endif /* EGL_EXT_image_flush_external */ +#endif #ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12 #define EGL_ANGLE_stream_producer_d3d_texture_nv12
diff --git a/third_party/liblouis/nacl_wrapper/liblouis_instance.cc b/third_party/liblouis/nacl_wrapper/liblouis_instance.cc index c771bc9..3f9541b5 100644 --- a/third_party/liblouis/nacl_wrapper/liblouis_instance.cc +++ b/third_party/liblouis/nacl_wrapper/liblouis_instance.cc
@@ -109,6 +109,7 @@ static const char kTableNamesKey[] = "table_names"; static const char kSuccessKey[] = "success"; static const char kTextKey[] = "text"; +static const char kFormTypeMapKey[] = "form_type_map"; static const char kCellsKey[] = "cells"; static const char kCursorPositionKey[] = "cursor_position"; static const char kTextToBrailleKey[] = "text_to_braille"; @@ -237,6 +238,7 @@ Json::Value table_names = message[kTableNamesKey]; Json::Value text = message[kTextKey]; Json::Value cursor_position = message[kCursorPositionKey]; + Json::Value form_type_map = message[kFormTypeMapKey]; if (!table_names.isString()) { PostError("expected table_names to be a string", message_id); return; @@ -246,12 +248,23 @@ } else if (!cursor_position.isNull() && !cursor_position.isIntegral()) { PostError("expected cursor_position to be null or integral", message_id); return; + } else if (!form_type_map.isArray()) { + PostError("expected form_type_map to be an array", message_id); + return; } TranslationParams params; params.table_names = table_names.asString(); params.text = text.asString(); params.cursor_position = cursor_position.isIntegral() ? cursor_position.asInt() : -1; + for (size_t i = 0; i < form_type_map.size(); ++i) { + Json::Value val = form_type_map[i]; + if (!val.isIntegral()) { + PostError("expected form_type_map to be an integral array", message_id); + return; + } + params.form_type_map.push_back(val.asInt()); + } PostWorkToBackground(cc_factory_.NewCallback( &LibLouisInstance::TranslateInBackground, params, message_id));
diff --git a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc index be51c13..514ab668 100644 --- a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc +++ b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc
@@ -140,6 +140,8 @@ out_cursor_position_ptr = &out_cursor_position; } + std::vector<unsigned char> form_type_map(params.form_type_map); + // Invoke liblouis. Do this in a loop since we can't precalculate the // translated size. We add an extra slot in the output buffer so that // common cases like single digits or capital letters won't always trigger @@ -152,11 +154,11 @@ outlen = outalloc; outbuf.resize(outalloc); braille_to_text.resize(outalloc); - int result = lou_translate(params.table_names.c_str(), - &inbuf[0], &inlen, &outbuf[0], &outlen, - NULL /* typeform */, NULL /* spacing */, - &text_to_braille[0], &braille_to_text[0], - out_cursor_position_ptr, dotsIO /* mode */); + form_type_map.resize(outalloc); + int result = lou_translate( + params.table_names.c_str(), &inbuf[0], &inlen, &outbuf[0], &outlen, + &form_type_map[0], NULL /* spacing */, &text_to_braille[0], + &braille_to_text[0], out_cursor_position_ptr, dotsIO /* mode */); if (result == 0) { // TODO(jbroman): log this return false;
diff --git a/third_party/liblouis/nacl_wrapper/translation_params.h b/third_party/liblouis/nacl_wrapper/translation_params.h index cb1938e5..44bed0a 100644 --- a/third_party/liblouis/nacl_wrapper/translation_params.h +++ b/third_party/liblouis/nacl_wrapper/translation_params.h
@@ -16,6 +16,7 @@ #define LIBLOUIS_NACL_TRANSLATION_PARAMS_H_ #include <string> +#include <vector> namespace liblouis_nacl { @@ -25,6 +26,7 @@ std::string table_names; std::string text; int cursor_position; + std::vector<unsigned char> form_type_map; }; }
diff --git a/third_party/mesa/BUILD.gn b/third_party/mesa/BUILD.gn index f799dbaf..0bef730 100644 --- a/third_party/mesa/BUILD.gn +++ b/third_party/mesa/BUILD.gn
@@ -774,26 +774,3 @@ ] } } - -if (is_linux) { - config("wayland_drm_protocol_config") { - include_dirs = [ "$generated_src_dir/egl/wayland/wayland-drm" ] - } - - static_library("wayland_drm_protocol") { - sources = [ - "$generated_src_dir/egl/wayland/wayland-drm/wayland-drm-client-protocol.h", - "$generated_src_dir/egl/wayland/wayland-drm/wayland-drm-protocol.c", - "$generated_src_dir/egl/wayland/wayland-drm/wayland-drm-server-protocol.h", - ] - - deps = [ - "//third_party/wayland:wayland_util", - ] - - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - - public_configs = [ ":wayland_drm_protocol_config" ] - } -}
diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn index 63a1af4..204a93c3 100644 --- a/third_party/wayland-protocols/BUILD.gn +++ b/third_party/wayland-protocols/BUILD.gn
@@ -262,3 +262,24 @@ public_configs = [ ":stylus_tools_protocol_config" ] } + +config("keyboard_extension_protocol_config") { + include_dirs = [ "include/protocol" ] +} + +source_set("keyboard_extension_protocol") { + sources = [ + "include/protocol/keyboard-extension-unstable-v1-client-protocol.h", + "include/protocol/keyboard-extension-unstable-v1-server-protocol.h", + "protocol/keyboard-extension-protocol.c", + ] + + deps = [ + "//third_party/wayland:wayland_util", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + + public_configs = [ ":keyboard_extension_protocol_config" ] +}
diff --git a/third_party/wayland-protocols/README.chromium b/third_party/wayland-protocols/README.chromium index b4dcdbfe4..57353b4 100644 --- a/third_party/wayland-protocols/README.chromium +++ b/third_party/wayland-protocols/README.chromium
@@ -61,4 +61,7 @@ wayland-scanner code < unstable/stylus-tools/stylus-tools-unstable-v1.xml > protocol/stylus-tools-protocol.c wayland-scanner server-header < unstable/stylus-tools/stylus-tools-unstable-v1.xml > include/protocol/stylus-tools-unstable-v1-server-protocol.h wayland-scanner client-header < unstable/stylus-tools/stylus-tools-unstable-v1.xml > include/protocol/stylus-tools-unstable-v1-client-protocol.h + wayland-scanner code < unstable/keyboard/keyboard-extension-unstable-v1.xml > protocol/keyboard-extension-protocol.c + wayland-scanner server-header < unstable/keyboard/keyboard-extension-unstable-v1.xml > include/protocol/keyboard-extension-unstable-v1-server-protocol.h + wayland-scanner client-header < unstable/keyboard/keyboard-extension-unstable-v1.xml > include/protocol/keyboard-extension-unstable-v1-client-protocol.h - Update this README to reflect the new version number.
diff --git a/third_party/wayland-protocols/include/protocol/keyboard-extension-unstable-v1-client-protocol.h b/third_party/wayland-protocols/include/protocol/keyboard-extension-unstable-v1-client-protocol.h new file mode 100644 index 0000000..ce8571f --- /dev/null +++ b/third_party/wayland-protocols/include/protocol/keyboard-extension-unstable-v1-client-protocol.h
@@ -0,0 +1,236 @@ +/* Generated by wayland-scanner 1.13.0 */ + +#ifndef KEYBOARD_EXTENSION_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define KEYBOARD_EXTENSION_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include <stdint.h> +#include <stddef.h> +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_keyboard_extension_unstable_v1 The keyboard_extension_unstable_v1 protocol + * @section page_ifaces_keyboard_extension_unstable_v1 Interfaces + * - @subpage page_iface_zcr_keyboard_extension_v1 - extends wl_keyboard with ack_key events + * - @subpage page_iface_zcr_extended_keyboard_v1 - extension of wl_keyboard protocol + * @section page_copyright_keyboard_extension_unstable_v1 Copyright + * <pre> + * + * Copyright 2017 The Chromium Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * </pre> + */ +struct wl_keyboard; +struct zcr_extended_keyboard_v1; +struct zcr_keyboard_extension_v1; + +/** + * @page page_iface_zcr_keyboard_extension_v1 zcr_keyboard_extension_v1 + * @section page_iface_zcr_keyboard_extension_v1_desc Description + * + * Allows a wl_keyboard to send ack_key requests for each key event of + * the keyboard to the server. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding uinterface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and uinterface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + * @section page_iface_zcr_keyboard_extension_v1_api API + * See @ref iface_zcr_keyboard_extension_v1. + */ +/** + * @defgroup iface_zcr_keyboard_extension_v1 The zcr_keyboard_extension_v1 interface + * + * Allows a wl_keyboard to send ack_key requests for each key event of + * the keyboard to the server. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding uinterface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and uinterface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + */ +extern const struct wl_interface zcr_keyboard_extension_v1_interface; +/** + * @page page_iface_zcr_extended_keyboard_v1 zcr_extended_keyboard_v1 + * @section page_iface_zcr_extended_keyboard_v1_desc Description + * + * The zcr_extended_keyboard_v1 interface extends the wl_keyboard interface + * with requests to notify whether sent key events are handled or not by + * the client. + * @section page_iface_zcr_extended_keyboard_v1_api API + * See @ref iface_zcr_extended_keyboard_v1. + */ +/** + * @defgroup iface_zcr_extended_keyboard_v1 The zcr_extended_keyboard_v1 interface + * + * The zcr_extended_keyboard_v1 interface extends the wl_keyboard interface + * with requests to notify whether sent key events are handled or not by + * the client. + */ +extern const struct wl_interface zcr_extended_keyboard_v1_interface; + +#ifndef ZCR_KEYBOARD_EXTENSION_V1_ERROR_ENUM +#define ZCR_KEYBOARD_EXTENSION_V1_ERROR_ENUM +enum zcr_keyboard_extension_v1_error { + /** + * the keyboard already has an extended_keyboard object associated + */ + ZCR_KEYBOARD_EXTENSION_V1_ERROR_EXTENDED_KEYBOARD_EXISTS = 0, +}; +#endif /* ZCR_KEYBOARD_EXTENSION_V1_ERROR_ENUM */ + +#define ZCR_KEYBOARD_EXTENSION_V1_GET_EXTENDED_KEYBOARD 0 + + +/** + * @ingroup iface_zcr_keyboard_extension_v1 + */ +#define ZCR_KEYBOARD_EXTENSION_V1_GET_EXTENDED_KEYBOARD_SINCE_VERSION 1 + +/** @ingroup iface_zcr_keyboard_extension_v1 */ +static inline void +zcr_keyboard_extension_v1_set_user_data(struct zcr_keyboard_extension_v1 *zcr_keyboard_extension_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zcr_keyboard_extension_v1, user_data); +} + +/** @ingroup iface_zcr_keyboard_extension_v1 */ +static inline void * +zcr_keyboard_extension_v1_get_user_data(struct zcr_keyboard_extension_v1 *zcr_keyboard_extension_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zcr_keyboard_extension_v1); +} + +static inline uint32_t +zcr_keyboard_extension_v1_get_version(struct zcr_keyboard_extension_v1 *zcr_keyboard_extension_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zcr_keyboard_extension_v1); +} + +/** @ingroup iface_zcr_keyboard_extension_v1 */ +static inline void +zcr_keyboard_extension_v1_destroy(struct zcr_keyboard_extension_v1 *zcr_keyboard_extension_v1) +{ + wl_proxy_destroy((struct wl_proxy *) zcr_keyboard_extension_v1); +} + +/** + * @ingroup iface_zcr_keyboard_extension_v1 + * + * Create extended_keyboard object. + * See zcr_extended_keyboard interface for details. + * If the given wl_keyboard object already has a extended_keyboard object + * associated, the extended_keyboard_exists protocol error is raised. + */ +static inline struct zcr_extended_keyboard_v1 * +zcr_keyboard_extension_v1_get_extended_keyboard(struct zcr_keyboard_extension_v1 *zcr_keyboard_extension_v1, struct wl_keyboard *keyboard) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor((struct wl_proxy *) zcr_keyboard_extension_v1, + ZCR_KEYBOARD_EXTENSION_V1_GET_EXTENDED_KEYBOARD, &zcr_extended_keyboard_v1_interface, NULL, keyboard); + + return (struct zcr_extended_keyboard_v1 *) id; +} + +#ifndef ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_ENUM +#define ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_ENUM +/** + * @ingroup iface_zcr_extended_keyboard_v1 + * whether a key event is handled by client or not + */ +enum zcr_extended_keyboard_v1_handled_state { + ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_NOT_HANDLED = 0, + ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_HANDLED = 1, +}; +#endif /* ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_ENUM */ + +#define ZCR_EXTENDED_KEYBOARD_V1_DESTROY 0 +#define ZCR_EXTENDED_KEYBOARD_V1_ACK_KEY 1 + + +/** + * @ingroup iface_zcr_extended_keyboard_v1 + */ +#define ZCR_EXTENDED_KEYBOARD_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zcr_extended_keyboard_v1 + */ +#define ZCR_EXTENDED_KEYBOARD_V1_ACK_KEY_SINCE_VERSION 1 + +/** @ingroup iface_zcr_extended_keyboard_v1 */ +static inline void +zcr_extended_keyboard_v1_set_user_data(struct zcr_extended_keyboard_v1 *zcr_extended_keyboard_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zcr_extended_keyboard_v1, user_data); +} + +/** @ingroup iface_zcr_extended_keyboard_v1 */ +static inline void * +zcr_extended_keyboard_v1_get_user_data(struct zcr_extended_keyboard_v1 *zcr_extended_keyboard_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zcr_extended_keyboard_v1); +} + +static inline uint32_t +zcr_extended_keyboard_v1_get_version(struct zcr_extended_keyboard_v1 *zcr_extended_keyboard_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zcr_extended_keyboard_v1); +} + +/** + * @ingroup iface_zcr_extended_keyboard_v1 + */ +static inline void +zcr_extended_keyboard_v1_destroy(struct zcr_extended_keyboard_v1 *zcr_extended_keyboard_v1) +{ + wl_proxy_marshal((struct wl_proxy *) zcr_extended_keyboard_v1, + ZCR_EXTENDED_KEYBOARD_V1_DESTROY); + + wl_proxy_destroy((struct wl_proxy *) zcr_extended_keyboard_v1); +} + +/** + * @ingroup iface_zcr_extended_keyboard_v1 + */ +static inline void +zcr_extended_keyboard_v1_ack_key(struct zcr_extended_keyboard_v1 *zcr_extended_keyboard_v1, uint32_t serial, uint32_t handled) +{ + wl_proxy_marshal((struct wl_proxy *) zcr_extended_keyboard_v1, + ZCR_EXTENDED_KEYBOARD_V1_ACK_KEY, serial, handled); +} + +#ifdef __cplusplus +} +#endif + +#endif
diff --git a/third_party/wayland-protocols/include/protocol/keyboard-extension-unstable-v1-server-protocol.h b/third_party/wayland-protocols/include/protocol/keyboard-extension-unstable-v1-server-protocol.h new file mode 100644 index 0000000..9eb8c2ba --- /dev/null +++ b/third_party/wayland-protocols/include/protocol/keyboard-extension-unstable-v1-server-protocol.h
@@ -0,0 +1,188 @@ +/* Generated by wayland-scanner 1.13.0 */ + +#ifndef KEYBOARD_EXTENSION_UNSTABLE_V1_SERVER_PROTOCOL_H +#define KEYBOARD_EXTENSION_UNSTABLE_V1_SERVER_PROTOCOL_H + +#include <stdint.h> +#include <stddef.h> +#include "wayland-server.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct wl_client; +struct wl_resource; + +/** + * @page page_keyboard_extension_unstable_v1 The keyboard_extension_unstable_v1 protocol + * @section page_ifaces_keyboard_extension_unstable_v1 Interfaces + * - @subpage page_iface_zcr_keyboard_extension_v1 - extends wl_keyboard with ack_key events + * - @subpage page_iface_zcr_extended_keyboard_v1 - extension of wl_keyboard protocol + * @section page_copyright_keyboard_extension_unstable_v1 Copyright + * <pre> + * + * Copyright 2017 The Chromium Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * </pre> + */ +struct wl_keyboard; +struct zcr_extended_keyboard_v1; +struct zcr_keyboard_extension_v1; + +/** + * @page page_iface_zcr_keyboard_extension_v1 zcr_keyboard_extension_v1 + * @section page_iface_zcr_keyboard_extension_v1_desc Description + * + * Allows a wl_keyboard to send ack_key requests for each key event of + * the keyboard to the server. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding uinterface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and uinterface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + * @section page_iface_zcr_keyboard_extension_v1_api API + * See @ref iface_zcr_keyboard_extension_v1. + */ +/** + * @defgroup iface_zcr_keyboard_extension_v1 The zcr_keyboard_extension_v1 interface + * + * Allows a wl_keyboard to send ack_key requests for each key event of + * the keyboard to the server. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding uinterface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and uinterface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + */ +extern const struct wl_interface zcr_keyboard_extension_v1_interface; +/** + * @page page_iface_zcr_extended_keyboard_v1 zcr_extended_keyboard_v1 + * @section page_iface_zcr_extended_keyboard_v1_desc Description + * + * The zcr_extended_keyboard_v1 interface extends the wl_keyboard interface + * with requests to notify whether sent key events are handled or not by + * the client. + * @section page_iface_zcr_extended_keyboard_v1_api API + * See @ref iface_zcr_extended_keyboard_v1. + */ +/** + * @defgroup iface_zcr_extended_keyboard_v1 The zcr_extended_keyboard_v1 interface + * + * The zcr_extended_keyboard_v1 interface extends the wl_keyboard interface + * with requests to notify whether sent key events are handled or not by + * the client. + */ +extern const struct wl_interface zcr_extended_keyboard_v1_interface; + +#ifndef ZCR_KEYBOARD_EXTENSION_V1_ERROR_ENUM +#define ZCR_KEYBOARD_EXTENSION_V1_ERROR_ENUM +enum zcr_keyboard_extension_v1_error { + /** + * the keyboard already has an extended_keyboard object associated + */ + ZCR_KEYBOARD_EXTENSION_V1_ERROR_EXTENDED_KEYBOARD_EXISTS = 0, +}; +#endif /* ZCR_KEYBOARD_EXTENSION_V1_ERROR_ENUM */ + +/** + * @ingroup iface_zcr_keyboard_extension_v1 + * @struct zcr_keyboard_extension_v1_interface + */ +struct zcr_keyboard_extension_v1_interface { + /** + * get extended_keyboard for a keyboard + * + * Create extended_keyboard object. See zcr_extended_keyboard + * interface for details. If the given wl_keyboard object already + * has a extended_keyboard object associated, the + * extended_keyboard_exists protocol error is raised. + */ + void (*get_extended_keyboard)(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *keyboard); +}; + + +/** + * @ingroup iface_zcr_keyboard_extension_v1 + */ +#define ZCR_KEYBOARD_EXTENSION_V1_GET_EXTENDED_KEYBOARD_SINCE_VERSION 1 + +#ifndef ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_ENUM +#define ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_ENUM +/** + * @ingroup iface_zcr_extended_keyboard_v1 + * whether a key event is handled by client or not + */ +enum zcr_extended_keyboard_v1_handled_state { + ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_NOT_HANDLED = 0, + ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_HANDLED = 1, +}; +#endif /* ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_ENUM */ + +/** + * @ingroup iface_zcr_extended_keyboard_v1 + * @struct zcr_extended_keyboard_v1_interface + */ +struct zcr_extended_keyboard_v1_interface { + /** + * destroy extended_keyboard object + * + * + */ + void (*destroy)(struct wl_client *client, + struct wl_resource *resource); + /** + * acknowledge a key event + * + * + */ + void (*ack_key)(struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + uint32_t handled); +}; + + +/** + * @ingroup iface_zcr_extended_keyboard_v1 + */ +#define ZCR_EXTENDED_KEYBOARD_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zcr_extended_keyboard_v1 + */ +#define ZCR_EXTENDED_KEYBOARD_V1_ACK_KEY_SINCE_VERSION 1 + +#ifdef __cplusplus +} +#endif + +#endif
diff --git a/third_party/wayland-protocols/protocol/keyboard-extension-protocol.c b/third_party/wayland-protocols/protocol/keyboard-extension-protocol.c new file mode 100644 index 0000000..fb2ea2ba --- /dev/null +++ b/third_party/wayland-protocols/protocol/keyboard-extension-protocol.c
@@ -0,0 +1,60 @@ +/* Generated by wayland-scanner 1.13.0 */ + +/* + * Copyright 2017 The Chromium Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdlib.h> +#include <stdint.h> +#include "wayland-util.h" + +extern const struct wl_interface wl_keyboard_interface; +extern const struct wl_interface zcr_extended_keyboard_v1_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + &zcr_extended_keyboard_v1_interface, + &wl_keyboard_interface, +}; + +static const struct wl_message zcr_keyboard_extension_v1_requests[] = { + { "get_extended_keyboard", "no", types + 2 }, +}; + +WL_EXPORT const struct wl_interface zcr_keyboard_extension_v1_interface = { + "zcr_keyboard_extension_v1", 1, + 1, zcr_keyboard_extension_v1_requests, + 0, NULL, +}; + +static const struct wl_message zcr_extended_keyboard_v1_requests[] = { + { "destroy", "", types + 0 }, + { "ack_key", "uu", types + 0 }, +}; + +WL_EXPORT const struct wl_interface zcr_extended_keyboard_v1_interface = { + "zcr_extended_keyboard_v1", 1, + 2, zcr_extended_keyboard_v1_requests, + 0, NULL, +}; +
diff --git a/third_party/wayland-protocols/unstable/keyboard/README b/third_party/wayland-protocols/unstable/keyboard/README new file mode 100644 index 0000000..700fff9 --- /dev/null +++ b/third_party/wayland-protocols/unstable/keyboard/README
@@ -0,0 +1,4 @@ +Extensions of wl_keyboard protocol. + +Maintainers: +Yuichiro Hanada <yhanada@chromium.org>
diff --git a/third_party/wayland-protocols/unstable/keyboard/keyboard-extension-unstable-v1.xml b/third_party/wayland-protocols/unstable/keyboard/keyboard-extension-unstable-v1.xml new file mode 100644 index 0000000..a90604dc --- /dev/null +++ b/third_party/wayland-protocols/unstable/keyboard/keyboard-extension-unstable-v1.xml
@@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="keyboard_extension_unstable_v1"> + + <copyright> + Copyright 2017 The Chromium Authors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + </copyright> + + <interface name="zcr_keyboard_extension_v1" version="1"> + <description summary="extends wl_keyboard with ack_key events"> + Allows a wl_keyboard to send ack_key requests for each key event of + the keyboard to the server. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding uinterface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and uinterface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + </description> + + <enum name="error"> + <entry name="extended_keyboard_exists" value="0" + summary="the keyboard already has an extended_keyboard object associated"/> + </enum> + + <request name="get_extended_keyboard"> + <description summary="get extended_keyboard for a keyboard"> + Create extended_keyboard object. + See zcr_extended_keyboard interface for details. + If the given wl_keyboard object already has a extended_keyboard object + associated, the extended_keyboard_exists protocol error is raised. + </description> + <arg name="id" type="new_id" interface="zcr_extended_keyboard_v1"/> + <arg name="keyboard" type="object" interface="wl_keyboard"/> + </request> + </interface> + + <interface name="zcr_extended_keyboard_v1" version="1"> + <description summary="extension of wl_keyboard protocol"> + The zcr_extended_keyboard_v1 interface extends the wl_keyboard interface + with requests to notify whether sent key events are handled or not by + the client. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy extended_keyboard object"/> + </request> + + <enum name="handled_state"> + <description summary="whether a key event is handled by client or not"/> + <entry name="not_handled" value="0"/> + <entry name="handled" value="1"/> + </enum> + + <request name="ack_key"> + <description summary="acknowledge a key event"/> + <arg name="serial" type="uint"/> + <arg name="handled" type="uint" enum="handled_state"/> + </request> + </interface> +</protocol>
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py index 88e9779..2f95c5f 100755 --- a/tools/clang/scripts/package.py +++ b/tools/clang/scripts/package.py
@@ -25,9 +25,7 @@ 'llvm-bootstrap-install') LLVM_BUILD_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-build') LLVM_RELEASE_DIR = os.path.join(LLVM_BUILD_DIR, 'Release+Asserts') -LLVM_LTO_GOLD_PLUGIN_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-lto-gold-plugin') -BINUTILS_LIB_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils', 'Linux_x64', - 'Release', 'lib') +LLVM_LTO_LLD_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-lto-lld') STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision') @@ -176,7 +174,6 @@ expected_stamp = GetExpectedStamp() pdir = 'clang-' + expected_stamp - golddir = 'llvmgold-' + expected_stamp print pdir if sys.platform == 'darwin': @@ -187,15 +184,10 @@ platform = 'Linux_x64' # Check if Google Cloud Storage already has the artifacts we want to build. - if (args.upload and GsutilArchiveExists(pdir, platform) and - (not sys.platform.startswith('linux') or - GsutilArchiveExists(golddir, platform))): + if args.upload and GsutilArchiveExists(pdir, platform): print ('Desired toolchain revision %s is already available ' 'in Google Cloud Storage:') % expected_stamp print 'gs://chromium-browser-clang-staging/%s/%s.tgz' % (platform, pdir) - if sys.platform.startswith('linux'): - print 'gs://chromium-browser-clang-staging/%s/%s.tgz' % (platform, - golddir) return 0 with open('buildlog.txt', 'w') as log: @@ -230,7 +222,7 @@ opt_flags = [] if sys.platform.startswith('linux'): - opt_flags += ['--lto-gold-plugin'] + opt_flags += ['--lto-lld'] build_cmd = [sys.executable, os.path.join(THIS_DIR, 'update.py'), '--bootstrap', '--force-local-build', '--run-tests'] + opt_flags @@ -325,12 +317,6 @@ shutil.copytree(os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'include', 'c++'), os.path.join(pdir, 'include', 'c++')) - # Copy tcmalloc from the binutils package. - # FIXME: We should eventually be building our own copy. - if sys.platform.startswith('linux'): - shutil.copy(os.path.join(BINUTILS_LIB_DIR, 'libtcmalloc_minimal.so.4'), - os.path.join(pdir, 'lib')) - # Copy buildlog over. shutil.copy('buildlog.txt', pdir) @@ -344,17 +330,6 @@ MaybeUpload(args, pdir, platform) - # Zip up gold plugin on Linux. - if sys.platform.startswith('linux'): - shutil.rmtree(golddir, ignore_errors=True) - os.makedirs(os.path.join(golddir, 'lib')) - shutil.copy(os.path.join(LLVM_LTO_GOLD_PLUGIN_DIR, 'lib', 'LLVMgold.so'), - os.path.join(golddir, 'lib')) - with tarfile.open(golddir + '.tgz', 'w:gz') as tar: - tar.add(os.path.join(golddir, 'lib'), arcname='lib', - filter=PrintTarProgress) - MaybeUpload(args, golddir, platform) - # Zip up llvm-objdump for sanitizer coverage. objdumpdir = 'llvmobjdump-' + stamp shutil.rmtree(objdumpdir, ignore_errors=True)
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index a1273615..e96e4b55 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -34,7 +34,7 @@ CLANG_REVISION = 'HEAD' # This is incremented when pushing a new build of Clang at the same revision. -CLANG_SUB_REVISION=1 +CLANG_SUB_REVISION=2 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION) @@ -46,7 +46,7 @@ LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap') LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap-install') -LLVM_LTO_GOLD_PLUGIN_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-lto-gold-plugin') +LLVM_LTO_LLD_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-lto-lld') CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools') LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', 'Release+Asserts') @@ -66,10 +66,6 @@ os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) STAMP_FILE = os.path.normpath( os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) -BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils', 'Linux_x64', 'Release') -BINUTILS_BIN_DIR = os.path.join(BINUTILS_DIR, 'bin') -BINUTILS_LIB_DIR = os.path.join(BINUTILS_DIR, 'lib') -BFD_PLUGINS_DIR = os.path.join(BINUTILS_LIB_DIR, 'bfd-plugins') VERSION = '5.0.0' ANDROID_NDK_DIR = os.path.join( CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk') @@ -489,16 +485,11 @@ '-DLLVM_USE_CRT_RELEASE=MT', ] - binutils_incdir = '' - if sys.platform.startswith('linux'): - binutils_incdir = os.path.join(BINUTILS_DIR, 'include') - if args.bootstrap: print 'Building bootstrap compiler' EnsureDirExists(LLVM_BOOTSTRAP_DIR) os.chdir(LLVM_BOOTSTRAP_DIR) bootstrap_args = base_cmake_args + [ - '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, '-DLLVM_TARGETS_TO_BUILD=host', '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR, '-DCMAKE_C_FLAGS=' + ' '.join(cflags), @@ -537,52 +528,35 @@ cxxflags = ['--gcc-toolchain=' + args.gcc_toolchain] print 'Building final compiler' - # Build LLVM gold plugin with LTO. That speeds up the linker by ~10%. + # Build lld with LTO. That speeds up the linker by ~10%. # We only use LTO for Linux now. - if args.bootstrap and args.lto_gold_plugin: - print 'Building LTO LLVM Gold plugin' - if os.path.exists(LLVM_LTO_GOLD_PLUGIN_DIR): - RmTree(LLVM_LTO_GOLD_PLUGIN_DIR) - EnsureDirExists(LLVM_LTO_GOLD_PLUGIN_DIR) - os.chdir(LLVM_LTO_GOLD_PLUGIN_DIR) + if args.bootstrap and args.lto_lld: + print 'Building LTO lld' + if os.path.exists(LLVM_LTO_LLD_DIR): + RmTree(LLVM_LTO_LLD_DIR) + EnsureDirExists(LLVM_LTO_LLD_DIR) + os.chdir(LLVM_LTO_LLD_DIR) - # Create a symlink to LLVMgold.so build in the previous step so that ar - # and ranlib could find it while linking LLVMgold.so with LTO. - EnsureDirExists(BFD_PLUGINS_DIR) - RunCommand(['ln', '-sf', - os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib', 'LLVMgold.so'), - os.path.join(BFD_PLUGINS_DIR, 'LLVMgold.so')]) + # The linker expects all archive members to have symbol tables, so the + # archiver needs to be able to create symbol tables for bitcode files. + # GNU ar and ranlib don't understand bitcode files, but llvm-ar and + # llvm-ranlib do, so use them. + ar = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'llvm-ar') + ranlib = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'llvm-ranlib') - # Link against binutils's copy of tcmalloc to speed up the linker by ~10%. - # In package.py we copy the .so into our package. - tcmalloc_ldflags = ['-L' + BINUTILS_LIB_DIR, '-ltcmalloc_minimal'] - # Make sure that tblgen and the test suite can find tcmalloc. - os.environ['LD_LIBRARY_PATH'] = \ - BINUTILS_LIB_DIR + os.pathsep + os.environ.get('LD_LIBRARY_PATH', '') - - lto_cflags = ['-flto=thin'] - lto_ldflags = ['-fuse-ld=lld'] - if args.gcc_toolchain: - # Tell the bootstrap compiler to use a specific gcc prefix to search - # for standard library headers and shared object files. - lto_cflags += ['--gcc-toolchain=' + args.gcc_toolchain] lto_cmake_args = base_cmake_args + [ - '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, '-DCMAKE_C_COMPILER=' + cc, '-DCMAKE_CXX_COMPILER=' + cxx, - '-DCMAKE_C_FLAGS=' + ' '.join(lto_cflags), - '-DCMAKE_CXX_FLAGS=' + ' '.join(lto_cflags), - '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(lto_ldflags + tcmalloc_ldflags), - '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(lto_ldflags), - '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(lto_ldflags)] - - # We need to use the proper binutils which support LLVM Gold plugin. - lto_env = os.environ.copy() - lto_env['PATH'] = BINUTILS_BIN_DIR + os.pathsep + lto_env.get('PATH', '') + '-DCMAKE_AR=' + ar, + '-DCMAKE_RANLIB=' + ranlib, + '-DLLVM_ENABLE_LTO=thin', + '-DLLVM_USE_LINKER=lld', + '-DCMAKE_C_FLAGS=' + ' '.join(cflags), + '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)] RmCmakeCache('.') - RunCommand(['cmake'] + lto_cmake_args + [LLVM_DIR], env=lto_env) - RunCommand(['ninja', 'LLVMgold', 'lld'], env=lto_env) + RunCommand(['cmake'] + lto_cmake_args + [LLVM_DIR]) + RunCommand(['ninja', 'lld']) # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is @@ -636,7 +610,6 @@ chrome_tools = list(set(default_tools + args.extra_tools)) cmake_args += base_cmake_args + [ '-DLLVM_ENABLE_THREADS=OFF', - '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, '-DCMAKE_C_FLAGS=' + ' '.join(cflags), '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags), '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags), @@ -663,8 +636,8 @@ RunCommand(['ninja'], msvc_arch='x64') # Copy LTO-optimized lld, if any. - if args.bootstrap and args.lto_gold_plugin: - CopyFile(os.path.join(LLVM_LTO_GOLD_PLUGIN_DIR, 'bin', 'lld'), + if args.bootstrap and args.lto_lld: + CopyFile(os.path.join(LLVM_LTO_LLD_DIR, 'bin', 'lld'), os.path.join(LLVM_BUILD_DIR, 'bin')) if chrome_tools: @@ -841,8 +814,8 @@ parser.add_argument('--gcc-toolchain', help='set the version for which gcc ' 'version be used for building; --gcc-toolchain=/opt/foo ' 'picks /opt/foo/bin/gcc') - parser.add_argument('--lto-gold-plugin', action='store_true', - help='build LLVM Gold plugin with LTO') + parser.add_argument('--lto-lld', action='store_true', + help='build lld with LTO') parser.add_argument('--llvm-force-head-revision', action='store_true', help=('use the revision in the repo when printing ' 'the revision')) @@ -860,12 +833,12 @@ default=sys.platform.startswith('linux')) args = parser.parse_args() - if args.lto_gold_plugin and not args.bootstrap: - print '--lto-gold-plugin requires --bootstrap' + if args.lto_lld and not args.bootstrap: + print '--lto-lld requires --bootstrap' return 1 - if args.lto_gold_plugin and not sys.platform.startswith('linux'): - print '--lto-gold-plugin is only effective on Linux. Ignoring the option.' - args.lto_gold_plugin = False + if args.lto_lld and not sys.platform.startswith('linux'): + print '--lto-lld is only effective on Linux. Ignoring the option.' + args.lto_lld = False if args.if_needed: # TODO(thakis): Can probably remove this and --if-needed altogether.
diff --git a/tools/gn/action_target_generator.cc b/tools/gn/action_target_generator.cc index b7efa43..52d64ac95 100644 --- a/tools/gn/action_target_generator.cc +++ b/tools/gn/action_target_generator.cc
@@ -8,6 +8,7 @@ #include "tools/gn/build_settings.h" #include "tools/gn/err.h" #include "tools/gn/filesystem_utils.h" +#include "tools/gn/functions.h" #include "tools/gn/parse_tree.h" #include "tools/gn/scope.h" #include "tools/gn/value.h" @@ -58,7 +59,7 @@ if (!FillDepfile()) return; - if (!FillConsole()) + if (!FillPool()) return; if (!FillCheckIncludes()) @@ -159,13 +160,20 @@ return true; } -bool ActionTargetGenerator::FillConsole() { - const Value* value = scope_->GetValue(variables::kConsole, true); +bool ActionTargetGenerator::FillPool() { + const Value* value = scope_->GetValue(variables::kPool, true); if (!value) return true; - if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) + + Label label = Label::Resolve(scope_->GetSourceDir(), + ToolchainLabelForScope(scope_), *value, err_); + if (err_->has_error()) return false; - target_->action_values().set_console(value->boolean_value()); + + LabelPtrPair<Pool> pair(label); + pair.origin = target_->defined_from(); + + target_->action_values().set_pool(std::move(pair)); return true; }
diff --git a/tools/gn/action_target_generator.h b/tools/gn/action_target_generator.h index 0a69eda..3833b81f 100644 --- a/tools/gn/action_target_generator.h +++ b/tools/gn/action_target_generator.h
@@ -27,7 +27,7 @@ bool FillScriptArgs(); bool FillResponseFileContents(); bool FillDepfile(); - bool FillConsole(); + bool FillPool(); // Checks for errors in the outputs variable. bool CheckOutputs();
diff --git a/tools/gn/action_values.cc b/tools/gn/action_values.cc index 28c4a11e..0a0c552 100644 --- a/tools/gn/action_values.cc +++ b/tools/gn/action_values.cc
@@ -8,7 +8,7 @@ #include "tools/gn/substitution_writer.h" #include "tools/gn/target.h" -ActionValues::ActionValues() : console_(false) {} +ActionValues::ActionValues() {} ActionValues::~ActionValues() {}
diff --git a/tools/gn/action_values.h b/tools/gn/action_values.h index 879ccf6..806a39f 100644 --- a/tools/gn/action_values.h +++ b/tools/gn/action_values.h
@@ -9,9 +9,11 @@ #include <vector> #include "base/macros.h" +#include "tools/gn/label_ptr.h" #include "tools/gn/source_file.h" #include "tools/gn/substitution_list.h" +class Pool; class Target; // Holds the values (outputs, args, script name, etc.) for either an action or @@ -50,9 +52,9 @@ } bool uses_rsp_file() const { return !rsp_file_contents_.list().empty(); } - // Console pool option - bool is_console() const { return console_; } - void set_console(bool value) { console_ = value; } + // Pool option + const LabelPtrPair<Pool>& pool() const { return pool_; } + void set_pool(LabelPtrPair<Pool> pool) { pool_ = std::move(pool); } private: SourceFile script_; @@ -60,7 +62,7 @@ SubstitutionList outputs_; SubstitutionPattern depfile_; SubstitutionList rsp_file_contents_; - bool console_; + LabelPtrPair<Pool> pool_; DISALLOW_COPY_AND_ASSIGN(ActionValues); };
diff --git a/tools/gn/builder.cc b/tools/gn/builder.cc index bb3f834..bfae69f6 100644 --- a/tools/gn/builder.cc +++ b/tools/gn/builder.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <utility> +#include "tools/gn/action_values.h" #include "tools/gn/config.h" #include "tools/gn/deps_iterator.h" #include "tools/gn/err.h" @@ -227,6 +228,7 @@ !AddDeps(record, target->configs().vector(), err) || !AddDeps(record, target->all_dependent_configs(), err) || !AddDeps(record, target->public_configs(), err) || + !AddActionValuesDep(record, target->action_values(), err) || !AddToolchainDep(record, target, err)) return false; @@ -389,6 +391,22 @@ return true; } +bool Builder::AddActionValuesDep(BuilderRecord* record, + const ActionValues& action_values, + Err* err) { + if (action_values.pool().label.is_null()) + return true; + + BuilderRecord* pool_record = GetResolvedRecordOfType( + action_values.pool().label, action_values.pool().origin, + BuilderRecord::ITEM_POOL, err); + if (!pool_record) + return false; + record->AddDep(pool_record); + + return true; +} + bool Builder::AddToolchainDep(BuilderRecord* record, const Target* target, Err* err) { @@ -439,6 +457,7 @@ !ResolveConfigs(&target->configs(), err) || !ResolveConfigs(&target->all_dependent_configs(), err) || !ResolveConfigs(&target->public_configs(), err) || + !ResolveActionValues(&target->action_values(), err) || !ResolveToolchain(target, err)) return false; } else if (record->type() == BuilderRecord::ITEM_CONFIG) { @@ -519,6 +538,20 @@ return true; } +bool Builder::ResolveActionValues(ActionValues* action_values, Err* err) { + if (action_values->pool().label.is_null()) + return true; + + BuilderRecord* record = GetResolvedRecordOfType( + action_values->pool().label, action_values->pool().origin, + BuilderRecord::ITEM_POOL, err); + if (!record) + return false; + action_values->set_pool(LabelPtrPair<Pool>(record->item()->AsPool())); + + return true; +} + bool Builder::ResolvePools(Toolchain* toolchain, Err* err) { for (int i = Toolchain::TYPE_NONE + 1; i < Toolchain::TYPE_NUMTYPES; i++) { Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(i);
diff --git a/tools/gn/builder.h b/tools/gn/builder.h index e10df4d8..d46bbd1 100644 --- a/tools/gn/builder.h +++ b/tools/gn/builder.h
@@ -14,6 +14,7 @@ #include "tools/gn/label_ptr.h" #include "tools/gn/unique_vector.h" +class ActionValues; class Err; class Loader; class ParseNode; @@ -90,6 +91,9 @@ bool AddDeps(BuilderRecord* record, const LabelTargetVector& targets, Err* err); + bool AddActionValuesDep(BuilderRecord* record, + const ActionValues& action_values, + Err* err); bool AddToolchainDep(BuilderRecord* record, const Target* target, Err* err); @@ -117,6 +121,7 @@ // if anything isn't found or if the type doesn't match. bool ResolveDeps(LabelTargetVector* deps, Err* err); bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err); + bool ResolveActionValues(ActionValues* action_values, Err* err); bool ResolveToolchain(Target* target, Err* err); bool ResolvePools(Toolchain* toolchain, Err* err);
diff --git a/tools/gn/command_help.cc b/tools/gn/command_help.cc index eb13456..a6777cfe 100644 --- a/tools/gn/command_help.cc +++ b/tools/gn/command_help.cc
@@ -245,10 +245,8 @@ // Check functions. const functions::FunctionInfoMap& function_map = functions::GetFunctions(); auto found_function = function_map.find(what); - if (found_function != function_map.end()) { + if (found_function != function_map.end()) PrintLongHelp(found_function->second.help); - return 0; - } for (const auto& entry : function_map) all_help_topics.push_back(entry.first); @@ -256,10 +254,8 @@ const variables::VariableInfoMap& builtin_vars = variables::GetBuiltinVariables(); auto found_builtin_var = builtin_vars.find(what); - if (found_builtin_var != builtin_vars.end()) { + if (found_builtin_var != builtin_vars.end()) PrintLongHelp(found_builtin_var->second.help); - return 0; - } for (const auto& entry : builtin_vars) all_help_topics.push_back(entry.first); @@ -267,13 +263,16 @@ const variables::VariableInfoMap& target_vars = variables::GetTargetVariables(); auto found_target_var = target_vars.find(what); - if (found_target_var != target_vars.end()) { + if (found_target_var != target_vars.end()) PrintLongHelp(found_target_var->second.help); - return 0; - } for (const auto& entry : target_vars) all_help_topics.push_back(entry.first); + if (found_function != function_map.end() || + found_builtin_var != builtin_vars.end() || + found_target_var != target_vars.end()) + return 0; + // Random other topics. std::map<std::string, void(*)()> random_topics; random_topics["all"] = PrintAllHelp;
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md index 5c50db5..de924a7 100644 --- a/tools/gn/docs/reference.md +++ b/tools/gn/docs/reference.md
@@ -42,6 +42,7 @@ * [get_target_outputs: [file list] Get the list of outputs from a target.](#get_target_outputs) * [getenv: Get an environment variable.](#getenv) * [import: Import a file into the current scope.](#import) + * [not_needed: Mark variables from scope as not needed.](#not_needed) * [pool: Defines a pool object.](#pool) * [print: Prints to the console.](#print) * [process_file_template: Do template expansion over a list of files.](#process_file_template) @@ -96,7 +97,7 @@ * [code_signing_sources: [file list] Sources for code signing step.](#code_signing_sources) * [complete_static_lib: [boolean] Links all deps into a static library.](#complete_static_lib) * [configs: [label list] Configs applying to this target or config.](#configs) - * [console: [boolean] Run this action in the console pool.](#console) + * [console: [label] Console pool object.](#console) * [data: [file list] Runtime data file dependencies.](#data) * [data_deps: [label list] Non-linked dependencies.](#data_deps) * [defines: [string list] C preprocessor defines.](#defines) @@ -112,6 +113,7 @@ * [output_name: [string] Name for the output file other than the default.](#output_name) * [output_prefix_override: [boolean] Don't use prefix for output name.](#output_prefix_override) * [outputs: [file list] Output files for actions and copy targets.](#outputs) + * [pool: [string] Label of the pool used by the action.](#pool) * [precompiled_header: [string] Header file to precompile.](#precompiled_header) * [precompiled_header_type: [string] "gcc" or "msvc".](#precompiled_header_type) * [precompiled_source: [file name] Source file to precompile.](#precompiled_source) @@ -2136,6 +2138,25 @@ # Looks in the current directory. import("my_vars.gni") ``` +### <a name="not_needed"></a>**not_needed**: Mark variables from scope as not needed. + +``` + not_needed(variable_list_or_star, variable_to_ignore_list = []) + not_needed(from_scope, variable_list_or_star, + variable_to_ignore_list = []) + + Mark the variables in the current or given scope as not needed, which means + you will not get an error about unused variables for these. +``` + +#### **Example** + +``` + not_needed("*", [ "config" ]) + not_needed([ "data_deps", "deps" ]) + not_needed(invoker, "*", [ "config" ]) + not_needed(invoker, [ "data_deps", "deps" ]) +``` ### <a name="pool"></a>**pool**: Defines a pool object. ``` @@ -2711,6 +2732,7 @@ Other tools: "stamp": Tool for creating stamp files "copy": Tool to copy files. + "action": Defaults for actions Platform specific tools: "copy_bundle_data": [iOS, OS X] Tool to copy files in a bundle. @@ -2721,7 +2743,7 @@ ``` command [string with substitutions] - Valid for: all tools (required) + Valid for: all tools except "action" (required) The command to run. @@ -2821,6 +2843,7 @@ ] pool [label, optional] + Valid for: all tools (optional) Label of the pool to use for the tool. Pools are used to limit the number of tasks that can execute concurrently during the build. @@ -2891,13 +2914,13 @@ restat = true rspfile [string with substitutions] - Valid for: all tools (optional) + Valid for: all tools except "action" (optional) Name of the response file. If empty, no response file will be used. See "rspfile_content". rspfile_content [string with substitutions] - Valid for: all tools (required when "rspfile" is specified) + Valid for: all tools except "action" (required when "rspfile" is used) The contents to be written to the response file. This may include all or part of the command to send to the tool which allows you to get @@ -4304,15 +4327,13 @@ } } ``` -### <a name="console"></a>**console**: Run this action in the console pool. +### <a name="console"></a>**console**: Console pool objects. ``` - Boolean. Defaults to false. - - Actions marked "console = true" will be run in the built-in ninja "console" - pool. They will have access to real stdin and stdout, and output will not be - buffered by ninja. This can be useful for long-running actions with progress - logs, or actions that require user input. + Console pool is a special pool object that uses the built-in ninja "console" + pool. Target using this pool will have access to real stdin and stdout, and + output will not be buffered by ninja. This can be useful for long-running + actions with progress logs, or actions that require user input. Only one console pool target can run at any one time in Ninja. Refer to the Ninja documentation on the console pool for more info. @@ -4321,8 +4342,10 @@ #### **Example** ``` - action("long_action_with_progress_logs") { - console = true + action("my_action") { + ... + pool = console + ... } ``` ### <a name="data"></a>**data**: Runtime data file dependencies. @@ -4870,6 +4893,21 @@ Action targets (excluding action_foreach) must list literal output file(s) with no source expansions. See "gn help action". ``` +### <a name="pool"></a>**pool**: Label of the pool used by the action. + +``` + A fully-qualified label representing the pool that will be used for the + action. Pools are defined using the pool() {...} declaration. +``` + +#### **Example** + +``` + action("action") { + pool = "//build:custom_pool" + ... + } +``` ### <a name="precompiled_header"></a>**precompiled_header**: [string] Header file to precompile. ```
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc index 05c764b..baac8ee 100644 --- a/tools/gn/function_toolchain.cc +++ b/tools/gn/function_toolchain.cc
@@ -531,6 +531,7 @@ Other tools: "stamp": Tool for creating stamp files "copy": Tool to copy files. + "action": Defaults for actions Platform specific tools: "copy_bundle_data": [iOS, OS X] Tool to copy files in a bundle. @@ -539,7 +540,7 @@ Tool variables command [string with substitutions] - Valid for: all tools (required) + Valid for: all tools except "action" (required) The command to run. @@ -639,6 +640,7 @@ ] pool [label, optional] + Valid for: all tools (optional) Label of the pool to use for the tool. Pools are used to limit the number of tasks that can execute concurrently during the build. @@ -709,13 +711,13 @@ restat = true rspfile [string with substitutions] - Valid for: all tools (optional) + Valid for: all tools except "action" (optional) Name of the response file. If empty, no response file will be used. See "rspfile_content". rspfile_content [string with substitutions] - Valid for: all tools (required when "rspfile" is specified) + Valid for: all tools except "action" (required when "rspfile" is used) The contents to be written to the response file. This may include all or part of the command to send to the tool which allows you to get @@ -1051,12 +1053,12 @@ return Value(); } - if (tool_type != Toolchain::TYPE_COPY && - tool_type != Toolchain::TYPE_STAMP && + if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP && tool_type != Toolchain::TYPE_COPY_BUNDLE_DATA && - tool_type != Toolchain::TYPE_COMPILE_XCASSETS) { + tool_type != Toolchain::TYPE_COMPILE_XCASSETS && + tool_type != Toolchain::TYPE_ACTION) { // All tools should have outputs, except the copy, stamp, copy_bundle_data - // and compile_xcassets tools that generate their outputs internally. + // compile_xcassets and action tools that generate their outputs internally. if (!ReadPatternList(&block_scope, "outputs", subst_output_validator, tool.get(), &Tool::set_outputs, err) || !ValidateOutputs(tool.get(), err))
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index 1d17d4298..23319e4 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc
@@ -638,6 +638,122 @@ return Value(); } +// not_needed ----------------------------------------------------------------- + +const char kNotNeeded[] = "not_needed"; +const char kNotNeeded_HelpShort[] = + "not_needed: Mark variables from scope as not needed."; +const char kNotNeeded_Help[] = + R"(not_needed: Mark variables from scope as not needed. + + not_needed(variable_list_or_star, variable_to_ignore_list = []) + not_needed(from_scope, variable_list_or_star, + variable_to_ignore_list = []) + + Mark the variables in the current or given scope as not needed, which means + you will not get an error about unused variables for these. The + variable_to_ignore_list allows excluding variables from "all matches" if + variable_list_or_star is "*". + +Example + + not_needed("*", [ "config" ]) + not_needed([ "data_deps", "deps" ]) + not_needed(invoker, "*", [ "config" ]) + not_needed(invoker, [ "data_deps", "deps" ]) +)"; + +Value RunNotNeeded(Scope* scope, + const FunctionCallNode* function, + const ListNode* args_list, + Err* err) { + const auto& args_vector = args_list->contents(); + if (args_vector.size() < 1 && args_vector.size() > 3) { + *err = Err(function, "Wrong number of arguments.", + "Expecting one, two or three arguments."); + return Value(); + } + auto args_cur = args_vector.begin(); + + Value* value = nullptr; // Value to use, may point to result_value. + Value result_value; // Storage for the "evaluate" case. + const IdentifierNode* identifier = (*args_cur)->AsIdentifier(); + if (identifier) { + // Optimize the common case where the input scope is an identifier. This + // prevents a copy of a potentially large Scope object. + value = scope->GetMutableValue(identifier->value().value(), + Scope::SEARCH_NESTED, true); + if (!value) { + *err = Err(identifier, "Undefined identifier."); + return Value(); + } + } else { + // Non-optimized case, just evaluate the argument. + result_value = (*args_cur)->Execute(scope, err); + if (err->has_error()) + return Value(); + value = &result_value; + } + args_cur++; + + // Extract the source scope if different from current one. + Scope* source = scope; + if (value->type() == Value::SCOPE) { + source = value->scope_value(); + result_value = (*args_cur)->Execute(scope, err); + if (err->has_error()) + return Value(); + value = &result_value; + args_cur++; + } + + // Extract the exclusion list if defined. + Value exclusion_value; + std::set<std::string> exclusion_set; + if (args_cur != args_vector.end()) { + exclusion_value = (*args_cur)->Execute(source, err); + if (err->has_error()) + return Value(); + + if (exclusion_value.type() != Value::LIST) { + *err = Err(exclusion_value, "Not a valid list of variables to exclude.", + "Expecting a list of strings."); + return Value(); + } + + for (const Value& cur : exclusion_value.list_value()) { + if (!cur.VerifyTypeIs(Value::STRING, err)) + return Value(); + + exclusion_set.insert(cur.string_value()); + } + } + + if (value->type() == Value::STRING) { + if (value->string_value() == "*") { + source->MarkAllUsed(exclusion_set); + return Value(); + } + } else if (value->type() == Value::LIST) { + if (exclusion_value.type() != Value::NONE) { + *err = Err(exclusion_value, "Not supported with a variable list.", + "Exclusion list can only be used with the string \"*\"."); + return Value(); + } + for (const Value& cur : value->list_value()) { + if (!cur.VerifyTypeIs(Value::STRING, err)) + return Value(); + source->MarkUsed(cur.string_value()); + } + return Value(); + } + + // Not the right type of argument. + *err = Err(*value, "Not a valid list of variables.", + "Expecting either the string \"*\" or a list of strings."); + return Value(); +} + // set_sources_assignment_filter ----------------------------------------------- const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; @@ -1040,6 +1156,7 @@ INSERT_FUNCTION(GetPathInfo, false) INSERT_FUNCTION(GetTargetOutputs, false) INSERT_FUNCTION(Import, false) + INSERT_FUNCTION(NotNeeded, false) INSERT_FUNCTION(Pool, false) INSERT_FUNCTION(Print, false) INSERT_FUNCTION(ProcessFileTemplate, false)
diff --git a/tools/gn/functions.h b/tools/gn/functions.h index 401384acb..c09612c 100644 --- a/tools/gn/functions.h +++ b/tools/gn/functions.h
@@ -221,6 +221,14 @@ BlockNode* block, Err* err); +extern const char kNotNeeded[]; +extern const char kNotNeeded_HelpShort[]; +extern const char kNotNeeded_Help[]; +Value RunNotNeeded(Scope* scope, + const FunctionCallNode* function, + const ListNode* args_list, + Err* err); + extern const char kPool[]; extern const char kPool_HelpShort[]; extern const char kPool_Help[];
diff --git a/tools/gn/functions_target_unittest.cc b/tools/gn/functions_target_unittest.cc index 525bc7c..cef75170 100644 --- a/tools/gn/functions_target_unittest.cc +++ b/tools/gn/functions_target_unittest.cc
@@ -37,6 +37,59 @@ ASSERT_TRUE(err.has_error()); } +// Checks that we find uses of identifiers marked as not needed. +TEST(FunctionsTarget, CheckNotNeeded) { + Scheduler scheduler; + TestWithScope setup; + + // The target generator needs a place to put the targets or it will fail. + Scope::ItemVector item_collector; + setup.scope()->set_item_collector(&item_collector); + + TestParseInput nonscoped_input( + "source_set(\"foo\") {\n" + " a = 1\n" + " not_needed([ \"a\" ])\n" + "}\n"); + ASSERT_FALSE(nonscoped_input.has_error()); + Err err; + nonscoped_input.parsed()->Execute(setup.scope(), &err); + ASSERT_FALSE(err.has_error()) << err.message(); + + TestParseInput scoped_input( + "source_set(\"foo\") {\n" + " a = {x = 1 y = 2}\n" + " not_needed(a, \"*\")\n" + "}\n"); + ASSERT_FALSE(scoped_input.has_error()); + err = Err(); + scoped_input.parsed()->Execute(setup.scope(), &err); + ASSERT_FALSE(err.has_error()) << err.message(); + + TestParseInput exclusion_input( + "source_set(\"foo\") {\n" + " x = 1\n" + " y = 2\n" + " not_needed(\"*\", [ \"y\" ])\n" + "}\n"); + ASSERT_FALSE(exclusion_input.has_error()); + err = Err(); + exclusion_input.parsed()->Execute(setup.scope(), &err); + ASSERT_TRUE(err.has_error()) << err.message(); + EXPECT_EQ("Assignment had no effect.", err.message()); + + TestParseInput error_input( + "source_set(\"foo\") {\n" + " a = {x = 1 y = 2}\n" + " not_needed(a, [ \"x \"], [ \"y\" ])\n" + "}\n"); + ASSERT_FALSE(error_input.has_error()); + err = Err(); + error_input.parsed()->Execute(setup.scope(), &err); + ASSERT_TRUE(err.has_error()); + EXPECT_EQ("Not supported with a variable list.", err.message()); +} + // Checks that the defaults applied to a template invoked by target() use // the name of the template, rather than the string "target" (which is the // name of the actual function being called).
diff --git a/tools/gn/ninja_action_target_writer.cc b/tools/gn/ninja_action_target_writer.cc index 9e56362..74270a0 100644 --- a/tools/gn/ninja_action_target_writer.cc +++ b/tools/gn/ninja_action_target_writer.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_util.h" #include "tools/gn/deps_iterator.h" #include "tools/gn/err.h" +#include "tools/gn/pool.h" #include "tools/gn/settings.h" #include "tools/gn/string_utils.h" #include "tools/gn/substitution_writer.h" @@ -76,8 +77,10 @@ WriteDepfile(SourceFile()); out_ << std::endl; } - if (target_->action_values().is_console()) { - out_ << " pool = console"; + if (target_->action_values().pool().ptr) { + out_ << " pool = "; + out_ << target_->action_values().pool().ptr->GetNinjaName( + settings_->default_toolchain_label()); out_ << std::endl; } } @@ -143,6 +146,13 @@ out_ << std::endl; out_ << " description = ACTION " << target_label << std::endl; out_ << " restat = 1" << std::endl; + const Tool* tool = target_->toolchain()->GetTool(Toolchain::TYPE_ACTION); + if (tool && tool->pool().ptr) { + out_ << " pool = "; + out_ << tool->pool().ptr->GetNinjaName( + settings_->default_toolchain_label()); + out_ << std::endl; + } return custom_rule_name; }
diff --git a/tools/gn/ninja_action_target_writer_unittest.cc b/tools/gn/ninja_action_target_writer_unittest.cc index ab871d1..2d42765 100644 --- a/tools/gn/ninja_action_target_writer_unittest.cc +++ b/tools/gn/ninja_action_target_writer_unittest.cc
@@ -8,6 +8,7 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "tools/gn/ninja_action_target_writer.h" +#include "tools/gn/pool.h" #include "tools/gn/substitution_list.h" #include "tools/gn/target.h" #include "tools/gn/test_with_scope.h" @@ -87,7 +88,10 @@ target.action_values().outputs() = SubstitutionList::MakeForTest("//out/Debug/foo.out"); - target.action_values().set_console(true); + + Pool pool(setup.settings(), Label(SourceDir("//foo/"), "pool")); + pool.set_console(true); + target.action_values().set_pool(LabelPtrPair<Pool>(&pool)); target.SetToolchain(setup.toolchain()); ASSERT_TRUE(target.OnResolved(&err));
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc index aace0ca8..be55270 100644 --- a/tools/gn/ninja_build_writer.cc +++ b/tools/gn/ninja_build_writer.cc
@@ -286,6 +286,14 @@ } } + for (const Target* target : default_toolchain_targets_) { + if (target->output_type() == Target::ACTION) { + const LabelPtrPair<Pool>& pool = target->action_values().pool(); + if (pool.ptr) + used_pools.insert(pool.ptr); + } + } + // Write pools sorted by their name, to make output deterministic. std::vector<const Pool*> sorted_pools(used_pools.begin(), used_pools.end()); auto pool_name = [this](const Pool* pool) {
diff --git a/tools/gn/ninja_toolchain_writer.cc b/tools/gn/ninja_toolchain_writer.cc index a48a8b9..911a474 100644 --- a/tools/gn/ninja_toolchain_writer.cc +++ b/tools/gn/ninja_toolchain_writer.cc
@@ -46,6 +46,8 @@ for (int i = Toolchain::TYPE_NONE + 1; i < Toolchain::TYPE_NUMTYPES; i++) { Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(i); const Tool* tool = toolchain_->GetTool(tool_type); + if (tool_type == Toolchain::TYPE_ACTION) + continue; if (tool) WriteToolRule(tool_type, tool, rule_prefix); }
diff --git a/tools/gn/pool.cc b/tools/gn/pool.cc index 75a7504..b1bb4904 100644 --- a/tools/gn/pool.cc +++ b/tools/gn/pool.cc
@@ -25,6 +25,9 @@ } std::string Pool::GetNinjaName(bool include_toolchain) const { + if (console_) + return "console"; + std::ostringstream buffer; if (include_toolchain) { DCHECK(label().toolchain_dir().is_source_absolute());
diff --git a/tools/gn/pool.h b/tools/gn/pool.h index 81a021db..08da33c 100644 --- a/tools/gn/pool.h +++ b/tools/gn/pool.h
@@ -29,6 +29,10 @@ int64_t depth() const { return depth_; } void set_depth(int64_t depth) { depth_ = depth; } + // Console pool option + bool is_console() const { return console_; } + void set_console(bool value) { console_ = value; } + // The pool name in generated ninja files. std::string GetNinjaName(const Label& default_toolchain) const; @@ -36,6 +40,7 @@ std::string GetNinjaName(bool include_toolchain) const; int64_t depth_ = 0; + bool console_ = false; }; #endif // TOOLS_GN_POOL_H_
diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc index f2fe7521..437fdba 100644 --- a/tools/gn/scope.cc +++ b/tools/gn/scope.cc
@@ -219,6 +219,16 @@ cur.second.used = true; } +void Scope::MarkAllUsed(const std::set<std::string>& excluded_values) { + for (auto& cur : values_) { + if (!excluded_values.empty() && + excluded_values.find(cur.first.as_string()) != excluded_values.end()) { + continue; // Skip this excluded value. + } + cur.second.used = true; + } +} + void Scope::MarkUnused(const base::StringPiece& ident) { RecordMap::iterator found = values_.find(ident); if (found == values_.end()) {
diff --git a/tools/gn/scope.h b/tools/gn/scope.h index 31bac626..eeabbeb 100644 --- a/tools/gn/scope.h +++ b/tools/gn/scope.h
@@ -206,6 +206,7 @@ // Marks the given identifier as (un)used in the current scope. void MarkUsed(const base::StringPiece& ident); void MarkAllUsed(); + void MarkAllUsed(const std::set<std::string>& excluded_values); void MarkUnused(const base::StringPiece& ident); // Checks to see if the scope has a var set that hasn't been used. This is
diff --git a/tools/gn/toolchain.cc b/tools/gn/toolchain.cc index 70c6ce06..28e0d9a 100644 --- a/tools/gn/toolchain.cc +++ b/tools/gn/toolchain.cc
@@ -26,6 +26,7 @@ const char* Toolchain::kToolCopy = "copy"; const char* Toolchain::kToolCopyBundleData = "copy_bundle_data"; const char* Toolchain::kToolCompileXCAssets = "compile_xcassets"; +const char* Toolchain::kToolAction = "action"; Toolchain::Toolchain(const Settings* settings, const Label& label) : Item(settings, label), @@ -59,6 +60,7 @@ if (str == kToolCopy) return TYPE_COPY; if (str == kToolCopyBundleData) return TYPE_COPY_BUNDLE_DATA; if (str == kToolCompileXCAssets) return TYPE_COMPILE_XCASSETS; + if (str == kToolAction) return TYPE_ACTION; return TYPE_NONE; } @@ -79,6 +81,7 @@ case TYPE_COPY: return kToolCopy; case TYPE_COPY_BUNDLE_DATA: return kToolCopyBundleData; case TYPE_COMPILE_XCASSETS: return kToolCompileXCAssets; + case TYPE_ACTION: return kToolAction; default: NOTREACHED(); return std::string();
diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h index 7b61f34..368c2db4 100644 --- a/tools/gn/toolchain.h +++ b/tools/gn/toolchain.h
@@ -47,6 +47,7 @@ TYPE_COPY, TYPE_COPY_BUNDLE_DATA, TYPE_COMPILE_XCASSETS, + TYPE_ACTION, TYPE_NUMTYPES // Must be last. }; @@ -65,6 +66,7 @@ static const char* kToolCopy; static const char* kToolCopyBundleData; static const char* kToolCompileXCAssets; + static const char* kToolAction; // The Settings of an Item is always the context in which the Item was // defined. For a toolchain this is confusing because this is NOT the
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc index bbb8791..0998b38 100644 --- a/tools/gn/variables.cc +++ b/tools/gn/variables.cc
@@ -927,29 +927,6 @@ } )"; -const char kConsole[] = "console"; -const char kConsole_HelpShort[] = - "console: [boolean] Run this action in the console pool."; -const char kConsole_Help[] = - R"(console: Run this action in the console pool. - - Boolean. Defaults to false. - - Actions marked "console = true" will be run in the built-in ninja "console" - pool. They will have access to real stdin and stdout, and output will not be - buffered by ninja. This can be useful for long-running actions with progress - logs, or actions that require user input. - - Only one console pool target can run at any one time in Ninja. Refer to the - Ninja documentation on the console pool for more info. - -Example - - action("long_action_with_progress_logs") { - console = true - } -)"; - const char kData[] = "data"; const char kData_HelpShort[] = "data: [file list] Runtime data file dependencies."; @@ -1441,6 +1418,23 @@ with no source expansions. See "gn help action". )"; +const char kPool[] = "pool"; +const char kPool_HelpShort[] = + "pool: [string] Label of the pool used by the action."; +const char kPool_Help[] = + R"(pool: Label of the pool used by the action. + + A fully-qualified label representing the pool that will be used for the + action. Pools are defined using the pool() {...} declaration. + +Example + + action("action") { + pool = "//build:custom_pool" + ... + } +)"; + const char kPrecompiledHeader[] = "precompiled_header"; const char kPrecompiledHeader_HelpShort[] = "precompiled_header: [string] Header file to precompile."; @@ -1905,7 +1899,6 @@ INSERT_VARIABLE(CodeSigningOutputs) INSERT_VARIABLE(CompleteStaticLib) INSERT_VARIABLE(Configs) - INSERT_VARIABLE(Console) INSERT_VARIABLE(Data) INSERT_VARIABLE(DataDeps) INSERT_VARIABLE(Defines) @@ -1921,6 +1914,7 @@ INSERT_VARIABLE(OutputName) INSERT_VARIABLE(OutputPrefixOverride) INSERT_VARIABLE(Outputs) + INSERT_VARIABLE(Pool) INSERT_VARIABLE(PrecompiledHeader) INSERT_VARIABLE(PrecompiledHeaderType) INSERT_VARIABLE(PrecompiledSource)
diff --git a/tools/gn/variables.h b/tools/gn/variables.h index 2af40c5e..7e56699 100644 --- a/tools/gn/variables.h +++ b/tools/gn/variables.h
@@ -171,10 +171,6 @@ extern const char kConfigs_HelpShort[]; extern const char kConfigs_Help[]; -extern const char kConsole[]; -extern const char kConsole_HelpShort[]; -extern const char kConsole_Help[]; - extern const char kData[]; extern const char kData_HelpShort[]; extern const char kData_Help[]; @@ -235,6 +231,10 @@ extern const char kOutputs_HelpShort[]; extern const char kOutputs_Help[]; +extern const char kPool[]; +extern const char kPool_HelpShort[]; +extern const char kPool_Help[]; + extern const char kPrecompiledHeader[]; extern const char kPrecompiledHeader_HelpShort[]; extern const char kPrecompiledHeader_Help[];
diff --git a/tools/luci-go/linux64/isolate.sha1 b/tools/luci-go/linux64/isolate.sha1 index f14d0ea..acecc79 100644 --- a/tools/luci-go/linux64/isolate.sha1 +++ b/tools/luci-go/linux64/isolate.sha1
@@ -1 +1 @@ -bcc0e73f051cc01452c24babbb4be9d5f4556c55 +21410c557b49620e8a44ec0f861f94605bdc6d5c
diff --git a/tools/luci-go/mac64/isolate.sha1 b/tools/luci-go/mac64/isolate.sha1 index 7506974..16a7dd6a 100644 --- a/tools/luci-go/mac64/isolate.sha1 +++ b/tools/luci-go/mac64/isolate.sha1
@@ -1 +1 @@ -47ffac85c87dd0a2cfd6c4ded9c29c5bbcc8245d +1966687828a068eee4c5da45bbb8afd91cddda6f
diff --git a/tools/luci-go/win64/isolate.exe.sha1 b/tools/luci-go/win64/isolate.exe.sha1 index 9dccf31..6f5491d 100644 --- a/tools/luci-go/win64/isolate.exe.sha1 +++ b/tools/luci-go/win64/isolate.exe.sha1
@@ -1 +1 @@ -1ed79378fe41640a963f1aa6d1674e8456993d10 +35482264cea0f9b9dd2efe0a01620557fc15b7c1
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index c6435fb..b5de931 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -582,7 +582,6 @@ 'ios-simulator-eg': 'ios', 'ios-simulator-cronet': 'ios', 'ios-simulator-xcode-clang': 'ios', - 'mac_chromium_10.10_rel_ng': 'gpu_tests_release_trybot', 'mac_chromium_10.10_macviews': 'mac_views_browser_release_trybot', 'mac_chromium_10.12_rel_ng': 'gpu_tests_release_trybot', 'mac_chromium_archive_rel_ng': 'release_bot_mac_strip',
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 1e3d77ec..a6188e6 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -5221,6 +5221,12 @@ <description>The user triggered an event in in-product help.</description> </action> +<action name="InProductHelp.NotifyEvent.IPH_IncognitoWindow"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>The user triggered an event in in-product help.</description> +</action> + <action name="InProductHelp.NotifyEvent.IPH_NewTab"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -5251,6 +5257,12 @@ <description>The user triggered a used event in in-product help.</description> </action> +<action name="InProductHelp.NotifyUsedEvent.IPH_IncognitoWindow"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>The user triggered a used event in in-product help.</description> +</action> + <action name="InProductHelp.NotifyUsedEvent.IPH_NewTab"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -5293,6 +5305,15 @@ </description> </action> +<action name="InProductHelp.ShouldTriggerHelpUI.IPH_IncognitoWindow"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + The feature engagement tracker tried to determine whether in-product help + should be shown to the user. + </description> +</action> + <action name="InProductHelp.ShouldTriggerHelpUI.IPH_NewTab"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -5338,6 +5359,15 @@ </description> </action> +<action + name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_IncognitoWindow"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description> + A user action that could have triggered In-Product Help did not. + </description> +</action> + <action name="InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.IPH_NewTab"> <owner>nyquist@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -5374,6 +5404,13 @@ <description>A user action triggered In-Product Help.</description> </action> +<action + name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_IncognitoWindow"> + <owner>nyquist@chromium.org</owner> + <owner>xingliu@chromium.org</owner> + <description>A user action triggered In-Product Help.</description> +</action> + <action name="InProductHelp.ShouldTriggerHelpUIResult.Triggered.IPH_NewTab"> <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 b27765cf..d42f56a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2757,6 +2757,69 @@ <int value="2" label="Unknown"/> </enum> +<enum name="BlueZReasonOfDisconnection"> + <int value="1" label="Disconnected by local host"/> + <int value="2" label="Disconnected by remote device"/> + <int value="3" label="Supervision timeout"/> + <int value="4" label="Unknown"/> +</enum> + +<enum name="BlueZResultOfAdvertisementRegistration"> + <int value="1" label="Success"/> + <int value="2" label="LE unsupported"/> + <int value="3" label="LE disabled"/> + <int value="4" label="Advertisement data too long"/> + <int value="5" label="Busy adding/removing advertisement"/> + <int value="6" label="Advertisement client not created"/> + <int value="7" label="Invalid advertisement parameters"/> + <int value="8" label="Parsing advertisement data failed"/> + <int value="9" label="MGMT op not sent"/> + <int value="10" label="Unknown"/> +</enum> + +<enum name="BlueZResultOfConnection"> + <int value="1" label="Success LE"/> + <int value="2" label="Success BR/EDR"/> + <int value="3" label="Already connected LE"/> + <int value="4" label="Already connected BR/EDR"/> + <int value="5" label="Busy connecting/disconnecting"/> + <int value="6" label="Adapter not powered"/> + <int value="7" label="Failed LE"/> + <int value="8" label="Failed BR/EDR"/> + <int value="9" label="Page timeout BR/EDR"/> + <int value="10" label="BR/EDR profile unavailable"/> + <int value="11" label="SDP browse failed"/> + <int value="12" label="GATT browse failed"/> + <int value="13" label="Unknown"/> +</enum> + +<enum name="BlueZResultOfPairing"> + <int value="1" label="Success"/> + <int value="2" label="Adapter not powered"/> + <int value="3" label="Already paired"/> + <int value="4" label="Invalid parameters"/> + <int value="5" label="Busy pairing"/> + <int value="6" label="Not supported"/> + <int value="7" label="Connection Establishment failed"/> + <int value="8" label="Authentication failed"/> + <int value="9" label="Authentication rejected"/> + <int value="10" label="Authentication cancelled"/> + <int value="11" label="Authentication timeout"/> + <int value="12" label="Unknown"/> +</enum> + +<enum name="BlueZTypeOfDiscovery"> + <int value="1" label="BR/EDR"/> + <int value="2" label="LE"/> + <int value="3" label="DUAL"/> +</enum> + +<enum name="BlueZTypeOfFoundDevice"> + <int value="1" label="BR/EDR"/> + <int value="2" label="LE with public address"/> + <int value="3" label="LE with random address"/> +</enum> + <enum name="BookmarkLaunchLocation"> <int value="0" label="Attached bookmark bar"/> <int value="1" label="Detached (floating) bookmark bar"/> @@ -3170,6 +3233,11 @@ <int value="1" label="Has seek penalty (e.g. spinning disk)"/> </enum> +<enum name="BooleanHasSlowPathsWithNonAAPaint"> + <int value="0" label="Has no slow paths with non-AA paint"/> + <int value="1" label="Has slow paths with non-AA paint"/> +</enum> + <enum name="BooleanHit"> <int value="0" label="Not_reached"/> <int value="1" label="Hit"/> @@ -3550,6 +3618,11 @@ <int value="1" label="Visible"/> </enum> +<enum name="BooleanWaited"> + <int value="0" label="Did not wait"/> + <int value="1" label="Waited"/> +</enum> + <enum name="BooleanWasFast"> <int value="0" label="Slow"/> <int value="1" label="Fast"/> @@ -6565,6 +6638,12 @@ <int value="3" label="UserPaused"/> </enum> +<enum name="CrossProcessTimeDelta"> + <int value="0" label="Normal time delta measured"/> + <int value="1" label="Unexpectedly negative time delta measured"/> + <int value="2" label="The system clock is known to be inaccurate"/> +</enum> + <enum name="CrosTPMDictionaryAttackResetStatusEnum"> <int value="0" label="Reset not necessary"/> <int value="1" label="Reset attempt succeeded"/> @@ -12818,6 +12897,7 @@ <int value="1182" label="LOCKSCREENDATA_GETCONTENT"/> <int value="1183" label="LOCKSCREENDATA_SETCONTENT"/> <int value="1184" label="LOCKSCREENDATA_DELETE"/> + <int value="1185" label="BLUETOOTHLOWENERGY_RESETADVERTISING"/> </enum> <enum name="ExtensionIconState"> @@ -15544,6 +15624,7 @@ <int value="2030" label="MIDIOutputSend"/> <int value="2031" label="MIDIMessageEvent"/> <int value="2032" label="FetchEventIsReload"/> + <int value="2033" label="ServiceWorkerClientFrameType"/> </enum> <enum name="FeedbackSource"> @@ -22324,6 +22405,7 @@ <int value="-1212273428" label="enable-experimental-app-list"/> <int value="-1212167260" label="disable-app-window-cycling"/> <int value="-1208501269" label="AutofillScanThemeDialog:enabled"/> + <int value="-1206698676" label="MacV2Sandbox:disabled"/> <int value="-1206337150" label="OmniboxUIExperimentHideSuggestionUrlScheme:disabled"/> <int value="-1203955801" label="enable-password-change-support:disabled"/> @@ -23169,6 +23251,7 @@ <int value="1785093465" label="enable-document-passive-event-listeners"/> <int value="1786229999" label="disable-md-downloads"/> <int value="1786386775" label="TranslateCompactUI:disabled"/> + <int value="1789517771" label="MacV2Sandbox:enabled"/> <int value="1803465156" label="enable-zero-suggest-most-visited"/> <int value="1809940714" label="SpeculativeLaunchServiceWorker:disabled"/> <int value="1812368073" label="enable-new-app-list-mixer"/> @@ -28651,6 +28734,12 @@ <int value="14" label="URL not valid for reputation computing"/> </enum> +<enum name="PasswordProtectionSyncAccountType"> + <int value="0" label="Not signed in"/> + <int value="1" label="@gmail.com or @googlemail.com"/> + <int value="2" label="G Suite account"/> +</enum> + <enum name="PasswordProtectionVerdict"> <int value="0" label="Verdict not specified"/> <int value="1" label="Safe"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f73b10d..f8e3fde 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -6511,6 +6511,119 @@ </summary> </histogram> +<histogram name="BlueZ.ReasonOfDisconnection" enum="BlueZReasonOfDisconnection"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the reason of Bluetooth disconnection between the local device and + the remote Bluetooth device. This helps us better understand the initiator + of disconnection request. + </summary> +</histogram> + +<histogram name="BlueZ.ResultOfAdvertisementRegistration" + enum="BlueZResultOfAdvertisementRegistration"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the outcomes of advertisement registration. This helps us better + understand the persentage of successful advertisements against failures and + the causes of failures. + </summary> +</histogram> + +<histogram name="BlueZ.ResultOfConnection" enum="BlueZResultOfConnection"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the outcomes of connection requests to remote devices. This helps us + better understand the persentage of successful connections against failures + and the causes of failures. + </summary> +</histogram> + +<histogram name="BlueZ.ResultOfPairing" enum="BlueZResultOfPairing"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the outcomes of pairing with remote devices. This helps us better + understand the persentage of successful pairing against failures and the + causes of failures. + </summary> +</histogram> + +<histogram name="BlueZ.TimeLengthOfAdvertisement" units="seconds"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the duration when the local device is performing Bluetooth + advertisment and discoverable as a Bluetooth Low Energy device by other + devices. This helps us better understand the amount of successful + advertisment sessions and the duration. + </summary> +</histogram> + +<histogram name="BlueZ.TimeLengthOfDiscoverable" units="seconds"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the duration when the local device is discoverable by other devices + as a Bluetooth classic device. This helps us better understand the amount of + requests to expose the local device as a Bluetooth classic device and the + duration. + </summary> +</histogram> + +<histogram name="BlueZ.TimeLengthOfDiscovering" units="seconds"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the duration for the local device to perform device discovery. This + helps us better understand the amount of device discovery request and the + duration for users to find the target device. + </summary> +</histogram> + +<histogram name="BlueZ.TimeLengthOfPairing" units="seconds"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the duration taken to finish a successful pairing between the local + device and a remote Bluetooth device. This helps us better understand the + latency of completing Bluetooth pairing. + </summary> +</histogram> + +<histogram name="BlueZ.TimeLengthOfSetupConnection" units="seconds"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the duration taken to finish a successful connection between the + local device and a remote Bluetooth device. This helps us better understand + the latency of connecting to a Bluetooth device. + </summary> +</histogram> + +<histogram name="BlueZ.TypeOfDiscovery" enum="BlueZTypeOfDiscovery"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the types of device discovery performed by the local device. This + helps us better understand the most common type of device discovery + performed. + </summary> +</histogram> + +<histogram name="BlueZ.TypeOfFoundDevice" enum="BlueZTypeOfFoundDevice"> + <owner>mcchou@chromium.org</owner> + <summary> + This is specific to Chrome OS. + Records the types of discovered devices in terms of Bluetooth classic, + Bluetooth low energy and Dual-mode supports. This helps us better understand + the persentage of Bluetooth devices in terms of type. + </summary> +</histogram> + <histogram name="BookmarkManager.NumDragged" units="bookmarks"> <owner>calamity@chromium.org</owner> <summary> @@ -15736,6 +15849,27 @@ </summary> </histogram> +<histogram name="EmbeddedWorkerInstance.Start.StartMessageLatency" units="ms"> + <owner>falken@chromium.org</owner> + <summary> + The time between the browser sending a "start a service worker" + message to the renderer, and the renderer receiving it. This may include + renderer startup time. Only recorded if the high-resolution system clock was + used and deemed consistent across proceses, and the time was non-negative + (see EmbeddedWorkerInstance.Start.StartMessageLatency.Type). Only recorded + for installed workers. Recorded upon successful startup. + </summary> +</histogram> + +<histogram name="EmbeddedWorkerInstance.Start.StartMessageLatency.Type" + enum="CrossProcessTimeDelta"> + <owner>falken@chromium.org</owner> + <summary> + See EmbeddedWorkerInstance.Start.StartMessageLatency. Describes the outcome + of taking the measurement and whether StartMessageLatency was recorded. + </summary> +</histogram> + <histogram name="EmbeddedWorkerInstance.Start.TimeToEvaluateScript" units="ms"> <owner>falken@chromium.org</owner> <summary> @@ -15795,6 +15929,32 @@ </summary> </histogram> +<histogram name="EmbeddedWorkerInstance.Start.WaitedForRendererSetup" + enum="BooleanWaited"> + <owner>falken@chromium.org</owner> + <summary> + Indicates if Blink was not initialized by the time the browser sent a + "start a service worker" message to the renderer. If this is true, + receiving the message had to wait until after Blink initialization finished. + Blink initialization is considered the time RenderThreadImpl::Init sets up + the Mojo interface for receiving the "start a service worker" + message. Only recorded for installed workers. Recorded upon successful + startup. + </summary> +</histogram> + +<histogram name="EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time" + units="ms"> + <owner>falken@chromium.org</owner> + <summary> + Recorded when EmbeddedWorkerInstance.Start.WaitedForRendererSetup is true. + The time between when the "start a service worker" was sent by the + browser, and Blink initialization finishing. The start time is recorded by + the browser process, and the end time by the renderer process, so process + clock skew could possibly affect the result. + </summary> +</histogram> + <histogram name="EnhancedBookmarks.AllBookmarksCount"> <obsolete> Removed 4/2016 after we no longer show "all bookamrks" in bookmark @@ -17346,17 +17506,20 @@ Time between sending a keyboard event to the renderer main thread and when the renderer begins to process that event, for events which were not preventDefaulted. Only recorded for key presses. + + Team: input-dev@chromium.org. </summary> </histogram> <histogram name="Event.Latency.QueueingTime.KeyPressDefaultPrevented" units="ms"> <owner>tdresser@chromium.org</owner> - <owner>input-dev@chromium.org</owner> <summary> Time between sending a keyboard event to the renderer main thread and when the renderer begins to process that event, for events which were preventDefaulted. Only recorded for key presses. + + Team: input-dev@chromium.org. </summary> </histogram> @@ -28952,6 +29115,15 @@ <summary>Duration in milliseconds of HTML5 media (when known).</summary> </histogram> +<histogram name="Media.DXVAVDA.ErrorLine"> + <owner>jbauman@chromium.org</owner> + <owner>sandersd@chromium.org</owner> + <summary> + Whenever an error is logged from the DXVAVDA, this records the line in + dxva_video_decode_accelerator.cc where the failure occurred. + </summary> +</histogram> + <histogram name="Media.EME.CdmFileIO.FileSizeKBOnError" units="KB"> <owner>xhwang@chromium.org</owner> <summary> @@ -32752,7 +32924,7 @@ <owner>jlebel@chromium.org</owner> <summary> Counts how many times the signin promo is implicitly dismissed (by closing - the bookmark manager) per impression. + the bookmark manager) per impression, only iOS. </summary> </histogram> @@ -32763,7 +32935,7 @@ Counts how many times one of the "sign in" buttons (any of the signed-out "Sign in to Chrome" button, the "Continue as |name|" button, or the "Not |email|?" button) is clicked per - impression. + impression, only iOS. </summary> </histogram> @@ -32772,7 +32944,27 @@ <owner>jlebel@chromium.org</owner> <summary> Counts how many times the explicit "X"-to-close button is clicked - per impression. + per impression, only iOS. + </summary> +</histogram> + +<histogram name="MobileSignInPromo.SettingsManager.ImpressionsTilDismiss" + units="impressions"> + <owner>jlebel@chromium.org</owner> + <summary> + Counts how many times the signin promo is implicitly dismissed (by closing + the settings view) per impression, only iOS. + </summary> +</histogram> + +<histogram name="MobileSignInPromo.SettingsManager.ImpressionsTilSigninButtons" + units="impressions"> + <owner>jlebel@chromium.org</owner> + <summary> + Counts how many times one of the "sign in" buttons (any of the + signed-out "Sign in to Chrome" button, the "Continue as + |name|" button, or the "Not |email|?" button) is clicked per + impression, only iOS. </summary> </histogram> @@ -52358,6 +52550,17 @@ </summary> </histogram> +<histogram name="PasswordProtection.PasswordReuseSyncAccountType" + enum="PasswordProtectionSyncAccountType"> + <owner>jialiul@chromium.org</owner> + <owner>nparker@chromium.org</owner> + <summary> + When password protection service detects a reuse of Chrome sync password, + record the type of Chrome sync account on which the reuse happens (e.g. + @gmail.com, @googlemail.com, or other dasher account). + </summary> +</histogram> + <histogram name="PasswordProtection.RequestNetworkDuration" units="ms"> <owner>jialiul@chromium.org</owner> <owner>nparker@chromium.org</owner> @@ -60835,13 +61038,24 @@ </summary> </histogram> +<histogram name="Renderer4.GpuRasterizationSlowPathsWithNonAAPaint" + enum="BooleanHasSlowPathsWithNonAAPaint"> + <owner>ericrk@chromium.org</owner> + <summary> + If gpu rasterization is enabled, whether this page contains both slow-paths + (making it suitable for MSAA) and non-AA paints (making it not-suitable for + MSAA). This indicates a case where we would like to use MSAA, but may have + to avoid it for correctness reasons. + </summary> +</histogram> + <histogram name="Renderer4.GpuRasterizationSuitableContent" enum="BooleanEnabled"> <owner>alokp@chromium.org</owner> <summary> - If gpu rasterization is enabled, whether the page contents are suitable for - gpu rasterization (checked once after the page is painted for the first - time). + If gpu rasterization is enabled, whether the page contents contain no more + than 5 slow paths, and is suitable for non-MSAA gpu rasterization (checked + once after the page is painted for the first time). </summary> </histogram> @@ -61328,6 +61542,18 @@ </summary> </histogram> +<histogram name="RendererScheduler.QueueingDurationWhenExpectedQueueingTime" + units="ms"> + <owner>tdresser@chromium.org</owner> + <summary> + Time between sending an event to the renderer main thread and when the + renderer begins to process that event, for events which were dispatched when + the expected queueing time was past some threshold. + + Team: input-dev@chromium.org. + </summary> +</histogram> + <histogram name="RendererScheduler.TaskDurationPerQueueType" enum="RendererSchedulerTaskQueueType" units="ms"> <obsolete> @@ -73604,6 +73830,19 @@ </histogram> <histogram name="Startup.FirstCommitNavigationTime2" units="ms"> + <obsolete> + Replaced with Startup.FirstCommitNavigationTime3 on 6/2017 + </obsolete> + <owner>pasko@chromium.org</owner> + <owner>wnwen@chromium.org</owner> + <summary> + [Android only] The time from the first foreground entry point in the app to + the moment the first navigation is committed, i.e. when renderer gets the + first byte of the document. + </summary> +</histogram> + +<histogram name="Startup.FirstCommitNavigationTime3" units="ms"> <owner>pasko@chromium.org</owner> <owner>wnwen@chromium.org</owner> <summary> @@ -79523,6 +79762,9 @@ </histogram> <histogram name="UMA.Debug.EnableCrashUpload.DeferredStartUptime2" units="ms"> + <obsolete> + Deprecated 2017. No longer tracked. + </obsolete> <owner>wnwen@chromium.org</owner> <owner>asvitkine@chromium.org</owner> <summary> @@ -79546,6 +79788,9 @@ <histogram name="UMA.Debug.EnableCrashUpload.PostDeferredStartUptime2" units="ms"> + <obsolete> + Deprecated 2017. No longer tracked. + </obsolete> <owner>wnwen@chromium.org</owner> <owner>asvitkine@chromium.org</owner> <summary> @@ -79580,6 +79825,9 @@ </histogram> <histogram name="UMA.Debug.EnableCrashUpload.Uptime3" units="ms"> + <obsolete> + Deprecated 2017. No longer tracked. + </obsolete> <owner>wnwen@chromium.org</owner> <owner>asvitkine@chromium.org</owner> <summary> @@ -89379,6 +89627,26 @@ <affected-histogram name="Stability.ExitFunnel"/> </histogram_suffixes> +<histogram_suffixes name="ExpectedQueueingDurationThreshold" separator="_"> + <suffix name="GreaterThan.10ms" + label="Expected Queueing Time greater than 10ms."/> + <suffix name="GreaterThan.150ms" + label="Expected Queueing Time greater than 150ms."/> + <suffix name="GreaterThan.300ms" + label="Expected Queueing Time greater than 300ms."/> + <suffix name="GreaterThan.450ms" + label="Expected Queueing Time greater than 450ms."/> + <suffix name="LessThan.10ms" label="Expected Queueing Time less than 10ms."/> + <suffix name="LessThan.150ms" + label="Expected Queueing Time less than 150ms."/> + <suffix name="LessThan.300ms" + label="Expected Queueing Time less than 300ms."/> + <suffix name="LessThan.450ms" + label="Expected Queueing Time less than 450ms."/> + <affected-histogram + name="RendererScheduler.QueueingDurationWhenExpectedQueueingTime"/> +</histogram_suffixes> + <histogram_suffixes name="ExtensionFunctionExecutionTime" separator="."> <suffix name="1msTo5ms" label="Execution took between 1ms and 5ms (tolerable)."/> @@ -90196,6 +90464,7 @@ <suffix name="IPH_DownloadPage" label="In product help download page."/> <suffix name="IPH_DownloadHome" label="In product help download home."/> <suffix name="IPH_NewTab" label="In product help new tab."/> + <suffix name="IPH_IncognitoWindow" label="In product help incognito window."/> </histogram_suffixes> <histogram_suffixes name="IPProtocolType" separator="_"> @@ -95513,6 +95782,7 @@ </histogram_suffixes> <histogram_suffixes name="ServiceWorker.StartSituation" separator="_"> + <affected-histogram name="EmbeddedWorkerInstance.Start.StartMessageLatency"/> <suffix name="DuringStartup" label="The worker started up during browser startup."/> <suffix name="NewProcess"
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index cb3d98c..4e330d2 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -35,6 +35,98 @@ <metric name="DeveloperEngagement"/> </event> +<event name="Autofill.FieldFillStatus"> + <owner>rogerm@chromium.org</owner> + <summary> + Recorded when Chrome validates field type predictions (on submit, on leaving + a form, on receiving a form with autocomplete attributes). + </summary> + <metric name="FieldSignature"> + <summary> + The signature of the field. This is the hash identifier used to denote + this field for query and voting purposes. See + components/autofill/core/common/signatures_util.cc for more details. + </summary> + </metric> + <metric name="FormSignature"> + <summary> + The signature of the form. This is the hash identifier used to denote this + form for query and voting purposes. See + components/autofill/core/common/signatures_util.cc for more details. + </summary> + </metric> + <metric name="IsAutofilled"> + <summary> + The field is currently autofilled. + </summary> + </metric> + <metric name="MillisecondsSinceFormParsed"> + <summary> + Time since form parse. + </summary> + </metric> + <metric name="PredictionSource"> + <summary> + The system which generated the prediction: heuristics, server, overall. + </summary> + </metric> + <metric name="ValidationEvent"> + <summary> + The event which triggered the validation: Submission, Left Form, Form has + Autocomplete attributes. + </summary> + </metric> + <metric name="WasPreviouslyAutofilled"> + <summary> + The field was autofilled and subsequently edited. + </summary> + </metric> +</event> + +<event name="Autofill.FieldTypeValidation"> + <owner>rogerm@chromium.org</owner> + <summary> + Recorded when Chrome validates field type predictions (on submit, on leaving + a form, on receiving a form with autocomplete attributes). + </summary> + <metric name="ActualType"> + <summary> + The observed type of the field. See: autofill::ServerFieldType + </summary> + </metric> + <metric name="FieldSignature"> + <summary> + The signature of the field + </summary> + </metric> + <metric name="FormSignature"> + <summary> + The signature of the form. + </summary> + </metric> + <metric name="MillisecondsSinceFormParsed"> + <summary> + Time since form parse. + </summary> + </metric> + <metric name="PredictedType"> + <summary> + The predicted type of the field. See: autofill::ServerFieldType + </summary> + </metric> + <metric name="PredictionSource"> + <summary> + The system which generated the prediction: heuristics, server, overall. + </summary> + </metric> + <metric name="ValidationEvent"> + <summary> + The event which triggered the validation: Submission, Left Form, Form has + Autocomplete attributes. + </summary> + </metric> +</event> + <event name="Autofill.FormSubmitted"> <owner>jiahuiguo@google.com</owner> <summary>
diff --git a/tools/perf/benchmarks/image_decoding.py b/tools/perf/benchmarks/image_decoding.py index 7c897723..2389107 100644 --- a/tools/perf/benchmarks/image_decoding.py +++ b/tools/perf/benchmarks/image_decoding.py
@@ -26,3 +26,11 @@ def GetExpectations(self): return page_sets.ImageDecodingMeasurementStoryExpectations() + + def SetExtraBrowserOptions(self, options): + options.AppendExtraBrowserArgs([ + # Disable asynchronous decodes in the renderer since these test + # rely on images have been decoded between consecutive + # requestAnimationFrames. + '--disable-checker-imaging' + ])
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index cb99411..3d95293a 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -74,6 +74,8 @@ 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.load:social:facebook', # pylint: disable=line-too-long 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.load:social:tumblr', # pylint: disable=line-too-long 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.load:social:pinterest', # pylint: disable=line-too-long + # crbug.com/725386 + 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:social:twitter', # pylint: disable=line-too-long })
diff --git a/tools/perf/core/benchmark_sharding_map.json b/tools/perf/core/benchmark_sharding_map.json index 94ecc5e..1ba10042 100644 --- a/tools/perf/core/benchmark_sharding_map.json +++ b/tools/perf/core/benchmark_sharding_map.json
@@ -470,27 +470,23 @@ "build164-b1--device2": { "benchmarks": [ "loading.desktop", - "smoothness.simple_mobile_sites", - "v8.browsing_desktop_classic" + "smoothness.simple_mobile_sites" ] }, "build164-b1--device3": { "benchmarks": [ - "system_health.common_desktop", - "v8.runtimestats.browsing_mobile_classic" + "system_health.common_desktop" ] }, "build164-b1--device4": { "benchmarks": [ - "smoothness.tough_animation_cases", - "v8.infinite_scroll-turbo_tbmv2" + "smoothness.tough_animation_cases" ] }, "build164-b1--device5": { "benchmarks": [ "battor.trivial_pages", - "v8.browsing_mobile", - "v8.browsing_mobile_turbo" + "v8.browsing_mobile" ] }, "build164-b1--device6": { @@ -510,8 +506,7 @@ "memory.blink_memory_mobile", "power.idle_platform", "smoothness.image_decoding_cases", - "start_with_ext.warm.blank_page", - "v8.browsing_mobile_classic" + "start_with_ext.warm.blank_page" ] }, "build165-b1--device1": { @@ -524,7 +519,6 @@ "smoothness.tough_image_decode_cases", "thread_times.key_idle_power_cases", "v8.browsing_desktop", - "v8.infinite_scroll-classic_tbmv2", "v8.runtimestats.browsing_mobile" ] }, @@ -558,15 +552,13 @@ "start_with_url.cold.startup_pages", "startup.large_profile.warm.blank_page", "startup.warm.chrome_signin", - "system_health.webview_startup", - "v8.browsing_desktop_turbo" + "system_health.webview_startup" ] }, "build165-b1--device5": { "benchmarks": [ "dromaeo.domcoreattr", "oortonline_tbmv2", - "power.android_acceptance", "smoothness.gpu_rasterization.tough_filters_cases", "smoothness.maps", "smoothness.tough_webgl_ad_cases", @@ -585,9 +577,7 @@ "thread_times.key_noop_cases", "thread_times.polymer", "thread_times.tough_compositor_cases", - "v8.detached_context_age_in_gc", - "v8.mobile_infinite_scroll-turbo_tbmv2", - "v8.runtimestats.browsing_mobile_turbo" + "v8.detached_context_age_in_gc" ] }, "build165-b1--device7": { @@ -597,7 +587,6 @@ "smoothness.tough_ad_cases", "smoothness.tough_scrolling_cases", "smoothness.tough_webgl_cases", - "speedometer-classic", "system_health.common_mobile" ] }, @@ -623,7 +612,6 @@ }, "build166-b1--device3": { "benchmarks": [ - "memory.top_10_mobile_stress", "page_cycler_v2.basic_oopif", "service_worker.service_worker_micro_benchmark", "smoothness.desktop_tough_pinch_zoom_cases", @@ -638,7 +626,6 @@ "blink_perf.parser", "page_cycler_v2_site_isolation.basic_oopif", "smoothness.tough_texture_upload_cases", - "speedometer-turbo", "start_with_ext.cold.blank_page", "thread_times.key_silk_cases" ] @@ -653,9 +640,7 @@ "smoothness.top_25_smooth", "start_with_url.warm.startup_pages", "tracing.tracing_with_background_memory_infra", - "v8.mobile_infinite_scroll-classic_tbmv2", - "v8.mobile_infinite_scroll_tbmv2", - "v8.runtimestats.browsing_desktop_turbo" + "v8.mobile_infinite_scroll_tbmv2" ] }, "build166-b1--device6": { @@ -675,158 +660,8 @@ "smoothness.gpu_rasterization.tough_path_rendering_cases", "v8.infinite_scroll_tbmv2", "v8.runtime_stats.top_25", - "v8.runtimestats.browsing_desktop", - "v8.runtimestats.browsing_desktop_classic" - ] - } - }, - "Android Nexus5X WebView Perf": { - "build243-m4--device1": { - "benchmarks": [ - "system_health.memory_desktop", - "thread_times.polymer", - "v8.mobile_infinite_scroll_tbmv2", - "v8.runtime_stats.top_25", - "v8.runtimestats.browsing_mobile" - ] - }, - "build243-m4--device2": { - "benchmarks": [ - "loading.desktop", - "rasterize_and_record_micro.polymer", - "smoothness.gpu_rasterization.top_25_smooth", - "smoothness.key_mobile_sites_smooth", - "smoothness.tough_pinch_zoom_cases", - "startup.warm.chrome_signin", - "thread_times.key_mobile_sites_smooth", - "thread_times.key_silk_cases", - "v8.browsing_mobile" - ] - }, - "build243-m4--device3": { - "benchmarks": [ - "blink_perf.events", - "blink_perf.svg", - "dromaeo.domcoreattr", - "kraken", - "memory.desktop", - "memory.long_running_idle_gmail_background_tbmv2", - "octane", - "rasterize_and_record_micro.top_25", - "smoothness.gpu_rasterization.tough_path_rendering_cases", - "smoothness.simple_mobile_sites", - "smoothness.sync_scroll.key_mobile_sites_smooth", - "smoothness.top_25_smooth", - "smoothness.tough_filters_cases", - "smoothness.tough_scrolling_cases", - "start_with_url.cold.startup_pages", - "start_with_url.warm.startup_pages", - "startup.large_profile.warm.blank_page", - "storage.indexeddb_endure_tracing", - "system_health.common_desktop", - "thread_times.key_noop_cases" - ] - }, - "build243-m4--device4": { - "benchmarks": [ - "blink_perf.bindings", - "blink_perf.dom", - "dromaeo.domcorequery", - "dromaeo.domcoretraverse", - "dummy_benchmark.stable_benchmark_1", - "loading.mobile", - "oortonline_tbmv2", - "power.typical_10_mobile", - "rasterize_and_record_micro.key_silk_cases", - "scheduler.tough_scheduling_cases", - "service_worker.service_worker_micro_benchmark", - "smoothness.tough_animation_cases", - "smoothness.tough_webgl_ad_cases", - "smoothness.tough_webgl_cases", - "speedometer", - "startup.cold.blank_page", - "system_health.common_mobile", - "tracing.tracing_with_background_memory_infra", - "v8.infinite_scroll_tbmv2" - ] - }, - "build243-m4--device5": { - "benchmarks": [ - "battor.trivial_pages", - "blink_perf.css", - "blink_perf.paint", - "blink_perf.parser", - "dummy_benchmark.noisy_benchmark_1", - "media.android.tough_video_cases", - "media.android.tough_video_cases_tbmv2", - "media.tough_video_cases", - "media.tough_video_cases_tbmv2", - "oortonline", - "power.idle_platform", - "power.steady_state", - "rasterize_and_record_micro.partial_invalidation", - "smoothness.key_silk_cases", - "startup.warm.blank_page", - "storage.indexeddb_endure", - "tab_switching.typical_25", - "thread_times.key_hit_test_cases", - "thread_times.simple_mobile_sites", - "thread_times.tough_compositor_cases", - "thread_times.tough_scrolling_cases", - "tracing.tracing_with_debug_overhead", "v8.runtimestats.browsing_desktop" ] - }, - "build243-m4--device6": { - "benchmarks": [ - "blink_perf.layout", - "blink_perf.shadow_dom", - "dromaeo.domcoremodify", - "jetstream", - "media.media_cns_cases", - "page_cycler_v2_site_isolation.basic_oopif", - "power.trivial_pages", - "rasterize_and_record_micro.key_mobile_sites", - "service_worker.service_worker", - "smoothness.gpu_rasterization.tough_filters_cases", - "smoothness.gpu_rasterization.tough_scrolling_cases", - "smoothness.image_decoding_cases", - "smoothness.tough_ad_cases", - "smoothness.tough_path_rendering_cases", - "start_with_ext.warm.blank_page", - "startup.large_profile.cold.blank_page", - "system_health.memory_mobile", - "v8.detached_context_age_in_gc" - ] - }, - "build243-m4--device7": { - "benchmarks": [ - "battor.steady_state", - "blink_perf.canvas", - "blob_storage.blob_storage", - "image_decoding.image_decoding_measurement", - "media.mse_cases", - "memory.blink_memory_mobile", - "memory.long_running_idle_gmail_tbmv2", - "memory.top_10_mobile", - "page_cycler_v2.basic_oopif", - "smoothness.desktop_tough_pinch_zoom_cases", - "smoothness.gpu_rasterization.polymer", - "smoothness.gpu_rasterization.tough_pinch_zoom_cases", - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases", - "smoothness.key_desktop_move_cases", - "smoothness.maps", - "smoothness.pathological_mobile_sites", - "smoothness.scrolling_tough_ad_cases", - "smoothness.tough_canvas_cases", - "smoothness.tough_image_decode_cases", - "smoothness.tough_texture_upload_cases", - "start_with_ext.cold.blank_page", - "system_health.webview_startup", - "thread_times.key_idle_power_cases", - "v8.browsing_desktop", - "webrtc" - ] } }, "Android Nexus6 Perf": { @@ -1070,27 +905,23 @@ "build112-b1--device2": { "benchmarks": [ "loading.desktop", - "smoothness.simple_mobile_sites", - "v8.browsing_desktop_classic" + "smoothness.simple_mobile_sites" ] }, "build112-b1--device3": { "benchmarks": [ - "system_health.common_desktop", - "v8.runtimestats.browsing_mobile_classic" + "system_health.common_desktop" ] }, "build112-b1--device4": { "benchmarks": [ - "smoothness.tough_animation_cases", - "v8.infinite_scroll-turbo_tbmv2" + "smoothness.tough_animation_cases" ] }, "build112-b1--device5": { "benchmarks": [ "battor.trivial_pages", - "v8.browsing_mobile", - "v8.browsing_mobile_turbo" + "v8.browsing_mobile" ] }, "build112-b1--device6": { @@ -1110,8 +941,7 @@ "memory.blink_memory_mobile", "power.idle_platform", "smoothness.image_decoding_cases", - "start_with_ext.warm.blank_page", - "v8.browsing_mobile_classic" + "start_with_ext.warm.blank_page" ] }, "build113-b1--device1": { @@ -1124,7 +954,6 @@ "smoothness.tough_image_decode_cases", "thread_times.key_idle_power_cases", "v8.browsing_desktop", - "v8.infinite_scroll-classic_tbmv2", "v8.runtimestats.browsing_mobile" ] }, @@ -1158,15 +987,13 @@ "start_with_url.cold.startup_pages", "startup.large_profile.warm.blank_page", "startup.warm.chrome_signin", - "system_health.webview_startup", - "v8.browsing_desktop_turbo" + "system_health.webview_startup" ] }, "build113-b1--device5": { "benchmarks": [ "dromaeo.domcoreattr", "oortonline_tbmv2", - "power.android_acceptance", "smoothness.gpu_rasterization.tough_filters_cases", "smoothness.maps", "smoothness.tough_webgl_ad_cases", @@ -1185,9 +1012,7 @@ "thread_times.key_noop_cases", "thread_times.polymer", "thread_times.tough_compositor_cases", - "v8.detached_context_age_in_gc", - "v8.mobile_infinite_scroll-turbo_tbmv2", - "v8.runtimestats.browsing_mobile_turbo" + "v8.detached_context_age_in_gc" ] }, "build113-b1--device7": { @@ -1197,7 +1022,6 @@ "smoothness.tough_ad_cases", "smoothness.tough_scrolling_cases", "smoothness.tough_webgl_cases", - "speedometer-classic", "system_health.common_mobile" ] }, @@ -1223,7 +1047,6 @@ }, "build114-b1--device3": { "benchmarks": [ - "memory.top_10_mobile_stress", "page_cycler_v2.basic_oopif", "service_worker.service_worker_micro_benchmark", "smoothness.desktop_tough_pinch_zoom_cases", @@ -1238,7 +1061,6 @@ "blink_perf.parser", "page_cycler_v2_site_isolation.basic_oopif", "smoothness.tough_texture_upload_cases", - "speedometer-turbo", "start_with_ext.cold.blank_page", "thread_times.key_silk_cases" ] @@ -1253,9 +1075,7 @@ "smoothness.top_25_smooth", "start_with_url.warm.startup_pages", "tracing.tracing_with_background_memory_infra", - "v8.mobile_infinite_scroll-classic_tbmv2", - "v8.mobile_infinite_scroll_tbmv2", - "v8.runtimestats.browsing_desktop_turbo" + "v8.mobile_infinite_scroll_tbmv2" ] }, "build114-b1--device6": { @@ -1275,8 +1095,7 @@ "smoothness.gpu_rasterization.tough_path_rendering_cases", "v8.infinite_scroll_tbmv2", "v8.runtime_stats.top_25", - "v8.runtimestats.browsing_desktop", - "v8.runtimestats.browsing_desktop_classic" + "v8.runtimestats.browsing_desktop" ] } }, @@ -2556,9 +2375,9 @@ "v8.browsing_desktop_classic", "v8.browsing_desktop_turbo", "v8.infinite_scroll-turbo_tbmv2", + "v8.runtime_stats.top_25", "v8.runtimestats.browsing_desktop_classic", - "v8.runtimestats.browsing_desktop_turbo", - "v8.runtime_stats.top_25" + "v8.runtimestats.browsing_desktop_turbo" ] }, "build126-b1": { @@ -5049,4 +4868,4 @@ "v8.runtimestats.browsing_mobile", "webrtc" ] -} +} \ No newline at end of file
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 3feac7e..01c2e71 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -122,27 +122,6 @@ } ]) - waterfall = add_tester( - waterfall, 'Android Nexus5X WebView Perf', - 'fyi-android-webview-nexus5X', 'android', swarming=[ - { - 'os': 'Android', - 'android_devices': '1', - 'pool': 'Chrome-perf-fyi', - 'device_ids': [ - 'build243-m4--device1', 'build243-m4--device2', - 'build243-m4--device3', 'build243-m4--device4', - 'build243-m4--device5', 'build243-m4--device6', - 'build243-m4--device7', - ], - 'perf_tests': [ - # TODO(martiniss): implement these isolate targets - # ('tracing_webview_perftests', 'build112-b1--device2'), - # ('gpu_webview_perftests', 'build113-b1--device2'), - # ('cc_webview_perftests', 'build114-b1--device2'), - ] - } - ], replace_system_webview=True) return waterfall @@ -290,66 +269,53 @@ } ]) - # TODO(martiniss): comment this back in once we're confident webview works - # waterfall = add_tester( - # waterfall, 'Android Nexus5X WebView Perf', 'android-webview-nexus5X', - # 'android', swarming=[ - # { - # 'os': 'Android', - # 'android_devices': '1', - # 'pool': 'Chrome-perf', - # 'device_ids': [ - # 'build164-b1--device1', 'build164-b1--device2', - # 'build164-b1--device3', 'build164-b1--device4', - # 'build164-b1--device5', 'build164-b1--device6', - # 'build164-b1--device7', - # 'build165-b1--device1', 'build165-b1--device2', - # 'build165-b1--device3', 'build165-b1--device4', - # 'build165-b1--device5', 'build165-b1--device6', - # 'build165-b1--device7', - # 'build166-b1--device1', 'build166-b1--device2', - # 'build166-b1--device3', 'build166-b1--device4', - # 'build166-b1--device5', 'build166-b1--device6', - # 'build166-b1--device7', - # ], - # 'perf_tests': [ - # # TODO(martiniss): implement these isolate targets - # # ('tracing_webview_perftests', 'build164-b1--device2'), - # # ('gpu_webview_perftests', 'build165-b1--device2'), - # # ('cc_webview_perftests', 'build166-b1--device2'), - # ] - # } - # ], replace_system_webview=True) + waterfall = add_tester( + waterfall, 'Android Nexus5X WebView Perf', 'android-webview-nexus5X', + 'android', swarming=[ + { + 'os': 'Android', + 'android_devices': '1', + 'pool': 'Chrome-perf', + 'device_ids': [ + 'build164-b1--device1', 'build164-b1--device2', + 'build164-b1--device3', 'build164-b1--device4', + 'build164-b1--device5', 'build164-b1--device6', + 'build164-b1--device7', + 'build165-b1--device1', 'build165-b1--device2', + 'build165-b1--device3', 'build165-b1--device4', + 'build165-b1--device5', 'build165-b1--device6', + 'build165-b1--device7', + 'build166-b1--device1', 'build166-b1--device2', + 'build166-b1--device3', 'build166-b1--device4', + 'build166-b1--device5', 'build166-b1--device6', + 'build166-b1--device7', + ], + } + ], replace_system_webview=True) - # waterfall = add_tester( - # waterfall, 'Android Nexus6 WebView Perf', 'android-webview-nexus6', - # 'android', swarming=[ - # { - # 'os': 'Android', - # 'android_devices': '1', - # 'pool': 'Chrome-perf', - # 'device_ids': [ - # 'build112-b1--device1', 'build112-b1--device2', - # 'build112-b1--device3', 'build112-b1--device4', - # 'build112-b1--device5', 'build112-b1--device6', - # 'build112-b1--device7', - # 'build113-b1--device1', 'build113-b1--device2', - # 'build113-b1--device3', 'build113-b1--device4', - # 'build113-b1--device5', 'build113-b1--device6', - # 'build113-b1--device7', - # 'build114-b1--device1', 'build114-b1--device2', - # 'build114-b1--device3', 'build114-b1--device4', - # 'build114-b1--device5', 'build114-b1--device6', - # 'build114-b1--device7', - # ], - # 'perf_tests': [ - # # TODO(martiniss): implement these isolate targets - # # ('tracing_webview_perftests', 'build112-b1--device2'), - # # ('gpu_webview_perftests', 'build113-b1--device2'), - # # ('cc_webview_perftests', 'build114-b1--device2'), - # ] - # } - # ], replace_system_webview=True) + waterfall = add_tester( + waterfall, 'Android Nexus6 WebView Perf', 'android-webview-nexus6', + 'android', swarming=[ + { + 'os': 'Android', + 'android_devices': '1', + 'pool': 'Chrome-perf', + 'device_ids': [ + 'build112-b1--device1', 'build112-b1--device2', + 'build112-b1--device3', 'build112-b1--device4', + 'build112-b1--device5', 'build112-b1--device6', + 'build112-b1--device7', + 'build113-b1--device1', 'build113-b1--device2', + 'build113-b1--device3', 'build113-b1--device4', + 'build113-b1--device5', 'build113-b1--device6', + 'build113-b1--device7', + 'build114-b1--device1', 'build114-b1--device2', + 'build114-b1--device3', 'build114-b1--device4', + 'build114-b1--device5', 'build114-b1--device6', + 'build114-b1--device7', + ], + } + ], replace_system_webview=True) waterfall = add_tester( waterfall, 'Win 10 High-DPI Perf', 'win-high-dpi', 'win',
diff --git a/tools/perf/core/sharding_map_generator.py b/tools/perf/core/sharding_map_generator.py index f487a52d..cecf34b 100644 --- a/tools/perf/core/sharding_map_generator.py +++ b/tools/perf/core/sharding_map_generator.py
@@ -108,22 +108,25 @@ benchmark_to_shard_dict[benchmark.Name()] = device_affinity return benchmark_to_shard_dict - -def regenerate(benchmarks, waterfall_configs, buildernames=None): +def regenerate( + benchmarks, waterfall_configs, dry_run, verbose, builder_names=None): """Regenerate the shard mapping file. This overwrites the current file with fresh data. """ + if not builder_names: + builder_names = [] + with open(get_sharding_map_path()) as f: sharding_map = json.load(f) sharding_map[u'all_benchmarks'] = [b.Name() for b in benchmarks] for name, config in waterfall_configs.items(): - for buildername, tester in config['testers'].items(): + for builder, tester in config['testers'].items(): if not tester.get('swarming'): continue - if buildernames and buildername not in buildernames: + if builder not in builder_names: continue per_builder = {} @@ -136,7 +139,7 @@ device_map = per_builder.get(device, {'benchmarks': []}) device_map['benchmarks'].append(name) per_builder[device] = device_map - sharding_map[buildername] = per_builder + sharding_map[builder] = per_builder for name, builder_values in sharding_map.items(): @@ -147,8 +150,17 @@ for value in builder_values.values(): value['benchmarks'].sort() - with open(get_sharding_map_path(), 'w') as f: - json.dump(sharding_map, f, indent=2, sort_keys=True, separators=(',', ': ')) + if not dry_run: + with open(get_sharding_map_path(), 'w') as f: + dump_json(sharding_map, f) + else: + f_string = 'Would have dumped new json file to %s.' + if verbose: + f_string += ' File contents:\n %s' + print f_string % (get_sharding_map_path(), dumps_json(sharding_map)) + else: + f_string += ' To see full file contents, pass in --verbose.' + print f_string % get_sharding_map_path() return 0 @@ -159,11 +171,29 @@ 'This needs to be done anytime you add/remove any existing' 'benchmarks in tools/perf/benchmarks.')) - parser.add_argument('mode', choices=['regenerate']) - parser.add_argument('--buildernames', '-b', action='append', default=None) + parser.add_argument( + '--builder-names', '-b', action='append', default=None, + help='Specifies a subset of builders which should be affected by commands' + '. By default, commands affect all builders.') + parser.add_argument( + '--dry-run', action='store_true', + help='If the current run should be a dry run. A dry run means that any' + ' action which would be taken (write out data to a file, for example) is' + ' instead simulated.') + parser.add_argument( + '--verbose', action='store_true', + help='Determines how verbose the script is.') return parser +def dump_json(data, f): + """Utility method to dump json which is indented, sorted, and readable""" + return json.dump(data, f, indent=2, sort_keys=True, separators=(',', ': ')) + +def dumps_json(data): + """Utility method to dump json which is indented, sorted, and readable""" + return json.dumps(data, indent=2, sort_keys=True, separators=(',', ': ')) + def main(args, benchmarks, configs): - if args.mode == 'regenerate': - return regenerate(benchmarks, configs, args.buildernames) + return regenerate( + benchmarks, configs, args.dry_run, args.verbose, args.builder_names)
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn index 330928c..979cde4 100644 --- a/ui/app_list/BUILD.gn +++ b/ui/app_list/BUILD.gn
@@ -124,6 +124,8 @@ "views/contents_view.h", "views/custom_launcher_page_view.cc", "views/custom_launcher_page_view.h", + "views/expand_arrow_view.cc", + "views/expand_arrow_view.h", "views/folder_background_view.cc", "views/folder_background_view.h", "views/folder_header_view.cc",
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc index ff85122..12c3ad2 100644 --- a/ui/app_list/app_list_constants.cc +++ b/ui/app_list/app_list_constants.cc
@@ -90,7 +90,9 @@ // Preferred number of columns and rows in apps grid. const int kPreferredCols = 6; +const int kPreferredColsFullscreen = 5; const int kPreferredRows = 4; +const int kPreferredRowsFullscreen = 5; const int kGridIconDimension = 48; // The preferred app badge icon size. @@ -122,6 +124,8 @@ // The padding around the outside of the search box (top and sides). const int kSearchBoxPadding = 16; +const int kSearchBoxTopPadding = 24; +const int kSearchBoxBottomPadding = 21; // Max items allowed in a folder. size_t kMaxFolderItems = 16;
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h index ecbeb6da..807a31e 100644 --- a/ui/app_list/app_list_constants.h +++ b/ui/app_list/app_list_constants.h
@@ -70,7 +70,9 @@ APP_LIST_EXPORT extern const gfx::Tween::Type kFolderFadeOutTweenType; APP_LIST_EXPORT extern const int kPreferredCols; +APP_LIST_EXPORT extern const int kPreferredColsFullscreen; APP_LIST_EXPORT extern const int kPreferredRows; +APP_LIST_EXPORT extern const int kPreferredRowsFullscreen; APP_LIST_EXPORT extern const int kGridIconDimension; APP_LIST_EXPORT extern const int kAppBadgeIconSize; @@ -92,6 +94,8 @@ APP_LIST_EXPORT extern const int kAppsGridPadding; APP_LIST_EXPORT extern const int kSearchBoxPadding; +APP_LIST_EXPORT extern const int kSearchBoxTopPadding; +APP_LIST_EXPORT extern const int kSearchBoxBottomPadding; APP_LIST_EXPORT extern size_t kMaxFolderItems; APP_LIST_EXPORT extern const size_t kNumFolderTopItems;
diff --git a/ui/app_list/vector_icons/BUILD.gn b/ui/app_list/vector_icons/BUILD.gn index 3574f90..87a6c2c 100644 --- a/ui/app_list/vector_icons/BUILD.gn +++ b/ui/app_list/vector_icons/BUILD.gn
@@ -8,6 +8,8 @@ icon_directory = "." icons = [ + "ic_arrow_up.1x.icon", + "ic_arrow_up.icon", "ic_badge_instant.1x.icon", "ic_badge_instant.icon", "ic_badge_play.1x.icon",
diff --git a/ui/app_list/vector_icons/ic_arrow_up.1x.icon b/ui/app_list/vector_icons/ic_arrow_up.1x.icon new file mode 100644 index 0000000..d28822f --- /dev/null +++ b/ui/app_list/vector_icons/ic_arrow_up.1x.icon
@@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 12, +MOVE_TO, 10.59f, 9, +LINE_TO, 6, 4.67f, +LINE_TO, 1.42f, 9, +LINE_TO, 0, 7.66f, +LINE_TO, 6, 2, +R_LINE_TO, 6, 5.66f, +CLOSE, +END
diff --git a/ui/app_list/vector_icons/ic_arrow_up.icon b/ui/app_list/vector_icons/ic_arrow_up.icon new file mode 100644 index 0000000..5f8b186 --- /dev/null +++ b/ui/app_list/vector_icons/ic_arrow_up.icon
@@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 21.17f, 19, +LINE_TO, 12, 10.34f, +LINE_TO, 2.83f, 19, +LINE_TO, 0, 16.33f, +LINE_TO, 12, 5, +R_LINE_TO, 12, 11.33f, +CLOSE, +END
diff --git a/ui/app_list/views/app_list_folder_view.cc b/ui/app_list/views/app_list_folder_view.cc index 53f2591..8c2f2c1 100644 --- a/ui/app_list/views/app_list_folder_view.cc +++ b/ui/app_list/views/app_list_folder_view.cc
@@ -111,6 +111,7 @@ show ? kFolderTransitionInDurationMs : kFolderTransitionOutDurationMs)); layer()->SetOpacity(show ? 1.0f : 0.0f); + app_list_main_view_->search_box_view()->ShowBackOrGoogleIcon(show); } gfx::Size AppListFolderView::CalculatePreferredSize() const {
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 79fa7426..48a26d96 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -847,11 +847,18 @@ break; } break; - case FULLSCREEN_ALL_APPS: + case FULLSCREEN_ALL_APPS: { new_widget_bounds.set_y(0); + AppsContainerView* apps_container_view = + app_list_main_view_->contents_view()->apps_container_view(); + + if (apps_container_view->IsInFolderView()) + apps_container_view->app_list_folder_view()->CloseFolderPage(); + app_list_main_view_->contents_view()->SetActiveState( AppListModel::STATE_APPS); break; + } case FULLSCREEN_SEARCH: new_widget_bounds.set_y(0); break;
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc index cd84ebec..de3fba6 100644 --- a/ui/app_list/views/apps_container_view.cc +++ b/ui/app_list/views/apps_container_view.cc
@@ -9,6 +9,7 @@ #include "base/command_line.h" #include "ui/app_list/app_list_constants.h" +#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_folder_item.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/views/app_list_folder_view.h" @@ -16,15 +17,35 @@ #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/apps_grid_view.h" #include "ui/app_list/views/folder_background_view.h" +#include "ui/app_list/views/indicator_chip_view.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/events/event.h" +#include "ui/strings/grit/ui_strings.h" namespace app_list { +namespace { + +// Layout constants. +constexpr int kAllAppsIndicatorExtraPadding = 2; + +} // namespace + AppsContainerView::AppsContainerView(AppListMainView* app_list_main_view, AppListModel* model) - : show_state_(SHOW_NONE), top_icon_animation_pending_count_(0) { + : is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) { + if (is_fullscreen_app_list_enabled_) { + all_apps_indicator_ = new IndicatorChipView( + l10n_util::GetStringUTF16(IDS_ALL_APPS_INDICATOR)); + AddChildView(all_apps_indicator_); + } apps_grid_view_ = new AppsGridView(app_list_main_view); - apps_grid_view_->SetLayout(kPreferredCols, kPreferredRows); + if (is_fullscreen_app_list_enabled_) { + apps_grid_view_->SetLayout(kPreferredColsFullscreen, + kPreferredRowsFullscreen); + } else { + apps_grid_view_->SetLayout(kPreferredCols, kPreferredRows); + } AddChildView(apps_grid_view_); folder_background_view_ = new FolderBackgroundView(); @@ -41,8 +62,7 @@ SetShowState(SHOW_APPS, false); } -AppsContainerView::~AppsContainerView() { -} +AppsContainerView::~AppsContainerView() = default; void AppsContainerView::ShowActiveFolder(AppListFolderItem* folder_item) { // Prevent new animations from starting if there are currently animations @@ -113,6 +133,16 @@ switch (show_state_) { case SHOW_APPS: + if (all_apps_indicator_) { + gfx::Rect indicator_rect(rect); + const gfx::Size indicator_size = + all_apps_indicator_->GetPreferredSize(); + indicator_rect.Inset( + (indicator_rect.width() - indicator_size.width()) / 2, 0); + all_apps_indicator_->SetBoundsRect(indicator_rect); + rect.Inset(0, indicator_size.height() + kAllAppsIndicatorExtraPadding, + 0, 0); + } apps_grid_view_->SetBoundsRect(rect); break; case SHOW_ACTIVE_FOLDER:
diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h index c249ef6..135a965b 100644 --- a/ui/app_list/views/apps_container_view.h +++ b/ui/app_list/views/apps_container_view.h
@@ -27,14 +27,14 @@ class AppListMainView; class AppListModel; class FolderBackgroundView; +class IndicatorChipView; // AppsContainerView contains a root level AppsGridView to render the root level // app items, and a AppListFolderView to render the app items inside the // active folder. Only one if them is visible to user at any time. class AppsContainerView : public AppListPage, public TopIconAnimationObserver { public: - AppsContainerView(AppListMainView* app_list_main_view, - AppListModel* model); + AppsContainerView(AppListMainView* app_list_main_view, AppListModel* model); ~AppsContainerView() override; // Shows the active folder content specified by |folder_item|. @@ -79,7 +79,7 @@ AppsGridView* apps_grid_view() { return apps_grid_view_; } FolderBackgroundView* folder_background_view() { - return folder_background_view_; + return folder_background_view_; } AppListFolderView* app_list_folder_view() { return app_list_folder_view_; } @@ -101,26 +101,30 @@ // Creates the transitional views for animating the top items in the folder // when opening or closing a folder. - void CreateViewsForFolderTopItemsAnimation( - AppListFolderItem* active_folder, bool open_folder); + void CreateViewsForFolderTopItemsAnimation(AppListFolderItem* active_folder, + bool open_folder); void PrepareToShowApps(AppListFolderItem* folder_item); - AppsGridView* apps_grid_view_; // Owned by views hierarchy. - AppListFolderView* app_list_folder_view_; // Owned by views hierarchy. - FolderBackgroundView* folder_background_view_; // Owned by views hierarchy. - ShowState show_state_; + // The views below are owned by views hierarchy. + IndicatorChipView* all_apps_indicator_ = nullptr; + AppsGridView* apps_grid_view_ = nullptr; + AppListFolderView* app_list_folder_view_ = nullptr; + FolderBackgroundView* folder_background_view_ = nullptr; + + ShowState show_state_ = SHOW_NONE; // The transitional views for animating the top items in folder // when opening or closing a folder. std::vector<views::View*> top_icon_views_; - size_t top_icon_animation_pending_count_; + size_t top_icon_animation_pending_count_ = 0u; + + const bool is_fullscreen_app_list_enabled_; DISALLOW_COPY_AND_ASSIGN(AppsContainerView); }; } // namespace app_list - #endif // UI_APP_LIST_VIEWS_APPS_CONTAINER_VIEW_H_
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index 8bc5d73..ae1bb11 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc
@@ -58,6 +58,9 @@ const int kTileLeftRightPadding = 10; const int kTileBottomPadding = 6; const int kTileTopPadding = 6; +const int kTileLeftRightPaddingFullscreen = 12; +const int kTileBottomPaddingFullscreen = 6; +const int kTileTopPaddingFullscreen = 6; // Width in pixels of the area on the sides that triggers a page flip. const int kPageFlipZoneSize = 40; @@ -83,11 +86,19 @@ // Returns the size of a tile view excluding its padding. gfx::Size GetTileViewSize() { + if (features::IsFullscreenAppListEnabled()) + return gfx::Size(kGridTileWidth, kGridTileHeight); return gfx::Size(kPreferredTileWidth, kPreferredTileHeight); } // Returns the padding around a tile view. gfx::Insets GetTilePadding() { + if (features::IsFullscreenAppListEnabled()) { + return gfx::Insets( + -kTileTopPaddingFullscreen, -kTileLeftRightPaddingFullscreen, + -kTileBottomPaddingFullscreen, -kTileLeftRightPaddingFullscreen); + } + return gfx::Insets(-kTileTopPadding, -kTileLeftRightPadding, -kTileBottomPadding, -kTileLeftRightPadding); } @@ -105,8 +116,7 @@ : view_(view), layer_(layer), layer_start_(layer ? layer->bounds() : gfx::Rect()), - layer_target_(layer_target) { - } + layer_target_(layer_target) {} ~RowMoveAnimationDelegate() override {} // gfx::AnimationDelegate overrides: @@ -116,8 +126,8 @@ if (layer_) { layer_->SetOpacity(1 - animation->GetCurrentValue()); - layer_->SetBounds(animation->CurrentValueBetween(layer_start_, - layer_target_)); + layer_->SetBounds( + animation->CurrentValueBetween(layer_start_, layer_target_)); layer_->ScheduleDraw(); } } @@ -146,9 +156,7 @@ // be removed from the original list after it is dropped into the folder. class ItemRemoveAnimationDelegate : public gfx::AnimationDelegate { public: - explicit ItemRemoveAnimationDelegate(views::View* view) - : view_(view) { - } + explicit ItemRemoveAnimationDelegate(views::View* view) : view_(view) {} ~ItemRemoveAnimationDelegate() override {} @@ -269,7 +277,10 @@ cols_ = cols; rows_per_page_ = rows_per_page; - SetBorder(views::CreateEmptyBorder(0, kAppsGridPadding, 0, kAppsGridPadding)); + if (!is_fullscreen_app_list_enabled_) { + SetBorder( + views::CreateEmptyBorder(0, kAppsGridPadding, 0, kAppsGridPadding)); + } } // static @@ -423,12 +434,12 @@ if (drop_attempt_ == DROP_FOR_REORDER) { folder_dropping_timer_.Stop(); reorder_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kReorderDelay), - this, &AppsGridView::OnReorderTimer); + base::TimeDelta::FromMilliseconds(kReorderDelay), + this, &AppsGridView::OnReorderTimer); } else if (drop_attempt_ == DROP_FOR_FOLDER) { reorder_timer_.Stop(); - folder_dropping_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kFolderDroppingDelay), + folder_dropping_timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(kFolderDroppingDelay), this, &AppsGridView::OnFolderDroppingTimer); } @@ -524,8 +535,8 @@ } void AppsGridView::SetTopItemViewsVisible(bool visible) { - int top_item_count = std::min(static_cast<int>(kNumFolderTopItems), - view_model_.view_size()); + int top_item_count = + std::min(static_cast<int>(kNumFolderTopItems), view_model_.view_size()); for (int i = 0; i < top_item_count; ++i) GetItemViewAt(i)->icon()->SetVisible(visible); } @@ -540,8 +551,8 @@ ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); animation.AddObserver(this); - animation.SetTweenType( - show ? kFolderFadeInTweenType : kFolderFadeOutTweenType); + animation.SetTweenType(show ? kFolderFadeInTweenType + : kFolderFadeOutTweenType); animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds( show ? kFolderTransitionInDurationMs : kFolderTransitionOutDurationMs)); @@ -641,12 +652,7 @@ gfx::Size AppsGridView::CalculatePreferredSize() const { const gfx::Insets insets(GetInsets()); gfx::Size size = GetTileGridSize(); - if (is_fullscreen_app_list_enabled_) { - // If we are in a folder, ignore the page switcher for width calculations. - int page_switcher_width = - folder_delegate_ ? 0 : page_switcher_view_->GetPreferredSize().width(); - size.Enlarge(insets.width() + page_switcher_width, insets.height()); - } else { + if (!is_fullscreen_app_list_enabled_) { // If we are in a folder, ignore the page switcher for height calculations. int page_switcher_height = folder_delegate_ ? 0 : page_switcher_view_->GetPreferredSize().height(); @@ -821,8 +827,8 @@ const int existing_items = item_list_ ? item_list_->item_count() : 0; const int available_slots = tiles_per_page() - existing_items % tiles_per_page(); - const int desired = model_->status() == AppListModel::STATUS_SYNCING ? - available_slots : 0; + const int desired = + model_->status() == AppListModel::STATUS_SYNCING ? available_slots : 0; if (pulsing_blocks_model_.view_size() == desired) return; @@ -844,8 +850,7 @@ // The drag_view_ might be pending for deletion, therefore view_model_ // may have one more item than item_list_. DCHECK_LE(index, item_list_->item_count()); - AppListItemView* view = new AppListItemView(this, - item_list_->item_at(index)); + AppListItemView* view = new AppListItemView(this, item_list_->item_at(index)); view->SetPaintToLayer(); view->layer()->SetFillsBoundsOpaquely(false); return view; @@ -1055,10 +1060,7 @@ const int y_diff = target.y() - current.y(); if (visible && y_diff && y_diff % GetTotalTileSize().height() == 0) { - AnimationBetweenRows(view, - current_visible, - current, - target_visible, + AnimationBetweenRows(view, current_visible, current, target_visible, target); } else if (visible || bounds_animator_.IsAnimating(view)) { bounds_animator_.AnimateViewTo(view, target); @@ -1078,13 +1080,14 @@ const gfx::Rect& target) { // Determine page of |current| and |target|. -1 means in the left invisible // page, 0 is the center visible page and 1 means in the right invisible page. - const int current_page = current.x() < 0 ? -1 : - current.x() >= width() ? 1 : 0; - const int target_page = target.x() < 0 ? -1 : - target.x() >= width() ? 1 : 0; + const int current_page = + current.x() < 0 ? -1 : current.x() >= width() ? 1 : 0; + const int target_page = target.x() < 0 ? -1 : target.x() >= width() ? 1 : 0; - const int dir = current_page < target_page || - (current_page == target_page && current.y() < target.y()) ? 1 : -1; + const int dir = current_page < target_page || (current_page == target_page && + current.y() < target.y()) + ? 1 + : -1; std::unique_ptr<ui::Layer> layer; if (animate_current) { @@ -1095,7 +1098,7 @@ view->layer()->SetOpacity(0.f); } - gfx::Size total_tile_size = GetTotalTileSize(); + const gfx::Size total_tile_size = GetTotalTileSize(); gfx::Rect current_out(current); current_out.Offset(dir * total_tile_size.width(), 0); @@ -1122,8 +1125,7 @@ if (GetWidget()) { aura::Window::ConvertPointToTarget( GetWidget()->GetNativeWindow()->GetRootWindow(), - GetWidget()->GetNativeWindow(), - drag_point); + GetWidget()->GetNativeWindow(), drag_point); } views::View::ConvertPointFromWidget(this, drag_point); @@ -1211,7 +1213,7 @@ x_offset_direction = reorder_placeholder_ < grid_index ? -1 : 1; } - gfx::Size total_tile_size = GetTotalTileSize(); + const gfx::Size total_tile_size = GetTotalTileSize(); int row = grid_index.slot / cols_; // Offset the target column based on the direction of the target. This will @@ -1241,8 +1243,8 @@ DCHECK(folder_delegate_); if (drag_out_of_folder_container_ && drag_view_) { bool has_native_drag = drag_and_drop_host_ != nullptr; - folder_delegate_->ReparentItem( - drag_view_, last_drag_point_, has_native_drag); + folder_delegate_->ReparentItem(drag_view_, last_drag_point_, + has_native_drag); // Set the flag in the folder's grid view. dragging_for_reparent_item_ = true; @@ -1283,8 +1285,7 @@ if (!drag_out_of_folder_container_) { folder_item_reparent_timer_.Start( FROM_HERE, - base::TimeDelta::FromMilliseconds(kFolderItemReparentDelay), - this, + base::TimeDelta::FromMilliseconds(kFolderItemReparentDelay), this, &AppsGridView::OnFolderItemReparentTimer); drag_out_of_folder_container_ = true; } @@ -1305,14 +1306,14 @@ gfx::Rect AppsGridView::GetTargetIconRectInFolder( AppListItemView* drag_item_view, AppListItemView* folder_item_view) { - gfx::Rect view_ideal_bounds = view_model_.ideal_bounds( - view_model_.GetIndexOfView(folder_item_view)); + gfx::Rect view_ideal_bounds = + view_model_.ideal_bounds(view_model_.GetIndexOfView(folder_item_view)); gfx::Rect icon_ideal_bounds = folder_item_view->GetIconBoundsForTargetViewBounds(view_ideal_bounds); AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(folder_item_view->item()); - return folder_item->GetTargetIconRectInFolderForItem( - drag_item_view->item(), icon_ideal_bounds); + return folder_item->GetTargetIconRectInFolderForItem(drag_item_view->item(), + icon_ideal_bounds); } bool AppsGridView::IsUnderOEMFolder() { @@ -1398,21 +1399,17 @@ // Determine the mouse offset to the center of the icon so that the drag and // drop host follows this layer. - gfx::Vector2d delta = drag_view_offset_ - - drag_view_->GetLocalBounds().CenterPoint(); + gfx::Vector2d delta = + drag_view_offset_ - drag_view_->GetLocalBounds().CenterPoint(); delta.set_y(delta.y() + drag_view_->title()->size().height() / 2); // We have to hide the original item since the drag and drop host will do // the OS dependent code to "lift off the dragged item". DCHECK(!IsDraggingForReparentInRootLevelGridView()); - drag_and_drop_host_->CreateDragIconProxy(screen_location, - drag_view_->item()->icon(), - drag_view_, - delta, - kDragAndDropProxyScale); - SetViewHidden(drag_view_, - true /* hide */, - true /* no animation */); + drag_and_drop_host_->CreateDragIconProxy( + screen_location, drag_view_->item()->icon(), drag_view_, delta, + kDragAndDropProxyScale); + SetViewHidden(drag_view_, true /* hide */, true /* no animation */); } void AppsGridView::DispatchDragEventToDragAndDropHost( @@ -1467,8 +1464,8 @@ } else { if (page_switcher_view_->bounds().Contains(drag_point)) { gfx::Point page_switcher_point(drag_point); - views::View::ConvertPointToTarget( - this, page_switcher_view_, &page_switcher_point); + views::View::ConvertPointToTarget(this, page_switcher_view_, + &page_switcher_point); new_page_flip_target = page_switcher_view_->GetPageForPoint(page_switcher_point); } @@ -1491,8 +1488,8 @@ page_flip_target_ = new_page_flip_target; if (page_flip_target_ != pagination_model_.selected_page()) { - page_flip_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(page_flip_delay_in_ms_), + page_flip_timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(page_flip_delay_in_ms_), this, &AppsGridView::OnPageFlipTimer); } } @@ -1730,10 +1727,9 @@ drag_item_view->ConvertRectToParent(drag_item_view->GetIconBounds()); drag_view_icon_to_grid.ClampToCenteredSize( gfx::Size(kGridIconDimension, kGridIconDimension)); - TopIconAnimationView* icon_view = new TopIconAnimationView( - drag_item_view->item()->icon(), - target_icon_rect, - false); /* animate like closing folder */ + TopIconAnimationView* icon_view = + new TopIconAnimationView(drag_item_view->item()->icon(), target_icon_rect, + false); /* animate like closing folder */ AddChildView(icon_view); icon_view->SetBoundsRect(drag_view_icon_to_grid); icon_view->TransformView(); @@ -1827,8 +1823,7 @@ EnsureViewVisible(GetIndexFromModelIndex(index)); } -void AppsGridView::TotalPagesChanged() { -} +void AppsGridView::TotalPagesChanged() {} void AppsGridView::SelectedPageChanged(int old_selected, int new_selected) { if (dragging()) { @@ -1884,11 +1879,10 @@ AppsGridView::Index AppsGridView::GetNearestTileIndexForPoint( const gfx::Point& point) const { gfx::Rect bounds = GetContentsBounds(); - gfx::Size total_tile_size = GetTotalTileSize(); - int col = ClampToRange( - (point.x() - bounds.x()) / total_tile_size.width(), 0, cols_ - 1); - int row = ClampToRange((point.y() - bounds.y()) / total_tile_size.height(), - 0, + const gfx::Size total_tile_size = GetTotalTileSize(); + int col = ClampToRange((point.x() - bounds.x()) / total_tile_size.width(), 0, + cols_ - 1); + int row = ClampToRange((point.y() - bounds.y()) / total_tile_size.height(), 0, rows_per_page_ - 1); return Index(pagination_model_.selected_page(), row * cols_ + col); } @@ -1906,7 +1900,7 @@ gfx::Rect AppsGridView::GetExpectedTileBounds(int row, int col) const { gfx::Rect bounds(GetContentsBounds()); - gfx::Size total_tile_size = GetTotalTileSize(); + const gfx::Size total_tile_size = GetTotalTileSize(); gfx::Rect tile_bounds(gfx::Point(bounds.x() + col * total_tile_size.width(), bounds.y() + row * total_tile_size.height()), total_tile_size);
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index 8508e106..6b092c1 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -38,7 +38,8 @@ custom_page_view_(nullptr), app_list_main_view_(app_list_main_view), app_list_view_(app_list_view), - page_before_search_(0) { + page_before_search_(0), + is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) { pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs, kOverscrollPageTransitionDurationMs); pagination_model_.AddObserver(this); @@ -210,13 +211,13 @@ DCHECK(start_page_view_); // Set the visibility of the search box's back button. - if (!features::IsFullscreenAppListEnabled()) { + const bool folder_active = state == AppListModel::STATE_APPS && + apps_container_view_->IsInFolderView(); + + if (!is_fullscreen_app_list_enabled_) { app_list_main_view_->search_box_view()->back_button()->SetVisible( state != AppListModel::STATE_START); app_list_main_view_->search_box_view()->Layout(); - bool folder_active = (state == AppListModel::STATE_APPS) - ? apps_container_view_->IsInFolderView() - : false; app_list_main_view_->search_box_view()->SetBackButtonLabel(folder_active); } @@ -317,8 +318,9 @@ gfx::Tween::LinearIntValueBetween( progress, original_shadow.y(), target_shadow.y())); search_box->SetShadow(gfx::ShadowValue( - offset, gfx::Tween::LinearIntValueBetween( - progress, original_shadow.blur(), target_shadow.blur()), + offset, + gfx::Tween::LinearIntValueBetween(progress, original_shadow.blur(), + target_shadow.blur()), gfx::Tween::ColorValueBetween(progress, original_shadow.color(), target_shadow.color()))); } @@ -365,10 +367,19 @@ } gfx::Rect ContentsView::GetDefaultSearchBoxBounds() const { - gfx::Rect search_box_bounds(0, 0, GetDefaultContentsSize().width(), - GetSearchBoxView()->GetPreferredSize().height()); - search_box_bounds.set_y(kSearchBoxPadding); - search_box_bounds.Inset(kSearchBoxPadding, 0); + gfx::Rect search_box_bounds; + if (is_fullscreen_app_list_enabled_) { + search_box_bounds.set_size(GetSearchBoxView()->GetPreferredSize()); + search_box_bounds.Offset( + (GetDefaultContentsSize().width() - search_box_bounds.width()) / 2, 0); + search_box_bounds.set_y(kSearchBoxTopPadding); + } else { + search_box_bounds = + gfx::Rect(0, 0, GetDefaultContentsSize().width(), + GetSearchBoxView()->GetPreferredSize().height()); + search_box_bounds.set_y(kSearchBoxPadding); + search_box_bounds.Inset(kSearchBoxPadding, 0); + } return search_box_bounds; } @@ -379,7 +390,10 @@ } gfx::Rect ContentsView::GetDefaultContentsBounds() const { - gfx::Rect bounds(gfx::Point(0, GetDefaultSearchBoxBounds().bottom()), + gfx::Rect bounds(gfx::Point(0, GetDefaultSearchBoxBounds().bottom() + + (is_fullscreen_app_list_enabled_ + ? kSearchBoxBottomPadding + : 0)), GetDefaultContentsSize()); return bounds; } @@ -473,8 +487,7 @@ return "ContentsView"; } -void ContentsView::TotalPagesChanged() { -} +void ContentsView::TotalPagesChanged() {} void ContentsView::SelectedPageChanged(int old_selected, int new_selected) { if (old_selected >= 0) @@ -484,8 +497,7 @@ app_list_pages_[new_selected]->OnShown(); } -void ContentsView::TransitionStarted() { -} +void ContentsView::TransitionStarted() {} void ContentsView::TransitionChanged() { UpdatePageBounds();
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h index a27300fe..277a09460 100644 --- a/ui/app_list/views/contents_view.h +++ b/ui/app_list/views/contents_view.h
@@ -207,6 +207,8 @@ // Manages the pagination for the launcher pages. PaginationModel pagination_model_; + const bool is_fullscreen_app_list_enabled_; + DISALLOW_COPY_AND_ASSIGN(ContentsView); };
diff --git a/ui/app_list/views/expand_arrow_view.cc b/ui/app_list/views/expand_arrow_view.cc new file mode 100644 index 0000000..632d3e18 --- /dev/null +++ b/ui/app_list/views/expand_arrow_view.cc
@@ -0,0 +1,108 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/app_list/views/expand_arrow_view.h" + +#include "base/metrics/histogram_macros.h" +#include "ui/app_list/app_list_constants.h" +#include "ui/app_list/vector_icons/vector_icons.h" +#include "ui/app_list/views/app_list_view.h" +#include "ui/app_list/views/contents_view.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/animation/flood_fill_ink_drop_ripple.h" +#include "ui/views/animation/ink_drop_highlight.h" +#include "ui/views/animation/ink_drop_impl.h" +#include "ui/views/animation/ink_drop_mask.h" +#include "ui/views/animation/ink_drop_painted_layer_delegates.h" +#include "ui/views/controls/image_view.h" + +namespace app_list { + +namespace { + +constexpr int kExpandArrowTileSize = 36; +constexpr int kExpandArrowIconSize = 12; +constexpr int kInkDropRadius = 18; + +constexpr SkColor kExpandArrowColor = SK_ColorWHITE; +constexpr SkColor kInkDropRippleColor = + SkColorSetARGBMacro(0x14, 0xFF, 0xFF, 0xFF); +constexpr SkColor kInkDropHighlightColor = + SkColorSetARGBMacro(0xF, 0xFF, 0xFF, 0xFF); + +} // namespace + +ExpandArrowView::ExpandArrowView(ContentsView* contents_view, + AppListView* app_list_view) + : views::CustomButton(this), + contents_view_(contents_view), + app_list_view_(app_list_view) { + icon_ = new views::ImageView; + icon_->SetVerticalAlignment(views::ImageView::CENTER); + icon_->SetImage(gfx::CreateVectorIcon(kIcArrowUpIcon, kExpandArrowIconSize, + kExpandArrowColor)); + AddChildView(icon_); + + SetInkDropMode(InkDropHostView::InkDropMode::ON); +} + +ExpandArrowView::~ExpandArrowView() {} + +void ExpandArrowView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + UMA_HISTOGRAM_ENUMERATION(kPageOpenedHistogram, AppListModel::STATE_APPS, + AppListModel::STATE_LAST); + + contents_view_->SetActiveState(AppListModel::STATE_APPS); + app_list_view_->SetState(AppListView::FULLSCREEN_ALL_APPS); + GetInkDrop()->AnimateToState(views::InkDropState::ACTION_TRIGGERED); +} + +gfx::Size ExpandArrowView::CalculatePreferredSize() const { + return gfx::Size(kExpandArrowTileSize, kExpandArrowTileSize); +} + +void ExpandArrowView::Layout() { + gfx::Rect rect(GetContentsBounds()); + gfx::Point center = rect.CenterPoint(); + rect.SetRect(center.x() - kExpandArrowIconSize / 2, + center.y() - kExpandArrowIconSize / 2, kExpandArrowIconSize, + kExpandArrowIconSize); + icon_->SetBoundsRect(rect); +} + +std::unique_ptr<views::InkDrop> ExpandArrowView::CreateInkDrop() { + std::unique_ptr<views::InkDropImpl> ink_drop = + CustomButton::CreateDefaultInkDropImpl(); + ink_drop->SetShowHighlightOnHover(false); + ink_drop->SetShowHighlightOnFocus(true); + ink_drop->SetAutoHighlightMode( + views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE); + return std::move(ink_drop); +} + +std::unique_ptr<views::InkDropMask> ExpandArrowView::CreateInkDropMask() const { + return base::MakeUnique<views::CircleInkDropMask>( + size(), GetLocalBounds().CenterPoint(), kInkDropRadius); +} + +std::unique_ptr<views::InkDropRipple> ExpandArrowView::CreateInkDropRipple() + const { + gfx::Point center = GetLocalBounds().CenterPoint(); + gfx::Rect bounds(center.x() - kInkDropRadius, center.y() - kInkDropRadius, + 2 * kInkDropRadius, 2 * kInkDropRadius); + return base::MakeUnique<views::FloodFillInkDropRipple>( + size(), GetLocalBounds().InsetsFrom(bounds), + GetInkDropCenterBasedOnLastEvent(), kInkDropRippleColor, 1.0f); +} + +std::unique_ptr<views::InkDropHighlight> +ExpandArrowView::CreateInkDropHighlight() const { + return base::MakeUnique<views::InkDropHighlight>( + gfx::PointF(GetLocalBounds().CenterPoint()), + base::MakeUnique<views::CircleLayerDelegate>(kInkDropHighlightColor, + kInkDropRadius)); +} + +} // namespace app_list
diff --git a/ui/app_list/views/expand_arrow_view.h b/ui/app_list/views/expand_arrow_view.h new file mode 100644 index 0000000..b1064ad4 --- /dev/null +++ b/ui/app_list/views/expand_arrow_view.h
@@ -0,0 +1,56 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_APP_LIST_VIEWS_EXPAND_ARROW_VIEW_H_ +#define UI_APP_LIST_VIEWS_EXPAND_ARROW_VIEW_H_ + +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/custom_button.h" + +namespace views { +class ImageView; +class InkDrop; +class InkDropMask; +class InkDropRipple; +class InkDropHighlight; +} // namespace views + +namespace app_list { + +class AppListView; +class ContentsView; + +// A tile item for the expand arrow on the start page. +class ExpandArrowView : public views::CustomButton, + public views::ButtonListener { + public: + ExpandArrowView(ContentsView* contents_view, AppListView* app_list_view); + ~ExpandArrowView() override; + + // Overridden from views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + // Overridden from views::View: + gfx::Size CalculatePreferredSize() const override; + void Layout() override; + + // Overridden from views::InkDropHost: + std::unique_ptr<views::InkDrop> CreateInkDrop() override; + std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; + std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; + std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() + const override; + + private: + ContentsView* const contents_view_; + AppListView* const app_list_view_; // Owned by the views hierarchy. + + views::ImageView* icon_; + + DISALLOW_COPY_AND_ASSIGN(ExpandArrowView); +}; + +} // namespace app_list + +#endif // UI_APP_LIST_VIEWS_EXPAND_ARROW_VIEW_H_
diff --git a/ui/app_list/views/page_switcher_vertical.cc b/ui/app_list/views/page_switcher_vertical.cc index a22d1d9..4d8731c 100644 --- a/ui/app_list/views/page_switcher_vertical.cc +++ b/ui/app_list/views/page_switcher_vertical.cc
@@ -31,11 +31,8 @@ constexpr int kInkDropRadius = 8; // The padding on top/bottom side of each button. constexpr int kButtonPadding = 12; -// The padding of a list of buttons as a button strip. -constexpr int kButtonStripPadding = 24; constexpr int kMaxButtonRadius = 8; -constexpr int kPreferredButtonStripWidth = - kMaxButtonRadius * 2 + kButtonStripPadding * 2; +constexpr int kPreferredButtonStripWidth = kMaxButtonRadius * 2; // The selected button color. constexpr SkColor kSelectedButtonColor = SK_ColorWHITE; @@ -171,8 +168,7 @@ PageSwitcherVertical::PageSwitcherVertical(PaginationModel* model) : model_(model), buttons_(new views::View) { buttons_->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kVertical, - gfx::Insets(kButtonStripPadding, kButtonStripPadding), kButtonPadding)); + views::BoxLayout::kVertical, gfx::Insets(), kButtonPadding)); AddChildView(buttons_);
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index bd0141c..48a22b3 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -172,6 +172,15 @@ search_box_->set_controller(this); search_box_->SetTextInputType(ui::TEXT_INPUT_TYPE_SEARCH); search_box_->SetTextInputFlags(ui::TEXT_INPUT_FLAG_AUTOCORRECT_OFF); + back_button_ = new SearchBoxImageButton(this); + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + back_button_->SetImage(views::ImageButton::STATE_NORMAL, + rb.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL)); + back_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, + views::ImageButton::ALIGN_MIDDLE); + SetBackButtonLabel(false); + content_container_->AddChildView(back_button_); + if (is_fullscreen_app_list_enabled_) { google_icon_ = new views::ImageView(); google_icon_->SetImage(gfx::CreateVectorIcon( @@ -182,17 +191,8 @@ search_box_->set_placeholder_text_draw_flags( gfx::Canvas::TEXT_ALIGN_CENTER); search_box_->SetFontList(search_box_->GetFontList().DeriveWithSizeDelta(2)); + back_button_->SetVisible(false); } else { - back_button_ = new SearchBoxImageButton(this); - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - back_button_->SetImage( - views::ImageButton::STATE_NORMAL, - rb.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL)); - back_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); - SetBackButtonLabel(false); - content_container_->AddChildView(back_button_); - search_box_->set_placeholder_text_color(kHintTextColor); } content_container_->AddChildView(search_box_); @@ -332,6 +332,15 @@ back_button_->SetTooltipText(back_button_label); } +void SearchBoxView::ShowBackOrGoogleIcon(bool show_back_button) { + if (!is_fullscreen_app_list_enabled_) + return; + + google_icon_->SetVisible(!show_back_button); + back_button_->SetVisible(show_back_button); + content_container_->Layout(); +} + bool SearchBoxView::OnMouseWheel(const ui::MouseWheelEvent& event) { if (contents_view_) return contents_view_->OnMouseWheel(event);
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index b03fdc6..d2cee93 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h
@@ -81,6 +81,9 @@ // Sets voice label for Back button depending on whether a folder is open. void SetBackButtonLabel(bool folder); + // Swaps the google icon with the back button. + void ShowBackOrGoogleIcon(bool show_back_button); + // Overridden from views::View: bool OnMouseWheel(const ui::MouseWheelEvent& event) override; void OnEnabledChanged() override;
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index ad3b9b8..8427adb 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -23,6 +23,7 @@ #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/custom_launcher_page_view.h" +#include "ui/app_list/views/expand_arrow_view.h" #include "ui/app_list/views/indicator_chip_view.h" #include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/search_result_container_view.h" @@ -45,10 +46,8 @@ namespace { // Layout constants. -constexpr int kSearchBoxTopPadding = 24; constexpr int kInstantContainerSpacing = 24; constexpr int kSearchBoxAndTilesSpacing = 35; -constexpr int kSearchBoxAndIndicatorSpacing = 21; constexpr int kStartPageSearchBoxWidth = 480; constexpr int kStartPageSearchBoxWidthFullscreen = 544; @@ -56,6 +55,7 @@ constexpr int kWebViewWidth = 700; constexpr int kWebViewHeight = 224; +constexpr int kExpandArrowTopPadding = 28; constexpr int kLauncherPageBackgroundWidth = 400; } // namespace @@ -103,11 +103,14 @@ instant_container_(new views::View), custom_launcher_page_background_(new CustomLauncherPageBackgroundView( view_delegate_->GetModel()->custom_launcher_page_name())), - suggestions_container_(new SuggestionsContainerView( - app_list_main_view->contents_view(), - new AllAppsTileItemView(app_list_main_view_->contents_view(), - app_list_view))), is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) { + suggestions_container_ = new SuggestionsContainerView( + app_list_main_view->contents_view(), + is_fullscreen_app_list_enabled_ + ? nullptr + : new AllAppsTileItemView(app_list_main_view_->contents_view(), + app_list_view)); + search_box_spacer_view_->SetPreferredSize(gfx::Size( is_fullscreen_app_list_enabled_ ? kStartPageSearchBoxWidthFullscreen : kStartPageSearchBoxWidth, @@ -125,6 +128,11 @@ // The view containing the start page tiles. AddChildView(suggestions_container_); + if (is_fullscreen_app_list_enabled_) { + expand_arrow_view_ = new ExpandArrowView( + app_list_main_view_->contents_view(), app_list_view); + AddChildView(expand_arrow_view_); + } AddChildView(custom_launcher_page_background_); suggestions_container_->SetResults(view_delegate_->GetModel()->results()); @@ -137,7 +145,7 @@ views::BoxLayout::kVertical, gfx::Insets(), kInstantContainerSpacing); if (is_fullscreen_app_list_enabled_) { instant_layout_manager->set_inside_border_insets( - gfx::Insets(kSearchBoxTopPadding, 0, kSearchBoxAndIndicatorSpacing, 0)); + gfx::Insets(kSearchBoxTopPadding, 0, kSearchBoxBottomPadding, 0)); } else { instant_layout_manager->set_inside_border_insets( gfx::Insets(0, 0, kSearchBoxAndTilesSpacing, 0)); @@ -245,6 +253,18 @@ } suggestions_container_->SetBoundsRect(bounds); + if (expand_arrow_view_) { + gfx::Rect expand_arrow_rect(GetContentsBounds()); + int left_right_padding = + (bounds.width() - expand_arrow_view_->GetPreferredSize().width()) / 2; + + expand_arrow_rect.Inset(left_right_padding, 0, left_right_padding, 0); + expand_arrow_rect.set_y(bounds.bottom() + kExpandArrowTopPadding); + expand_arrow_rect.set_height( + expand_arrow_view_->GetPreferredSize().height()); + expand_arrow_view_->SetBoundsRect(expand_arrow_rect); + } + CustomLauncherPageView* custom_launcher_page_view = app_list_main_view_->contents_view()->custom_page_view(); if (!custom_launcher_page_view)
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h index 0c4aef3c..e1df339 100644 --- a/ui/app_list/views/start_page_view.h +++ b/ui/app_list/views/start_page_view.h
@@ -19,6 +19,7 @@ class AppListView; class AppListViewDelegate; class CustomLauncherPageBackgroundView; +class ExpandArrowView; class IndicatorChipView; class SearchResultTileItemView; class SuggestionsContainerView; @@ -79,6 +80,7 @@ IndicatorChipView* indicator_ = nullptr; // Owned by views hierarchy. SuggestionsContainerView* suggestions_container_; // Owned by views hierarchy. + ExpandArrowView* expand_arrow_view_ = nullptr; // Owned by views hierarchy. const bool is_fullscreen_app_list_enabled_;
diff --git a/ui/app_list/views/suggestions_container_view.cc b/ui/app_list/views/suggestions_container_view.cc index b3d2ca6..0edfa3a 100644 --- a/ui/app_list/views/suggestions_container_view.cc +++ b/ui/app_list/views/suggestions_container_view.cc
@@ -20,7 +20,6 @@ constexpr int kTileSpacing = 7; constexpr int kNumTilesCols = 5; constexpr int kTilesHorizontalMarginLeft = 145; -constexpr int kCenterColumnOfStartPageAppGrid = 3; } // namespace @@ -90,8 +89,10 @@ } parent()->Layout(); - // Add 1 to the results size to account for the all apps button. - return display_results.size() + 1; + // If |is_fullscreen_app_list_enabled_| is not enabled, add 1 to the results + // size to account for the all apps button. + return is_fullscreen_app_list_enabled_ ? display_results.size() + : display_results.size() + 1; } void SuggestionsContainerView::UpdateSelectedIndex(int old_selected, @@ -148,21 +149,14 @@ search_result_tile_views_.emplace_back(tile_item); } - if (all_apps_button_) + if (all_apps_button_ && !is_fullscreen_app_list_enabled_) { all_apps_button_->UpdateIcon(); - if (is_fullscreen_app_list_enabled_) { - // Also add a special "all apps" button to the middle of the next row of the - // container. - tiles_layout_manager->StartRow(0, 0); - tiles_layout_manager->SkipColumns(kCenterColumnOfStartPageAppGrid); - } else { + // Also add a special "all apps" button to the end of the next row of the // container. if (i % kNumTilesCols == 0) tiles_layout_manager->StartRow(0, 0); - } - if (all_apps_button_) { tiles_layout_manager->AddView(all_apps_button_); AddChildView(all_apps_button_); }
diff --git a/ui/app_list/views/suggestions_container_view.h b/ui/app_list/views/suggestions_container_view.h index 498d6b9..a7091e64 100644 --- a/ui/app_list/views/suggestions_container_view.h +++ b/ui/app_list/views/suggestions_container_view.h
@@ -18,7 +18,8 @@ class SearchResultTileItemView; class TileItemView; -// A container that holds the suggested app tiles and the all apps tile. +// A container that holds the suggested app tiles. If fullscreen app list is not +// enabled, it also holds the all apps button. class SuggestionsContainerView : public SearchResultContainerView { public: SuggestionsContainerView(ContentsView* contents_view,
diff --git a/ui/chromeos/touch_exploration_controller.cc b/ui/chromeos/touch_exploration_controller.cc index bd0473c..7520145f 100644 --- a/ui/chromeos/touch_exploration_controller.cc +++ b/ui/chromeos/touch_exploration_controller.cc
@@ -431,7 +431,7 @@ // If the user moves far enough from the initial touch location (outside // the "slop" region, jump to passthrough mode early. float delta = (event.location() - initial_press_->location()).Length(); - if (delta > gesture_detector_config_.touch_slop) { + if (delta > gesture_detector_config_.double_tap_slop) { tap_timer_.Stop(); OnTapTimerFired(); } @@ -919,15 +919,14 @@ } location = gesture->location(); - root_window_->GetHost()->ConvertScreenInPixelsToDIP(&location); - float volume_adjust_height = - root_window_->bounds().height() - 2 * kMaxDistanceFromEdge; + gfx::Rect bounds = GetRootWindowBoundsInScreenUnits(); + float volume_adjust_height = bounds.height() - 2 * kMaxDistanceFromEdge; float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; float volume = 100 - 100 * ratio; if (VLOG_on_) { VLOG(1) << "\n Volume = " << volume << "\n Location = " << location.ToString() - << "\n Bounds = " << root_window_->bounds().right(); + << "\n Bounds = " << bounds.right(); } delegate_->SetOutputLevel(static_cast<int>(volume)); } @@ -1017,12 +1016,15 @@ delegate_->HandleAccessibilityGesture(gesture); } +gfx::Rect TouchExplorationController::GetRootWindowBoundsInScreenUnits() { + gfx::Point root_window_size = root_window_->bounds().bottom_right(); + root_window_->GetHost()->ConvertDIPToScreenInPixels(&root_window_size); + return gfx::Rect(0, 0, root_window_size.x(), root_window_size.y()); +} + int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, float bounds) { - // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be - // converted. - root_window_->GetHost()->ConvertScreenInPixelsToDIP(&point); - gfx::Rect window = root_window_->GetBoundsInScreen(); + gfx::Rect window = GetRootWindowBoundsInScreenUnits(); float left_edge_limit = window.x() + bounds; float right_edge_limit = window.right() - bounds;
diff --git a/ui/chromeos/touch_exploration_controller.h b/ui/chromeos/touch_exploration_controller.h index 4076433f..6040682 100644 --- a/ui/chromeos/touch_exploration_controller.h +++ b/ui/chromeos/touch_exploration_controller.h
@@ -432,6 +432,11 @@ BOTTOM_RIGHT_CORNER = RIGHT_EDGE | BOTTOM_EDGE, }; + // Return the bounds of the root window in actual device pixels, not DIP, + // in order to match the coordinate system of touch events. Note that this + // is not the same as screen coordinates, which span multiple displays. + gfx::Rect GetRootWindowBoundsInScreenUnits(); + // Given a point, if it is within the given bounds of an edge, returns the // edge. If it is within the given bounds of two edges, returns an int with // both bits that represent the respective edges turned on. Otherwise returns
diff --git a/ui/gfx/animation/tween.cc b/ui/gfx/animation/tween.cc index f9498d9..a341548 100644 --- a/ui/gfx/animation/tween.cc +++ b/ui/gfx/animation/tween.cc
@@ -58,6 +58,9 @@ case FAST_OUT_SLOW_IN: return gfx::CubicBezier(0.4, 0, 0.2, 1).Solve(state); + case FAST_OUT_SLOW_IN_2: + return gfx::CubicBezier(0.2, 0, 0.2, 1).Solve(state); + case LINEAR_OUT_SLOW_IN: return gfx::CubicBezier(0, 0, .2, 1).Solve(state);
diff --git a/ui/gfx/animation/tween.h b/ui/gfx/animation/tween.h index c2f76167..3be0e95 100644 --- a/ui/gfx/animation/tween.h +++ b/ui/gfx/animation/tween.h
@@ -31,6 +31,7 @@ SMOOTH_IN_OUT, // Smooth, consistent speeds in and out (sine wave). FAST_OUT_SLOW_IN, // Variant of EASE_IN_OUT which should be used in most // cases. + FAST_OUT_SLOW_IN_2, // Variant of FAST_OUT_SLOW_IN that starts out quicker. LINEAR_OUT_SLOW_IN, // Variant of EASE_OUT which should be used for // fading in from 0% or motion when entering a scene. SLOW_OUT_LINEAR_IN, // Reverse of LINEAR_OUT_SLOW_IN which should be used
diff --git a/ui/gfx/font_fallback_mac.mm b/ui/gfx/font_fallback_mac.mm index 6cfc7e3..6a4d66f1 100644 --- a/ui/gfx/font_fallback_mac.mm +++ b/ui/gfx/font_fallback_mac.mm
@@ -40,6 +40,7 @@ } // namespace std::vector<Font> GetFallbackFonts(const Font& font) { + DCHECK(font.GetNativeFont()); // On Mac "There is a system default cascade list (which is polymorphic, based // on the user's language setting and current font)" - CoreText Programming // Guide. @@ -51,6 +52,8 @@ static_cast<CTFontRef>(font.GetNativeFont()), languages_cf)); std::vector<Font> fallback_fonts; + if (!cascade_list) + return fallback_fonts; // This should only happen for an invalid |font|. const CFIndex fallback_count = CFArrayGetCount(cascade_list); for (CFIndex i = 0; i < fallback_count; ++i) {
diff --git a/ui/gfx/mojo/buffer_types_struct_traits.cc b/ui/gfx/mojo/buffer_types_struct_traits.cc index 6eb1495..186e2eb5 100644 --- a/ui/gfx/mojo/buffer_types_struct_traits.cc +++ b/ui/gfx/mojo/buffer_types_struct_traits.cc
@@ -11,31 +11,25 @@ void* StructTraits<gfx::mojom::NativePixmapHandleDataView, gfx::NativePixmapHandle>:: SetUpContext(const gfx::NativePixmapHandle& pixmap_handle) { - return new PixmapHandleFdList(); + auto* handles = new std::vector<mojo::ScopedHandle>(); +#if defined(OS_LINUX) + for (const base::FileDescriptor& fd : pixmap_handle.fds) + handles->emplace_back(mojo::WrapPlatformFile(fd.fd)); +#endif // defined(OS_LINUX) + return handles; } void StructTraits<gfx::mojom::NativePixmapHandleDataView, gfx::NativePixmapHandle>:: TearDownContext(const gfx::NativePixmapHandle& handle, void* context) { - delete static_cast<PixmapHandleFdList*>(context); + delete static_cast<std::vector<mojo::ScopedHandle>*>(context); } -std::vector<mojo::ScopedHandle> StructTraits< +std::vector<mojo::ScopedHandle>& StructTraits< gfx::mojom::NativePixmapHandleDataView, gfx::NativePixmapHandle>::fds(const gfx::NativePixmapHandle& pixmap_handle, void* context) { - PixmapHandleFdList* handles = static_cast<PixmapHandleFdList*>(context); -#if defined(OS_LINUX) - if (handles->empty()) { - // Generate the handles here, but do not send them yet. - for (const base::FileDescriptor& fd : pixmap_handle.fds) { - base::PlatformFile platform_file = fd.fd; - handles->push_back(mojo::WrapPlatformFile(platform_file)); - } - return PixmapHandleFdList(handles->size()); - } -#endif // defined(OS_LINUX) - return std::move(*handles); + return *static_cast<std::vector<mojo::ScopedHandle>*>(context); } bool StructTraits<
diff --git a/ui/gfx/mojo/buffer_types_struct_traits.h b/ui/gfx/mojo/buffer_types_struct_traits.h index ce05fe9..ea132ae 100644 --- a/ui/gfx/mojo/buffer_types_struct_traits.h +++ b/ui/gfx/mojo/buffer_types_struct_traits.h
@@ -238,8 +238,6 @@ template <> struct StructTraits<gfx::mojom::NativePixmapHandleDataView, gfx::NativePixmapHandle> { - using PixmapHandleFdList = std::vector<mojo::ScopedHandle>; - static void* SetUpContext(const gfx::NativePixmapHandle& handle); static void TearDownContext(const gfx::NativePixmapHandle& handle, void* context); @@ -252,8 +250,9 @@ return true; #endif } - static PixmapHandleFdList fds(const gfx::NativePixmapHandle& pixmap_handle, - void* context); + static std::vector<mojo::ScopedHandle>& fds( + const gfx::NativePixmapHandle& pixmap_handle, + void* context); static const std::vector<gfx::NativePixmapPlane>& planes( const gfx::NativePixmapHandle& pixmap_handle) {
diff --git a/ui/gfx/platform_font_mac.h b/ui/gfx/platform_font_mac.h index 5b2f5be..e127fa1 100644 --- a/ui/gfx/platform_font_mac.h +++ b/ui/gfx/platform_font_mac.h
@@ -55,8 +55,8 @@ // The NSFont instance for this object. If this object was constructed from an // NSFont instance, this holds that NSFont instance. Otherwise this NSFont - // instance is constructed from the name, size, and style, and if there is no - // active font that matched those criteria, this object may be nil. + // instance is constructed from the name, size, and style. If there is no + // active font that matched those criteria a default font is used. base::scoped_nsobject<NSFont> native_font_; // The name/size/style trio that specify the font. Initialized in the
diff --git a/ui/gfx/platform_font_mac.mm b/ui/gfx/platform_font_mac.mm index 7745bf9..1906c81a 100644 --- a/ui/gfx/platform_font_mac.mm +++ b/ui/gfx/platform_font_mac.mm
@@ -87,8 +87,7 @@ // Returns the Font weight for |font|. Font::Weight GetFontWeightFromNSFont(NSFont* font) { - if (!font) - return Font::Weight::INVALID; + DCHECK(font); // Map CoreText weights in a manner similar to ct_weight_to_fontstyle() from // SkFontHost_mac.cpp, but adjust for MEDIUM so that the San Francisco's @@ -174,6 +173,11 @@ return [NSFont fontWithDescriptor:descriptor size:font_size]; } +// Returns |font| or a default font if |font| is nil. +NSFont* ValidateFont(NSFont* font) { + return font ? font : [NSFont systemFontOfSize:[NSFont systemFontSize]]; +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -188,7 +192,9 @@ base::SysNSStringToUTF8([native_font familyName]), [native_font pointSize], GetFontStyleFromNSFont(native_font), - GetFontWeightFromNSFont(native_font)) {} + GetFontWeightFromNSFont(native_font)) { + DCHECK(native_font); // Null should not be passed to this constructor. +} PlatformFontMac::PlatformFontMac(const std::string& font_name, int font_size) : PlatformFontMac(font_name, @@ -256,7 +262,7 @@ } int PlatformFontMac::GetExpectedTextWidth(int length) { - if (!average_width_ && native_font_) { + if (!average_width_) { // -[NSFont boundingRectForGlyph:] seems to always return the largest // bounding rect that could be needed, which produces very wide expected // widths for strings. Instead, compute the actual width of a string @@ -319,7 +325,7 @@ int font_size, int font_style, Font::Weight font_weight) - : native_font_([font retain]), + : native_font_([ValidateFont(font) retain]), font_name_(font_name), font_size_(font_size), font_style_(font_style), @@ -332,15 +338,7 @@ void PlatformFontMac::CalculateMetricsAndInitRenderParams() { NSFont* font = native_font_.get(); - if (!font) { - // This object was constructed from a font name that doesn't correspond to - // an actual font. Don't waste time working out metrics. - height_ = 0; - ascent_ = 0; - cap_height_ = 0; - return; - } - + DCHECK(font); ascent_ = ceil([font ascender]); cap_height_ = ceil([font capHeight]); @@ -371,7 +369,7 @@ // static PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { - return new PlatformFontMac(native_font); + return new PlatformFontMac(ValidateFont(native_font)); } // static
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc index c4fb25c1..97dcfec 100644 --- a/ui/gfx/render_text_harfbuzz.cc +++ b/ui/gfx/render_text_harfbuzz.cc
@@ -602,7 +602,7 @@ // Applies a forced text rendering direction if specified by a command-line // switch. -void CheckForcedDirection(UBiDiLevel* level) { +void ApplyForcedDirection(UBiDiLevel* level) { static bool has_switch = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kForceTextDirection); if (!has_switch) @@ -1396,7 +1396,7 @@ int32_t script_item_break = 0; bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); CHECK_GT(static_cast<size_t>(script_item_break), run_break); - CheckForcedDirection(&run->level); + ApplyForcedDirection(&run->level); // Odd BiDi embedding levels correspond to RTL runs. run->is_rtl = (run->level % 2) == 1; // Find the length and script of this script run.
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index 9317032..7081122 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -4532,11 +4532,6 @@ // Tests that RenderText doesn't crash even if it's passed an invalid font. Test // for crbug.com/668058. TEST_P(RenderTextTest, InvalidFont) { -// TODO(crbug.com/699820): This crashes with RenderTextHarfBuzz on Mac. -#if defined(OS_MACOSX) - if (GetParam() == RENDER_TEXT_HARFBUZZ) - return; -#endif const std::string font_name = "invalid_font"; const int kFontSize = 13; RenderText* render_text = GetRenderText();
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc index 3f05795..e2c0c4c 100644 --- a/ui/gl/gl_image_native_pixmap.cc +++ b/ui/gl/gl_image_native_pixmap.cc
@@ -133,16 +133,9 @@ gfx::BufferFormat format) { DCHECK(!pixmap_); if (pixmap->GetEGLClientBuffer()) { - std::vector<EGLint> attrs; - attrs.push_back(EGL_IMAGE_PRESERVED_KHR); - attrs.push_back(EGL_TRUE); - if (has_image_flush_external_) { - attrs.push_back(EGL_IMAGE_EXTERNAL_FLUSH_EXT); - attrs.push_back(EGL_TRUE); - } - attrs.push_back(EGL_NONE); + EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; if (!GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR, - pixmap->GetEGLClientBuffer(), &attrs[0])) { + pixmap->GetEGLClientBuffer(), attrs)) { return false; } } else if (pixmap->AreDmaBufFdsValid()) { @@ -196,10 +189,6 @@ attrs.push_back(static_cast<uint32_t>(modifier >> 32)); } } - if (has_image_flush_external_) { - attrs.push_back(EGL_IMAGE_EXTERNAL_FLUSH_EXT); - attrs.push_back(EGL_TRUE); - } attrs.push_back(EGL_NONE); if (!GLImageEGL::Initialize(EGL_LINUX_DMA_BUF_EXT, @@ -244,10 +233,13 @@ return; EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay(); - EGLAttrib attrs[] = { EGL_NONE }; - EGLBoolean rv = eglImageFlushExternalEXT(display, egl_image_, attrs); - LOG_IF(ERROR, !rv) << "Failed to flush rendering"; - DCHECK_EQ(rv, static_cast<EGLBoolean>(EGL_TRUE)); + const EGLAttrib attribs[] = { + EGL_NONE, + }; + if (!eglImageFlushExternalEXT(display, egl_image_, attribs)) { + LOG(ERROR) << "Failed to flush rendering"; + return; + } } void GLImageNativePixmap::OnMemoryDump(
diff --git a/ui/gl/test/gl_image_test_template.h b/ui/gl/test/gl_image_test_template.h index 168d32e..fdd9983 100644 --- a/ui/gl/test/gl_image_test_template.h +++ b/ui/gl/test/gl_image_test_template.h
@@ -212,28 +212,6 @@ REGISTER_TYPED_TEST_CASE_P(GLImageTest, Create); template <typename GLImageTestDelegate> -class GLImageFlushTest : public GLImageTest<GLImageTestDelegate> {}; - -TYPED_TEST_CASE_P(GLImageFlushTest); - -TYPED_TEST_P(GLImageFlushTest, Flush) { - const gfx::Size image_size(256, 256); - const uint8_t* image_color = this->delegate_.GetImageColor(); - - // Create a solid color green image of preferred format. - scoped_refptr<GLImage> image = - this->delegate_.CreateSolidColorImage(image_size, image_color); - ASSERT_TRUE(image); - - // Flush image. This must succeed in order for a GLImage to be conformant. - image->Flush(); -} - -// The GLImageTest test case verifies the flush behaviour that is expected from -// a GLImage in order to be conformant. -REGISTER_TYPED_TEST_CASE_P(GLImageFlushTest, Flush); - -template <typename GLImageTestDelegate> class GLImageOddSizeTest : public GLImageTest<GLImageTestDelegate> {}; // This test verifies that odd-sized GLImages can be created and destroyed.
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn index f84ffcd8..99a86da 100644 --- a/ui/keyboard/BUILD.gn +++ b/ui/keyboard/BUILD.gn
@@ -25,8 +25,6 @@ "keyboard_ui.h", "keyboard_util.cc", "keyboard_util.h", - "scoped_keyboard_disabler.cc", - "scoped_keyboard_disabler.h", ] defines = [ "KEYBOARD_IMPLEMENTATION" ] @@ -161,6 +159,7 @@ test("keyboard_unittests") { sources = [ + "content/keyboard_ui_content_unittest.cc", "keyboard_controller_unittest.cc", "keyboard_event_filter_unittest.cc", "keyboard_util_unittest.cc", @@ -169,8 +168,10 @@ deps = [ ":keyboard", + ":keyboard_with_content", "//base", "//base/test:test_support", + "//content/test:test_support", "//mojo/edk/system", "//skia", "//testing/gtest",
diff --git a/ui/keyboard/content/keyboard_ui_content.cc b/ui/keyboard/content/keyboard_ui_content.cc index 9f15673..5e6f4dd 100644 --- a/ui/keyboard/content/keyboard_ui_content.cc +++ b/ui/keyboard/content/keyboard_ui_content.cc
@@ -209,11 +209,7 @@ aura::Window* KeyboardUIContent::GetKeyboardWindow() { if (!keyboard_contents_) { - content::BrowserContext* context = browser_context(); - keyboard_contents_.reset(content::WebContents::Create( - content::WebContents::CreateParams(context, - content::SiteInstance::CreateForURL(context, - GetVirtualKeyboardUrl())))); + keyboard_contents_.reset(CreateWebContents()); keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this)); SetupWebContents(keyboard_contents_.get()); LoadContents(GetVirtualKeyboardUrl()); @@ -301,22 +297,18 @@ void KeyboardUIContent::OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { - if (!shadow_) { - shadow_.reset(new wm::Shadow()); - shadow_->Init(wm::ShadowElevation::LARGE); - shadow_->layer()->SetVisible(true); - DCHECK(keyboard_contents_->GetNativeView()->parent()); - keyboard_contents_->GetNativeView()->parent()->layer()->Add( - shadow_->layer()); - } - - shadow_->SetContentBounds(new_bounds); + SetShadowAroundKeyboard(); } void KeyboardUIContent::OnWindowDestroyed(aura::Window* window) { window->RemoveObserver(this); } +void KeyboardUIContent::OnWindowParentChanged(aura::Window* window, + aura::Window* parent) { + SetShadowAroundKeyboard(); +} + const aura::Window* KeyboardUIContent::GetKeyboardRootWindow() const { if (!keyboard_contents_) { return nullptr; @@ -324,6 +316,13 @@ return keyboard_contents_->GetNativeView()->GetRootWindow(); } +content::WebContents* KeyboardUIContent::CreateWebContents() { + content::BrowserContext* context = browser_context(); + return content::WebContents::Create(content::WebContents::CreateParams( + context, + content::SiteInstance::CreateForURL(context, GetVirtualKeyboardUrl()))); +} + void KeyboardUIContent::LoadContents(const GURL& url) { if (keyboard_contents_) { TRACE_EVENT0("vk", "LoadContents"); @@ -357,4 +356,19 @@ window_bounds_observer_->AddObservedWindow(target_window); } +void KeyboardUIContent::SetShadowAroundKeyboard() { + aura::Window* contents_window = keyboard_contents_->GetNativeView(); + if (!contents_window->parent()) + return; + + if (!shadow_) { + shadow_.reset(new wm::Shadow()); + shadow_->Init(wm::ShadowElevation::LARGE); + shadow_->layer()->SetVisible(true); + contents_window->parent()->layer()->Add(shadow_->layer()); + } + + shadow_->SetContentBounds(contents_window->bounds()); +} + } // namespace keyboard
diff --git a/ui/keyboard/content/keyboard_ui_content.h b/ui/keyboard/content/keyboard_ui_content.h index fe1a37d..f86e07a 100644 --- a/ui/keyboard/content/keyboard_ui_content.h +++ b/ui/keyboard/content/keyboard_ui_content.h
@@ -86,11 +86,15 @@ const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) override; void OnWindowDestroyed(aura::Window* window) override; + void OnWindowParentChanged(aura::Window* window, + aura::Window* parent) override; content::BrowserContext* browser_context() { return browser_context_; } const aura::Window* GetKeyboardRootWindow() const; + virtual content::WebContents* CreateWebContents(); + private: friend class TestApi; @@ -108,6 +112,10 @@ // invalidates insets for overscrolling. void AddBoundsChangedObserver(aura::Window* window); + // Sets shadow around the keyboard. If shadow has not been created yet, + // this method creates it. + void SetShadowAroundKeyboard(); + // The BrowserContext to use for creating the WebContents hosting the // keyboard. content::BrowserContext* browser_context_;
diff --git a/ui/keyboard/content/keyboard_ui_content_unittest.cc b/ui/keyboard/content/keyboard_ui_content_unittest.cc new file mode 100644 index 0000000..bbac466c --- /dev/null +++ b/ui/keyboard/content/keyboard_ui_content_unittest.cc
@@ -0,0 +1,70 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/keyboard/content/keyboard_ui_content.h" + +#include "content/public/browser/web_contents.h" +#include "content/public/test/test_content_client_initializer.h" +#include "content/public/test/test_renderer_host.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/window.h" +#include "ui/gfx/geometry/rect.h" + +namespace keyboard { +namespace { + +class TestKeyboardUIContent : public KeyboardUIContent { + public: + TestKeyboardUIContent(content::BrowserContext* context, + content::WebContents* contents) + : KeyboardUIContent(context), contents_(contents) {} + ~TestKeyboardUIContent() override {} + + ui::InputMethod* GetInputMethod() override { return nullptr; } + void SetUpdateInputType(ui::TextInputType type) override {} + void RequestAudioInput( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) override {} + + content::WebContents* CreateWebContents() override { return contents_; } + + private: + content::WebContents* contents_; +}; + +} // namespace + +class KeyboardUIContentTest : public content::RenderViewHostTestHarness { + public: + void SetUp() override { + initializer_ = base::MakeUnique<content::TestContentClientInitializer>(); + content::RenderViewHostTestHarness::SetUp(); + } + + void TearDown() override { + content::RenderViewHostTestHarness::TearDown(); + initializer_.reset(); + } + + private: + std::unique_ptr<content::TestContentClientInitializer> initializer_; +}; + +// A test for crbug.com/734534 +TEST_F(KeyboardUIContentTest, DoesNotCrashWhenParentDoesNotExist) { + content::WebContents* contents = CreateTestWebContents(); + TestKeyboardUIContent keyboard_ui(contents->GetBrowserContext(), contents); + + EXPECT_FALSE(keyboard_ui.HasKeyboardWindow()); + aura::Window* view = keyboard_ui.GetKeyboardWindow(); + EXPECT_TRUE(keyboard_ui.HasKeyboardWindow()); + + EXPECT_FALSE(view->parent()); + + // Change window size to trigger OnWindowBoundsChanged. + view->SetBounds(gfx::Rect(0, 0, 1200, 800)); +} + +} // namespace keyboard
diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc index 4dbe12a0..db4d360 100644 --- a/ui/keyboard/keyboard_util.cc +++ b/ui/keyboard/keyboard_util.cc
@@ -26,7 +26,6 @@ #include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_switches.h" #include "ui/keyboard/keyboard_ui.h" -#include "ui/keyboard/scoped_keyboard_disabler.h" namespace keyboard { @@ -113,9 +112,6 @@ } bool IsKeyboardEnabled() { - // Blocks keyboard from showing up regardless of other settings. - if (ScopedKeyboardDisabler::GetForceDisableVirtualKeyboard()) - return false; // Accessibility setting prioritized over policy setting. if (g_accessibility_keyboard_enabled) return true;
diff --git a/ui/keyboard/scoped_keyboard_disabler.cc b/ui/keyboard/scoped_keyboard_disabler.cc deleted file mode 100644 index e3fd8c5..0000000 --- a/ui/keyboard/scoped_keyboard_disabler.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/keyboard/scoped_keyboard_disabler.h" - -namespace keyboard { -namespace { - -bool g_force_disable_keyboard = false; - -} - -ScopedKeyboardDisabler::ScopedKeyboardDisabler() - : force_disable_keyboard_state_(g_force_disable_keyboard) {} - -ScopedKeyboardDisabler::~ScopedKeyboardDisabler() { - g_force_disable_keyboard = force_disable_keyboard_state_; -} - -void ScopedKeyboardDisabler::SetForceDisableVirtualKeyboard(bool disable) { - g_force_disable_keyboard = disable; -} - -// static -bool ScopedKeyboardDisabler::GetForceDisableVirtualKeyboard() { - return g_force_disable_keyboard; -} - -} // namespace keyboard
diff --git a/ui/keyboard/scoped_keyboard_disabler.h b/ui/keyboard/scoped_keyboard_disabler.h deleted file mode 100644 index bc042e1..0000000 --- a/ui/keyboard/scoped_keyboard_disabler.h +++ /dev/null
@@ -1,37 +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 UI_KEYBOARD_SCOPED_KEYBOARD_DISABLER_H_ -#define UI_KEYBOARD_SCOPED_KEYBOARD_DISABLER_H_ - -#include "base/macros.h" -#include "ui/keyboard/keyboard_export.h" - -namespace keyboard { - -// Saves the force disable keyboard state, and restores the state when going out -// of scope. -class KEYBOARD_EXPORT ScopedKeyboardDisabler { - public: - ScopedKeyboardDisabler(); - ~ScopedKeyboardDisabler(); - - // Blocks the keyboard from showing up. This should only be used for cases - // where the focus needs to be passed around without poping up the keyboard. - // It needs to be turned off or this object needs to go out of scope when done - // with, otherwise the keyboard will not pop up again. - void SetForceDisableVirtualKeyboard(bool disable); - - // Return true if keyboard has been blocked from showing up. - static bool GetForceDisableVirtualKeyboard(); - - private: - const bool force_disable_keyboard_state_; - - DISALLOW_COPY_AND_ASSIGN(ScopedKeyboardDisabler); -}; - -} // namespace keyboard - -#endif // UI_KEYBOARD_SCOPED_KEYBOARD_DISABLER_H_
diff --git a/ui/latency/ipc/latency_info_param_traits.cc b/ui/latency/ipc/latency_info_param_traits.cc index 89dd8b3..87b9a89 100644 --- a/ui/latency/ipc/latency_info_param_traits.cc +++ b/ui/latency/ipc/latency_info_param_traits.cc
@@ -46,6 +46,7 @@ GetParamSize(s, p.began_); GetParamSize(s, p.terminated_); GetParamSize(s, p.source_event_type_); + GetParamSize(s, p.expected_queueing_time_on_dispatch_); } void ParamTraits<ui::LatencyInfo>::Write(base::Pickle* m, const param_type& p) { @@ -55,6 +56,7 @@ WriteParam(m, p.began_); WriteParam(m, p.terminated_); WriteParam(m, p.source_event_type_); + WriteParam(m, p.expected_queueing_time_on_dispatch_); } bool ParamTraits<ui::LatencyInfo>::Read(const base::Pickle* m, @@ -73,6 +75,8 @@ return false; if (!ReadParam(m, iter, &p->source_event_type_)) return false; + if (!ReadParam(m, iter, &p->expected_queueing_time_on_dispatch_)) + return false; return true; } @@ -89,6 +93,8 @@ LogParam(p.terminated_, l); l->append(" "); LogParam(p.source_event_type_, l); + l->append(" "); + LogParam(p.expected_queueing_time_on_dispatch_, l); } } // namespace IPC
diff --git a/ui/latency/latency_info.cc b/ui/latency/latency_info.cc index 68523af..ff1fffe 100644 --- a/ui/latency/latency_info.cc +++ b/ui/latency/latency_info.cc
@@ -173,6 +173,10 @@ lc.second.event_count); } } + + expected_queueing_time_on_dispatch_ = + other.expected_queueing_time_on_dispatch_; + trace_id_ = other.trace_id(); coalesced_ = other.coalesced(); // TODO(tdresser): Ideally we'd copy |began_| here as well, but |began_| isn't @@ -191,6 +195,10 @@ lc.second.event_count); } } + + expected_queueing_time_on_dispatch_ = + other.expected_queueing_time_on_dispatch_; + trace_id_ = other.trace_id(); coalesced_ = other.coalesced(); // TODO(tdresser): Ideally we'd copy |began_| here as well, but |began_| isn't
diff --git a/ui/latency/latency_info.h b/ui/latency/latency_info.h index 2dcf550..218dce9 100644 --- a/ui/latency/latency_info.h +++ b/ui/latency/latency_info.h
@@ -208,6 +208,15 @@ source_event_type_ = type; } + void set_expected_queueing_time_on_dispatch( + base::TimeDelta expected_queueing_time) { + expected_queueing_time_on_dispatch_ = expected_queueing_time; + } + + base::TimeDelta expected_queueing_time_on_dispatch() const { + return expected_queueing_time_on_dispatch_; + } + bool began() const { return began_; } bool terminated() const { return terminated_; } void set_coalesced() { coalesced_ = true; } @@ -243,6 +252,9 @@ bool terminated_; // Stores the type of the first source event. SourceEventType source_event_type_; + // The expected queueing time on the main thread when this event was + // dispatched. + base::TimeDelta expected_queueing_time_on_dispatch_; #if !defined(OS_IOS) friend struct IPC::ParamTraits<ui::LatencyInfo>;
diff --git a/ui/latency/mojo/DEPS b/ui/latency/mojo/DEPS index 77a2762..248dbde 100644 --- a/ui/latency/mojo/DEPS +++ b/ui/latency/mojo/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+mojo/common", "+mojo/public", "+ui/gfx/geometry/mojo", "+ui/latency",
diff --git a/ui/latency/mojo/latency_info.mojom b/ui/latency/mojo/latency_info.mojom index bc56a99..03c41d1 100644 --- a/ui/latency/mojo/latency_info.mojom +++ b/ui/latency/mojo/latency_info.mojom
@@ -118,4 +118,5 @@ bool began; bool terminated; SourceEventType source_event_type; + mojo.common.mojom.TimeDelta expected_queueing_time_on_dispatch; };
diff --git a/ui/latency/mojo/latency_info_struct_traits.cc b/ui/latency/mojo/latency_info_struct_traits.cc index 8e27b54..955de5fd 100644 --- a/ui/latency/mojo/latency_info_struct_traits.cc +++ b/ui/latency/mojo/latency_info_struct_traits.cc
@@ -310,6 +310,12 @@ } // static +base::TimeDelta StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>:: + expected_queueing_time_on_dispatch(const ui::LatencyInfo& info) { + return info.expected_queueing_time_on_dispatch(); +} + +// static bool StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::Read( ui::mojom::LatencyInfoDataView data, ui::LatencyInfo* out) { @@ -334,7 +340,9 @@ out->began_ = data.began(); out->terminated_ = data.terminated(); out->source_event_type_ = MojoSourceEventTypeToUI(data.source_event_type()); - return true; + + return data.ReadExpectedQueueingTimeOnDispatch( + &out->expected_queueing_time_on_dispatch_); } } // namespace mojo
diff --git a/ui/latency/mojo/latency_info_struct_traits.h b/ui/latency/mojo/latency_info_struct_traits.h index 0084adc..b6b5edc 100644 --- a/ui/latency/mojo/latency_info_struct_traits.h +++ b/ui/latency/mojo/latency_info_struct_traits.h
@@ -5,6 +5,7 @@ #ifndef UI_LATENCY_MOJO_LATENCY_INFO_STRUCT_TRAITS_H_ #define UI_LATENCY_MOJO_LATENCY_INFO_STRUCT_TRAITS_H_ +#include "mojo/common/common_custom_types_struct_traits.h" #include "ui/gfx/geometry/mojo/geometry_struct_traits.h" #include "ui/latency/latency_info.h" #include "ui/latency/mojo/latency_info.mojom-shared.h" @@ -100,6 +101,8 @@ static bool terminated(const ui::LatencyInfo& info); static ui::mojom::SourceEventType source_event_type( const ui::LatencyInfo& info); + static base::TimeDelta expected_queueing_time_on_dispatch( + const ui::LatencyInfo& info); static bool Read(ui::mojom::LatencyInfoDataView data, ui::LatencyInfo* out); };
diff --git a/ui/login/account_picker/md_screen_account_picker.js b/ui/login/account_picker/md_screen_account_picker.js index 32ea93ca8..c0516a3 100644 --- a/ui/login/account_picker/md_screen_account_picker.js +++ b/ui/login/account_picker/md_screen_account_picker.js
@@ -496,6 +496,11 @@ this.lockScreenAppsState_ = state; $('login-header-bar').lockScreenAppsState = state; + + // Reset the focused pod if app window is being shown on top of the user + // pods. Main goal is to clear any credentials the user might have input. + if (state === LOCK_SCREEN_APPS_STATE.FOREGROUND) + $('pod-row').clearFocusedPod(); }, /**
diff --git a/ui/login/account_picker/md_user_pod_row.css b/ui/login/account_picker/md_user_pod_row.css index 85bb691..44a37fc 100644 --- a/ui/login/account_picker/md_user_pod_row.css +++ b/ui/login/account_picker/md_user_pod_row.css
@@ -718,8 +718,7 @@ .pod.legacy-supervised .action-box-remove-non-owner-user-warning-text, .pod:not(.legacy-supervised) .action-box-remove-legacy-supervised-user-warning-text, -.pod.synced .non-sync, -.pod.has-no-stats .has-stats { +.pod.synced .non-sync { display: none; }
diff --git a/ui/login/account_picker/md_user_pod_row.js b/ui/login/account_picker/md_user_pod_row.js index 5173f7a..c3931221 100644 --- a/ui/login/account_picker/md_user_pod_row.js +++ b/ui/login/account_picker/md_user_pod_row.js
@@ -831,8 +831,6 @@ this.handlePasswordKeyPress_.bind(this)); this.passwordElement.addEventListener('input', this.handleInputChanged_.bind(this)); - this.passwordElement.addEventListener('mouseup', - this.handleInputMouseUp_.bind(this)); if (this.submitButton) { this.submitButton.addEventListener('click', @@ -1346,8 +1344,6 @@ // Adjust the vertical position based on the pin keyboard visibility. var podHeight = visible ? CROS_POD_HEIGHT_WITH_PIN : CROS_POD_HEIGHT; this.top = ($('pod-row').screenSize.height - podHeight) / 2; - - chrome.send('setForceDisableVirtualKeyboard', [visible]); }, isPinShown: function() { @@ -1840,15 +1836,10 @@ } } - // this.classList is used for selecting the appropriate dialog. - if (total_count) - this.classList.remove('has-no-stats'); - var is_synced_user = this.user.emailAddress !== ""; // Write total number if all statistics are loaded. if (num_stats_loaded === Object.keys(stats_elements).length) { if (!total_count) { - this.classList.add('has-no-stats'); var message = loadTimeData.getString( is_synced_user ? 'removeUserWarningTextSyncNoStats' : 'removeUserWarningTextNonSyncNoStats'); @@ -2108,19 +2099,6 @@ }, /** - * Handles mouse up event on the password element. - * @param {Event} e Mouse up event. - */ - handleInputMouseUp_: function(e) { - // If the PIN keyboard is shown and the user clicks on the password - // element, the virtual keyboard should pop up if it is enabled, so we - // must disable the virtual keyboard override. - if (this.isPinShown()) { - chrome.send('setForceDisableVirtualKeyboard', [false]); - } - }, - - /** * Handles click event on a user pod. * @param {Event} e Click event. */ @@ -2629,8 +2607,6 @@ this.classList.toggle('legacy-supervised', isLegacySupervisedUser); this.classList.toggle('child', isChildUser); this.classList.toggle('synced', isSyncedUser); - this.classList.toggle('has-no-stats', - !isProfileLoaded && !this.user.statistics.length); if (this.isAuthTypeUserClick) this.passwordLabelElement.textContent = this.authValue; @@ -3575,7 +3551,7 @@ } else { // When the user count exceeds the limit (currently set to 2), only the // main pod still has pow row as parent, all other pods should be - // appended to the container with scroll bar. + // appended to the container with scroll bar. for (var pod of pods) { if (pod == this.mainPod_) this.appendChild(pod); @@ -3673,7 +3649,7 @@ var MIDDLE_PADDING = this.isPortraitMode_() ? 84 : 220; var contentsWidth = LEFT_PADDING + CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH; - var blankWidth = this.screenSize.width - contentsWidth; + var blankWidth = this.screenSize.width - contentsWidth; var actualLeftPadding = LEFT_PADDING; actualLeftPadding += this.isPortraitMode_() ? blankWidth * 2 / 3 : blankWidth / 2; @@ -3705,10 +3681,10 @@ return; } } - + // Start positioning of the main pod and the smallPodsContainer. this.mainPod_.left = actualLeftPadding; - this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; + this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; this.smallPodsContainer.style.left = cr.ui.toCssPx(actualLeftPadding + CROS_POD_WIDTH + MIDDLE_PADDING); this.smallPodsContainer.style.top = cr.ui.toCssPx(0); @@ -3781,7 +3757,7 @@ SCROLL_RIGHT_PADDING); // SCROLL_TOP_PADDING denotes the smallest top padding we can tolerate - // before allowing the container to overflow and show the scroll bar. + // before allowing the container to overflow and show the scroll bar. var actualTopPadding = SCROLL_TOP_PADDING; if ((this.screenSize.height - scrollHeight) / 2 > actualTopPadding) { // Edge case: the total height of the scrollable container does not @@ -3795,10 +3771,10 @@ // The scroll bar will definitely be shown if we reach here. A gradient // mask is applied to avoid blocking the header bar if the virtual // keyboard is not shown. When the keyboard is shown, there's no need - // to add the mask and the original top padding value should be kept. + // to add the mask and the original top padding value should be kept. actualTopPadding = SCROLL_MASK_HEIGHT; this.showScrollMask_(); - } + } // Start positioning of the small pods inside the smallPodsContainer. var topPadding = actualTopPadding; @@ -4107,7 +4083,7 @@ var top = pod.top; // Edge case: paddingBottom should be switched too because there's a // chance that the small pod was at the end of the scrollable container - // and had a non-zero paddingBottom. + // and had a non-zero paddingBottom. var paddingBottom = pod.style.paddingBottom; var parent = pod.parentNode; parent.removeChild(pod);
diff --git a/ui/login/account_picker/screen_account_picker.js b/ui/login/account_picker/screen_account_picker.js index 2dd65c2..9af9bf0 100644 --- a/ui/login/account_picker/screen_account_picker.js +++ b/ui/login/account_picker/screen_account_picker.js
@@ -498,6 +498,10 @@ // noticeable that the app widow in background is not actionable. $('background').classList.toggle( 'dimmed-background', state == LOCK_SCREEN_APPS_STATE.BACKGROUND); + + if (state === LOCK_SCREEN_APPS_STATE.FOREGROUND) + $('pod-row').clearFocusedPod(); + }, /**
diff --git a/ui/login/account_picker/user_pod_row.css b/ui/login/account_picker/user_pod_row.css index 0f43faf..553b4cc 100644 --- a/ui/login/account_picker/user_pod_row.css +++ b/ui/login/account_picker/user_pod_row.css
@@ -695,8 +695,7 @@ .pod.legacy-supervised .action-box-remove-non-owner-user-warning-text, .pod:not(.legacy-supervised) .action-box-remove-legacy-supervised-user-warning-text, -.pod.synced .non-sync, -.pod.has-no-stats .has-stats { +.pod.synced .non-sync { display: none; }
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js index 65d49d3..9ef5e41 100644 --- a/ui/login/account_picker/user_pod_row.js +++ b/ui/login/account_picker/user_pod_row.js
@@ -821,8 +821,6 @@ this.handlePasswordKeyPress_.bind(this)); this.passwordElement.addEventListener('input', this.handleInputChanged_.bind(this)); - this.passwordElement.addEventListener('mouseup', - this.handleInputMouseUp_.bind(this)); if (this.submitButton) { this.submitButton.addEventListener('click', @@ -1270,8 +1268,6 @@ // Change the password placeholder based on pin keyboard visibility. this.passwordElement.placeholder = loadTimeData.getString(visible ? 'pinKeyboardPlaceholderPinPassword' : 'passwordHint'); - - chrome.send('setForceDisableVirtualKeyboard', [visible]); }, isPinShown: function() { @@ -1775,15 +1771,10 @@ } } - // this.classList is used for selecting the appropriate dialog. - if (total_count) - this.classList.remove('has-no-stats'); - var is_synced_user = this.user.emailAddress !== ""; // Write total number if all statistics are loaded. if (num_stats_loaded === Object.keys(stats_elements).length) { if (!total_count) { - this.classList.add('has-no-stats'); var message = loadTimeData.getString( is_synced_user ? 'removeUserWarningTextSyncNoStats' : 'removeUserWarningTextNonSyncNoStats'); @@ -2039,19 +2030,6 @@ }, /** - * Handles mouse up event on the password element. - * @param {Event} e Mouse up event. - */ - handleInputMouseUp_: function(e) { - // If the PIN keyboard is shown and the user clicks on the password - // element, the virtual keyboard should pop up if it is enabled, so we - // must disable the virtual keyboard override. - if (this.isPinShown()) { - chrome.send('setForceDisableVirtualKeyboard', [false]); - } - }, - - /** * Handles click event on a user pod. * @param {Event} e Click event. */ @@ -2553,8 +2531,6 @@ this.classList.toggle('legacy-supervised', isLegacySupervisedUser); this.classList.toggle('child', isChildUser); this.classList.toggle('synced', isSyncedUser); - this.classList.toggle('has-no-stats', - !isProfileLoaded && !this.user.statistics.length); if (this.isAuthTypeUserClick) this.passwordLabelElement.textContent = this.authValue;
diff --git a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc index e78a216..525ba66 100644 --- a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc +++ b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -85,10 +85,6 @@ GLImageTest, GLImageScanoutType); -INSTANTIATE_TYPED_TEST_CASE_P(GLImageNativePixmapScanout, - GLImageFlushTest, - GLImageScanoutType); - using GLImageReadWriteType = testing::Types< GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::BufferFormat::R_8>>;
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc index d93439c..ed3ee76 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -17,18 +17,6 @@ namespace { -const size_t kMaxCacheSize = 200; - -bool NeedsAlphaComposition(uint32_t format) { - switch (format) { - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_UYVY: - return false; - default: - return true; - } -} - scoped_refptr<ScanoutBuffer> GetBufferForPageFlipTest( const scoped_refptr<DrmDevice>& drm_device, const gfx::Size& size, @@ -51,56 +39,12 @@ return scanout_buffer; } -gfx::Size GetScaledSize(const gfx::Size original_size, - const gfx::Rect display_rect, - const gfx::RectF crop_rect) { - if (!crop_rect.IsEmpty()) { - return gfx::ToCeiledSize( - gfx::SizeF(display_rect.width() / crop_rect.width(), - display_rect.height() / crop_rect.height())); - } - - return original_size; -} - -uint32_t FindOptimalBufferFormat(uint32_t original_format, - uint32_t plane_z_order, - const gfx::Rect& plane_bounds, - const gfx::Rect& window_bounds, - HardwareDisplayController* controller) { - uint32_t z_order = plane_z_order; - // If Overlay completely covers primary and isn't transparent, try to find - // optimal format w.r.t primary plane. This guarantees that optimal format - // would not fail page flip when plane manager/CC collapses planes. - if (plane_bounds == window_bounds && - !NeedsAlphaComposition(original_format)) { - z_order = 0; - } - - // YUV is preferable format if supported. - if (controller->IsFormatSupported(DRM_FORMAT_UYVY, z_order)) { - return DRM_FORMAT_UYVY; - } else if (controller->IsFormatSupported(DRM_FORMAT_XRGB8888, z_order)) { - return DRM_FORMAT_XRGB8888; - } - - return original_format; -} - } // namespace -DrmOverlayValidator::OverlayHints::OverlayHints(uint32_t format, - bool scale_buffer) - : optimal_format(format), handle_scaling(scale_buffer) {} - -DrmOverlayValidator::OverlayHints::~OverlayHints() {} - DrmOverlayValidator::DrmOverlayValidator( DrmWindow* window, ScanoutBufferGenerator* buffer_generator) - : window_(window), - buffer_generator_(buffer_generator), - overlay_hints_cache_(kMaxCacheSize) {} + : window_(window), buffer_generator_(buffer_generator) {} DrmOverlayValidator::~DrmOverlayValidator() {} @@ -130,13 +74,16 @@ continue; } - gfx::Size scaled_buffer_size = GetScaledSize( - params[i].buffer_size, params[i].display_rect, params[i].crop_rect); - uint32_t original_format = params[i].plane_z_order ? GetFourCCFormatFromBufferFormat(params[i].format) : GetFourCCFormatForOpaqueFramebuffer(params[i].format); + if (!controller->IsFormatSupported(original_format, + params[i].plane_z_order)) { + returns[i].status = OverlayCheckReturn_Params::Status::NOT; + continue; + } + scoped_refptr<ScanoutBuffer> buffer = GetBufferForPageFlipTest(drm, params[i].buffer_size, original_format, buffer_generator_, &reusable_buffers); @@ -147,38 +94,6 @@ if (buffer && controller->TestPageFlip(test_list)) { returns[i].status = OverlayCheckReturn_Params::Status::ABLE; - - // If size scaling is needed, find an optimal format. - if (params[i].plane_z_order && - scaled_buffer_size != params[i].buffer_size) { - uint32_t optimal_format = FindOptimalBufferFormat( - original_format, params[i].plane_z_order, params[i].display_rect, - window_->bounds(), controller); - - if (original_format != optimal_format) { - OverlayPlane original_plain = test_list.back(); - test_list.pop_back(); - scoped_refptr<ScanoutBuffer> optimal_buffer = - GetBufferForPageFlipTest(drm, scaled_buffer_size, optimal_format, - buffer_generator_, &reusable_buffers); - DCHECK(optimal_buffer); - - OverlayPlane optimal_plane( - optimal_buffer, params[i].plane_z_order, params[i].transform, - params[i].display_rect, params[i].crop_rect); - test_list.push_back(optimal_plane); - - // If test failed here, it means even though optimal_format is - // supported, platform cannot support it with current combination of - // layers. This is usually the case when optimal_format needs certain - // capabilites (i.e. conversion, scaling etc) and needed hardware - // resources might be already in use. Fall back to original format. - if (!controller->TestPageFlip(test_list)) { - test_list.pop_back(); - test_list.push_back(original_plain); - } - } - } } else { // If test failed here, platform cannot support this configuration // with current combination of layers. This is usually the case when this @@ -191,86 +106,7 @@ } } - UpdateOverlayHintsCache(test_list); - return returns; } -OverlayPlaneList DrmOverlayValidator::PrepareBuffersForPageFlip( - const OverlayPlaneList& planes) { - if (planes.size() <= 1) - return planes; - - HardwareDisplayController* controller = window_->GetController(); - if (!controller) - return planes; - - OverlayPlaneList pending_planes = planes; - const auto& overlay_hints = overlay_hints_cache_.Get(planes); - - size_t size = planes.size(); - bool use_hints = overlay_hints != overlay_hints_cache_.end(); - - for (size_t i = 0; i < size; i++) { - auto& plane = pending_planes.at(i); - if (plane.processing_callback.is_null()) - continue; - - uint32_t original_format = plane.buffer->GetFramebufferPixelFormat(); - uint32_t target_format = original_format; - - const gfx::Size& original_size = plane.buffer->GetSize(); - gfx::Size target_size = - GetScaledSize(original_size, plane.display_bounds, plane.crop_rect); - - if (use_hints) { - DCHECK(size == overlay_hints->second.size()); - const OverlayHints& hints = overlay_hints->second.at(i); - target_format = hints.optimal_format; - - // We can handle plane scaling, avoid scaling buffer here. - if (!hints.handle_scaling) - target_size = original_size; - } - - // The size scaling piggybacks the format conversion. - if (original_size != target_size) { - scoped_refptr<ScanoutBuffer> processed_buffer = - plane.processing_callback.Run(target_size, target_format); - - if (processed_buffer) - plane.buffer = processed_buffer; - } - } - - return pending_planes; -} - -void DrmOverlayValidator::ClearCache() { - overlay_hints_cache_.Clear(); -} - -void DrmOverlayValidator::UpdateOverlayHintsCache( - const OverlayPlaneList& plane_list) { - const auto& iter = overlay_hints_cache_.Get(plane_list); - if (iter != overlay_hints_cache_.end()) - return; - - OverlayPlaneList hints_plane_list = plane_list; - OverlayHintsList overlay_hints; - for (auto& plane : hints_plane_list) { - uint32_t format = plane.buffer->GetFramebufferPixelFormat(); - // TODO(kalyank): We always request scaling to be done by 3D engine, VPP - // etc. We should use them only if downscaling is needed and let display - // controller handle up-scaling on platforms which support it. - overlay_hints.push_back(OverlayHints(format, true /* scaling */)); - - // Make sure we dont hold reference to buffer when caching this plane list. - plane.buffer = nullptr; - } - - DCHECK(hints_plane_list.size() == overlay_hints.size()); - overlay_hints_cache_.Put(hints_plane_list, overlay_hints); -} - } // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.h b/ui/ozone/platform/drm/gpu/drm_overlay_validator.h index aba3185..64dc7b9 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.h +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.h
@@ -28,45 +28,10 @@ const std::vector<OverlayCheck_Params>& params, const OverlayPlaneList& last_used_planes); - // Checks if buffers bound to planes can be optimized (i.e. format, scaling)to - // reduce Display Read bandwidth. This should be called before an actual page - // flip. Expects |planes| to be sorted by Z order. - OverlayPlaneList PrepareBuffersForPageFlip(const OverlayPlaneList& planes); - - // Clears internal cache of validated overlay configurations. This should be - // usually called when |window_| size has changed or moved controller. - void ClearCache(); - private: - // Contains hints which can be used to reduce display read memory bandwidth, - // for a given OverlayPlane. These are useful in case of video to determine - // if converting the buffer storage format before composition could lead to - // any potential bandwidth savings. Other useful hint is to determine if - // scaling needs to be done before page flip or can be handled by plane. - struct OverlayHints { - OverlayHints(uint32_t optimal_format, bool handle_scaling); - ~OverlayHints(); - // Optimal buffer storage format supported by hardware for a given - // OverlayPlane. This hint can be ignored and still compositing an - // OverlayPlane should not fail page flip or cause any visual artifacts. - uint32_t optimal_format; - // Hints if buffer scaling needs to be done before page flip as plane cannot - // support it. Ignoring this hint may result in displaying buffer with wrong - // resolution. - bool handle_scaling; - }; - - using OverlayHintsList = std::vector<OverlayHints>; - - // Update hints cache. - void UpdateOverlayHintsCache(const OverlayPlaneList& plane_list); - DrmWindow* window_; // Not owned. ScanoutBufferGenerator* buffer_generator_; // Not owned. - // List of all configurations which have been validated. - base::MRUCache<OverlayPlaneList, OverlayHintsList> overlay_hints_cache_; - DISALLOW_COPY_AND_ASSIGN(DrmOverlayValidator); };
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc index 3bb43de..60993857 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
@@ -52,16 +52,13 @@ last_swap_buffers_result_ = result; } - scoped_refptr<ui::ScanoutBuffer> ProcessBuffer(const gfx::Size& size, - uint32_t format) { - return buffer_generator_->Create(drm_, format, size); - } - scoped_refptr<ui::ScanoutBuffer> ReturnNullBuffer(const gfx::Size& size, uint32_t format) { return nullptr; } + void AddPlane(const ui::OverlayCheck_Params& params); + protected: std::unique_ptr<base::MessageLoop> message_loop_; scoped_refptr<ui::MockDrmDevice> drm_; @@ -73,7 +70,6 @@ std::unique_ptr<ui::DrmOverlayValidator> overlay_validator_; std::vector<ui::OverlayCheck_Params> overlay_params_; ui::OverlayPlaneList plane_list_; - ui::OverlayPlane::ProcessBufferCallback process_buffer_handler_; int on_swap_buffers_count_; gfx::SwapResult last_swap_buffers_result_; @@ -87,8 +83,6 @@ void DrmOverlayValidatorTest::SetUp() { on_swap_buffers_count_ = 0; last_swap_buffers_result_ = gfx::SwapResult::SWAP_FAILED; - process_buffer_handler_ = base::Bind(&DrmOverlayValidatorTest::ProcessBuffer, - base::Unretained(this)); message_loop_.reset(new base::MessageLoopForUI); std::vector<uint32_t> crtcs; @@ -124,6 +118,7 @@ primary_candidate.display_rect = primary_rect_; primary_candidate.format = gfx::BufferFormat::BGRX_8888; overlay_params_.push_back(primary_candidate); + AddPlane(primary_candidate); ui::OverlayCheck_Params overlay_candidate; overlay_candidate.buffer_size = overlay_rect_.size(); @@ -131,18 +126,20 @@ overlay_candidate.plane_z_order = 1; overlay_candidate.format = gfx::BufferFormat::BGRX_8888; overlay_params_.push_back(overlay_candidate); + AddPlane(overlay_candidate); +} +void DrmOverlayValidatorTest::AddPlane(const ui::OverlayCheck_Params& params) { scoped_refptr<ui::DrmDevice> drm = window_->GetController()->GetAllocationDrmDevice(); - for (const auto& param : overlay_params_) { - scoped_refptr<ui::ScanoutBuffer> scanout_buffer = buffer_generator_->Create( - drm, ui::GetFourCCFormatFromBufferFormat(param.format), - param.buffer_size); - ui::OverlayPlane plane(std::move(scanout_buffer), param.plane_z_order, - param.transform, param.display_rect, param.crop_rect, - process_buffer_handler_); - plane_list_.push_back(plane); - } + scoped_refptr<ui::ScanoutBuffer> scanout_buffer = buffer_generator_->Create( + drm, ui::GetFourCCFormatFromBufferFormat(params.format), + params.buffer_size); + ui::OverlayPlane plane(std::move(scanout_buffer), params.plane_z_order, + params.transform, params.display_rect, + params.crop_rect, + ui::OverlayPlane::ProcessBufferCallback()); + plane_list_.push_back(plane); } void DrmOverlayValidatorTest::TearDown() { @@ -187,185 +184,7 @@ EXPECT_EQ(returns.back().status, ui::OverlayCheckReturn_Params::Status::NOT); } -TEST_F(DrmOverlayValidatorTest, ClearCacheOnReset) { - // This test checks if we invalidate cache when Reset is called. - overlay_params_.back().buffer_size = overlay_rect_.size(); - overlay_params_.back().display_rect = overlay_rect_; - plane_list_.back().display_bounds = overlay_rect_; - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); - std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; - plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); - - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); - // Check if ClearCache actually clears the cache. - overlay_validator_->ClearCache(); - plane_list = overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - // There should be no entry in cache for this configuration and should return - // default value of DRM_FORMAT_XRGB8888. - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); -} - -TEST_F(DrmOverlayValidatorTest, ClearCacheOnResetWithScaling) { - // This test checks if we invalidate cache when Reset is called. - gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5); - overlay_params_.back().buffer_size = overlay_rect_.size(); - overlay_params_.back().display_rect = overlay_rect_; - overlay_params_.back().crop_rect = crop_rect; - plane_list_.back().display_bounds = overlay_rect_; - plane_list_.back().crop_rect = crop_rect; - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); - std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; - plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); - - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - // Scaling allows format conversion. - EXPECT_EQ(DRM_FORMAT_UYVY, - plane_list.back().buffer->GetFramebufferPixelFormat()); - // Check if ClearCache actually clears the cache. - overlay_validator_->ClearCache(); - plane_list = overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - // There should be no entry in cache for this configuration and should return - // default value of DRM_FORMAT_XRGB8888. - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); -} - -TEST_F(DrmOverlayValidatorTest, OptimalFormatForOverlayInFullScreen_XRGB) { - // Optimal format for Overlay configuration should be XRGB, when primary plane - // supports only XRGB and overlay obscures primary. - overlay_params_.back().buffer_size = primary_rect_.size(); - overlay_params_.back().display_rect = primary_rect_; - plane_list_.back().display_bounds = primary_rect_; - - // Check optimal format for Overlay. - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - ui::FakePlaneInfo plane_info(101, 1 << 0, xrgb_yuv_packed_formats); - - std::vector<ui::FakePlaneInfo> planes{primary_plane_info, plane_info}; - plane_manager_->SetPlaneProperties(planes); - overlay_validator_->ClearCache(); - - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); -} - -TEST_F(DrmOverlayValidatorTest, OptimalFormatForOverlayInFullScreen_YUV) { - overlay_params_.back().buffer_size = primary_rect_.size(); - overlay_params_.back().display_rect = primary_rect_; - plane_list_.back().display_bounds = primary_rect_; - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - - // We should prefer YUV when primary can support it. - ui::FakePlaneInfo primary_plane_info(100, 1 << 0, xrgb_yuv_packed_formats); - ui::FakePlaneInfo plane_info(101, 1 << 0, xrgb_yuv_packed_formats); - - std::vector<ui::FakePlaneInfo> planes{primary_plane_info, plane_info}; - plane_manager_->SetPlaneProperties(planes); - overlay_validator_->ClearCache(); - - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - // TODO(dcastagna): If Atomic support is enabled, a packed format (UYVY) might - // be the optimal one and should be preferred. - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); -} - -TEST_F(DrmOverlayValidatorTest, OverlayPreferredFormat) { - plane_manager_->ResetPlaneCount(); - // This test checks for optimal format in case of non full screen video case. - overlay_params_.back().buffer_size = overlay_rect_.size(); - overlay_params_.back().display_rect = overlay_rect_; - plane_list_.back().display_bounds = overlay_rect_; - - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); - std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; - plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); - - std::vector<ui::OverlayCheckReturn_Params> returns = - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - - for (const auto& param : returns) - EXPECT_EQ(param.status, ui::OverlayCheckReturn_Params::Status::ABLE); - - EXPECT_EQ(3, plane_manager_->plane_count()); - - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); -} - -TEST_F(DrmOverlayValidatorTest, OverlayPreferredFormat_YUV) { - plane_manager_->ResetPlaneCount(); - // This test checks for optimal format in case of non full screen video case. - // Prefer YUV as optimal format when Overlay supports it and scaling is - // needed. - gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5); - overlay_params_.back().buffer_size = overlay_rect_.size(); - overlay_params_.back().display_rect = overlay_rect_; - overlay_params_.back().crop_rect = crop_rect; - plane_list_.back().display_bounds = overlay_rect_; - plane_list_.back().crop_rect = crop_rect; - - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); - std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; - plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); - - std::vector<ui::OverlayCheckReturn_Params> returns = - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - - for (const auto& param : returns) - EXPECT_EQ(param.status, ui::OverlayCheckReturn_Params::Status::ABLE); - - EXPECT_EQ(5, plane_manager_->plane_count()); - - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_UYVY, - plane_list.back().buffer->GetFramebufferPixelFormat()); -} - -TEST_F(DrmOverlayValidatorTest, OverlayPreferredFormat_XRGB) { +TEST_F(DrmOverlayValidatorTest, OverlayFormat_XRGB) { plane_manager_->ResetPlaneCount(); // This test checks for optimal format in case of non full screen video case. // This should be XRGB when overlay doesn't support YUV. @@ -380,17 +199,44 @@ std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); std::vector<ui::OverlayCheckReturn_Params> returns = overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); EXPECT_EQ(3, plane_manager_->plane_count()); for (const auto& param : returns) EXPECT_EQ(param.status, ui::OverlayCheckReturn_Params::Status::ABLE); + + EXPECT_EQ(3, plane_manager_->plane_count()); +} + +TEST_F(DrmOverlayValidatorTest, OverlayFormat_YUV) { + plane_manager_->ResetPlaneCount(); + // This test checks for optimal format in case of non full screen video case. + // Prefer YUV as optimal format when Overlay supports it and scaling is + // needed. + gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5); + overlay_params_.back().buffer_size = overlay_rect_.size(); + overlay_params_.back().display_rect = overlay_rect_; + overlay_params_.back().crop_rect = crop_rect; + overlay_params_.back().format = gfx::BufferFormat::UYVY_422; + plane_list_.pop_back(); + AddPlane(overlay_params_.back()); + + std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, + DRM_FORMAT_UYVY}; + ui::FakePlaneInfo primary_plane_info( + 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); + ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); + std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; + plane_manager_->SetPlaneProperties(planes_info); + + std::vector<ui::OverlayCheckReturn_Params> returns = + overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); + + for (const auto& param : returns) + EXPECT_EQ(param.status, ui::OverlayCheckReturn_Params::Status::ABLE); + + EXPECT_EQ(3, plane_manager_->plane_count()); } TEST_F(DrmOverlayValidatorTest, RejectYUVBuffersIfNotSupported) { @@ -399,19 +245,18 @@ // support it. overlay_params_.back().buffer_size = overlay_rect_.size(); overlay_params_.back().display_rect = overlay_rect_; - plane_list_.back().display_bounds = overlay_rect_; + overlay_params_.back().format = gfx::BufferFormat::UYVY_422; + plane_list_.pop_back(); + AddPlane(overlay_params_.back()); - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - ui::FakePlaneInfo primary_plane_info(100, 1 << 0, xrgb_yuv_packed_formats); + ui::FakePlaneInfo primary_plane_info( + 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); ui::FakePlaneInfo overlay_info(101, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); std::vector<ui::OverlayCheck_Params> validated_params = overlay_params_; - validated_params.back().format = gfx::BufferFormat::UYVY_422; plane_manager_->ResetPlaneCount(); std::vector<ui::OverlayCheckReturn_Params> returns = overlay_validator_->TestPageFlip(validated_params, @@ -452,7 +297,6 @@ primary_crtc_primary_plane, primary_crtc_overlay, secondary_crtc_primary_plane, secondary_crtc_overlay}; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); std::vector<ui::OverlayCheck_Params> validated_params = overlay_params_; validated_params.back().format = gfx::BufferFormat::UYVY_422; @@ -463,20 +307,12 @@ EXPECT_EQ(returns.back().status, ui::OverlayCheckReturn_Params::Status::ABLE); - // Both controllers have Overlay which support DRM_FORMAT_UYVY, and scaling is - // needed, hence this should be picked as the optimal format. - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_UYVY, - plane_list.back().buffer->GetFramebufferPixelFormat()); - // This configuration should not be promoted to Overlay when either of the // controllers dont support UYVY format. // Check case where we dont have support for packed formats in Mirrored CRTC. planes_info.back().allowed_formats = only_rgb_format; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); returns = overlay_validator_->TestPageFlip(validated_params, ui::OverlayPlaneList()); @@ -487,7 +323,6 @@ planes_info.back().allowed_formats = xrgb_yuv_packed_formats; planes_info[1].allowed_formats = only_rgb_format; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); returns = overlay_validator_->TestPageFlip(validated_params, ui::OverlayPlaneList()); @@ -498,7 +333,6 @@ TEST_F(DrmOverlayValidatorTest, OptimalFormatYUV_MirroredControllers) { std::vector<uint32_t> crtcs{kDefaultCrtc, kSecondaryCrtc}; plane_manager_->SetCrtcInfo(crtcs); - overlay_validator_->ClearCache(); ui::HardwareDisplayController* controller = window_->GetController(); controller->AddCrtc(std::unique_ptr<ui::CrtcController>( @@ -524,117 +358,34 @@ primary_crtc_primary_plane, primary_crtc_overlay, secondary_crtc_primary_plane, secondary_crtc_overlay}; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); plane_manager_->ResetPlaneCount(); std::vector<ui::OverlayCheckReturn_Params> returns = overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); EXPECT_EQ(returns.back().status, ui::OverlayCheckReturn_Params::Status::ABLE); - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); // Check case where we dont have support for packed formats in Mirrored CRTC. planes_info.back().allowed_formats = only_rgb_format; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); returns = overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); EXPECT_EQ(returns.back().status, ui::OverlayCheckReturn_Params::Status::ABLE); - plane_list = overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); - // Check case where we dont have support for packed formats in primary // display. planes_info.back().allowed_formats = xrgb_yuv_packed_formats; planes_info[1].allowed_formats = only_rgb_format; plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); returns = overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); EXPECT_EQ(returns.back().status, ui::OverlayCheckReturn_Params::Status::ABLE); - plane_list = overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(DRM_FORMAT_XRGB8888, - plane_list.back().buffer->GetFramebufferPixelFormat()); controller->RemoveCrtc(drm_, kSecondaryCrtc); } -TEST_F(DrmOverlayValidatorTest, OptimizeOnlyIfProcessingCallbackPresent) { - // This test checks that we dont manipulate overlay buffers in case Processing - // callback is not present. - gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5); - overlay_params_.back().buffer_size = overlay_rect_.size(); - overlay_params_.back().display_rect = overlay_rect_; - overlay_params_.back().crop_rect = crop_rect; - plane_list_.back().display_bounds = overlay_rect_; - plane_list_.back().crop_rect = crop_rect; - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); - std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; - plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); - - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - // Scaling allows format conversion. - EXPECT_EQ(DRM_FORMAT_UYVY, - plane_list.back().buffer->GetFramebufferPixelFormat()); - plane_list_.back().processing_callback.Reset(); - plane_list = overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(plane_list_.back().buffer->GetFramebufferPixelFormat(), - plane_list.back().buffer->GetFramebufferPixelFormat()); - plane_list_.back().processing_callback = process_buffer_handler_; -} - -TEST_F(DrmOverlayValidatorTest, DontResetOriginalBufferIfProcessedIsInvalid) { - // This test checks that we dont manipulate overlay buffers in case Processing - // callback is not present. - gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5); - overlay_params_.back().buffer_size = overlay_rect_.size(); - overlay_params_.back().display_rect = overlay_rect_; - overlay_params_.back().crop_rect = crop_rect; - plane_list_.back().display_bounds = overlay_rect_; - plane_list_.back().crop_rect = crop_rect; - std::vector<uint32_t> xrgb_yuv_packed_formats = {DRM_FORMAT_XRGB8888, - DRM_FORMAT_UYVY}; - - ui::FakePlaneInfo primary_plane_info( - 100, 1 << 0, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888)); - ui::FakePlaneInfo overlay_info(101, 1 << 0, xrgb_yuv_packed_formats); - std::vector<ui::FakePlaneInfo> planes_info{primary_plane_info, overlay_info}; - plane_manager_->SetPlaneProperties(planes_info); - overlay_validator_->ClearCache(); - - overlay_validator_->TestPageFlip(overlay_params_, ui::OverlayPlaneList()); - - ui::OverlayPlaneList plane_list = - overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - // Scaling allows format conversion. - EXPECT_EQ(DRM_FORMAT_UYVY, - plane_list.back().buffer->GetFramebufferPixelFormat()); - plane_list_.back().processing_callback = base::Bind( - &DrmOverlayValidatorTest::ReturnNullBuffer, base::Unretained(this)); - - plane_list = overlay_validator_->PrepareBuffersForPageFlip(plane_list_); - EXPECT_EQ(plane_list_.back().buffer->GetFramebufferPixelFormat(), - plane_list.back().buffer->GetFramebufferPixelFormat()); - plane_list_.back().processing_callback = base::Bind( - &DrmOverlayValidatorTest::ProcessBuffer, base::Unretained(this)); -} - TEST_F(DrmOverlayValidatorTest, RejectBufferAllocationFail) { // Buffer allocation for scanout might fail. // In that case we should reject the overlay candidate.
diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc index 2ec7689..29447bc 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.cc +++ b/ui/ozone/platform/drm/gpu/drm_window.cc
@@ -74,10 +74,8 @@ void DrmWindow::SetBounds(const gfx::Rect& bounds) { TRACE_EVENT2("drm", "DrmWindow::SetBounds", "widget", widget_, "bounds", bounds.ToString()); - if (bounds_.size() != bounds.size()) { + if (bounds_.size() != bounds.size()) last_submitted_planes_.clear(); - overlay_validator_->ClearCache(); - } bounds_ = bounds; screen_manager_->UpdateControllerToWindowMapping(); @@ -136,8 +134,7 @@ return; } - last_submitted_planes_ = - overlay_validator_->PrepareBuffersForPageFlip(planes); + last_submitted_planes_ = planes; if (!controller_) { std::move(callback).Run(gfx::SwapResult::SWAP_ACK); @@ -223,8 +220,6 @@ UpdateCursorBuffers(); // We changed displays, so we want to update the cursor as well. ResetCursor(false /* bitmap_only */); - // Reset any cache in Validator. - overlay_validator_->ClearCache(); } void DrmWindow::UpdateCursorBuffers() {
diff --git a/ui/ozone/platform/drm/gpu/overlay_plane.h b/ui/ozone/platform/drm/gpu/overlay_plane.h index 1225049..cccf0759 100644 --- a/ui/ozone/platform/drm/gpu/overlay_plane.h +++ b/ui/ozone/platform/drm/gpu/overlay_plane.h
@@ -56,6 +56,7 @@ gfx::OverlayTransform plane_transform; gfx::Rect display_bounds; gfx::RectF crop_rect; + // TODO(dshwang): remove unused |processing_callback|. crbug.com/683347 ProcessBufferCallback processing_callback; };
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 144bd6ba..be51a99 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -658,7 +658,11 @@ sources += [ "widget/desktop_aura/desktop_window_tree_host_ozone.cc" ] } if (is_linux) { - sources += [ "style/platform_style_linux.cc" ] + sources += [ + "style/platform_style_linux.cc", + "widget/desktop_aura/window_event_filter.cc", + "widget/desktop_aura/window_event_filter.h", + ] } } }
diff --git a/ui/views/widget/desktop_aura/OWNERS b/ui/views/widget/desktop_aura/OWNERS index c216dcda..deec896 100644 --- a/ui/views/widget/desktop_aura/OWNERS +++ b/ui/views/widget/desktop_aura/OWNERS
@@ -1,2 +1,3 @@ # Elliot is the owner of all the X11 stuff. per-file *x11*=erg@chromium.org +per-file window_event_filter*=erg@chromium.org
diff --git a/ui/views/widget/desktop_aura/window_event_filter.cc b/ui/views/widget/desktop_aura/window_event_filter.cc new file mode 100644 index 0000000..7215f17 --- /dev/null +++ b/ui/views/widget/desktop_aura/window_event_filter.cc
@@ -0,0 +1,139 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/widget/desktop_aura/window_event_filter.h" + +#include "services/ui/public/interfaces/window_manager_constants.mojom.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/window.h" +#include "ui/aura/window_delegate.h" +#include "ui/aura/window_tree_host.h" +#include "ui/base/hit_test.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" +#include "ui/events/event.h" +#include "ui/events/event_utils.h" +#include "ui/views/linux_ui/linux_ui.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h" +#include "ui/views/widget/native_widget_aura.h" +#include "ui/views/widget/widget.h" + +namespace views { + +WindowEventFilter::WindowEventFilter(DesktopWindowTreeHost* window_tree_host) + : window_tree_host_(window_tree_host), click_component_(HTNOWHERE) {} + +WindowEventFilter::~WindowEventFilter() {} + +void WindowEventFilter::OnMouseEvent(ui::MouseEvent* event) { + if (event->type() != ui::ET_MOUSE_PRESSED) + return; + + aura::Window* target = static_cast<aura::Window*>(event->target()); + if (!target->delegate()) + return; + + int previous_click_component = HTNOWHERE; + int component = target->delegate()->GetNonClientComponent(event->location()); + if (event->IsLeftMouseButton()) { + previous_click_component = click_component_; + click_component_ = component; + } + + if (component == HTCAPTION) { + OnClickedCaption(event, previous_click_component); + } else if (component == HTMAXBUTTON) { + OnClickedMaximizeButton(event); + } else { + if (target->GetProperty(aura::client::kResizeBehaviorKey) & + ui::mojom::kResizeBehaviorCanResize) { + MaybeDispatchHostWindowDragMovement(component, event); + } + } +} + +void WindowEventFilter::OnClickedCaption(ui::MouseEvent* event, + int previous_click_component) { + aura::Window* target = static_cast<aura::Window*>(event->target()); + + if (event->IsMiddleMouseButton()) { + LinuxUI::NonClientMiddleClickAction action = + LinuxUI::MIDDLE_CLICK_ACTION_LOWER; + LinuxUI* linux_ui = LinuxUI::instance(); + if (linux_ui) + action = linux_ui->GetNonClientMiddleClickAction(); + + switch (action) { + case LinuxUI::MIDDLE_CLICK_ACTION_NONE: + break; + case LinuxUI::MIDDLE_CLICK_ACTION_LOWER: + LowerWindow(); + break; + case LinuxUI::MIDDLE_CLICK_ACTION_MINIMIZE: + window_tree_host_->Minimize(); + break; + case LinuxUI::MIDDLE_CLICK_ACTION_TOGGLE_MAXIMIZE: + if (target->GetProperty(aura::client::kResizeBehaviorKey) & + ui::mojom::kResizeBehaviorCanMaximize) + ToggleMaximizedState(); + break; + } + + event->SetHandled(); + return; + } + + if (event->IsLeftMouseButton() && event->flags() & ui::EF_IS_DOUBLE_CLICK) { + click_component_ = HTNOWHERE; + if ((target->GetProperty(aura::client::kResizeBehaviorKey) & + ui::mojom::kResizeBehaviorCanMaximize) && + previous_click_component == HTCAPTION) { + // Our event is a double click in the caption area in a window that can be + // maximized. We are responsible for dispatching this as a minimize/ + // maximize on X11 (Windows converts this to min/max events for us). + ToggleMaximizedState(); + event->SetHandled(); + return; + } + } + + MaybeDispatchHostWindowDragMovement(HTCAPTION, event); +} + +void WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) { + aura::Window* target = static_cast<aura::Window*>(event->target()); + views::Widget* widget = views::Widget::GetWidgetForNativeView(target); + if (!widget) + return; + + gfx::Rect display_work_area = + display::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area(); + gfx::Rect bounds = widget->GetWindowBoundsInScreen(); + if (event->IsMiddleMouseButton()) { + bounds.set_y(display_work_area.y()); + bounds.set_height(display_work_area.height()); + widget->SetBounds(bounds); + event->StopPropagation(); + } else if (event->IsRightMouseButton()) { + bounds.set_x(display_work_area.x()); + bounds.set_width(display_work_area.width()); + widget->SetBounds(bounds); + event->StopPropagation(); + } +} + +void WindowEventFilter::ToggleMaximizedState() { + if (window_tree_host_->IsMaximized()) + window_tree_host_->Restore(); + else + window_tree_host_->Maximize(); +} + +void WindowEventFilter::LowerWindow() {} + +void WindowEventFilter::MaybeDispatchHostWindowDragMovement( + int hittest, + ui::MouseEvent* event) {} + +} // namespace views
diff --git a/ui/views/widget/desktop_aura/window_event_filter.h b/ui/views/widget/desktop_aura/window_event_filter.h new file mode 100644 index 0000000..9d765cf --- /dev/null +++ b/ui/views/widget/desktop_aura/window_event_filter.h
@@ -0,0 +1,61 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_WINDOW_EVENT_FILTER_H_ +#define UI_VIEWS_WIDGET_DESKTOP_AURA_WINDOW_EVENT_FILTER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "ui/events/event_handler.h" +#include "ui/views/views_export.h" + +namespace views { +class DesktopWindowTreeHost; + +// An EventFilter that sets properties on native windows. +// The downstream effort to add wayland and x11 support with ozone +// are using this class (to be upstreamed later). +class VIEWS_EXPORT WindowEventFilter : public ui::EventHandler { + public: + explicit WindowEventFilter(DesktopWindowTreeHost* window_tree_host); + ~WindowEventFilter() override; + + // Overridden from ui::EventHandler: + void OnMouseEvent(ui::MouseEvent* event) override; + + private: + // Called when the user clicked the caption area. + void OnClickedCaption(ui::MouseEvent* event, int previous_click_component); + + // Called when the user clicked the maximize button. + void OnClickedMaximizeButton(ui::MouseEvent* event); + + void ToggleMaximizedState(); + + // Dispatches a message to the window manager to tell it to act as if a border + // or titlebar drag occurred with left mouse click. In case of X11, a + // _NET_WM_MOVERESIZE message is sent. + virtual void MaybeDispatchHostWindowDragMovement(int hittest, + ui::MouseEvent* event); + + // A signal to lower an attached to this filter window to the bottom of the + // stack. + virtual void LowerWindow(); + + DesktopWindowTreeHost* window_tree_host_; + + // The non-client component for the target of a MouseEvent. Mouse events can + // be destructive to the window tree, which can cause the component of a + // ui::EF_IS_DOUBLE_CLICK event to no longer be the same as that of the + // initial click. Acting on a double click should only occur for matching + // components. + int click_component_; + + DISALLOW_COPY_AND_ASSIGN(WindowEventFilter); +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_WINDOW_EVENT_FILTER_H_
diff --git a/ui/views/widget/desktop_aura/x11_window_event_filter.cc b/ui/views/widget/desktop_aura/x11_window_event_filter.cc index 5e01cd6..be85b35 100644 --- a/ui/views/widget/desktop_aura/x11_window_event_filter.cc +++ b/ui/views/widget/desktop_aura/x11_window_event_filter.cc
@@ -46,131 +46,28 @@ X11WindowEventFilter::X11WindowEventFilter( DesktopWindowTreeHost* window_tree_host) - : xdisplay_(gfx::GetXDisplay()), + : WindowEventFilter(window_tree_host), + xdisplay_(gfx::GetXDisplay()), xwindow_(window_tree_host->AsWindowTreeHost()->GetAcceleratedWidget()), - x_root_window_(DefaultRootWindow(xdisplay_)), - window_tree_host_(window_tree_host), - click_component_(HTNOWHERE) { -} + x_root_window_(DefaultRootWindow(xdisplay_)) {} X11WindowEventFilter::~X11WindowEventFilter() { } -void X11WindowEventFilter::OnMouseEvent(ui::MouseEvent* event) { - if (event->type() != ui::ET_MOUSE_PRESSED) - return; - - aura::Window* target = static_cast<aura::Window*>(event->target()); - if (!target->delegate()) - return; - - int previous_click_component = HTNOWHERE; - int component = - target->delegate()->GetNonClientComponent(event->location()); - if (event->IsLeftMouseButton()) { - previous_click_component = click_component_; - click_component_ = component; - } - - if (component == HTCAPTION) { - OnClickedCaption(event, previous_click_component); - } else if (component == HTMAXBUTTON) { - OnClickedMaximizeButton(event); - } else { - // Get the |x_root_window_| location out of the native event. - if (event->IsLeftMouseButton() && event->native_event()) { - const gfx::Point x_root_location = - ui::EventSystemLocationFromNative(event->native_event()); - if ((target->GetProperty(aura::client::kResizeBehaviorKey) & - ui::mojom::kResizeBehaviorCanResize) && - DispatchHostWindowDragMovement(component, x_root_location)) { - event->StopPropagation(); - } - } - } -} - -void X11WindowEventFilter::OnClickedCaption(ui::MouseEvent* event, - int previous_click_component) { - aura::Window* target = static_cast<aura::Window*>(event->target()); - - if (event->IsMiddleMouseButton()) { - LinuxUI::NonClientMiddleClickAction action = - LinuxUI::MIDDLE_CLICK_ACTION_LOWER; - LinuxUI* linux_ui = LinuxUI::instance(); - if (linux_ui) - action = linux_ui->GetNonClientMiddleClickAction(); - - switch (action) { - case LinuxUI::MIDDLE_CLICK_ACTION_NONE: - break; - case LinuxUI::MIDDLE_CLICK_ACTION_LOWER: - XLowerWindow(xdisplay_, xwindow_); - break; - case LinuxUI::MIDDLE_CLICK_ACTION_MINIMIZE: - window_tree_host_->Minimize(); - break; - case LinuxUI::MIDDLE_CLICK_ACTION_TOGGLE_MAXIMIZE: - if (target->GetProperty(aura::client::kResizeBehaviorKey) & - ui::mojom::kResizeBehaviorCanMaximize) - ToggleMaximizedState(); - break; - } - - event->SetHandled(); - return; - } - - if (event->IsLeftMouseButton() && event->flags() & ui::EF_IS_DOUBLE_CLICK) { - click_component_ = HTNOWHERE; - if ((target->GetProperty(aura::client::kResizeBehaviorKey) & - ui::mojom::kResizeBehaviorCanMaximize) && - previous_click_component == HTCAPTION) { - // Our event is a double click in the caption area in a window that can be - // maximized. We are responsible for dispatching this as a minimize/ - // maximize on X11 (Windows converts this to min/max events for us). - ToggleMaximizedState(); - event->SetHandled(); - return; - } - } - - // Get the |x_root_window_| location out of the native event. +void X11WindowEventFilter::MaybeDispatchHostWindowDragMovement( + int hittest, + ui::MouseEvent* event) { if (event->IsLeftMouseButton() && event->native_event()) { + // Get the |x_root_window_| location out of the native event. const gfx::Point x_root_location = ui::EventSystemLocationFromNative(event->native_event()); - if (DispatchHostWindowDragMovement(HTCAPTION, x_root_location)) + if (DispatchHostWindowDragMovement(hittest, x_root_location)) event->StopPropagation(); } } -void X11WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) { - aura::Window* target = static_cast<aura::Window*>(event->target()); - views::Widget* widget = views::Widget::GetWidgetForNativeView(target); - if (!widget) - return; - - gfx::Rect display_work_area = - display::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area(); - gfx::Rect bounds = widget->GetWindowBoundsInScreen(); - if (event->IsMiddleMouseButton()) { - bounds.set_y(display_work_area.y()); - bounds.set_height(display_work_area.height()); - widget->SetBounds(bounds); - event->StopPropagation(); - } else if (event->IsRightMouseButton()) { - bounds.set_x(display_work_area.x()); - bounds.set_width(display_work_area.width()); - widget->SetBounds(bounds); - event->StopPropagation(); - } -} - -void X11WindowEventFilter::ToggleMaximizedState() { - if (window_tree_host_->IsMaximized()) - window_tree_host_->Restore(); - else - window_tree_host_->Maximize(); +void X11WindowEventFilter::LowerWindow() { + XLowerWindow(xdisplay_, xwindow_); } bool X11WindowEventFilter::DispatchHostWindowDragMovement(
diff --git a/ui/views/widget/desktop_aura/x11_window_event_filter.h b/ui/views/widget/desktop_aura/x11_window_event_filter.h index 49aa5672..4fc53ea1 100644 --- a/ui/views/widget/desktop_aura/x11_window_event_filter.h +++ b/ui/views/widget/desktop_aura/x11_window_event_filter.h
@@ -13,10 +13,7 @@ #include "ui/events/event_handler.h" #include "ui/gfx/x/x11_types.h" #include "ui/views/views_export.h" - -namespace aura { -class Window; -} +#include "ui/views/widget/desktop_aura/window_event_filter.h" namespace gfx { class Point; @@ -26,26 +23,17 @@ class DesktopWindowTreeHost; // An EventFilter that sets properties on X11 windows. -class VIEWS_EXPORT X11WindowEventFilter : public ui::EventHandler { +class VIEWS_EXPORT X11WindowEventFilter : public WindowEventFilter { public: explicit X11WindowEventFilter(DesktopWindowTreeHost* window_tree_host); ~X11WindowEventFilter() override; - // Overridden from ui::EventHandler: - void OnMouseEvent(ui::MouseEvent* event) override; - private: - // Called when the user clicked the caption area. - void OnClickedCaption(ui::MouseEvent* event, - int previous_click_component); + // WindowEventFilter override: + void MaybeDispatchHostWindowDragMovement(int hittest, + ui::MouseEvent* event) override; + void LowerWindow() override; - // Called when the user clicked the maximize button. - void OnClickedMaximizeButton(ui::MouseEvent* event); - - void ToggleMaximizedState(); - - // Dispatches a _NET_WM_MOVERESIZE message to the window manager to tell it - // to act as if a border or titlebar drag occurred. bool DispatchHostWindowDragMovement(int hittest, const gfx::Point& screen_location); @@ -56,15 +44,6 @@ // The native root window. ::Window x_root_window_; - DesktopWindowTreeHost* window_tree_host_; - - // The non-client component for the target of a MouseEvent. Mouse events can - // be destructive to the window tree, which can cause the component of a - // ui::EF_IS_DOUBLE_CLICK event to no longer be the same as that of the - // initial click. Acting on a double click should only occur for matching - // components. - int click_component_; - DISALLOW_COPY_AND_ASSIGN(X11WindowEventFilter); };
diff --git a/ui/webui/resources/cr_elements/network/cellular_0.svg b/ui/webui/resources/cr_elements/chromeos/network/cellular_0.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/cellular_0.svg rename to ui/webui/resources/cr_elements/chromeos/network/cellular_0.svg
diff --git a/ui/webui/resources/cr_elements/network/cellular_1.svg b/ui/webui/resources/cr_elements/chromeos/network/cellular_1.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/cellular_1.svg rename to ui/webui/resources/cr_elements/chromeos/network/cellular_1.svg
diff --git a/ui/webui/resources/cr_elements/network/cellular_2.svg b/ui/webui/resources/cr_elements/chromeos/network/cellular_2.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/cellular_2.svg rename to ui/webui/resources/cr_elements/chromeos/network/cellular_2.svg
diff --git a/ui/webui/resources/cr_elements/network/cellular_3.svg b/ui/webui/resources/cr_elements/chromeos/network/cellular_3.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/cellular_3.svg rename to ui/webui/resources/cr_elements/chromeos/network/cellular_3.svg
diff --git a/ui/webui/resources/cr_elements/network/cellular_4.svg b/ui/webui/resources/cr_elements/chromeos/network/cellular_4.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/cellular_4.svg rename to ui/webui/resources/cr_elements/chromeos/network/cellular_4.svg
diff --git a/ui/webui/resources/cr_elements/network/compiled_resources2.gyp b/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp similarity index 70% rename from ui/webui/resources/cr_elements/network/compiled_resources2.gyp rename to ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp index b77b35b..77ed996 100644 --- a/ui/webui/resources/cr_elements/network/compiled_resources2.gyp +++ b/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp
@@ -9,11 +9,11 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', 'cr_onc_types', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'cr_network_icon_externs', - 'includes': ['../../../../../third_party/closure_compiler/include_js.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/include_js.gypi'], }, { 'target_name': 'cr_network_list', @@ -22,7 +22,7 @@ 'cr_network_list_types', 'cr_onc_types', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'cr_network_list_item', @@ -32,14 +32,14 @@ 'cr_network_list_types', 'cr_onc_types', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'cr_network_list_types', 'dependencies': [ 'cr_onc_types', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'cr_network_select', @@ -48,14 +48,14 @@ 'cr_network_list_types', 'cr_onc_types', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { 'target_name': 'cr_onc_types', 'dependencies': [ '<(EXTERNS_GYP):networking_private', ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'], }, ], }
diff --git a/ui/webui/resources/cr_elements/network/cr_network_icon.html b/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon.html similarity index 94% rename from ui/webui/resources/cr_elements/network/cr_network_icon.html rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_icon.html index 9936f489..0f24a9c 100644 --- a/ui/webui/resources/cr_elements/network/cr_network_icon.html +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon.html
@@ -1,7 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> -<link rel="import" href="chrome://resources/cr_elements/network/network_icons.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/network_icons.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <dom-module id="cr-network-icon">
diff --git a/ui/webui/resources/cr_elements/network/cr_network_icon.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_icon.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_icon.js
diff --git a/ui/webui/resources/cr_elements/network/cr_network_icon_externs.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_icon_externs.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list.html b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.html similarity index 84% rename from ui/webui/resources/cr_elements/network/cr_network_list.html rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_list.html index 0df1997..855875a 100644 --- a/ui/webui/resources/cr_elements/network/cr_network_list.html +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_list_item.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_scrollable_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_list_item.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.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/iron-list/iron-list.html">
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_list.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_list.js
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list_item.html b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.html similarity index 94% rename from ui/webui/resources/cr_elements/network/cr_network_list_item.html rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.html index ada6c354..8a15cdad 100644 --- a/ui/webui/resources/cr_elements/network/cr_network_list_item.html +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.html
@@ -3,8 +3,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys/iron-a11y-keys.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-icon-button/paper-icon-button-light.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list_item.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_list_item.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list_types.html b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_types.html similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_list_types.html rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_list_types.html
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list_types.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_types.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_list_types.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_list_types.js
diff --git a/ui/webui/resources/cr_elements/network/cr_network_select.html b/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html similarity index 77% rename from ui/webui/resources/cr_elements/network/cr_network_select.html rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html index 34a8e49..8fea14c 100644 --- a/ui/webui/resources/cr_elements/network/cr_network_select.html +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_network_list.html"> -<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_list.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <dom-module id="cr-network-select"> <template>
diff --git a/ui/webui/resources/cr_elements/network/cr_network_select.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_network_select.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js
diff --git a/ui/webui/resources/cr_elements/network/cr_onc_types.html b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.html similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_onc_types.html rename to ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.html
diff --git a/ui/webui/resources/cr_elements/network/cr_onc_types.js b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js similarity index 100% rename from ui/webui/resources/cr_elements/network/cr_onc_types.js rename to ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
diff --git a/ui/webui/resources/cr_elements/network/ethernet.svg b/ui/webui/resources/cr_elements/chromeos/network/ethernet.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/ethernet.svg rename to ui/webui/resources/cr_elements/chromeos/network/ethernet.svg
diff --git a/ui/webui/resources/cr_elements/network/network_icons.html b/ui/webui/resources/cr_elements/chromeos/network/network_icons.html similarity index 63% rename from ui/webui/resources/cr_elements/network/network_icons.html rename to ui/webui/resources/cr_elements/chromeos/network/network_icons.html index 8097dbf..f7633f0 100644 --- a/ui/webui/resources/cr_elements/network/network_icons.html +++ b/ui/webui/resources/cr_elements/chromeos/network/network_icons.html
@@ -7,16 +7,16 @@ <svg> <defs> <!-- Badges --> - <g id="badge-1x"><path d="M0 1h1V0h1v5H1V2H0M3 2h1v1H3V2zm1 1h1v1H4V3zM3 4h1v1H3V4zm2 0h1v1H5V4zm0-2h1v1H5V2z"/></g> - <g id="badge-3g"><path d="M9 0H5v5h4V2H7v1h1v1H6V1h3M3 3v2h1V0H0v1h3v1H1v1h2zM0 4h3v1H0V4z"/></g> - <g id="badge-4g"><path d="M3 4v1h1V0H3v3H0v1h3zM0 2h1v1H0V2zm1-1h1v1H1V1zm1-1h1v1H2V0zM9 0H5v5h4V2H7v1h1v1H6V1h3"/></g> - <g id="badge-edge"><path d="M0 0v5h3V4H1V3h1V2H1V1h2V0"/></g> - <g id="badge-evdo"><path d="M0 0v5h3V4H1V3h1V2H1V1h2V0M4 0h1v2H4V0zm1 2h1v2H5V2zm2 0h1v2H7V2zm1-2h1v2H8V0zM6 4h1v1H6V4z"/></g> - <g id="badge-gsm"><path d="M4 0H0v5h4V2H2v1h1v1H1V1h3"/></g> - <g id="badge-hspa"><path d="M0 0h1v2h2V0h1v5H3V3H1v2H0"/></g> - <g id="badge-hspa-plus"><path d="M0 0h1v2h2V0h1v5H3V3H1v2H0M7 1V0H6v1H5v1h1v1h1V2h1V1H7z"/></g> - <g id="badge-lte"><path d="M0 0v5h3V4H1V0M3 0h5v1H6v4H5V1H3M9 0v5h3V4h-2V3h1V2h-1V1h2V0"/></g> - <g id="badge-lte-advanced"><path d="M0 0v5h3V4H1V0M3 0h5v1H6v4H5V1H3M9 0v5h3V4h-2V3h1V2h-1V1h2V0M15 1V0h-1v1h-1v1h1v1h1V2h1V1h-1z"/></g> + <g id="badge-1x"><path d="M0 1h1V0h1v5H1V2H0M3 2h1v1H3V2zm1 1h1v1H4V3zM3 4h1v1H3V4zm2 0h1v1H5V4zm0-2h1v1H5V2z"></path></g> + <g id="badge-3g"><path d="M9 0H5v5h4V2H7v1h1v1H6V1h3M3 3v2h1V0H0v1h3v1H1v1h2zM0 4h3v1H0V4z"></path></g> + <g id="badge-4g"><path d="M3 4v1h1V0H3v3H0v1h3zM0 2h1v1H0V2zm1-1h1v1H1V1zm1-1h1v1H2V0zM9 0H5v5h4V2H7v1h1v1H6V1h3"></path></g> + <g id="badge-edge"><path d="M0 0v5h3V4H1V3h1V2H1V1h2V0"></path></g> + <g id="badge-evdo"><path d="M0 0v5h3V4H1V3h1V2H1V1h2V0M4 0h1v2H4V0zm1 2h1v2H5V2zm2 0h1v2H7V2zm1-2h1v2H8V0zM6 4h1v1H6V4z"></path></g> + <g id="badge-gsm"><path d="M4 0H0v5h4V2H2v1h1v1H1V1h3"></path></g> + <g id="badge-hspa"><path d="M0 0h1v2h2V0h1v5H3V3H1v2H0"></path></g> + <g id="badge-hspa-plus"><path d="M0 0h1v2h2V0h1v5H3V3H1v2H0M7 1V0H6v1H5v1h1v1h1V2h1V1H7z"></path></g> + <g id="badge-lte"><path d="M0 0v5h3V4H1V0M3 0h5v1H6v4H5V1H3M9 0v5h3V4h-2V3h1V2h-1V1h2V0"></path></g> + <g id="badge-lte-advanced"><path d="M0 0v5h3V4H1V0M3 0h5v1H6v4H5V1H3M9 0v5h3V4h-2V3h1V2h-1V1h2V0M15 1V0h-1v1h-1v1h1v1h1V2h1V1h-1z"></path></g> </defs> </svg> </iron-iconset-svg> @@ -25,8 +25,8 @@ <svg> <defs> <g id="badge-secure" fill-rule="evenodd"> - <path d="M1 4c0-.552.45-1 .99-1h4.02c.546 0 .99.444.99 1v3c0 .552-.45 1-.99 1H1.99C1.445 8 1 7.556 1 7V4zm2.5 1h1v1h-1V5z"/> - <path d="M2 1h1v3H2V1zm3 0h1v3H5V1zm.5-1v1h-3V0h3z"/> + <path d="M1 4c0-.552.45-1 .99-1h4.02c.546 0 .99.444.99 1v3c0 .552-.45 1-.99 1H1.99C1.445 8 1 7.556 1 7V4zm2.5 1h1v1h-1V5z"></path> + <path d="M2 1h1v3H2V1zm3 0h1v3H5V1zm.5-1v1h-3V0h3z"></path> </g> </defs> </svg>
diff --git a/ui/webui/resources/cr_elements/network/vpn.svg b/ui/webui/resources/cr_elements/chromeos/network/vpn.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/vpn.svg rename to ui/webui/resources/cr_elements/chromeos/network/vpn.svg
diff --git a/ui/webui/resources/cr_elements/network/wifi_0.svg b/ui/webui/resources/cr_elements/chromeos/network/wifi_0.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/wifi_0.svg rename to ui/webui/resources/cr_elements/chromeos/network/wifi_0.svg
diff --git a/ui/webui/resources/cr_elements/network/wifi_1.svg b/ui/webui/resources/cr_elements/chromeos/network/wifi_1.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/wifi_1.svg rename to ui/webui/resources/cr_elements/chromeos/network/wifi_1.svg
diff --git a/ui/webui/resources/cr_elements/network/wifi_2.svg b/ui/webui/resources/cr_elements/chromeos/network/wifi_2.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/wifi_2.svg rename to ui/webui/resources/cr_elements/chromeos/network/wifi_2.svg
diff --git a/ui/webui/resources/cr_elements/network/wifi_3.svg b/ui/webui/resources/cr_elements/chromeos/network/wifi_3.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/wifi_3.svg rename to ui/webui/resources/cr_elements/chromeos/network/wifi_3.svg
diff --git a/ui/webui/resources/cr_elements/network/wifi_4.svg b/ui/webui/resources/cr_elements/chromeos/network/wifi_4.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/wifi_4.svg rename to ui/webui/resources/cr_elements/chromeos/network/wifi_4.svg
diff --git a/ui/webui/resources/cr_elements/network/wifi_off.svg b/ui/webui/resources/cr_elements/chromeos/network/wifi_off.svg similarity index 100% rename from ui/webui/resources/cr_elements/network/wifi_off.svg rename to ui/webui/resources/cr_elements/chromeos/network/wifi_off.svg
diff --git a/ui/webui/resources/cr_elements/compiled_resources2.gyp b/ui/webui/resources/cr_elements/compiled_resources2.gyp index cd63239..7183950 100644 --- a/ui/webui/resources/cr_elements/compiled_resources2.gyp +++ b/ui/webui/resources/cr_elements/compiled_resources2.gyp
@@ -7,12 +7,12 @@ 'target_name': 'cr_elements_resources', 'type': 'none', 'dependencies': [ + 'chromeos/network/compiled_resources2.gyp:*', 'cr_action_menu/compiled_resources2.gyp:*', 'cr_dialog/compiled_resources2.gyp:*', 'cr_drawer/compiled_resources2.gyp:*', 'cr_expand_button/compiled_resources2.gyp:*', 'cr_profile_avatar_selector/compiled_resources2.gyp:*', - 'network/compiled_resources2.gyp:*', 'policy/compiled_resources2.gyp:*', ], },
diff --git a/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp b/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp index d1fc61e3..357d75a 100644 --- a/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp +++ b/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp
@@ -37,7 +37,7 @@ { 'target_name': 'cr_policy_network_behavior', 'dependencies': [ - '../network/compiled_resources2.gyp:cr_onc_types', + '../chromeos/network/compiled_resources2.gyp:cr_onc_types', 'cr_policy_indicator_behavior', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], @@ -45,7 +45,7 @@ { 'target_name': 'cr_policy_network_indicator', 'dependencies': [ - '../network/compiled_resources2.gyp:cr_onc_types', + '../chromeos/network/compiled_resources2.gyp:cr_onc_types', 'cr_policy_indicator_behavior', 'cr_policy_network_behavior', ],
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.html b/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.html index 82c6f905..eefd837 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.html +++ b/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.html
@@ -1 +1,2 @@ +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <script src="cr_policy_network_behavior.js"></script>
diff --git a/ui/webui/resources/cr_elements_images.grdp b/ui/webui/resources/cr_elements_images.grdp index 000fa26..b6f13a0 100644 --- a/ui/webui/resources/cr_elements_images.grdp +++ b/ui/webui/resources/cr_elements_images.grdp
@@ -26,30 +26,35 @@ file="images/icon_arrow_dropdown.svg" type="BINDATA" /> <if expr="chromeos"> <include name="IDR_CR_ELEMENTS_CELLULAR_0_SVG" - file="cr_elements/network/cellular_0.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/cellular_0.svg" + type="BINDATA" /> <include name="IDR_CR_ELEMENTS_CELLULAR_1_SVG" - file="cr_elements/network/cellular_1.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/cellular_1.svg" + type="BINDATA" /> <include name="IDR_CR_ELEMENTS_CELLULAR_2_SVG" - file="cr_elements/network/cellular_2.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/cellular_2.svg" + type="BINDATA" /> <include name="IDR_CR_ELEMENTS_CELLULAR_3_SVG" - file="cr_elements/network/cellular_3.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/cellular_3.svg" + type="BINDATA" /> <include name="IDR_CR_ELEMENTS_CELLULAR_4_SVG" - file="cr_elements/network/cellular_4.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/cellular_4.svg" + type="BINDATA" /> <include name="IDR_CR_ELEMENTS_ETHERNET_SVG" - file="cr_elements/network/ethernet.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/ethernet.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_VPN_SVG" - file="cr_elements/network/vpn.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/vpn.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_WIFI_0_SVG" - file="cr_elements/network/wifi_0.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/wifi_0.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_WIFI_1_SVG" - file="cr_elements/network/wifi_1.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/wifi_1.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_WIFI_2_SVG" - file="cr_elements/network/wifi_2.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/wifi_2.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_WIFI_3_SVG" - file="cr_elements/network/wifi_3.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/wifi_3.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_WIFI_4_SVG" - file="cr_elements/network/wifi_4.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/wifi_4.svg" type="BINDATA" /> <include name="IDR_CR_ELEMENTS_WIFI_OFF_SVG" - file="cr_elements/network/wifi_off.svg" type="BINDATA" /> + file="cr_elements/chromeos/network/wifi_off.svg" type="BINDATA" /> </if> </grit-part>
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index ef0d0c8..843031b8 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -42,44 +42,44 @@ file="../../webui/resources/cr_elements/cr_lazy_render/cr_lazy_render.js" type="chrome_html" /> <if expr="chromeos"> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_ICON_HTML" - file="../../webui/resources/cr_elements/network/cr_network_icon.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_ICON_HTML" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_icon.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_ICON_JS" - file="../../webui/resources/cr_elements/network/cr_network_icon.js" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_ICON_JS" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_icon.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_LIST_HTML" - file="../../webui/resources/cr_elements/network/cr_network_list.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_LIST_HTML" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_list.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_LIST_JS" - file="../../webui/resources/cr_elements/network/cr_network_list.js" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_LIST_JS" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_list.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_LIST_ITEM_HTML" - file="../../webui/resources/cr_elements/network/cr_network_list_item.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_LIST_ITEM_HTML" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_list_item.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_LIST_ITEM_JS" - file="../../webui/resources/cr_elements/network/cr_network_list_item.js" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_LIST_ITEM_JS" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_list_item.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_LIST_TYPES_HTML" - file="../../webui/resources/cr_elements/network/cr_network_list_types.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_LIST_TYPES_HTML" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_list_types.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_LIST_TYPES_JS" - file="../../webui/resources/cr_elements/network/cr_network_list_types.js" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_LIST_TYPES_JS" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_list_types.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_SELECT_HTML" - file="../../webui/resources/cr_elements/network/cr_network_select.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_SELECT_HTML" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_select.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_NETWORK_SELECT_JS" - file="../../webui/resources/cr_elements/network/cr_network_select.js" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_NETWORK_SELECT_JS" + file="../../webui/resources/cr_elements/chromeos/network/cr_network_select.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_ONC_TYPES_HTML" - file="../../webui/resources/cr_elements/network/cr_onc_types.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_ONC_TYPES_HTML" + file="../../webui/resources/cr_elements/chromeos/network/cr_onc_types.html" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_ONC_TYPES_JS" - file="../../webui/resources/cr_elements/network/cr_onc_types.js" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_ONC_TYPES_JS" + file="../../webui/resources/cr_elements/chromeos/network/cr_onc_types.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_NETWORK_ICONS_HTML" - file="../../webui/resources/cr_elements/network/network_icons.html" + <structure name="IDR_CR_ELEMENTS_CHROMEOS_NETWORK_ICONS_HTML" + file="../../webui/resources/cr_elements/chromeos/network/network_icons.html" type="chrome_html" preprocess="true" /> </if>
diff --git a/ui/webui/resources/js/cr.js b/ui/webui/resources/js/cr.js index 8cc8124..75a4e86 100644 --- a/ui/webui/resources/js/cr.js +++ b/ui/webui/resources/js/cr.js
@@ -357,7 +357,7 @@ * A variation of chrome.send, suitable for messages that expect a single * response from C++. * @param {string} methodName The name of the WebUI handler API. - * @param {...*} var_args Varibale number of arguments to be forwarded to the + * @param {...*} var_args Variable number of arguments to be forwarded to the * C++ call. * @return {!Promise} */
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp index 1f97fedd..938d6961 100644 --- a/ui/webui/resources/polymer_resources.grdp +++ b/ui/webui/resources/polymer_resources.grdp
@@ -449,24 +449,26 @@ <structure name="IDR_POLYMER_1_0_PAPER_CHECKBOX_PAPER_CHECKBOX_HTML" file="../../../third_party/polymer/v1_0/components-chromium/paper-checkbox/paper-checkbox.html" type="chrome_html" /> - <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_BEHAVIOR_EXTRACTED_JS" - file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-behavior-extracted.js" - type="chrome_html" /> - <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_BEHAVIOR_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-behavior.html" - type="chrome_html" /> - <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_COMMON_CSS" - file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-common.css" - type="chrome_html" /> - <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_SHARED_STYLES_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-shared-styles.html" - type="chrome_html" /> - <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_PAPER_DIALOG_EXTRACTED_JS" - file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog/paper-dialog-extracted.js" - type="chrome_html" /> - <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_PAPER_DIALOG_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog/paper-dialog.html" - type="chrome_html" /> + <if expr="chromeos"> + <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_BEHAVIOR_EXTRACTED_JS" + file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-behavior-extracted.js" + type="chrome_html" /> + <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_BEHAVIOR_HTML" + file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-behavior.html" + type="chrome_html" /> + <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_COMMON_CSS" + file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-common.css" + type="chrome_html" /> + <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_BEHAVIOR_PAPER_DIALOG_SHARED_STYLES_HTML" + file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog-behavior/paper-dialog-shared-styles.html" + type="chrome_html" /> + <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_PAPER_DIALOG_EXTRACTED_JS" + file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog/paper-dialog-extracted.js" + type="chrome_html" /> + <structure name="IDR_POLYMER_1_0_PAPER_DIALOG_PAPER_DIALOG_HTML" + file="../../../third_party/polymer/v1_0/components-chromium/paper-dialog/paper-dialog.html" + type="chrome_html" /> + </if> <structure name="IDR_POLYMER_1_0_PAPER_DRAWER_PANEL_PAPER_DRAWER_PANEL_EXTRACTED_JS" file="../../../third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js" type="chrome_html" />